[
  {
    "path": ".gitignore",
    "content": "ssdb-server*\nios\n888*.conf\nvar888*\n*.exe\n*.o\n*.a\n*.out\n*.class\ntmp\n.DS_Store\n*.pyc\nvar/*\nvar_*\nvar_slave/*\ndev_ssdb.conf*\ndev_slave.conf\n*.swp\n*_cpy_*\n*.dSYM*\nssdb-server\ntools/ssdb-dump\ntools/ssdb-bench\ntools/ssdb-repair\ntools/ssdb-migrate\ntools/leveldb-import\n_pack\nbuild_config.mk\nlog.txt\nrepair.log\nlog_slave.txt\nsrc/client/demo\nsrc/client/hello-ssdb\napi/cpp/SSDB_client.h\napi/cpp/test\napi/cpp/html\napi/php/a.php\napi/php/b.php\napi/php/c.php\napi/java/Test.java\nsrc/util/test_sorted_set\n\n"
  },
  {
    "path": "ChangeLog",
    "content": "* 1.9.9\n\t* Bug fixeds:\n\t\t- Fix binlog resource leak bug(2020-09-25)\n* 1.9.8\n\t* New features:\n\t\t- optimize hclear performance(2020-07-31)\n\t\t- ssdb-repair/ssdb-dump set leveldb.option.max_file_size to 32MB(2020-07-30)\n\t\t- Support multi auth password configs(2020-05-10)\n\t\t- Support IP v6(2020-02-15)\n\t\t- Add add_slave and del_slave command(2020-02-19)\n\t* Bug fixes:\n\t\t- Fix `hfix` bug(2020-08-10)\n* 1.9.7\n\t* New features:\n\t\t- Support slaveof command(2018-04-27)\n\t\t- Add hfix command(2018-11-21)\n\t* Bug fixes:\n\t\t- Fix queue/list replication bug(2019-01-02)\n\t\t- Fix logrotate issue when log to stdout/stderr(2018-06-05)\n\t\t- Fix coredump on exit(2018-07-18)\n\t\t- Fix startup blocked by BinlogQueue::find_last()(2018-08-08)\n* 1.9.6\n\t* New features:\n\t\t- ssdb-cli supports command history(2018-04-24)\n\t\t- Log slow query with WARN level(2017-11-08)\n\t\t- Upgrade leveldb to version 1.20, fix MANIFEST file too large issue(2017-09-25)\n\t* Incompatible changes:\n\t\t- The SSDB_KEY_LEN_MAX limit will be applied to KV, as described in docs(2017-11-08)\n\t* Bug fixes:\n\t\t- Fix Xcode 9, iOS SDK 11 compile issue(2017-11-20)\n\t\t- Fix Redis zrange, zrevrange, zremrangebyrank handle negative start/end bug(2017-12-05)\n* 1.9.5\n\t* New features:\n\t\t- C++ SDK add disconnected() method(2017-08-29)\n\t\t- ssdb-cli supports -a option to connect with password(2017-07-19)\n\t\t- Add slaveof.recv_timeout configuration(2017-05-03)\n\t* Incompatible changes:\n\t\t- setbit/getbit will be compatible with Redis, from LSB 0 to MSB 0(2017-05-16)\n\t* Bug fixes:\n\t\t- Fix ssdb-cli escape bug(2017-08-24)\n* 1.9.4\n\t* Incompatible changes:\n\t\t- Treat unsupported redis command's reply as REPLY_MULTI_BULK(2016-07-26)\n\t\t- Not writting pidfile when not running daemonized(2016-07-17)\n\t* New features:\n\t\t- Support readonly mode(2016-10-11)\n\t\t- Add OUT_OF_SYNC status, slave not flushdb when this status(2016-06-17)\n\t\t- Config default block_size as 32(2017-01-18)\n\t* Bug fixes:\n\t\t- Fix bug that busy expiration blocks setx request(2016-10-14)\n\t\t- Fix issues/1003, binlogs null pointer error caused by multi-threading during shutdown(2016-10-20)\n\t\t- Make RedisLink AUTH reply exactly as Redis(2017-01-17)\n* 1.9.3\n\t* New features:\n\t\t- Do not allow slave request binlogs with seq greater than max_seq(2016-03-18)\n\t\t- CLI comands with nagios output format(2016-03-06)\n\t\t- User can input binary data via ssdb-cli(2016-02-24)\n\t\t- Add ip_filter relative commands(2016-02-17)\n\t* Bug fixes:\n\t\t- Report error when setting ttl(expire) fail(2016-04-25)\n\t\t- Fix ttl not be deleted when deleting the only one key with ttl in the db, issue#885(2016-03-02)\n\t\t- Fix bug when connecting to multi masters, the slave saves only one master's status(2016-03-01)\n* 1.9.2\n\t* New features:\n\t\t- Binlog capacity can be set in config file(2016-01-14)\n\t\t- Provide zfix command to repair broken zset(2015-12-02)\n\t\t- Supports specifying slaveof.host in ssdb.conf(2015-11-23)\n\t\t- Do not allow flushdb when replication is in use(2015-11-16)\n\t\t- Provide server side flushdb(2015-09-17)\n\t\t- The slave will flush db when receive copy_begin(2015-07-28)\n\t* Incompatible changes:\n\t\t- Will not support db size for redis clients(2015-08-07)\n\t* Bug fixes:\n\t\t- Fix ttl not be deleted when deleting the only one key with ttl in the db, issue#885(2016-03-02)\n\t\t- Fix Logger bug on multi-threads, which halt the service for seconds(2016-01-25)\n\t\t- Fix bug when ssdb-cli is soft linked(2016-01-25)\n\t\t- Fix zclear infinite loop when data is broken(2015-12-02)\n\t\t- Fix setbit crash on very big offset(2015-11-17)\n\t\t- Fix Jedis zadd() score in scientific notation(2015-10-22)\n* 1.9.1\n\t* Incompatible changes:\n\t\t- zrank/zrrank return not_found(prev is error) if member not exists(2015-07-16)\n\t\t- PHP API zrank/zrrank return null(prev is false) if member not exists(2015-07-16)\n* 1.9.0\n\t* New features:\n\t\t- Update MAX_PACKET_SIZE to 128MB(2015-04-28)\n\t\t- Process most read commands in reader threads, not main thread(2015-04-28)\n\t\t- Add bitcount command, which is similar to Redis's bitcount(2015-04-15)\n\t\t- Add zpop_front, zpop_back command(2015-04-01)\n\t\t- Support static library build for iOS(2015-03-26)\n\t\t- Update options.max_open_files default value to 500(2015-03-15)\n\t\t- Add version command(2015-03-10)\n\t\t- Add rkeys command(2015-02-15)\n\t* Bug fixes:\n\t\t- Fix replication status display error(2015-04-09)\n* 1.8.1\n\t* Bug fixes:\n\t\t- Fix ttl bug(https://github.com/ideawu/ssdb/issues/628)(2015-03-14)\n* 1.8.0\n\t* New features:\n\t\t- Support SSDB style keys command through redis-cli(2014-12-08)\n\t\t- Replication supports AUTH(2014-12-01)\n\t\t- Sync qset operations(2014-11-05)\n\t\t- Add dbsize command(2014-11-02)\n\t\t- Include sync clients' stats in info(2014-11-02)\n\t\t- Refactor codes, separate into: libutil, libnet, libssdb(2014-11-02)\n\t* Bug fixes:\n\t\t- Fix bug when process dump and sync140 command with redis-cli(2015-01-27)\n* 1.7.0.1\n\t* New features:\n\t\t- Sync qset operations(2014-11-05)\n\t\t- *incr commands return error if value cannot be converted to integer(2014-10-24)\n\t\t- Include replication/sync stats in info(2014-10-23)\n\t\t- Add set_key_range, get_key_range(for KV) command(2014-10-22)\n\t\t- Add qset/lset command(sync won't work), rewrite Response(2014-10-19)\n* 1.7.0.0\n\t* New features:\n\t\t- export(ssdb-cli) command supports -i(interactive) option(2014-10-16)\n\t\t- ssdb-cli performance improved(2014-10-11)\n\t\t- Add export, import commands in ssdb-cli(2014-10-11)\n\t\t- Add qtrim_front, qtrim_back commands(2014-10-11)\n\t\t- ssdb-dump support auth(2014-10-10)\n\t\t- Add max_open_files config, default is 100(2014-10-08)\n\t\t- Add auth command(2014-09-20)\n\t\t- Enable qpop multi elements at a time(2014-09-16)\n\t* Incompatible changes:\n\t\t- Rewrite hexmem, this affects log messages(2014-10-10)\n* 1.6.8.8\n\t* New features:\n\t\t- Add hrlist, zrlist, qrlist commands(2014-07-27)\n\t\t- Add string/bit operations: getbit, setbit, bitcount, strlen, substr(getrange)(2014-06-07)\n\t\t- Put multi_*get commands to execute in worker thread(2014-06-17)\n\t* Incompatible changes:\n\t\t- Delete expireation info when deleting key(2014-06-28)\n\t\t- Inlucde links, total_calls in info cmd's reply(2014-06-17)\n\t\t- Rename redis_getrange command to getrange(2014-07-27)\n\t* Bug fixes:\n\t\t- Fix ssdb-bench bug on del bench(2014-08-21)\n\t\t- Return entrire string when substr's params are ommitted(2014-07-27)\n\t\t- Fix key expiration/ttl bug(2014-07-02)\n\t\t- Fix zRangeByScore(redis) bug(2014-06-28)\n\n* 1.6.8.7\n\t* New features:\n\t\t- Add string/bit operations: getbit, setbit, bitcount, strlen, substr(getrange)(2014-06-07)\n\t\t- Add expire command(2014-05-28)\n\t\t- Add ttl command(2014-05-26)\n\t\t- Add `flushdb list`(2014-05-22)\n\t\t- Support Android build\n\t\t- Add sync speed limit\n\n* 1.6.8.6 (2014-03-29)\n\t* New features:\n\t\t- Reduce round trip time for single request(2014-04-04)\n\t\t- Add zcount, zsum, zavg, zRemRangeByScore, zRemRangeByRank commands(2014-04-06)\n\t\t- Update redis-import.php to use Redis SCAN command if available(2014-04-07)\n\t\t- qpush/qpush_* accept multiple values(2014-04-13)\n\t\t- Don't push all expiration keys in memory, use less memory(2014-05-03)\n\t\t- Provide an option to disable binlog(2014-05-03)\n\t\t- Add hgetall command(2014-05-03)\n\t\t- Fix memory issue on cache_size larger than 2048(2014-05-12);\n\t* Incompatible changes:\n\t\t- qpush returns the length of the queue/list after the push operations(2014-04-10)\n\t\t- zrscan returns keys with score equal to score_start if key_start is ommit, previously it only returns keys with scores less than score_start(2014-04-23)\n\t* Bug fixes:\n\t\t- Redesign network flow, support very large batch commands\n\t\t- Fix bug on ssdb-dump that lose data, print out error message(2014-04-05)\n\n* 1.6.8.5 (2014-03-05)\n\t* New features:\n\t\t- Add qslice(lrange), qget(lindex, lget) commands.\n\t\t- Add getset, setnx commands.\n\t* Incompatible changes:\n\t\t- Queue/List data will be replicated(sync) to slaves.\n\t* Bug fixes:\n\t\t- Fix ssdb::Client::connect() possible memory leak\n\t\t- Fix ttl overflow bug\n\t\t- Fix nodejs api bug on binary data(2014-03-27)\n\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM ubuntu\nMAINTAINER wendal \"wendal1985@gmail.com\"\n\n# Set the env variable DEBIAN_FRONTEND to noninteractive\nENV DEBIAN_FRONTEND noninteractive\n\nRUN apt-get update && \\\n  apt-get install -y python2.7 && \\\n  apt-get install -y --force-yes git make gcc g++ autoconf && apt-get clean && \\\n  git clone --depth 1 https://github.com/ideawu/ssdb.git ssdb && \\\n  cd ssdb && make && make install && cp ssdb-server /usr/bin && \\\n  apt-get remove -y --force-yes git make gcc g++ autoconf && \\\n  apt-get autoremove -y && \\\n  rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \\\n  cp ssdb.conf /etc && cd .. && yes | rm -r ssdb\n\nRUN mkdir -p /var/lib/ssdb && \\\n  sed \\\n    -e 's@home.*@home /var/lib@' \\\n    -e 's/loglevel.*/loglevel info/' \\\n    -e 's@work_dir = .*@work_dir = /var/lib/ssdb@' \\\n    -e 's@pidfile = .*@pidfile = /run/ssdb.pid@' \\\n    -e 's@level:.*@level: info@' \\\n    -e 's@ip:.*@ip: 0.0.0.0@' \\\n    -i /etc/ssdb.conf\n\n\nENV TZ Asia/Shanghai\nEXPOSE 8888\nVOLUME /var/lib/ssdb\nENTRYPOINT /usr/bin/ssdb-server /etc/ssdb.conf\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2013 SSDB Authors\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n\n3. Neither the name of the SSDB nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "Makefile",
    "content": "PREFIX=/usr/local/ssdb\n\n$(shell sh build.sh 1>&2)\ninclude build_config.mk\n\nall:\n\tmkdir -p var var_slave\n\tchmod u+x \"${LEVELDB_PATH}/build_detect_platform\"\n\tchmod u+x deps/cpy/cpy\n\tchmod u+x tools/ssdb-cli\n\tcd \"${LEVELDB_PATH}\"; ${MAKE}\n\tcd src/util; ${MAKE}\n\tcd src/net; ${MAKE}\n\tcd src/client; ${MAKE}\n\tcd src/ssdb; ${MAKE}\n\tcd src; ${MAKE}\n\tcd tools; ${MAKE}\n\n.PHONY: ios\n\t\nios:\n\tcd \"${LEVELDB_PATH}\"; make clean; CXXFLAGS=-stdlib=libc++ ${MAKE} PLATFORM=IOS\n\tcd \"${SNAPPY_PATH}\"; make clean; make -f Makefile-ios\n\tmkdir -p ios\n\tmv ${LEVELDB_PATH}/out-ios-universal/libleveldb.a ios/libleveldb-ios.a\n\tmv ${SNAPPY_PATH}/libsnappy-ios.a ios/\n\tcd src/util; make clean; ${MAKE} -f Makefile-ios\n\tcd src/ssdb; make clean; ${MAKE} -f Makefile-ios\n\ninstall:\n\tmkdir -p ${PREFIX}\n\tmkdir -p ${PREFIX}/_cpy_\n\tmkdir -p ${PREFIX}/deps\n\tmkdir -p ${PREFIX}/var\n\tmkdir -p ${PREFIX}/var_slave\n\tcp -f ssdb-server ssdb.conf ssdb_slave.conf ${PREFIX}\n\tcp -rf api ${PREFIX}\n\tcp -rf \\\n\t\ttools/ssdb-bench \\\n\t\ttools/ssdb-cli tools/ssdb_cli \\\n\t\ttools/ssdb-cli.cpy tools/ssdb-dump \\\n\t\ttools/ssdb-repair \\\n\t\t${PREFIX}\n\tcp -rf deps/cpy ${PREFIX}/deps\n\tchmod 755 ${PREFIX}\n\trm -f ${PREFIX}/Makefile\n\nclean:\n\trm -f *.exe.stackdump\n\trm -rf api/cpy/_cpy_\n\trm -f api/python/SSDB.pyc\n\trm -rf db_test\n\tcd deps/cpy; ${MAKE} clean\n\tcd src/util; ${MAKE} clean\n\tcd src/ssdb; ${MAKE} clean\n\tcd src/net; ${MAKE} clean\n\tcd src; ${MAKE} clean\n\tcd tools; ${MAKE} clean\n\nclean_all: clean\n\tcd \"${LEVELDB_PATH}\"; ${MAKE} clean\n\trm -f ${JEMALLOC_PATH}/Makefile\n\tcd \"${SNAPPY_PATH}\"; ${MAKE} clean\n\trm -f ${SNAPPY_PATH}/Makefile\n\t\n"
  },
  {
    "path": "README.md",
    "content": "# SSDB - A Redis compatible NoSQL database stored on disk\n\n[![Author](https://img.shields.io/badge/author-@ideawu-blue.svg?style=flat)](http://www.ideawu.net/) [![Platform](https://img.shields.io/badge/platform-Linux,%20BSD,%20OS%20X,%20Windows-green.svg?style=flat)](https://github.com/ideawu/ssdb) [![NoSQL](https://img.shields.io/badge/db-NoSQL-pink.svg?tyle=flat)](https://github.com/ideawu/ssdb) [![License](https://img.shields.io/badge/license-New%20BSD-yellow.svg?style=flat)](LICENSE)\n\n\nSSDB is a high performace key-value(key-string, key-zset, key-hashmap) NoSQL database, __an alternative to Redis__.\n\nSSDB is stable, production-ready and is widely used by many Internet companies including QIHU 360.\n\n## Features\n\n* LevelDB client-server support, written in C/C++\n* Designed to store collection data\n* Persistent key-value, key-zset, key-map('hashmap'), key-list storage\n* Redis clients are supported\n* Client API supports including C++, PHP, Python, Cpy, Java, nodejs, Ruby, Go([see all](http://ssdb.io/docs/clients.html))\n* Persistent queue service\n* **Replication(master-slave), load balance**\n* GUI administration tool([phpssdbadmin](https://github.com/ssdb/phpssdbadmin))\n* Built-in CLI nagios self-checks\n\n## PHP client API example\n\n```php\n<?php\nrequire_once('SSDB.php');\n$ssdb = new SimpleSSDB('127.0.0.1', 8888);\n$resp = $ssdb->set('key', '123');\n$resp = $ssdb->get('key');\necho $resp; // output: 123\n```\n\n[More...](http://ssdb.io/docs/php/)\n\n\n## Who's using SSDB?\n\n[SSDB users...](http://ssdb.io/docs/users.html)\n\n\n## Documentation\n\n* [View online](http://ssdb.io/docs/)\n* [Contribute to SSDB documentation project](https://github.com/ideawu/ssdb-docs)\n\n## Compile and Install\n\n```sh\n$ wget --no-check-certificate https://github.com/ideawu/ssdb/archive/master.zip\n$ unzip master\n$ cd ssdb-master\n$ make\n$ #optional, install ssdb in /usr/local/ssdb\n$ sudo make install\n\n# start master\n$ ./ssdb-server ssdb.conf\n\n# or start as daemon\n$ ./ssdb-server -d ssdb.conf\n\n# ssdb command line\n$ ./tools/ssdb-cli -p 8888\n\n# stop ssdb-server\n$ ./ssdb-server ssdb.conf -s stop\n # for older version\n$ kill `cat ./var/ssdb.pid`\n```\n\nSee [Compile and Install wiki](http://ssdb.io/docs/install.html)\n\n## Performance\n\n### Typical performance\n\nTotal 1000 requests.\n\n```\nwriteseq  :    0.546 ms/op      178.7 MB/s\nwriterand :    0.519 ms/op      188.1 MB/s\nreadseq   :    0.304 ms/op      321.6 MB/s\nreadrand  :    0.310 ms/op      315.0 MB/s\n```\n\n### SSDB vs Redis\n\n![Benchmark vs Redis](http://ssdb.io/ssdb-vs-redis.png?github)\n\n[View full SSDB vs Redis benchmark charts...](http://ssdb.io/)\n\n### Concurrency benchmark\n\n```\n========== set ==========\nqps: 44251, time: 0.226 s\n========== get ==========\nqps: 55541, time: 0.180 s\n========== del ==========\nqps: 46080, time: 0.217 s\n========== hset ==========\nqps: 42338, time: 0.236 s\n========== hget ==========\nqps: 55601, time: 0.180 s\n========== hdel ==========\nqps: 46529, time: 0.215 s\n========== zset ==========\nqps: 37381, time: 0.268 s\n========== zget ==========\nqps: 41455, time: 0.241 s\n========== zdel ==========\nqps: 38792, time: 0.258 s\n```\n\nRun on a 2013 MacBook Pro 13 inch with Retina display.\n\n## Architecture\n\n![ssdb architecture](http://ssdb.io/ssdb.png)\n\n## Windows executable\n\nDownload ssdb-server.exe from here: https://github.com/ideawu/ssdb-bin\n\n\n## SSDB library for iOS\n\n\tmake ios\n\t# ls ios/\n\tinclude/ libleveldb-ios.a libsnappy-ios.a libssdb-ios.a libutil-ios.a\n\nDrag the static libraies files into your iOS project. Then add `ios/include` to your iOS project's __Header Search Paths__, which is set in __Build Settings__.\n\n## Links\n\n* [Author's homepage](http://www.ideawu.com/blog/)\n* [Cpy Scripting Language](https://github.com/ideawu/cpy)\n* [Google LevelDB](https://code.google.com/p/leveldb/)\n* [Lua ssdb client driver for the ngx_lua](https://github.com/LazyZhu/lua-resty-ssdb)\n* [Yet another ssdb client for Python](https://github.com/ifduyue/pyssdb)\n* [SSDB 中文文档](http://www.ideawu.net/blog/category/ssdb)\n\n## Changes made to LevelDB\n\nSee [Changes-Made-to-LevelDB wiki](https://github.com/ideawu/ssdb/wiki/Changes-Made-to-LevelDB)\n\n## LICENSE\n\nSSDB is licensed under [New BSD License](http://opensource.org/licenses/BSD-3-Clause), a very flexible license to use.\n\n## Authors\n\n@ideawu(wuzuyang1@gmail.com)\n\n## Thanks\n\n* 刘建辉, liujianhui@gongchang.com\n* wendal(陈镇铖), wendal1985@gmail.com, http://wendal.net \n"
  },
  {
    "path": "api/README.md",
    "content": "See https://github.com/ssdb\n"
  },
  {
    "path": "api/cpp/README.md",
    "content": "Moved to src/client\n\n"
  },
  {
    "path": "api/cpy/SSDB.cpy",
    "content": "/**\r\n * Copyright (c) 2012, ideawu\r\n * All rights reserved.\r\n * @author: ideawu\r\n * @link: http://www.ideawu.com/\r\n *\r\n * SSDB Cpy client SDK.\r\n */\r\n\r\nimport socket;\r\n\r\nclass SSDB_Response{\r\n\tfunction init(code='', data_or_message=null){\r\n\t\tthis.type = 'none';\r\n\t\tthis.code = code;\r\n\t\tthis.data = null;\r\n\t\tthis.message = null;\r\n\t\tthis.set(code, data_or_message);\r\n\t}\r\n\t\r\n\tfunction set(code, data_or_message=null){\r\n\t\tthis.code = code;\r\n\t\tif(code == 'ok'){\r\n\t\t\tthis.data = data_or_message;\r\n\t\t}else{\r\n\t\t\tif(isinstance(data_or_message, list)){\r\n\t\t\t\tif(len(data_or_message) > 0){\r\n\t\t\t\t\tthis.message = data_or_message[0];\r\n\t\t\t\t}\r\n\t\t\t}else{\r\n\t\t\t\tthis.message = data_or_message;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tfunction __repr__(){\r\n\t\treturn str(this.code) + ' ' + str(this.message) + ' ' + str(this.data);\r\n\t}\r\n\r\n\tfunction ok(){\r\n\t\treturn this.code == 'ok';\r\n\t}\r\n\r\n\tfunction not_found(){\r\n\t\treturn this.code == 'not_found';\r\n\t}\r\n\t\r\n\tfunction str_resp(resp){\r\n\t\tthis.type = 'val';\r\n\t\tif(resp[0] == 'ok'){\r\n\t\t\tif(len(resp) == 2){\r\n\t\t\t\tthis.set('ok', resp[1]);\r\n\t\t\t}else{\r\n\t\t\t\tthis.set('server_error', 'Invalid response');\r\n\t\t\t}\r\n\t\t}else{\r\n\t\t\tthis.set(resp[0], resp[1 .. ]);\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n\t\r\n\tfunction str_resp(resp){\r\n\t\tthis.type = 'val';\r\n\t\tif(resp[0] == 'ok'){\r\n\t\t\tif(len(resp) == 2){\r\n\t\t\t\tthis.set('ok', resp[1]);\r\n\t\t\t}else{\r\n\t\t\t\tthis.set('server_error', 'Invalid response');\r\n\t\t\t}\r\n\t\t}else{\r\n\t\t\tthis.set(resp[0], resp[1 .. ]);\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n\t\r\n\tfunction int_resp(resp){\r\n\t\tthis.type = 'val';\r\n\t\tif(resp[0] == 'ok'){\r\n\t\t\tif(len(resp) == 2){\r\n\t\t\t\ttry{\r\n\t\t\t\t\tval = int(resp[1]);\r\n\t\t\t\t\tthis.set('ok', val);\r\n\t\t\t\t}catch(Exception e){\r\n\t\t\t\t\tthis.set('server_error', 'Invalid response');\r\n\t\t\t\t}\r\n\t\t\t}else{\r\n\t\t\t\tthis.set('server_error', 'Invalid response');\r\n\t\t\t}\r\n\t\t}else{\r\n\t\t\tthis.set(resp[0], resp[1 .. ]);\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n\t\r\n\tfunction float_resp(resp){\r\n\t\tthis.type = 'val';\r\n\t\tif(resp[0] == 'ok'){\r\n\t\t\tif(len(resp) == 2){\r\n\t\t\t\ttry{\r\n\t\t\t\t\tval = float(resp[1]);\r\n\t\t\t\t\tthis.set('ok', val);\r\n\t\t\t\t}catch(Exception e){\r\n\t\t\t\t\tthis.set('server_error', 'Invalid response');\r\n\t\t\t\t}\r\n\t\t\t}else{\r\n\t\t\t\tthis.set('server_error', 'Invalid response');\r\n\t\t\t}\r\n\t\t}else{\r\n\t\t\tthis.set(resp[0], resp[1 .. ]);\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n\t\r\n\tfunction list_resp(resp){\r\n\t\tthis.type = 'list';\r\n\t\tthis.set(resp[0], resp[1 ..]);\r\n\t\treturn this;\r\n\t}\r\n\t\r\n\tfunction int_map_resp(resp){\r\n\t\tthis.type = 'map';\r\n\t\tif(resp[0] == 'ok'){\r\n\t\t\tif(len(resp) % 2 == 1){\r\n\t\t\t\tdata = {'index':[], 'items':{}};\r\n\t\t\t\tfor(i=1; i<len(resp); i+=2){\r\n\t\t\t\t\tk = resp[i];\r\n\t\t\t\t\tv = resp[i + 1];\r\n\t\t\t\t\ttry{\r\n\t\t\t\t\t\tv = int(v);\r\n\t\t\t\t\t}catch(Exception e){\r\n\t\t\t\t\t\tv = -1;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tdata['index'].append(k);\r\n\t\t\t\t\tdata['items'][k] = v;\r\n\t\t\t\t}\r\n\t\t\t\tthis.set('ok', data);\r\n\t\t\t}else{\r\n\t\t\t\tthis.set('server_error', 'Invalid response');\r\n\t\t\t}\r\n\t\t}else{\r\n\t\t\tthis.set(resp[0], resp[1 .. ]);\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n\t\r\n\tfunction str_map_resp(resp){\r\n\t\tthis.type = 'map';\r\n\t\tif(resp[0] == 'ok'){\r\n\t\t\tif(len(resp) % 2 == 1){\r\n\t\t\t\tdata = {'index':[], 'items':{}};\r\n\t\t\t\tfor(i=1; i<len(resp); i+=2){\r\n\t\t\t\t\tk = resp[i];\r\n\t\t\t\t\tv = resp[i + 1];\r\n\t\t\t\t\tdata['index'].append(k);\r\n\t\t\t\t\tdata['items'][k] = v;\r\n\t\t\t\t}\r\n\t\t\t\tthis.set('ok', data);\r\n\t\t\t}else{\r\n\t\t\t\tthis.set('server_error', 'Invalid response');\r\n\t\t\t}\r\n\t\t}else{\r\n\t\t\tthis.set(resp[0], resp[1 .. ]);\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n}\r\n\r\nclass SSDB{\r\n\tfunction init(host, port){\r\n\t\tthis.recv_buf = '';\r\n\t\tthis._closed = false;\r\n\t\tfamily = socket.AF_INET;\r\n\t\tif(host.find(':') != -1){\r\n\t\t\tfamily = socket.AF_INET6;\r\n\t\t}\r\n\t\tthis.sock = socket.socket(family, socket.SOCK_STREAM);\r\n\t\tthis.sock.connect(tuple([host, port]));\r\n\t\tthis.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1);\r\n\t}\r\n\r\n\tfunction close(){\r\n\t\tif(!this._closed){\r\n\t\t\tthis.sock.close();\r\n\t\t\tthis._closed = True;\r\n\t\t}\r\n\t}\r\n\r\n\tfunction closed(){\r\n\t\treturn this._closed;\r\n\t}\r\n\r\n\tfunction request(cmd, params=null){        \r\n\t\tif(params == null){\r\n\t\t\tparams = [];\r\n\t\t}\r\n\t\tparams = [cmd] + params;\r\n\t\tthis.send(params);\r\n\r\n\t\tresp = this.recv();\r\n\t\tif(resp == null){\r\n\t\t\treturn new SSDB_Response('error', 'Unknown error');\r\n\t\t}\r\n\t\tif(len(resp) == 0){\r\n\t\t\treturn new SSDB_Response('disconnected', 'Connection closed');\r\n\t\t}\r\n\t\t\r\n\t\tret = new SSDB_Response();\r\n\t\tswitch(cmd){\r\n\t\t\tcase 'ping':\r\n\t\t\tcase 'set':\r\n\t\t\tcase 'del':\r\n\t\t\tcase 'qset':\r\n\t\t\tcase 'zset':\r\n\t\t\tcase 'hset':\r\n\t\t\tcase 'qpush':\r\n\t\t\tcase 'qpush_front':\r\n\t\t\tcase 'qpush_back':\r\n\t\t\tcase 'zdel':\r\n\t\t\tcase 'hdel':\r\n\t\t\tcase 'multi_set':\r\n\t\t\tcase 'multi_del':\r\n\t\t\tcase 'multi_hset':\r\n\t\t\tcase 'multi_hdel':\r\n\t\t\tcase 'multi_zset':\r\n\t\t\tcase 'multi_zdel':\r\n\t\t\t\tif(len(resp) > 1){\r\n\t\t\t\t\treturn ret.int_resp(resp);\r\n\t\t\t\t}else{\r\n\t\t\t\t\treturn new SSDB_Response(resp[0], null);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'version':\r\n\t\t\tcase 'substr':\r\n\t\t\tcase 'get':\r\n\t\t\tcase 'getset':\r\n\t\t\tcase 'hget':\r\n\t\t\tcase 'qfront':\r\n\t\t\tcase 'qback':\r\n\t\t\tcase 'qget':\r\n\t\t\t\treturn ret.str_resp(resp);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'qpop':\r\n\t\t\tcase 'qpop_front':\r\n\t\t\tcase 'qpop_back':\r\n\t\t\t\tsize = 1;\r\n\t\t\t\ttry{\r\n\t\t\t\t\tsize = int(params[2]);\r\n\t\t\t\t}catch(Exception e){\r\n\t\t\t\t}\r\n\t\t\t\tif(size == 1){\r\n\t\t\t\t\treturn ret.str_resp(resp);\r\n\t\t\t\t}else{\r\n\t\t\t\t\treturn ret.list_resp(resp);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'dbsize':\r\n\t\t\tcase 'getbit':\r\n\t\t\tcase 'setbit':\r\n\t\t\tcase 'countbit':\r\n\t\t\tcase 'bitcount':\r\n\t\t\tcase 'strlen':\r\n\t\t\tcase 'ttl':\r\n\t\t\tcase 'expire':\r\n\t\t\tcase 'setnx':\r\n\t\t\tcase 'incr':\r\n\t\t\tcase 'decr':\r\n\t\t\tcase 'zincr':\r\n\t\t\tcase 'zdecr':\r\n\t\t\tcase 'hincr':\r\n\t\t\tcase 'hdecr':\r\n\t\t\tcase 'hsize':\r\n\t\t\tcase 'zsize':\r\n\t\t\tcase 'qsize':\r\n\t\t\tcase 'zget':\r\n\t\t\tcase 'zrank':\r\n\t\t\tcase 'zrrank':\r\n\t\t\tcase 'zsum':\r\n\t\t\tcase 'zcount':\r\n\t\t\tcase 'zremrangebyrank':\r\n\t\t\tcase 'zremrangebyscore':\r\n\t\t\tcase 'hclear':\r\n\t\t\tcase 'zclear':\r\n\t\t\tcase 'qclear':\r\n\t\t\tcase 'qpush':\r\n\t\t\tcase 'qpush_front':\r\n\t\t\tcase 'qpush_back':\r\n\t\t\tcase 'qtrim_front':\r\n\t\t\tcase 'qtrim_back':\r\n\t\t\t\treturn ret.int_resp(resp);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'zavg':\r\n\t\t\t\treturn ret.float_resp(resp);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'keys':\r\n\t\t\tcase 'rkeys':\r\n\t\t\tcase 'zkeys':\r\n\t\t\tcase 'zrkeys':\r\n\t\t\tcase 'hkeys':\r\n\t\t\tcase 'hrkeys':\r\n\t\t\tcase 'list':\r\n\t\t\tcase 'hlist':\r\n\t\t\tcase 'hrlist':\r\n\t\t\tcase 'zlist':\r\n\t\t\tcase 'zrlist':\r\n\t\t\t\treturn ret.list_resp(resp);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'scan':\r\n\t\t\tcase 'rscan':\r\n\t\t\tcase 'hgetall':\r\n\t\t\tcase 'hscan':\r\n\t\t\tcase 'hrscan':\r\n\t\t\t\treturn ret.str_map_resp(resp);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'zscan':\r\n\t\t\tcase 'zrscan':\r\n\t\t\tcase 'zrange':\r\n\t\t\tcase 'zrrange':\r\n\t\t\tcase 'zpop_front':\r\n\t\t\tcase 'zpop_back':\r\n\t\t\t\treturn ret.int_map_resp(resp);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'auth':\r\n            case 'exists':\r\n            case 'hexists':\r\n            case 'zexists':\r\n\t\t\t\treturn ret.int_resp(resp);\r\n                break;\r\n            case 'multi_exists':\r\n            case 'multi_hexists':\r\n            case 'multi_zexists':\r\n\t\t\t\treturn ret.int_map_resp(resp);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'multi_get':\r\n\t\t\tcase 'multi_hget':\r\n\t\t\t\treturn ret.str_map_resp(resp);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'multi_hsize':\r\n\t\t\tcase 'multi_zsize':\r\n\t\t\tcase 'multi_zget':\r\n\t\t\t\treturn ret.int_map_resp(resp);\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\treturn ret.list_resp(resp);\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t\treturn new SSDB_Response('error', 'Unknown error');\r\n\t}\r\n\r\n\tfunction send(data){\r\n\t\tps = [];\r\n\t\tforeach(data as p){\r\n\t\t\tp = str(p);\r\n\t\t\tps.append(str(len(p)));\r\n\t\t\tps.append(p);\r\n\t\t}\r\n\t\tnl = '\\n';\r\n\t\ts = nl.join(ps) + '\\n\\n';\r\n\t\t#print '> ' + repr(s);\r\n\t\ttry{\r\n\t\t\twhile(true){\r\n\t\t\t\tret = this.sock.send(s);\r\n\t\t\t\tif(ret == 0){\r\n\t\t\t\t\treturn -1;\r\n\t\t\t\t}\r\n\t\t\t\ts = s[ret .. ];\r\n\t\t\t\tif(len(s) == 0){\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}catch(socket.error e){\r\n\t\t\treturn -1;\r\n\t\t}\r\n\t\t//except socket.error as (val, msg):\r\n\t\treturn ret;\r\n\t}\r\n\r\n\tfunction net_read(){\r\n\t\ttry{\r\n\t\t\tdata = this.sock.recv(1024*8);\r\n\t\t\t#print '< ' + repr(data);\r\n\t\t}catch(Exception e){\r\n\t\t\tdata = '';\r\n\t\t}\r\n\t\tif(data == ''){\r\n\t\t\tthis.close();\r\n\t\t\treturn 0;\r\n\t\t}\r\n\t\tthis.recv_buf += data;\r\n\t\treturn len(data);\r\n\t}\r\n\r\n\tfunction recv(){\r\n\t\twhile(true){\r\n\t\t\tret = this.parse();\r\n\t\t\tif(ret == null){\r\n\t\t\t\tif(this.net_read() == 0){\r\n\t\t\t\t\treturn [];\r\n\t\t\t\t}\r\n\t\t\t}else{\r\n\t\t\t\treturn ret;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tfunction parse(){\r\n\t\t//if(len(this.recv_buf)){print 'recv_buf: ' + repr(this.recv_buf);}\r\n\t\tret = [];\r\n\t\tspos = 0;\r\n\t\tepos = 0;\r\n\t\twhile(true){\r\n\t\t\tspos = epos;\r\n\t\t\tepos = this.recv_buf.find('\\n', spos);\r\n\t\t\tif(epos == -1){\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tepos += 1;\r\n\t\t\tline = this.recv_buf[spos .. epos];\r\n\t\t\tspos = epos;\r\n\r\n\t\t\tif(line.strip() == ''){ // head end\r\n\t\t\t\tif(len(ret) == 0){\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}else{\r\n\t\t\t\t\tthis.recv_buf = this.recv_buf[spos .. ];\r\n\t\t\t\t\treturn ret;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\ttry{\r\n\t\t\t\tnum = int(line);\r\n\t\t\t}catch(Exception e){\r\n\t\t\t\t// error\r\n\t\t\t\treturn [];\r\n\t\t\t}\r\n\t\t\tepos = spos + num;\r\n\t\t\tif(epos > len(this.recv_buf)){\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tdata = this.recv_buf[spos .. epos];\r\n\t\t\tret.append(data);\r\n\r\n\t\t\tspos = epos;\r\n\t\t\tepos = this.recv_buf.find('\\n', spos);\r\n\t\t\tif(epos == -1){\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tepos += 1;\r\n\t\t}\r\n\r\n\t\treturn null;\r\n\t}\r\n}\r\n"
  },
  {
    "path": "api/cpy/demo.cpy",
    "content": "/**\n * Copyright (c) 2012, ideawu\n * All rights reserved.\n * @author: ideawu\n * @link: http://www.ideawu.com/\n *\n * SSDB cpy API demo.\n */\n\nimport SSDB.SSDB;\n\ntry{\n\tssdb = new SSDB('127.0.0.1', 8888);\n}catch(Exception e){\n\tprint e;\n\tsys.exit(0);\n}\n\nprint(ssdb.request('set', ['test', '123']));\nprint(ssdb.request('get', ['test']));\nprint(ssdb.request('incr', ['test', '1']));\nprint(ssdb.request('decr', ['test', '1']));\nprint(ssdb.request('scan', ['a', 'z', 10]));\nprint(ssdb.request('rscan', ['z', 'a', 10]));\nprint(ssdb.request('keys', ['a', 'z', 10]));\nprint(ssdb.request('del', ['test']));\nprint(ssdb.request('get', ['test']));\nprint \"\\n\";\nprint(ssdb.request('zset', ['test', 'a', 20]));\nprint(ssdb.request('zget', ['test', 'a']));\nprint(ssdb.request('zincr', ['test', 'a', 20]));\nprint(ssdb.request('zdecr', ['test', 'a', 20]));\nprint(ssdb.request('zscan', ['test', 'a', 0, 100, 10]));\nprint(ssdb.request('zrscan', ['test', 'a', 100, 0, 10]));\nprint(ssdb.request('zkeys', ['test', 'a', 0, 100, 10]));\nprint(ssdb.request('zdel', ['test', 'a']));\nprint(ssdb.request('zget', ['test', 'a']));\nprint \"\\n\";\nprint(ssdb.request('hset', ['test', 'a', 20]));\nprint(ssdb.request('hget', ['test', 'a']));\nprint(ssdb.request('hincr', ['test', 'a', 20]));\nprint(ssdb.request('hdecr', ['test', 'a', 20]));\nprint(ssdb.request('hscan', ['test', '0', 'z', 10]));\nprint(ssdb.request('hrscan', ['test', 'z', '0', 10]));\nprint(ssdb.request('hkeys', ['test', '0', 'z', 10]));\nprint(ssdb.request('hdel', ['test', 'a']));\nprint(ssdb.request('hget', ['test', 'a']));\nprint \"\\n\";\n"
  },
  {
    "path": "api/php/SSDB.php",
    "content": "<?php\n/**\n * Copyright (c) 2012, ideawu\n * All rights reserved.\n * @author: ideawu\n * @link: http://www.ideawu.com/\n *\n * SSDB PHP client SDK.\n */\n\nclass SSDBException extends Exception\n{\n}\n\nclass SSDBTimeoutException extends SSDBException\n{\n}\n\n/**\n * All methods(except *exists) returns false on error,\n * so one should use Identical(if($ret === false)) to test the return value.\n */\nclass SimpleSSDB extends SSDB\n{\n\tfunction __construct($host, $port, $timeout_ms=2000){\n\t\tparent::__construct($host, $port, $timeout_ms);\n\t\t$this->easy();\n\t}\n}\n\nclass SSDB_Response\n{\n\tpublic $cmd;\n\tpublic $code;\n\tpublic $data = null;\n\tpublic $message;\n\n\tfunction __construct($code='ok', $data_or_message=null){\n\t\t$this->code = $code;\n\t\tif($code == 'ok'){\n\t\t\t$this->data = $data_or_message;\n\t\t}else{\n\t\t\t$this->message = $data_or_message;\n\t\t}\n\t}\n\n\tfunction __toString(){\n\t\tif($this->code == 'ok'){\n\t\t\t$s = $this->data === null? '' : json_encode($this->data);\n\t\t}else{\n\t\t\t$s = $this->message;\n\t\t}\n\t\treturn sprintf('%-13s %12s %s', $this->cmd, $this->code, $s);\n\t}\n\n\tfunction ok(){\n\t\treturn $this->code == 'ok';\n\t}\n\n\tfunction not_found(){\n\t\treturn $this->code == 'not_found';\n\t}\n}\n\n// Depricated, use SimpleSSDB instead!\nclass SSDB\n{\n\tprivate $debug = false;\n\tpublic $sock = null;\n\tprivate $_closed = false;\n\tprivate $recv_buf = '';\n\tprivate $_easy = false;\n\tpublic $last_resp = null;\n\n\tfunction __construct($host, $port, $timeout_ms=2000){\n\t\t$timeout_f = (float)$timeout_ms/1000;\n\t\t$this->sock = @stream_socket_client(\"[$host]:$port\", $errno, $errstr, $timeout_f);\n\t\tif(!$this->sock){\n\t\t\tthrow new SSDBException(\"$errno: $errstr\");\n\t\t}\n\t\t$timeout_sec = intval($timeout_ms/1000);\n\t\t$timeout_usec = ($timeout_ms - $timeout_sec * 1000) * 1000;\n\t\t@stream_set_timeout($this->sock, $timeout_sec, $timeout_usec);\n\t\tif(function_exists('stream_set_chunk_size')){\n\t\t\t@stream_set_chunk_size($this->sock, 1024 * 1024);\n\t\t}\n\t}\n\t\n\tfunction set_timeout($timeout_ms){\n\t\t$timeout_sec = intval($timeout_ms/1000);\n\t\t$timeout_usec = ($timeout_ms - $timeout_sec * 1000) * 1000;\n\t\t@stream_set_timeout($this->sock, $timeout_sec, $timeout_usec);\n\t}\n\t\n\t/**\n\t * After this method invoked with yesno=true, all requesting methods\n\t * will not return a SSDB_Response object.\n\t * And some certain methods like get/zget will return false\n\t * when response is not ok(not_found, etc)\n\t */\n\tfunction easy(){\n\t\t$this->_easy = true;\n\t}\n\n\tfunction close(){\n\t\tif(!$this->_closed){\n\t\t\t@fclose($this->sock);\n\t\t\t$this->_closed = true;\n\t\t\t$this->sock = null;\n\t\t}\n\t}\n\n\tfunction closed(){\n\t\treturn $this->_closed;\n\t}\n\n\tprivate $batch_mode = false;\n\tprivate $batch_cmds = array();\n\n\tfunction batch(){\n\t\t$this->batch_mode = true;\n\t\t$this->batch_cmds = array();\n\t\treturn $this;\n\t}\n\n\tfunction multi(){\n\t\treturn $this->batch();\n\t}\n\n\tfunction exec(){\n\t\t$ret = array();\n\t\tforeach($this->batch_cmds as $op){\n\t\t\tlist($cmd, $params) = $op;\n\t\t\t$this->send_req($cmd, $params);\n\t\t}\n\t\tforeach($this->batch_cmds as $op){\n\t\t\tlist($cmd, $params) = $op;\n\t\t\t$resp = $this->recv_resp($cmd, $params);\n\t\t\t$resp = $this->check_easy_resp($cmd, $resp);\n\t\t\t$ret[] = $resp;\n\t\t}\n\t\t$this->batch_mode = false;\n\t\t$this->batch_cmds = array();\n\t\treturn $ret;\n\t}\n\t\n\tfunction request(){\n\t\t$args = func_get_args();\n\t\t$cmd = array_shift($args);\n\t\treturn $this->__call($cmd, $args);\n\t}\n\t\n\tprivate $async_auth_password = null;\n\t\n\tfunction auth($password){\n\t\t$this->async_auth_password = $password;\n\t\treturn null;\n\t}\n\n\tfunction __call($cmd, $params=array()){\n\t\t$cmd = strtolower($cmd);\n\t\tif($this->async_auth_password !== null){\n\t\t\t$pass = $this->async_auth_password;\n\t\t\t$this->async_auth_password = null;\n\t\t\t$auth = $this->__call('auth', array($pass));\n\t\t\tif($auth !== true){\n\t\t\t\tthrow new Exception(\"Authentication failed\");\n\t\t\t}\n\t\t}\n\n\t\tif($this->batch_mode){\n\t\t\t$this->batch_cmds[] = array($cmd, $params);\n\t\t\treturn $this;\n\t\t}\n\n\t\ttry{\n\t\t\tif($this->send_req($cmd, $params) === false){\n\t\t\t\t$resp = new SSDB_Response('error', 'send error');\n\t\t\t}else{\n\t\t\t\t$resp = $this->recv_resp($cmd, $params);\n\t\t\t}\n\t\t}catch(SSDBException $e){\n\t\t\tif($this->_easy){\n\t\t\t\tthrow $e;\n\t\t\t}else{\n\t\t\t\t$resp = new SSDB_Response('error', $e->getMessage());\n\t\t\t}\n\t\t}\n\n\t\tif($resp->code == 'noauth'){\n\t\t\t$msg = $resp->message;\n\t\t\tthrow new Exception($msg);\n\t\t}\n\t\t\n\t\t$resp = $this->check_easy_resp($cmd, $resp);\n\t\treturn $resp;\n\t}\n\n\tprivate function check_easy_resp($cmd, $resp){\n\t\t$this->last_resp = $resp;\n\t\tif($this->_easy){\n\t\t\tif($resp->not_found()){\n\t\t\t\treturn NULL;\n\t\t\t}else if(!$resp->ok() && !is_array($resp->data)){\n\t\t\t\treturn false;\n\t\t\t}else{\n\t\t\t\treturn $resp->data;\n\t\t\t}\n\t\t}else{\n\t\t\t$resp->cmd = $cmd;\n\t\t\treturn $resp;\n\t\t}\n\t}\n\n\tfunction multi_set($kvs=array()){\n\t\t$args = array();\n\t\tforeach($kvs as $k=>$v){\n\t\t\t$args[] = $k;\n\t\t\t$args[] = $v;\n\t\t}\n\t\treturn $this->__call(__FUNCTION__, $args);\n\t}\n\n\tfunction multi_hset($name, $kvs=array()){\n\t\t$args = array($name);\n\t\tforeach($kvs as $k=>$v){\n\t\t\t$args[] = $k;\n\t\t\t$args[] = $v;\n\t\t}\n\t\treturn $this->__call(__FUNCTION__, $args);\n\t}\n\n\tfunction multi_zset($name, $kvs=array()){\n\t\t$args = array($name);\n\t\tforeach($kvs as $k=>$v){\n\t\t\t$args[] = $k;\n\t\t\t$args[] = $v;\n\t\t}\n\t\treturn $this->__call(__FUNCTION__, $args);\n\t}\n\n\tfunction incr($key, $val=1){\n\t\t$args = func_get_args();\n\t\treturn $this->__call(__FUNCTION__, $args);\n\t}\n\n\tfunction decr($key, $val=1){\n\t\t$args = func_get_args();\n\t\treturn $this->__call(__FUNCTION__, $args);\n\t}\n\n\tfunction zincr($name, $key, $score=1){\n\t\t$args = func_get_args();\n\t\treturn $this->__call(__FUNCTION__, $args);\n\t}\n\n\tfunction zdecr($name, $key, $score=1){\n\t\t$args = func_get_args();\n\t\treturn $this->__call(__FUNCTION__, $args);\n\t}\n\n\tfunction zadd($key, $score, $value){\n\t\t$args = array($key, $value, $score);\n\t\treturn $this->__call('zset', $args);\n\t}\n\n\tfunction zRevRank($name, $key){\n\t\t$args = func_get_args();\n\t\treturn $this->__call(\"zrrank\", $args);\n\t}\n\n\tfunction zRevRange($name, $offset, $limit){\n\t\t$args = func_get_args();\n\t\treturn $this->__call(\"zrrange\", $args);\n\t}\n\n\tfunction hincr($name, $key, $val=1){\n\t\t$args = func_get_args();\n\t\treturn $this->__call(__FUNCTION__, $args);\n\t}\n\n\tfunction hdecr($name, $key, $val=1){\n\t\t$args = func_get_args();\n\t\treturn $this->__call(__FUNCTION__, $args);\n\t}\n\n\tprivate function send_req($cmd, $params){\n\t\t$req = array($cmd);\n\t\tforeach($params as $p){\n\t\t\tif(is_array($p)){\n\t\t\t\t$req = array_merge($req, $p);\n\t\t\t}else{\n\t\t\t\t$req[] = $p;\n\t\t\t}\n\t\t}\n\t\treturn $this->send($req);\n\t}\n\n\tprivate function recv_resp($cmd, $params){\n\t\t$resp = $this->recv();\n\t\tif($resp === false){\n\t\t\treturn new SSDB_Response('error', 'Unknown error');\n\t\t}else if(!$resp){\n\t\t\treturn new SSDB_Response('disconnected', 'Connection closed');\n\t\t}\n\t\tif($resp[0] == 'noauth'){\n\t\t\t$errmsg = isset($resp[1])? $resp[1] : '';\n\t\t\treturn new SSDB_Response($resp[0], $errmsg);\n\t\t}\n\t\tswitch($cmd){\n\t\t\tcase 'dbsize':\n\t\t\tcase 'ping':\n\t\t\tcase 'qset':\n\t\t\tcase 'getbit':\n\t\t\tcase 'setbit':\n\t\t\tcase 'countbit':\n\t\t\tcase 'strlen':\n\t\t\tcase 'set':\n\t\t\tcase 'setx':\n\t\t\tcase 'setnx':\n\t\t\tcase 'zset':\n\t\t\tcase 'hset':\n\t\t\tcase 'qpush':\n\t\t\tcase 'qpush_front':\n\t\t\tcase 'qpush_back':\n\t\t\tcase 'qtrim_front':\n\t\t\tcase 'qtrim_back':\n\t\t\tcase 'del':\n\t\t\tcase 'zdel':\n\t\t\tcase 'hdel':\n\t\t\tcase 'hsize':\n\t\t\tcase 'zsize':\n\t\t\tcase 'qsize':\n\t\t\tcase 'hclear':\n\t\t\tcase 'zclear':\n\t\t\tcase 'qclear':\n\t\t\tcase 'multi_set':\n\t\t\tcase 'multi_del':\n\t\t\tcase 'multi_hset':\n\t\t\tcase 'multi_hdel':\n\t\t\tcase 'multi_zset':\n\t\t\tcase 'multi_zdel':\n\t\t\tcase 'incr':\n\t\t\tcase 'decr':\n\t\t\tcase 'zincr':\n\t\t\tcase 'zdecr':\n\t\t\tcase 'hincr':\n\t\t\tcase 'hdecr':\n\t\t\tcase 'zget':\n\t\t\tcase 'zrank':\n\t\t\tcase 'zrrank':\n\t\t\tcase 'zcount':\n\t\t\tcase 'zsum':\n\t\t\tcase 'zremrangebyrank':\n\t\t\tcase 'zremrangebyscore':\n\t\t\tcase 'ttl':\n\t\t\tcase 'expire':\n\t\t\t\tif($resp[0] == 'ok'){\n\t\t\t\t\t$val = isset($resp[1])? intval($resp[1]) : 0;\n\t\t\t\t\treturn new SSDB_Response($resp[0], $val);\n\t\t\t\t}else{\n\t\t\t\t\t$errmsg = isset($resp[1])? $resp[1] : '';\n\t\t\t\t\treturn new SSDB_Response($resp[0], $errmsg);\n\t\t\t\t}\n\t\t\tcase 'zavg':\n\t\t\t\tif($resp[0] == 'ok'){\n\t\t\t\t\t$val = isset($resp[1])? floatval($resp[1]) : (float)0;\n\t\t\t\t\treturn new SSDB_Response($resp[0], $val);\n\t\t\t\t}else{\n\t\t\t\t\t$errmsg = isset($resp[1])? $resp[1] : '';\n\t\t\t\t\treturn new SSDB_Response($resp[0], $errmsg);\n\t\t\t\t}\n\t\t\tcase 'get':\n\t\t\tcase 'substr':\n\t\t\tcase 'getset':\n\t\t\tcase 'hget':\n\t\t\tcase 'qget':\n\t\t\tcase 'qfront':\n\t\t\tcase 'qback':\n\t\t\t\tif($resp[0] == 'ok'){\n\t\t\t\t\tif(count($resp) == 2){\n\t\t\t\t\t\treturn new SSDB_Response('ok', $resp[1]);\n\t\t\t\t\t}else{\n\t\t\t\t\t\treturn new SSDB_Response('server_error', 'Invalid response');\n\t\t\t\t\t}\n\t\t\t\t}else{\n\t\t\t\t\t$errmsg = isset($resp[1])? $resp[1] : '';\n\t\t\t\t\treturn new SSDB_Response($resp[0], $errmsg);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'qpop':\n\t\t\tcase 'qpop_front':\n\t\t\tcase 'qpop_back':\n\t\t\t\tif($resp[0] == 'ok'){\n\t\t\t\t\t$size = 1;\n\t\t\t\t\tif(isset($params[1])){\n\t\t\t\t\t\t$size = intval($params[1]);\n\t\t\t\t\t}\n\t\t\t\t\tif($size <= 1){\n\t\t\t\t\t\tif(count($resp) == 2){\n\t\t\t\t\t\t\treturn new SSDB_Response('ok', $resp[1]);\n\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\treturn new SSDB_Response('server_error', 'Invalid response');\n\t\t\t\t\t\t}\n\t\t\t\t\t}else{\n\t\t\t\t\t\t$data = array_slice($resp, 1);\n\t\t\t\t\t\treturn new SSDB_Response('ok', $data);\n\t\t\t\t\t}\n\t\t\t\t}else{\n\t\t\t\t\t$errmsg = isset($resp[1])? $resp[1] : '';\n\t\t\t\t\treturn new SSDB_Response($resp[0], $errmsg);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'keys':\n\t\t\tcase 'zkeys':\n\t\t\tcase 'hkeys':\n\t\t\tcase 'hlist':\n\t\t\tcase 'zlist':\n\t\t\tcase 'qslice':\n\t\t\t\tif($resp[0] == 'ok'){\n\t\t\t\t\t$data = array();\n\t\t\t\t\tif($resp[0] == 'ok'){\n\t\t\t\t\t\t$data = array_slice($resp, 1);\n\t\t\t\t\t}\n\t\t\t\t\treturn new SSDB_Response($resp[0], $data);\n\t\t\t\t}else{\n\t\t\t\t\t$errmsg = isset($resp[1])? $resp[1] : '';\n\t\t\t\t\treturn new SSDB_Response($resp[0], $errmsg);\n\t\t\t\t}\n\t\t\tcase 'auth':\n\t\t\tcase 'exists':\n\t\t\tcase 'hexists':\n\t\t\tcase 'zexists':\n\t\t\t\tif($resp[0] == 'ok'){\n\t\t\t\t\tif(count($resp) == 2){\n\t\t\t\t\t\treturn new SSDB_Response('ok', (bool)$resp[1]);\n\t\t\t\t\t}else{\n\t\t\t\t\t\treturn new SSDB_Response('server_error', 'Invalid response');\n\t\t\t\t\t}\n\t\t\t\t}else{\n\t\t\t\t\t$errmsg = isset($resp[1])? $resp[1] : '';\n\t\t\t\t\treturn new SSDB_Response($resp[0], $errmsg);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'multi_exists':\n\t\t\tcase 'multi_hexists':\n\t\t\tcase 'multi_zexists':\n\t\t\t\tif($resp[0] == 'ok'){\n\t\t\t\t\tif(count($resp) % 2 == 1){\n\t\t\t\t\t\t$data = array();\n\t\t\t\t\t\tfor($i=1; $i<count($resp); $i+=2){\n\t\t\t\t\t\t\t$data[$resp[$i]] = (bool)$resp[$i + 1];\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn new SSDB_Response('ok', $data);\n\t\t\t\t\t}else{\n\t\t\t\t\t\treturn new SSDB_Response('server_error', 'Invalid response');\n\t\t\t\t\t}\n\t\t\t\t}else{\n\t\t\t\t\t$errmsg = isset($resp[1])? $resp[1] : '';\n\t\t\t\t\treturn new SSDB_Response($resp[0], $errmsg);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'scan':\n\t\t\tcase 'rscan':\n\t\t\tcase 'zscan':\n\t\t\tcase 'zrscan':\n\t\t\tcase 'zrange':\n\t\t\tcase 'zrrange':\n\t\t\tcase 'hscan':\n\t\t\tcase 'hrscan':\n\t\t\tcase 'hgetall':\n\t\t\tcase 'multi_hsize':\n\t\t\tcase 'multi_zsize':\n\t\t\tcase 'multi_get':\n\t\t\tcase 'multi_hget':\n\t\t\tcase 'multi_zget':\n\t\t\tcase 'zpop_front':\n\t\t\tcase 'zpop_back':\n\t\t\t\tif($resp[0] == 'ok'){\n\t\t\t\t\tif(count($resp) % 2 == 1){\n\t\t\t\t\t\t$data = array();\n\t\t\t\t\t\tfor($i=1; $i<count($resp); $i+=2){\n\t\t\t\t\t\t\tif($cmd[0] == 'z'){\n\t\t\t\t\t\t\t\t$data[$resp[$i]] = intval($resp[$i + 1]);\n\t\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t\t$data[$resp[$i]] = $resp[$i + 1];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn new SSDB_Response('ok', $data);\n\t\t\t\t\t}else{\n\t\t\t\t\t\treturn new SSDB_Response('server_error', 'Invalid response');\n\t\t\t\t\t}\n\t\t\t\t}else{\n\t\t\t\t\t$errmsg = isset($resp[1])? $resp[1] : '';\n\t\t\t\t\treturn new SSDB_Response($resp[0], $errmsg);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn new SSDB_Response($resp[0], array_slice($resp, 1));\n\t\t}\n\t\treturn new SSDB_Response('error', 'Unknown command: $cmd');\n\t}\n\n\tfunction send($data){\n\t\t$ps = array();\n\t\tforeach($data as $p){\n\t\t\t$ps[] = strlen($p);\n\t\t\t$ps[] = $p;\n\t\t}\n\t\t$s = join(\"\\n\", $ps) . \"\\n\\n\";\n\t\tif($this->debug){\n\t\t\techo '> ' . str_replace(array(\"\\r\", \"\\n\"), array('\\r', '\\n'), $s) . \"\\n\";\n\t\t}\n\t\ttry{\n\t\t\twhile(true){\n\t\t\t\t$ret = @fwrite($this->sock, $s);\n\t\t\t\tif($ret === false || $ret === 0){\n\t\t\t\t\t$this->close();\n\t\t\t\t\tthrow new SSDBException('Connection lost');\n\t\t\t\t}\n\t\t\t\t$s = substr($s, $ret);\n\t\t\t\tif(strlen($s) == 0){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t@fflush($this->sock);\n\t\t\t}\n\t\t}catch(Exception $e){\n\t\t\t$this->close();\n\t\t\tthrow new SSDBException($e->getMessage());\n\t\t}\n\t\treturn $ret;\n\t}\n\n\tfunction recv(){\n\t\t$this->step = self::STEP_SIZE;\n\t\twhile(true){\n\t\t\t$ret = $this->parse();\n\t\t\tif($ret === null){\n\t\t\t\ttry{\n\t\t\t\t\t$data = @fread($this->sock, 1024 * 1024);\n\t\t\t\t\tif($this->debug){\n\t\t\t\t\t\techo '< ' . str_replace(array(\"\\r\", \"\\n\"), array('\\r', '\\n'), $data) . \"\\n\";\n\t\t\t\t\t}\n\t\t\t\t}catch(Exception $e){\n\t\t\t\t\t$data = '';\n\t\t\t\t}\n\t\t\t\tif($data === false || $data === ''){\n\t\t\t\t\tif(feof($this->sock)){\n\t\t\t\t\t\t$this->close();\n\t\t\t\t\t\tthrow new SSDBException('Connection lost');\n\t\t\t\t\t}else{\n\t\t\t\t\t\tthrow new SSDBTimeoutException('Connection timeout');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$this->recv_buf .= $data;\n#\t\t\t\techo \"read \" . strlen($data) . \" total: \" . strlen($this->recv_buf) . \"\\n\";\n\t\t\t}else{\n\t\t\t\treturn $ret;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst STEP_SIZE = 0;\n\tconst STEP_DATA = 1;\n\tpublic $resp = array();\n\tpublic $step;\n\tpublic $block_size;\n\n\tprivate function parse(){\n\t\t$spos = 0;\n\t\t$epos = 0;\n\t\t$buf_size = strlen($this->recv_buf);\n\t\t// performance issue for large reponse\n\t\t//$this->recv_buf = ltrim($this->recv_buf);\n\t\twhile(true){\n\t\t\t$spos = $epos;\n\t\t\tif($this->step === self::STEP_SIZE){\n\t\t\t\t$epos = strpos($this->recv_buf, \"\\n\", $spos);\n\t\t\t\tif($epos === false){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t$epos += 1;\n\t\t\t\t$line = substr($this->recv_buf, $spos, $epos - $spos);\n\t\t\t\t$spos = $epos;\n\n\t\t\t\t$line = trim($line);\n\t\t\t\tif(strlen($line) == 0){ // head end\n\t\t\t\t\t$this->recv_buf = substr($this->recv_buf, $spos);\n\t\t\t\t\t$ret = $this->resp;\n\t\t\t\t\t$this->resp = array();\n\t\t\t\t\treturn $ret;\n\t\t\t\t}\n\t\t\t\t$this->block_size = intval($line);\n\t\t\t\t$this->step = self::STEP_DATA;\n\t\t\t}\n\t\t\tif($this->step === self::STEP_DATA){\n\t\t\t\t$epos = $spos + $this->block_size;\n\t\t\t\tif($epos <= $buf_size){\n\t\t\t\t\t$n = strpos($this->recv_buf, \"\\n\", $epos);\n\t\t\t\t\tif($n !== false){\n\t\t\t\t\t\t$data = substr($this->recv_buf, $spos, $epos - $spos);\n\t\t\t\t\t\t$this->resp[] = $data;\n\t\t\t\t\t\t$epos = $n + 1;\n\t\t\t\t\t\t$this->step = self::STEP_SIZE;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// packet not ready\n\t\tif($spos > 0){\n\t\t\t$this->recv_buf = substr($this->recv_buf, $spos);\n\t\t}\n\t\treturn null;\n\t}\n}\n"
  },
  {
    "path": "api/php/demo.php",
    "content": "<?php\n/**\n * Copyright (c) 2012, ideawu\n * All rights reserved.\n * @author: ideawu\n * @link: http://www.ideawu.com/\n *\n * SSDB PHP API demo.\n */\n\ninclude(dirname(__FILE__) . '/SSDB.php');\n$host = '127.0.0.1';\n$port = 8888;\n\n\ntry{\n\t$ssdb = new SimpleSSDB($host, $port);\n\t//$ssdb->easy();\n}catch(Exception $e){\n\tdie(__LINE__ . ' ' . $e->getMessage());\n}\n\nvar_dump($ssdb->set('test', time()));\nvar_dump($ssdb->set('test', time()));\necho $ssdb->get('test') . \"\\n\";\nvar_dump($ssdb->del('test'));\nvar_dump($ssdb->del('test'));\nvar_dump($ssdb->get('test'));\necho \"\\n\";\n\nvar_dump($ssdb->hset('test', 'b', time()));\nvar_dump($ssdb->hset('test', 'b', time()));\necho $ssdb->hget('test', 'b') . \"\\n\";\nvar_dump($ssdb->hdel('test', 'b'));\nvar_dump($ssdb->hdel('test', 'b'));\nvar_dump($ssdb->hget('test', 'b'));\necho \"\\n\";\n\nvar_dump($ssdb->zset('test', 'a', time()));\nvar_dump($ssdb->zset('test', 'a', time()));\necho $ssdb->zget('test', 'a') . \"\\n\";\nvar_dump($ssdb->zdel('test', 'a'));\nvar_dump($ssdb->zdel('test', 'a'));\nvar_dump($ssdb->zget('test', 'a'));\necho \"\\n\";\n\n$ssdb->close();\n\ndie();\n\n/* a simple bench mark */\n\n$data = array();\nfor($i=0; $i<1000; $i++){\n\t$k = '' . mt_rand(0, 100000);\n\t$v = mt_rand(100000, 100000 * 10 - 1) . '';\n\t$data[$k] = $v;\n}\n\nspeed();\ntry{\n\t$ssdb = new SSDB($host, $port);\n}catch(Exception $e){\n\tdie(__LINE__ . ' ' . $e->getMessage());\n}\nforeach($data as $k=>$v){\n\t$ret = $ssdb->set($k, $v);\n\tif($ret === false){\n\t\techo \"error\\n\";\n\t\tbreak;\n\t}\n}\n$ssdb->close();\nspeed('set speed: ', count($data));\n\n\nspeed();\ntry{\n\t$ssdb = new SSDB($host, $port);\n}catch(Exception $e){\n\tdie(__LINE__ . ' ' . $e->getMessage());\n}\nforeach($data as $k=>$v){\n\t$ret = $ssdb->get($k);\n\tif($ret === false){\n\t\techo \"error\\n\";\n\t\tbreak;\n\t}\n}\n$ssdb->close();\nspeed('get speed: ', count($data));\n\n\n\nfunction speed($msg=null, $count=0){\n\tstatic $stime;\n\tif(!$msg && !$count){\n\t\t$stime = microtime(1);\n\t}else{\n\t\t$etime = microtime(1);\n\t\t$ts = ($etime - $stime == 0)? 1 : $etime - $stime;\n\t\t$speed = $count / floatval($ts);\n\t\t$speed = sprintf('%.2f', $speed);\n\t\techo \"$msg: \" . $speed . \"\\n\";\n\n\t\t$stime = $etime;\n\t}\n}\n"
  },
  {
    "path": "api/php/perf.php",
    "content": "<?php\nrequire_once(\"SSDB.php\");\n$ssdb = new SimpleSSDB('127.0.0.1', 8888);\n\n$DATA_LEN = 100 * 1024;\n\n$str = str_pad('', $DATA_LEN);\n$resp = $ssdb->set('key', $str);\n\n\n$keys = array(\n\t\t'seq' => array(),\n\t\t);\nfor($i=0; $i<1000; $i++){\n\t$key = sprintf('%010s', $i);\n\t$keys['seq'][] = $key;\n}\n\n$REQUESTS = 1000;\n$stime = 0;\n$etime = 0;\n\n\nstart();\nforeach($keys['seq'] as $key){\n\t$resp = $ssdb->set($key, $str);\n}\noutput('writeseq');\n\n$ks = $keys['seq'];\nshuffle($ks);\nstart();\nforeach($ks as $key){\n\t$resp = $ssdb->set($key, $str);\n}\noutput('writerand');\n\nstart();\nforeach($keys['seq'] as $key){\n\t$resp = $ssdb->get($key);\n\tif(strlen($resp) != $DATA_LEN){\n\t\techo \"$key ERROR!\\n\";\n\t\tdie();\n\t}\n}\noutput('readseq');\n\n\n$ks = $keys['seq'];\nshuffle($ks);\nstart();\nforeach($ks as $key){\n\t$resp = $ssdb->get($key);\n\tif(strlen($resp) != $DATA_LEN){\n\t\techo \"$key ERROR!\\n\";\n\t\tdie();\n\t}\n}\noutput('readrand');\n\n\n\n\nfunction start(){\n\tglobal $stime, $etime, $DATA_LEN, $REQUESTS;\n\t$stime = microtime(1);\n}\n\nfunction output($op){\n\tglobal $stime, $etime, $DATA_LEN, $REQUESTS;\n\t$etime = microtime(1);\n\t$time_consumed = $etime - $stime;\n\t$tpr = $time_consumed/$REQUESTS * 1000;\n\t$sps = ($REQUESTS * $DATA_LEN)/$time_consumed/1024/1024;\n\tprintf(\"%-10s: %8s ms/op %10.1f MB/s\\n\", $op, number_format($tpr, 3), $sps);// . \"ms/op\\n\";\n}\n\n"
  },
  {
    "path": "api/python/SSDB.py",
    "content": "# encoding=utf-8\n# Generated by cpy\n# 2020-02-15 18:42:38.728393\nimport os, sys\nfrom sys import stdin, stdout\n\nimport socket\nclass SSDB_Response(object):\n\tpass\n\n\n\tdef __init__(this, code='', data_or_message=None):\n\t\tpass\n\t\tthis.type = 'none'\n\t\tthis.code = code\n\t\tthis.data = None\n\t\tthis.message = None\n\t\tthis.set(code, data_or_message)\n\n\tdef set(this, code, data_or_message=None):\n\t\tpass\n\t\tthis.code = code\n\n\t\tif code=='ok':\n\t\t\tpass\n\t\t\tthis.data = data_or_message\n\t\telse:\n\t\t\tpass\n\n\t\t\tif isinstance(data_or_message, list):\n\t\t\t\tpass\n\n\t\t\t\tif len(data_or_message)>0:\n\t\t\t\t\tpass\n\t\t\t\t\tthis.message = data_or_message[0]\n\t\t\telse:\n\t\t\t\tpass\n\t\t\t\tthis.message = data_or_message\n\n\tdef __repr__(this):\n\t\tpass\n\t\treturn ((((str(this.code) + ' ') + str(this.message)) + ' ') + str(this.data))\n\n\tdef ok(this):\n\t\tpass\n\t\treturn this.code=='ok'\n\n\tdef not_found(this):\n\t\tpass\n\t\treturn this.code=='not_found'\n\n\tdef str_resp(this, resp):\n\t\tpass\n\t\tthis.type = 'val'\n\n\t\tif resp[0]=='ok':\n\t\t\tpass\n\n\t\t\tif len(resp)==2:\n\t\t\t\tpass\n\t\t\t\tthis.set('ok', resp[1])\n\t\t\telse:\n\t\t\t\tpass\n\t\t\t\tthis.set('server_error', 'Invalid response')\n\t\telse:\n\t\t\tpass\n\t\t\tthis.set(resp[0], resp[1 : ])\n\t\treturn this\n\n\tdef str_resp(this, resp):\n\t\tpass\n\t\tthis.type = 'val'\n\n\t\tif resp[0]=='ok':\n\t\t\tpass\n\n\t\t\tif len(resp)==2:\n\t\t\t\tpass\n\t\t\t\tthis.set('ok', resp[1])\n\t\t\telse:\n\t\t\t\tpass\n\t\t\t\tthis.set('server_error', 'Invalid response')\n\t\telse:\n\t\t\tpass\n\t\t\tthis.set(resp[0], resp[1 : ])\n\t\treturn this\n\n\tdef int_resp(this, resp):\n\t\tpass\n\t\tthis.type = 'val'\n\n\t\tif resp[0]=='ok':\n\t\t\tpass\n\n\t\t\tif len(resp)==2:\n\t\t\t\tpass\n\t\t\t\ttry:\n\t\t\t\t\tpass\n\t\t\t\t\tval = int(resp[1])\n\t\t\t\t\tthis.set('ok', val)\n\t\t\t\texcept Exception , e:\n\t\t\t\t\tpass\n\t\t\t\t\tthis.set('server_error', 'Invalid response')\n\t\t\telse:\n\t\t\t\tpass\n\t\t\t\tthis.set('server_error', 'Invalid response')\n\t\telse:\n\t\t\tpass\n\t\t\tthis.set(resp[0], resp[1 : ])\n\t\treturn this\n\n\tdef float_resp(this, resp):\n\t\tpass\n\t\tthis.type = 'val'\n\n\t\tif resp[0]=='ok':\n\t\t\tpass\n\n\t\t\tif len(resp)==2:\n\t\t\t\tpass\n\t\t\t\ttry:\n\t\t\t\t\tpass\n\t\t\t\t\tval = float(resp[1])\n\t\t\t\t\tthis.set('ok', val)\n\t\t\t\texcept Exception , e:\n\t\t\t\t\tpass\n\t\t\t\t\tthis.set('server_error', 'Invalid response')\n\t\t\telse:\n\t\t\t\tpass\n\t\t\t\tthis.set('server_error', 'Invalid response')\n\t\telse:\n\t\t\tpass\n\t\t\tthis.set(resp[0], resp[1 : ])\n\t\treturn this\n\n\tdef list_resp(this, resp):\n\t\tpass\n\t\tthis.type = 'list'\n\t\tthis.set(resp[0], resp[1 : ])\n\t\treturn this\n\n\tdef int_map_resp(this, resp):\n\t\tpass\n\t\tthis.type = 'map'\n\n\t\tif resp[0]=='ok':\n\t\t\tpass\n\n\t\t\tif len(resp) % 2==1:\n\t\t\t\tpass\n\t\t\t\tdata = {'index': [],'items': {},}\n\t\t\t\ti = 1\n\n\t\t\t\twhile i<len(resp):\n\t\t\t\t\tpass\n\t\t\t\t\tk = resp[i]\n\t\t\t\t\tv = resp[(i + 1)]\n\t\t\t\t\ttry:\n\t\t\t\t\t\tpass\n\t\t\t\t\t\tv = int(v)\n\t\t\t\t\texcept Exception , e:\n\t\t\t\t\t\tpass\n\t\t\t\t\t\tv = - (1)\n\t\t\t\t\tdata['index'].append(k)\n\t\t\t\t\tdata['items'][k] = v\n\t\t\t\t\tpass\n\t\t\t\t\ti += 2\n\t\t\t\tthis.set('ok', data)\n\t\t\telse:\n\t\t\t\tpass\n\t\t\t\tthis.set('server_error', 'Invalid response')\n\t\telse:\n\t\t\tpass\n\t\t\tthis.set(resp[0], resp[1 : ])\n\t\treturn this\n\n\tdef str_map_resp(this, resp):\n\t\tpass\n\t\tthis.type = 'map'\n\n\t\tif resp[0]=='ok':\n\t\t\tpass\n\n\t\t\tif len(resp) % 2==1:\n\t\t\t\tpass\n\t\t\t\tdata = {'index': [],'items': {},}\n\t\t\t\ti = 1\n\n\t\t\t\twhile i<len(resp):\n\t\t\t\t\tpass\n\t\t\t\t\tk = resp[i]\n\t\t\t\t\tv = resp[(i + 1)]\n\t\t\t\t\tdata['index'].append(k)\n\t\t\t\t\tdata['items'][k] = v\n\t\t\t\t\tpass\n\t\t\t\t\ti += 2\n\t\t\t\tthis.set('ok', data)\n\t\t\telse:\n\t\t\t\tpass\n\t\t\t\tthis.set('server_error', 'Invalid response')\n\t\telse:\n\t\t\tpass\n\t\t\tthis.set(resp[0], resp[1 : ])\n\t\treturn this\n\nclass SSDB(object):\n\tpass\n\n\n\tdef __init__(this, host, port):\n\t\tpass\n\t\tthis.recv_buf = ''\n\t\tthis._closed = False\n\t\tfamily = socket.AF_INET\n\n\t\tif host.find(':')!=- (1):\n\t\t\tpass\n\t\t\tfamily = socket.AF_INET6\n\t\tthis.sock = socket.socket(family, socket.SOCK_STREAM)\n\t\tthis.sock.connect(tuple([host, port]))\n\t\tthis.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)\n\n\tdef close(this):\n\t\tpass\n\n\t\tif not (this._closed):\n\t\t\tpass\n\t\t\tthis.sock.close()\n\t\t\tthis._closed = True\n\n\tdef closed(this):\n\t\tpass\n\t\treturn this._closed\n\n\tdef request(this, cmd, params=None):\n\t\tpass\n\n\t\tif params==None:\n\t\t\tpass\n\t\t\tparams = []\n\t\tparams = ([cmd] + params)\n\t\tthis.send(params)\n\t\tresp = this.recv()\n\n\t\tif resp==None:\n\t\t\tpass\n\t\t\treturn SSDB_Response('error', 'Unknown error')\n\n\t\tif len(resp)==0:\n\t\t\tpass\n\t\t\treturn SSDB_Response('disconnected', 'Connection closed')\n\t\tret = SSDB_Response()\n\n\t\t# {{{ switch: cmd\n\t\t_continue_1 = False\n\t\twhile True:\n\t\t\tif False or ((cmd) == 'ping') or ((cmd) == 'set') or ((cmd) == 'del') or ((cmd) == 'qset') or ((cmd) == 'zset') or ((cmd) == 'hset') or ((cmd) == 'qpush') or ((cmd) == 'qpush_front') or ((cmd) == 'qpush_back') or ((cmd) == 'zdel') or ((cmd) == 'hdel') or ((cmd) == 'multi_set') or ((cmd) == 'multi_del') or ((cmd) == 'multi_hset') or ((cmd) == 'multi_hdel') or ((cmd) == 'multi_zset') or ((cmd) == 'multi_zdel'):\n\t\t\t\tpass\n\n\t\t\t\tif len(resp)>1:\n\t\t\t\t\tpass\n\t\t\t\t\treturn ret.int_resp(resp)\n\t\t\t\telse:\n\t\t\t\t\tpass\n\t\t\t\t\treturn SSDB_Response(resp[0], None)\n\t\t\t\tbreak\n\t\t\tif False or ((cmd) == 'version') or ((cmd) == 'substr') or ((cmd) == 'get') or ((cmd) == 'getset') or ((cmd) == 'hget') or ((cmd) == 'qfront') or ((cmd) == 'qback') or ((cmd) == 'qget'):\n\t\t\t\tpass\n\t\t\t\treturn ret.str_resp(resp)\n\t\t\t\tbreak\n\t\t\tif False or ((cmd) == 'qpop') or ((cmd) == 'qpop_front') or ((cmd) == 'qpop_back'):\n\t\t\t\tpass\n\t\t\t\tsize = 1\n\t\t\t\ttry:\n\t\t\t\t\tpass\n\t\t\t\t\tsize = int(params[2])\n\t\t\t\texcept Exception , e:\n\t\t\t\t\tpass\n\n\t\t\t\tif size==1:\n\t\t\t\t\tpass\n\t\t\t\t\treturn ret.str_resp(resp)\n\t\t\t\telse:\n\t\t\t\t\tpass\n\t\t\t\t\treturn ret.list_resp(resp)\n\t\t\t\tbreak\n\t\t\tif False or ((cmd) == 'dbsize') or ((cmd) == 'getbit') or ((cmd) == 'setbit') or ((cmd) == 'countbit') or ((cmd) == 'bitcount') or ((cmd) == 'strlen') or ((cmd) == 'ttl') or ((cmd) == 'expire') or ((cmd) == 'setnx') or ((cmd) == 'incr') or ((cmd) == 'decr') or ((cmd) == 'zincr') or ((cmd) == 'zdecr') or ((cmd) == 'hincr') or ((cmd) == 'hdecr') or ((cmd) == 'hsize') or ((cmd) == 'zsize') or ((cmd) == 'qsize') or ((cmd) == 'zget') or ((cmd) == 'zrank') or ((cmd) == 'zrrank') or ((cmd) == 'zsum') or ((cmd) == 'zcount') or ((cmd) == 'zremrangebyrank') or ((cmd) == 'zremrangebyscore') or ((cmd) == 'hclear') or ((cmd) == 'zclear') or ((cmd) == 'qclear') or ((cmd) == 'qpush') or ((cmd) == 'qpush_front') or ((cmd) == 'qpush_back') or ((cmd) == 'qtrim_front') or ((cmd) == 'qtrim_back'):\n\t\t\t\tpass\n\t\t\t\treturn ret.int_resp(resp)\n\t\t\t\tbreak\n\t\t\tif False or ((cmd) == 'zavg'):\n\t\t\t\tpass\n\t\t\t\treturn ret.float_resp(resp)\n\t\t\t\tbreak\n\t\t\tif False or ((cmd) == 'keys') or ((cmd) == 'rkeys') or ((cmd) == 'zkeys') or ((cmd) == 'zrkeys') or ((cmd) == 'hkeys') or ((cmd) == 'hrkeys') or ((cmd) == 'list') or ((cmd) == 'hlist') or ((cmd) == 'hrlist') or ((cmd) == 'zlist') or ((cmd) == 'zrlist'):\n\t\t\t\tpass\n\t\t\t\treturn ret.list_resp(resp)\n\t\t\t\tbreak\n\t\t\tif False or ((cmd) == 'scan') or ((cmd) == 'rscan') or ((cmd) == 'hgetall') or ((cmd) == 'hscan') or ((cmd) == 'hrscan'):\n\t\t\t\tpass\n\t\t\t\treturn ret.str_map_resp(resp)\n\t\t\t\tbreak\n\t\t\tif False or ((cmd) == 'zscan') or ((cmd) == 'zrscan') or ((cmd) == 'zrange') or ((cmd) == 'zrrange') or ((cmd) == 'zpop_front') or ((cmd) == 'zpop_back'):\n\t\t\t\tpass\n\t\t\t\treturn ret.int_map_resp(resp)\n\t\t\t\tbreak\n\t\t\tif False or ((cmd) == 'auth') or ((cmd) == 'exists') or ((cmd) == 'hexists') or ((cmd) == 'zexists'):\n\t\t\t\tpass\n\t\t\t\treturn ret.int_resp(resp)\n\t\t\t\tbreak\n\t\t\tif False or ((cmd) == 'multi_exists') or ((cmd) == 'multi_hexists') or ((cmd) == 'multi_zexists'):\n\t\t\t\tpass\n\t\t\t\treturn ret.int_map_resp(resp)\n\t\t\t\tbreak\n\t\t\tif False or ((cmd) == 'multi_get') or ((cmd) == 'multi_hget'):\n\t\t\t\tpass\n\t\t\t\treturn ret.str_map_resp(resp)\n\t\t\t\tbreak\n\t\t\tif False or ((cmd) == 'multi_hsize') or ((cmd) == 'multi_zsize') or ((cmd) == 'multi_zget'):\n\t\t\t\tpass\n\t\t\t\treturn ret.int_map_resp(resp)\n\t\t\t\tbreak\n\t\t\t### default\n\t\t\treturn ret.list_resp(resp)\n\t\t\tbreak\n\t\t\tbreak\n\t\t\tif _continue_1:\n\t\t\t\tcontinue\n\t\t# }}} switch\n\n\t\treturn SSDB_Response('error', 'Unknown error')\n\n\tdef send(this, data):\n\t\tpass\n\t\tps = []\n\n\t\t_cpy_r_0 = _cpy_l_1 = data\n\t\tif type(_cpy_r_0).__name__ == 'dict': _cpy_b_3=True; _cpy_l_1=_cpy_r_0.iterkeys()\n\t\telse: _cpy_b_3=False;\n\t\tfor _cpy_k_2 in _cpy_l_1:\n\t\t\tif _cpy_b_3: p=_cpy_r_0[_cpy_k_2]\n\t\t\telse: p=_cpy_k_2\n\t\t\tpass\n\t\t\tp = str(p)\n\t\t\tps.append(str(len(p)))\n\t\t\tps.append(p)\n\t\tnl = '\\n'\n\t\ts = (nl.join(ps) + '\\n\\n')\n\t\ttry:\n\t\t\tpass\n\n\t\t\twhile True:\n\t\t\t\tpass\n\t\t\t\tret = this.sock.send(s)\n\n\t\t\t\tif ret==0:\n\t\t\t\t\tpass\n\t\t\t\t\treturn - (1)\n\t\t\t\ts = s[ret : ]\n\n\t\t\t\tif len(s)==0:\n\t\t\t\t\tpass\n\t\t\t\t\tbreak\n\t\texcept socket.error , e:\n\t\t\tpass\n\t\t\treturn - (1)\n\t\treturn ret\n\n\tdef net_read(this):\n\t\tpass\n\t\ttry:\n\t\t\tpass\n\t\t\tdata = this.sock.recv(1024 * 8)\n\t\texcept Exception , e:\n\t\t\tpass\n\t\t\tdata = ''\n\n\t\tif data=='':\n\t\t\tpass\n\t\t\tthis.close()\n\t\t\treturn 0\n\t\tthis.recv_buf += data\n\t\treturn len(data)\n\n\tdef recv(this):\n\t\tpass\n\n\t\twhile True:\n\t\t\tpass\n\t\t\tret = this.parse()\n\n\t\t\tif ret==None:\n\t\t\t\tpass\n\n\t\t\t\tif this.net_read()==0:\n\t\t\t\t\tpass\n\t\t\t\t\treturn []\n\t\t\telse:\n\t\t\t\tpass\n\t\t\t\treturn ret\n\n\tdef parse(this):\n\t\tpass\n\t\tret = []\n\t\tspos = 0\n\t\tepos = 0\n\n\t\twhile True:\n\t\t\tpass\n\t\t\tspos = epos\n\t\t\tepos = this.recv_buf.find('\\n', spos)\n\n\t\t\tif epos==- (1):\n\t\t\t\tpass\n\t\t\t\tbreak\n\t\t\tepos += 1\n\t\t\tline = this.recv_buf[spos : epos]\n\t\t\tspos = epos\n\n\t\t\tif line.strip()=='':\n\t\t\t\tpass\n\n\t\t\t\tif len(ret)==0:\n\t\t\t\t\tpass\n\t\t\t\t\tcontinue\n\t\t\t\telse:\n\t\t\t\t\tpass\n\t\t\t\t\tthis.recv_buf = this.recv_buf[spos : ]\n\t\t\t\t\treturn ret\n\t\t\ttry:\n\t\t\t\tpass\n\t\t\t\tnum = int(line)\n\t\t\texcept Exception , e:\n\t\t\t\tpass\n\t\t\t\treturn []\n\t\t\tepos = (spos + num)\n\n\t\t\tif epos>len(this.recv_buf):\n\t\t\t\tpass\n\t\t\t\tbreak\n\t\t\tdata = this.recv_buf[spos : epos]\n\t\t\tret.append(data)\n\t\t\tspos = epos\n\t\t\tepos = this.recv_buf.find('\\n', spos)\n\n\t\t\tif epos==- (1):\n\t\t\t\tpass\n\t\t\t\tbreak\n\t\t\tepos += 1\n\t\treturn None\n\n"
  },
  {
    "path": "api/python/demo.py",
    "content": "# encoding=utf-8\r\n# Generated by cpy\r\n# 2013-01-26 21:04:47.984000\r\nimport os, sys\r\nfrom sys import stdin, stdout\r\n\r\nfrom SSDB import SSDB\r\ntry:\r\n\tpass\r\n\tssdb = SSDB('127.0.0.1', 8888)\r\nexcept Exception , e:\r\n\tpass\r\n\tprint e\r\n\tsys.exit(0)\r\nprint ssdb.request('set', ['test', '123'])\r\nprint ssdb.request('get', ['test'])\r\nprint ssdb.request('incr', ['test', '1'])\r\nprint ssdb.request('decr', ['test', '1'])\r\nprint ssdb.request('scan', ['a', 'z', 10])\r\nprint ssdb.request('rscan', ['z', 'a', 10])\r\nprint ssdb.request('keys', ['a', 'z', 10])\r\nprint ssdb.request('del', ['test'])\r\nprint ssdb.request('get', ['test'])\r\nprint \"\\n\"\r\nprint ssdb.request('zset', ['test', 'a', 20])\r\nprint ssdb.request('zget', ['test', 'a'])\r\nprint ssdb.request('zincr', ['test', 'a', 20])\r\nprint ssdb.request('zdecr', ['test', 'a', 20])\r\nprint ssdb.request('zscan', ['test', 'a', 0, 100, 10])\r\nprint ssdb.request('zrscan', ['test', 'a', 100, 0, 10])\r\nprint ssdb.request('zkeys', ['test', 'a', 0, 100, 10])\r\nprint ssdb.request('zdel', ['test', 'a'])\r\nprint ssdb.request('zget', ['test', 'a'])\r\nprint \"\\n\"\r\nprint ssdb.request('hset', ['test', 'a', 20])\r\nprint ssdb.request('hget', ['test', 'a'])\r\nprint ssdb.request('hincr', ['test', 'a', 20])\r\nprint ssdb.request('hdecr', ['test', 'a', 20])\r\nprint ssdb.request('hscan', ['test', '0', 'z', 10])\r\nprint ssdb.request('hrscan', ['test', 'z', '0', 10])\r\nprint ssdb.request('hkeys', ['test', '0', 'z', 10])\r\nprint ssdb.request('hdel', ['test', 'a'])\r\nprint ssdb.request('hget', ['test', 'a'])\r\nprint \"\\n\"\r\n"
  },
  {
    "path": "build.sh",
    "content": "#!/bin/sh\nBASE_DIR=`pwd`\nJEMALLOC_PATH=\"$BASE_DIR/deps/jemalloc-4.1.0\"\nLEVELDB_PATH=\"$BASE_DIR/deps/leveldb-1.20\"\nSNAPPY_PATH=\"$BASE_DIR/deps/snappy-1.1.0\"\n\n# dependency check\nwhich autoconf > /dev/null 2>&1\nif [ \"$?\" -ne 0 ]; then\n\techo \"\"\n\techo \"ERROR! autoconf required! install autoconf first\"\n\techo \"\"\n\texit 1\nfi\n\nif test -z \"$TARGET_OS\"; then\n\tTARGET_OS=`uname -s`\nfi\nif test -z \"$MAKE\"; then\n\tMAKE=make\nfi\nif test -z \"$CC\"; then\n\tCC=gcc\nfi\nif test -z \"$CXX\"; then\n\tCXX=g++\nfi\n\ncase \"$TARGET_OS\" in\n    Darwin)\n        #PLATFORM_CLIBS=\"-pthread\"\n\t\t#PLATFORM_CFLAGS=\"\"\n        ;;\n    Linux)\n        PLATFORM_CLIBS=\"-pthread -lrt\"\n        ;;\n    OS_ANDROID_CROSSCOMPILE)\n        PLATFORM_CLIBS=\"-pthread\"\n        SNAPPY_HOST=\"--host=i386-linux\"\n        ;;\n    CYGWIN_*)\n        PLATFORM_CLIBS=\"-lpthread\"\n        ;;\n    SunOS)\n        PLATFORM_CLIBS=\"-lpthread -lrt\"\n        ;;\n    FreeBSD)\n        PLATFORM_CLIBS=\"-lpthread\"\n\t\tMAKE=gmake\n        ;;\n    NetBSD)\n        PLATFORM_CLIBS=\"-lpthread -lgcc_s\"\n        ;;\n    OpenBSD)\n        PLATFORM_CLIBS=\"-pthread\"\n        ;;\n    DragonFly)\n        PLATFORM_CLIBS=\"-lpthread\"\n        ;;\n    HP-UX)\n        PLATFORM_CLIBS=\"-pthread\"\n        ;;\n    *)\n        echo \"Unknown platform!\" >&2\n        exit 1\nesac\n\n\nDIR=`pwd`\ncd $SNAPPY_PATH\nif [ ! -f Makefile ]; then\n\techo \"\"\n\techo \"##### building snappy... #####\"\n\t./configure $SNAPPY_HOST\n\t# FUCK! snappy compilation doesn't work on some linux!\n\tfind . | xargs touch\n\tmake\n\techo \"##### building snappy finished #####\"\n\techo \"\"\nfi\ncd \"$DIR\"\n\n\ncase \"$TARGET_OS\" in\n\tCYGWIN*|FreeBSD|OS_ANDROID_CROSSCOMPILE)\n\t\techo \"not using jemalloc on $TARGET_OS\"\n\t;;\n\t*)\n\t\tDIR=`pwd`\n\t\tcd $JEMALLOC_PATH\n\t\tif [ ! -f Makefile ]; then\n\t\t\techo \"\"\n\t\t\techo \"##### building jemalloc... #####\"\n\t\t\tsh ./autogen.sh\n\t\t\t./configure\n\t\t\tmake\n\t\t\techo \"##### building jemalloc finished #####\"\n\t\t\techo \"\"\n\t\tfi\n\t\tcd \"$DIR\"\n\t;;\nesac\n\n\nrm -f src/version.h\necho \"#ifndef SSDB_DEPS_H\" >> src/version.h\necho \"#ifndef SSDB_VERSION\" >> src/version.h\necho \"#define SSDB_VERSION \\\"`cat version`\\\"\" >> src/version.h\necho \"#endif\" >> src/version.h\necho \"#endif\" >> src/version.h\ncase \"$TARGET_OS\" in\n\tCYGWIN*|FreeBSD)\n\t;;\n\tOS_ANDROID_CROSSCOMPILE)\n        echo \"#define OS_ANDROID 1\" >> src/version.h\n\t;;\n\t*)\n\t\techo \"#ifndef IOS\" >> src/version.h\n\t\techo \"#include <stdlib.h>\" >> src/version.h\n\t\techo \"#include <jemalloc/jemalloc.h>\" >> src/version.h\n\t\techo \"#endif\" >> src/version.h\n\t;;\nesac\n\nrm -f build_config.mk\necho CC=$CC >> build_config.mk\necho CXX=$CXX >> build_config.mk\necho \"MAKE=$MAKE\" >> build_config.mk\necho \"LEVELDB_PATH=$LEVELDB_PATH\" >> build_config.mk\necho \"JEMALLOC_PATH=$JEMALLOC_PATH\" >> build_config.mk\necho \"SNAPPY_PATH=$SNAPPY_PATH\" >> build_config.mk\n\necho \"CFLAGS=\" >> build_config.mk\necho \"CFLAGS = -DNDEBUG -D__STDC_FORMAT_MACROS -Wall -O2 -Wno-sign-compare\" >> build_config.mk\necho \"CFLAGS += ${PLATFORM_CFLAGS}\" >> build_config.mk\necho \"CFLAGS += -I \\\"$LEVELDB_PATH/include\\\"\" >> build_config.mk\n\necho \"CLIBS=\" >> build_config.mk\necho \"CLIBS += \\\"$LEVELDB_PATH/out-static/libleveldb.a\\\"\" >> build_config.mk\necho \"CLIBS += \\\"$SNAPPY_PATH/.libs/libsnappy.a\\\"\" >> build_config.mk\n\ncase \"$TARGET_OS\" in\n\tCYGWIN*|FreeBSD|OS_ANDROID_CROSSCOMPILE)\n\t;;\n\t*)\n\t\techo \"CLIBS += \\\"$JEMALLOC_PATH/lib/libjemalloc.a\\\"\" >> build_config.mk\n\t\techo \"CFLAGS += -I \\\"$JEMALLOC_PATH/include\\\"\" >> build_config.mk\n\t;;\nesac\n\necho \"CLIBS += ${PLATFORM_CLIBS}\" >> build_config.mk\n\n\nif test -z \"$TMPDIR\"; then\n    TMPDIR=/tmp\nfi\n\ng++ -x c++ - -o $TMPDIR/ssdb_build_test.$$ 2>/dev/null <<EOF\n\t#include <unordered_map>\n\tint main() {}\nEOF\nif [ \"$?\" = 0 ]; then\n\techo \"CFLAGS += -DNEW_MAC\" >> build_config.mk\nfi\n\n"
  },
  {
    "path": "deps/cpy/Eval.g",
    "content": "/********************************\r\n * Author: ideawu\r\n * Link: http://www.ideawu.net/\r\n ********************************/\r\n\r\ntree grammar Eval;\r\n\r\noptions {\r\n    language=Python;\r\n    tokenVocab=Expr;\r\n    ASTLabelType=CommonTree;\r\n}\r\n\r\n@header{\r\n\tfrom engine import CpyBuilder\r\n}\r\n\r\n@init{\r\n}\r\n\r\nprog[cpy]\r\n\t@init{\r\n\t\tself.cpy = cpy\r\n\t}\r\n\t@after{\r\n\t\tself.cpy.close()\r\n\t}\r\n\t: stmt*\r\n\t;\r\n\r\nstmt\r\n\t: import_stmt\r\n\t| exec_stmt\r\n\t| print_stmt | printf_stmt\r\n\t| break_stmt\r\n\t| continue_stmt\r\n\t| return_stmt\r\n\t| if_stmt\r\n\t| while_stmt\r\n\t| do_while_stmt\r\n\t| switch_stmt\r\n\t| throw_stmt\r\n\t| try_stmt\r\n\t| func_decl\r\n\t| class_decl\r\n\t| for_stmt\r\n\t| foreach_stmt\r\n\t;\r\n\r\n/***** statements *****/\r\n\r\nblock\r\n\t@init{\r\n\t\tself.cpy.block_enter()\r\n\t}\r\n\t@after{\r\n\t\tself.cpy.block_leave()\r\n\t}\r\n\t: ^(BLOCK stmt*)\r\n\t;\r\n\r\nimport_stmt\r\n\t: ^(IMPORT\r\n\t\t( a=module\r\n\t\t\t{self.cpy.op_import($a.text, None)}\r\n\t\t| b=module '.*'\r\n\t\t\t{self.cpy.op_import($b.text, '*')}\r\n\t\t)+\r\n\t\t)\r\n\t;\r\n\r\nexec_stmt\r\n\t: ^(EXEC_STMT exec_list)\r\n\t\t{self.cpy.stmt($exec_list.text)}\r\n\t;\r\nexec_expr returns[text]\r\n\t: member_expr\r\n\t\t{$text = $member_expr.text}\r\n\t| ^(ASSIGN member_expr op=('='|'+='|'-='|'*='|'/='|'%='|'&='|'^='|'|=') expr)\r\n\t\t{$text = self.cpy.op_assign($member_expr.text, $expr.text, $op.text)}\r\n\t| ^(POST_INC member_expr)\r\n\t\t{$text = self.cpy.op_inc($member_expr.text)}\r\n\t| ^(POST_DEC member_expr)\r\n\t\t{$text = self.cpy.op_dec($member_expr.text)}\r\n\t| ^(PRE_INC member_expr)\r\n\t\t{$text = self.cpy.op_inc($member_expr.text)}\r\n\t| ^(PRE_DEC member_expr)\r\n\t\t{$text = self.cpy.op_dec($member_expr.text)}\r\n\t;\r\nexec_list returns[text]\r\n\t@init{ps = []}\r\n\t: ^(EXEC_LIST (exec_expr {ps.append($exec_expr.text)} ) +)\r\n\t\t{$text = ', '.join(ps)}\r\n\t;\r\n\r\nprintf_stmt\r\n\t: ^(PRINTF expr expr_list?)\r\n\t\t{self.cpy.op_printf($expr.text, $expr_list.text)}\r\n\t;\r\nprint_stmt\r\n\t: ^(PRINT expr_list)\r\n\t\t{self.cpy.op_print($expr_list.text)}\r\n\t//: ^(PRINT (expr {self.cpy.op_print($expr.text)} )+)\r\n\t//\t{self.cpy.op_print_leave()}\r\n\t;\r\n\r\nbreak_stmt\r\n\t: BREAK\r\n\t\t{self.cpy.op_break()}\r\n\t;\r\ncontinue_stmt\r\n\t: CONTINUE\r\n\t\t{self.cpy.op_continue()}\r\n\t;\r\nreturn_stmt\r\n\t: ^(RETURN expr?)\r\n\t\t{self.cpy.op_return($expr.text)}\r\n\t;\r\n\r\n\r\nif_stmt\r\n\t@init{\r\n\t\tself.cpy.if_enter()\r\n\t}\r\n\t@after{\r\n\t\tself.cpy.if_leave()\r\n\t}\r\n\t: if_clause else_if_clause* else_clause?\r\n\t;\r\nif_clause\r\n\t: ^(IF expr {self.cpy.op_if($expr.text)} block)\r\n\t;\r\nelse_if_clause\r\n\t: ^(ELSE_IF {self.cpy.op_else_if()} if_clause)\r\n\t;\r\nelse_clause\r\n\t: ^(ELSE {self.cpy.op_else()} block)\r\n\t;\r\n\r\n\r\nwhile_stmt\r\n\t: ^(WHILE expr {self.cpy.op_while($expr.text)} block)\r\n\t;\r\n\r\ndo_while_stmt\r\n\t: ^(DO_WHILE {self.cpy.op_do_while_enter()}\r\n\t\tblock\r\n\t\texpr {self.cpy.op_do_while_leave($expr.text)}\r\n\t\t)\r\n\t;\r\n\r\n\r\nswitch_stmt\r\n\t: ^(SWITCH expr {self.cpy.op_switch_enter($expr.text)} case_block)\r\n\t\t{self.cpy.op_switch_leave()}\r\n\t;\r\ncase_block\r\n\t: '{' (case_clause)+ (default_clause)? '}'\r\n\t;\r\ncase_clause\r\n\t@init{self.cpy.op_case_enter()}\r\n\t: ^(CASE case_test+ {self.cpy.op_case()} stmt* break_stmt)\r\n\t\t{self.cpy.op_case_leave()}\r\n\t;\r\ncase_test\r\n\t: ^(CASE expr)\r\n\t\t{self.cpy.op_case_test($expr.text)}\r\n\t;\r\ndefault_clause\r\n\t@init{\r\n\t\tself.cpy.op_default_enter()\r\n\t}\r\n\t: ^(DEFAULT stmt*)\r\n\t\t{self.cpy.op_default_leave()}\r\n\t;\r\n\r\n\r\nfor_stmt\r\n\t: ^(FOR (a=exec_list {self.cpy.stmt($a.text)})?\r\n\t\texpr {self.cpy.op_while($expr.text)}\r\n\t\tblock\r\n\t\t{self.cpy.block_enter()}\r\n\t\t(b=exec_list {self.cpy.stmt($b.text)})?\r\n\t\t{self.cpy.block_leave()}\r\n\t\t)\r\n\t;\r\n// for in 是一种 trackback 结构, 而 foreach as 不是\r\nforeach_stmt\r\n\t: ^(FOREACH expr\r\n\t\t( ^(EACH k=ID v=each_val)\r\n\t\t\t{self.cpy.op_foreach($expr.text, $k.text, $v.text)}\r\n\t\t| ^(EACH v=each_val)\r\n\t\t\t{self.cpy.op_foreach($expr.text, None, $v.text)}\r\n\t\t)\r\n\t\tblock\r\n\t\t)\r\n\t;\r\neach_val returns[text]\r\n\t@init{ps = []}\r\n\t: ^(EACH_VAL (ID {ps.append($ID.text)} )+)\r\n\t\t{$text = ','.join(ps)}\r\n\t;\r\n\r\n\r\nthrow_stmt\r\n\t: ^(THROW expr)\r\n\t\t{self.cpy.op_throw($expr.text)}\r\n\t;\r\ntry_stmt\r\n\t@init{self.cpy.op_try()}\r\n\t: ^(TRY block catch_clause+ finally_clause?)\r\n\t;\r\ncatch_clause\r\n\t: ^(CATCH module ID?\r\n\t\t{self.cpy.op_catch($module.text, $ID.text)}\r\n\t\tblock)\r\n\t;\r\nfinally_clause\r\n\t@init{self.cpy.op_finally()}\r\n\t: ^(FINALLY block)\r\n\t;\r\n\r\n\r\nfunc_decl\r\n\t: ^(FUNCTION ID params\r\n\t\t{self.cpy.op_function($ID.text, $params.text)}\r\n\t\tblock\r\n\t\t)\r\n\t;\r\nparams returns[text]\r\n\t@init{ps = []}\r\n\t: ^(PARAMS (param_decl {ps.append($param_decl.text)} ) *)\r\n\t\t{$text = ', '.join(ps)}\r\n\t;\r\nparam_decl returns[text]\r\n\t: ID\r\n\t\t{$text = $ID.text}\r\n\t\t('=' atom\r\n\t\t\t{$text += ('=' + $atom.text)}\r\n\t\t)?\r\n\t;\r\n\r\n\r\nclass_decl\r\n\t@after{self.cpy.op_class_leave()}\r\n\t: ^(CLASS a=ID\r\n\t\t\t{self.cpy.op_class_enter($a.text, None)}\r\n\t\tclass_element*)\r\n\t| ^(CLASS b=ID c=ID\r\n\t\t\t{self.cpy.op_class_enter($b.text, $c.text)}\r\n\t\tclass_element*)\r\n\t;\r\nclass_element\r\n\t: var_def | constructor | func_decl\r\n\t;\r\nvar_def\r\n\t: ^(VAR ID expr?)\r\n\t\t{self.cpy.op_var_def(False, $ID.text, $expr.text)}\r\n\t| ^(VAR 'static' ID expr?)\r\n\t\t{self.cpy.op_var_def(True, $ID.text, $expr.text)}\r\n\t;\r\nconstructor\r\n\t: ^(CONSTRUCTOR params\r\n\t\t{self.cpy.op_construct($params.text)}\r\n\t\tblock)\r\n\t;\r\n\r\n\r\n/***** expressions *****/\r\nmodule returns[text]\r\n\t@init{ps = []}\r\n\t: ^(MODULE (ID {ps.append($ID.text)} ) +)\r\n\t\t{$text = '.'.join(ps)}\r\n\t;\r\n\r\nmember_expr returns[text]\r\n\t@init{ps = []}\r\n\t: ^(MEMBER (primary {ps.append($primary.text)} ) +)\r\n\t\t{$text = '.'.join(ps)}\r\n\t;\r\nprimary returns[text]\r\n\t@init{a=''}\r\n\t: ID (index_expr{a += $index_expr.text})*\r\n\t\tcall_expr?\r\n\t\t{\r\n\t\tb = $call_expr.text\r\n\t\tif b == None: b = ''\r\n\t\t$text = $ID.text + a + b\r\n\t\t}\r\n\t;\r\ncall_expr returns[text]\r\n\t: ^(CALL expr_list?)\r\n\t\t{\r\n\t\ts = $expr_list.text\r\n\t\tif s == None: s = ''\r\n\t\t$text = '(' + s + ')'\r\n\t\t}\r\n\t;\r\nindex_expr returns[text]\r\n\t: ^(INDEX expr)\r\n\t\t{$text = '[' + $expr.text + ']'}\r\n\t| ^(SLICE a=expr b=expr?)\r\n\t\t{\r\n\t\ts = $b.text\r\n\t\tif s == None: s = ''\r\n\t\t$text = '[\\%s : \\%s]' \\%($a.text, s)\r\n\t\t}\r\n\t;\r\n\r\n\r\nexpr_list returns[text]\r\n\t@init{ps = []}\r\n\t: ^(EXPR_LIST (expr {ps.append($expr.text)} )+)\r\n\t\t{\r\n\t\t$text = ', '.join(ps)\r\n\t\t}\r\n\t;\r\n\r\nexpr returns[text]\r\n\t: a=relation_expr\t{$text = $a.text}\r\n\t| a=logic_or_expr\t{$text = $a.text}\r\n\t| a=logic_and_expr\t{$text = $a.text}\r\n\t| a=bitwise_or_expr\t{$text = $a.text}\r\n\t| a=bitwise_xor_expr\t{$text = $a.text}\r\n\t| a=bitwise_and_expr\t{$text = $a.text}\r\n\t| a=add_expr\t\t{$text = $a.text}\r\n\t| a=mul_expr\t\t{$text = $a.text}\r\n\t| a=not_expr\t\t{$text = $a.text}\r\n\t| a=negative_expr\t{$text = $a.text}\r\n\t| a=atom\t\t\t{$text = $a.text}\r\n\t;\r\nlogic_or_expr returns[text]\r\n\t: ^('||' b=expr c=expr)\r\n\t\t{$text = '(' + $b.text + ' or ' + $c.text + ')'}\r\n\t;\r\nlogic_and_expr returns[text]\r\n\t: ^('&&' b=expr c=expr)\r\n\t\t{$text = $b.text + ' and ' + $c.text}\r\n\t;\r\nbitwise_or_expr returns[text]\r\n\t: ^('|' b=expr c=expr)\r\n\t\t{$text = $b.text + ' | ' + $c.text}\r\n\t;\r\nbitwise_xor_expr returns[text]\r\n\t: ^('^' b=expr c=expr)\r\n\t\t{$text = $b.text + ' ^ ' + $c.text}\r\n\t;\r\nbitwise_and_expr returns[text]\r\n\t: ^('&' b=expr c=expr)\r\n\t\t{$text = $b.text + ' & ' + $c.text}\r\n\t;\r\nrelation_expr returns[text]\r\n\t: ^(op=('<'|'>'|'<='|'>='|'=='|'!=') b=expr c=expr)\r\n\t\t{$text = $b.text + $op.text + $c.text}\r\n\t;\r\nadd_expr returns[text]\r\n\t: ^(op=('+'|'-') b=expr c=expr)\r\n\t\t{$text = '(' + $b.text + ' ' + $op.text + ' ' + $c.text + ')'}\r\n\t;\r\nmul_expr returns[text]\r\n\t: ^(op=('*'|'/'|'%') b=expr c=expr)\r\n\t\t{$text = $b.text + ' ' + $op.text + ' ' + $c.text}\r\n\t;\r\nnot_expr returns[text]\r\n\t: ^('!' a=expr)\r\n\t\t{$text = 'not (' + $a.text + ')'}\r\n\t;\r\nnegative_expr returns[text]\r\n\t: ^(NEGATIVE a=expr)\r\n\t\t{$text = '- (' + $a.text + ')'}\r\n\t;\r\n\r\n\r\nsprintf returns[text]\r\n\t: ^(SPRINTF expr a=expr_list?)\r\n\t\t{\r\n\t\ts = $a.text\r\n\t\tif not s: s=''\r\n\t\t$text = $expr.text + '\\%(' + s + ')'\r\n\t\t}\r\n\t;\r\n\r\nnew_clause returns[text]\r\n\t: ^(NEW module call_expr)\r\n\t\t{$text = $module.text + $call_expr.text}\r\n\t;\r\n\r\narray_decl returns[text]\r\n\t: ^(ARRAY expr_list?)\r\n\t\t{\r\n\t\ts = $expr_list.text\r\n\t\tif s == None: s = ''\r\n\t\t$text = '[' + s + ']'\r\n\t\t}\r\n\t;\r\nobject_decl returns[text]\r\n\t@init{s = ''}\r\n\t: ^(OBJECT (property {s += $property.text} )*)\r\n\t\t{$text = '{' + s + '}'}\r\n\t;\r\nproperty returns[text]\r\n\t: a=(ID | STRING | INT) ':' expr\r\n\t\t{$text = $a.text + ': ' + $expr.text + ','}\r\n\t;\r\n\r\n\r\natom returns[text]\r\n\t: a=literal\t\t{$text = $a.text}\r\n\t| a=member_expr\t{$text = $a.text}\r\n\t| a=new_clause\t{$text = $a.text}\r\n\t| a=array_decl\t{$text = $a.text}\r\n\t| a=object_decl\t{$text = $a.text}\r\n\t| a=sprintf\t\t{$text = $a.text}\r\n\t;\r\nliteral returns[text]\r\n\t: NULL {$text = 'None'}\r\n\t| BOOL {$text = $BOOL.text.capitalize()}\r\n\t| INT {$text = $INT.text}\r\n\t| FLOAT {$text = $FLOAT.text}\r\n\t| STRING {$text = $STRING.text}\r\n\t;\r\n"
  },
  {
    "path": "deps/cpy/Eval.py",
    "content": "# $ANTLR 3.4 Eval.g 2012-12-09 16:07:29\r\n\r\nimport sys\r\nfrom antlr3 import *\r\nfrom antlr3.tree import *\r\n\r\nfrom antlr3.compat import set, frozenset\r\n\r\n       \r\nfrom engine import CpyBuilder\r\n\r\n\r\n\r\n# for convenience in actions\r\nHIDDEN = BaseRecognizer.HIDDEN\r\n\r\n# token types\r\nEOF=-1\r\nT__68=68\r\nT__69=69\r\nT__70=70\r\nT__71=71\r\nT__72=72\r\nT__73=73\r\nT__74=74\r\nT__75=75\r\nT__76=76\r\nT__77=77\r\nT__78=78\r\nT__79=79\r\nT__80=80\r\nT__81=81\r\nT__82=82\r\nT__83=83\r\nT__84=84\r\nT__85=85\r\nT__86=86\r\nT__87=87\r\nT__88=88\r\nT__89=89\r\nT__90=90\r\nT__91=91\r\nT__92=92\r\nT__93=93\r\nT__94=94\r\nT__95=95\r\nT__96=96\r\nT__97=97\r\nT__98=98\r\nT__99=99\r\nT__100=100\r\nT__101=101\r\nT__102=102\r\nT__103=103\r\nT__104=104\r\nT__105=105\r\nT__106=106\r\nT__107=107\r\nT__108=108\r\nT__109=109\r\nT__110=110\r\nT__111=111\r\nT__112=112\r\nT__113=113\r\nT__114=114\r\nT__115=115\r\nT__116=116\r\nT__117=117\r\nT__118=118\r\nT__119=119\r\nT__120=120\r\nT__121=121\r\nT__122=122\r\nT__123=123\r\nT__124=124\r\nT__125=125\r\nT__126=126\r\nT__127=127\r\nT__128=128\r\nT__129=129\r\nT__130=130\r\nT__131=131\r\nT__132=132\r\nT__133=133\r\nT__134=134\r\nT__135=135\r\nT__136=136\r\nALPHA=4\r\nARRAY=5\r\nASSIGN=6\r\nBLOCK=7\r\nBOOL=8\r\nBREAK=9\r\nCALL=10\r\nCASE=11\r\nCATCH=12\r\nCLASS=13\r\nCOMMENT=14\r\nCONSTRUCTOR=15\r\nCONTINUE=16\r\nDEFAULT=17\r\nDIGIT=18\r\nDOUBLE_QUOTE_CHARS=19\r\nDO_WHILE=20\r\nEACH=21\r\nEACH_VAL=22\r\nELSE=23\r\nELSE_IF=24\r\nEMPTY_LINE=25\r\nEXEC_LIST=26\r\nEXEC_STMT=27\r\nEXPR_LIST=28\r\nFINALLY=29\r\nFLOAT=30\r\nFOR=31\r\nFOREACH=32\r\nFUNCTION=33\r\nID=34\r\nID_LIST=35\r\nIF=36\r\nIMPORT=37\r\nINDEX=38\r\nINT=39\r\nLINECOMMENT=40\r\nMEMBER=41\r\nMODULE=42\r\nNEGATIVE=43\r\nNEW=44\r\nNEWLINE=45\r\nNOP=46\r\nNULL=47\r\nOBJECT=48\r\nOP_ASSIGN=49\r\nPARAMS=50\r\nPOST_DEC=51\r\nPOST_INC=52\r\nPRE_DEC=53\r\nPRE_INC=54\r\nPRINT=55\r\nPRINTF=56\r\nRETURN=57\r\nSINGLE_QUOTE_CHARS=58\r\nSLICE=59\r\nSPRINTF=60\r\nSTRING=61\r\nSWITCH=62\r\nTHROW=63\r\nTRY=64\r\nVAR=65\r\nWHILE=66\r\nWS=67\r\n\r\n# token names\r\ntokenNames = [\r\n    \"<invalid>\", \"<EOR>\", \"<DOWN>\", \"<UP>\",\r\n    \"ALPHA\", \"ARRAY\", \"ASSIGN\", \"BLOCK\", \"BOOL\", \"BREAK\", \"CALL\", \"CASE\", \r\n    \"CATCH\", \"CLASS\", \"COMMENT\", \"CONSTRUCTOR\", \"CONTINUE\", \"DEFAULT\", \"DIGIT\", \r\n    \"DOUBLE_QUOTE_CHARS\", \"DO_WHILE\", \"EACH\", \"EACH_VAL\", \"ELSE\", \"ELSE_IF\", \r\n    \"EMPTY_LINE\", \"EXEC_LIST\", \"EXEC_STMT\", \"EXPR_LIST\", \"FINALLY\", \"FLOAT\", \r\n    \"FOR\", \"FOREACH\", \"FUNCTION\", \"ID\", \"ID_LIST\", \"IF\", \"IMPORT\", \"INDEX\", \r\n    \"INT\", \"LINECOMMENT\", \"MEMBER\", \"MODULE\", \"NEGATIVE\", \"NEW\", \"NEWLINE\", \r\n    \"NOP\", \"NULL\", \"OBJECT\", \"OP_ASSIGN\", \"PARAMS\", \"POST_DEC\", \"POST_INC\", \r\n    \"PRE_DEC\", \"PRE_INC\", \"PRINT\", \"PRINTF\", \"RETURN\", \"SINGLE_QUOTE_CHARS\", \r\n    \"SLICE\", \"SPRINTF\", \"STRING\", \"SWITCH\", \"THROW\", \"TRY\", \"VAR\", \"WHILE\", \r\n    \"WS\", \"'!'\", \"'!='\", \"'%'\", \"'%='\", \"'&&'\", \"'&'\", \"'&='\", \"'('\", \"')'\", \r\n    \"'*'\", \"'*='\", \"'+'\", \"'++'\", \"'+='\", \"','\", \"'-'\", \"'--'\", \"'-='\", \r\n    \"'.'\", \"'.*'\", \"'..'\", \"'/'\", \"'/='\", \"':'\", \"';'\", \"'<'\", \"'<='\", \"'='\", \r\n    \"'=='\", \"'=>'\", \"'>'\", \"'>='\", \"'['\", \"']'\", \"'^'\", \"'^='\", \"'as'\", \r\n    \"'break'\", \"'case'\", \"'catch'\", \"'class'\", \"'continue'\", \"'default'\", \r\n    \"'do'\", \"'else'\", \"'extends'\", \"'finally'\", \"'for'\", \"'foreach'\", \"'function'\", \r\n    \"'if'\", \"'import'\", \"'init'\", \"'new'\", \"'print'\", \"'printf'\", \"'public'\", \r\n    \"'return'\", \"'sprintf'\", \"'static'\", \"'switch'\", \"'throw'\", \"'try'\", \r\n    \"'while'\", \"'{'\", \"'|'\", \"'|='\", \"'||'\", \"'}'\"\r\n]\r\n\r\n\r\n\r\n\r\nclass Eval(TreeParser):\r\n    grammarFileName = \"Eval.g\"\r\n    api_version = 1\r\n    tokenNames = tokenNames\r\n\r\n    def __init__(self, input, state=None, *args, **kwargs):\r\n        if state is None:\r\n            state = RecognizerSharedState()\r\n\r\n        super(Eval, self).__init__(input, state, *args, **kwargs)\r\n\r\n        self.dfa4 = self.DFA4(\r\n            self, 4,\r\n            eot = self.DFA4_eot,\r\n            eof = self.DFA4_eof,\r\n            min = self.DFA4_min,\r\n            max = self.DFA4_max,\r\n            accept = self.DFA4_accept,\r\n            special = self.DFA4_special,\r\n            transition = self.DFA4_transition\r\n            )\r\n\r\n\r\n\r\n             \r\n\r\n\r\n        self.delegates = []\r\n\r\n\r\n\r\n\r\n\r\n\r\n    # $ANTLR start \"prog\"\r\n    # Eval.g:21:1: prog[cpy] : ( stmt )* ;\r\n    def prog(self, cpy):\r\n              \r\n        self.cpy = cpy\r\n        \t\r\n        try:\r\n            try:\r\n                # Eval.g:28:2: ( ( stmt )* )\r\n                # Eval.g:28:4: ( stmt )*\r\n                pass \r\n                # Eval.g:28:4: ( stmt )*\r\n                while True: #loop1\r\n                    alt1 = 2\r\n                    LA1_0 = self.input.LA(1)\r\n\r\n                    if (LA1_0 == BREAK or LA1_0 == CLASS or LA1_0 == CONTINUE or LA1_0 == DO_WHILE or LA1_0 == EXEC_STMT or (FOR <= LA1_0 <= FUNCTION) or (IF <= LA1_0 <= IMPORT) or (PRINT <= LA1_0 <= RETURN) or (SWITCH <= LA1_0 <= TRY) or LA1_0 == WHILE) :\r\n                        alt1 = 1\r\n\r\n\r\n                    if alt1 == 1:\r\n                        # Eval.g:28:4: stmt\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_stmt_in_prog69)\r\n                        self.stmt()\r\n\r\n                        self._state.following.pop()\r\n\r\n\r\n                    else:\r\n                        break #loop1\r\n\r\n\r\n\r\n\r\n                #action start\r\n                       \r\n                self.cpy.close()\r\n                \t\r\n                #action end\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"prog\"\r\n\r\n\r\n\r\n    # $ANTLR start \"stmt\"\r\n    # Eval.g:31:1: stmt : ( import_stmt | exec_stmt | print_stmt | printf_stmt | break_stmt | continue_stmt | return_stmt | if_stmt | while_stmt | do_while_stmt | switch_stmt | throw_stmt | try_stmt | func_decl | class_decl | for_stmt | foreach_stmt );\r\n    def stmt(self, ):\r\n        try:\r\n            try:\r\n                # Eval.g:32:2: ( import_stmt | exec_stmt | print_stmt | printf_stmt | break_stmt | continue_stmt | return_stmt | if_stmt | while_stmt | do_while_stmt | switch_stmt | throw_stmt | try_stmt | func_decl | class_decl | for_stmt | foreach_stmt )\r\n                alt2 = 17\r\n                LA2 = self.input.LA(1)\r\n                if LA2 == IMPORT:\r\n                    alt2 = 1\r\n                elif LA2 == EXEC_STMT:\r\n                    alt2 = 2\r\n                elif LA2 == PRINT:\r\n                    alt2 = 3\r\n                elif LA2 == PRINTF:\r\n                    alt2 = 4\r\n                elif LA2 == BREAK:\r\n                    alt2 = 5\r\n                elif LA2 == CONTINUE:\r\n                    alt2 = 6\r\n                elif LA2 == RETURN:\r\n                    alt2 = 7\r\n                elif LA2 == IF:\r\n                    alt2 = 8\r\n                elif LA2 == WHILE:\r\n                    alt2 = 9\r\n                elif LA2 == DO_WHILE:\r\n                    alt2 = 10\r\n                elif LA2 == SWITCH:\r\n                    alt2 = 11\r\n                elif LA2 == THROW:\r\n                    alt2 = 12\r\n                elif LA2 == TRY:\r\n                    alt2 = 13\r\n                elif LA2 == FUNCTION:\r\n                    alt2 = 14\r\n                elif LA2 == CLASS:\r\n                    alt2 = 15\r\n                elif LA2 == FOR:\r\n                    alt2 = 16\r\n                elif LA2 == FOREACH:\r\n                    alt2 = 17\r\n                else:\r\n                    nvae = NoViableAltException(\"\", 2, 0, self.input)\r\n\r\n                    raise nvae\r\n\r\n\r\n                if alt2 == 1:\r\n                    # Eval.g:32:4: import_stmt\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_import_stmt_in_stmt81)\r\n                    self.import_stmt()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt2 == 2:\r\n                    # Eval.g:33:4: exec_stmt\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_exec_stmt_in_stmt86)\r\n                    self.exec_stmt()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt2 == 3:\r\n                    # Eval.g:34:4: print_stmt\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_print_stmt_in_stmt91)\r\n                    self.print_stmt()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt2 == 4:\r\n                    # Eval.g:34:17: printf_stmt\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_printf_stmt_in_stmt95)\r\n                    self.printf_stmt()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt2 == 5:\r\n                    # Eval.g:35:4: break_stmt\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_break_stmt_in_stmt100)\r\n                    self.break_stmt()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt2 == 6:\r\n                    # Eval.g:36:4: continue_stmt\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_continue_stmt_in_stmt105)\r\n                    self.continue_stmt()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt2 == 7:\r\n                    # Eval.g:37:4: return_stmt\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_return_stmt_in_stmt110)\r\n                    self.return_stmt()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt2 == 8:\r\n                    # Eval.g:38:4: if_stmt\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_if_stmt_in_stmt115)\r\n                    self.if_stmt()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt2 == 9:\r\n                    # Eval.g:39:4: while_stmt\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_while_stmt_in_stmt120)\r\n                    self.while_stmt()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt2 == 10:\r\n                    # Eval.g:40:4: do_while_stmt\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_do_while_stmt_in_stmt125)\r\n                    self.do_while_stmt()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt2 == 11:\r\n                    # Eval.g:41:4: switch_stmt\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_switch_stmt_in_stmt130)\r\n                    self.switch_stmt()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt2 == 12:\r\n                    # Eval.g:42:4: throw_stmt\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_throw_stmt_in_stmt135)\r\n                    self.throw_stmt()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt2 == 13:\r\n                    # Eval.g:43:4: try_stmt\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_try_stmt_in_stmt140)\r\n                    self.try_stmt()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt2 == 14:\r\n                    # Eval.g:44:4: func_decl\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_func_decl_in_stmt145)\r\n                    self.func_decl()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt2 == 15:\r\n                    # Eval.g:45:4: class_decl\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_class_decl_in_stmt150)\r\n                    self.class_decl()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt2 == 16:\r\n                    # Eval.g:46:4: for_stmt\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_for_stmt_in_stmt155)\r\n                    self.for_stmt()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt2 == 17:\r\n                    # Eval.g:47:4: foreach_stmt\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_foreach_stmt_in_stmt160)\r\n                    self.foreach_stmt()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"stmt\"\r\n\r\n\r\n\r\n    # $ANTLR start \"block\"\r\n    # Eval.g:52:1: block : ^( BLOCK ( stmt )* ) ;\r\n    def block(self, ):\r\n              \r\n        self.cpy.block_enter()\r\n        \t\r\n        try:\r\n            try:\r\n                # Eval.g:59:2: ( ^( BLOCK ( stmt )* ) )\r\n                # Eval.g:59:4: ^( BLOCK ( stmt )* )\r\n                pass \r\n                self.match(self.input, BLOCK, self.FOLLOW_BLOCK_in_block185)\r\n\r\n                if self.input.LA(1) == DOWN:\r\n                    self.match(self.input, DOWN, None)\r\n                    # Eval.g:59:12: ( stmt )*\r\n                    while True: #loop3\r\n                        alt3 = 2\r\n                        LA3_0 = self.input.LA(1)\r\n\r\n                        if (LA3_0 == BREAK or LA3_0 == CLASS or LA3_0 == CONTINUE or LA3_0 == DO_WHILE or LA3_0 == EXEC_STMT or (FOR <= LA3_0 <= FUNCTION) or (IF <= LA3_0 <= IMPORT) or (PRINT <= LA3_0 <= RETURN) or (SWITCH <= LA3_0 <= TRY) or LA3_0 == WHILE) :\r\n                            alt3 = 1\r\n\r\n\r\n                        if alt3 == 1:\r\n                            # Eval.g:59:12: stmt\r\n                            pass \r\n                            self._state.following.append(self.FOLLOW_stmt_in_block187)\r\n                            self.stmt()\r\n\r\n                            self._state.following.pop()\r\n\r\n\r\n                        else:\r\n                            break #loop3\r\n\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n\r\n\r\n\r\n                #action start\r\n                       \r\n                self.cpy.block_leave()\r\n                \t\r\n                #action end\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"block\"\r\n\r\n\r\n\r\n    # $ANTLR start \"import_stmt\"\r\n    # Eval.g:62:1: import_stmt : ^( IMPORT (a= module |b= module '.*' )+ ) ;\r\n    def import_stmt(self, ):\r\n        a = None\r\n\r\n        b = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:63:2: ( ^( IMPORT (a= module |b= module '.*' )+ ) )\r\n                # Eval.g:63:4: ^( IMPORT (a= module |b= module '.*' )+ )\r\n                pass \r\n                self.match(self.input, IMPORT, self.FOLLOW_IMPORT_in_import_stmt201)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                # Eval.g:64:3: (a= module |b= module '.*' )+\r\n                cnt4 = 0\r\n                while True: #loop4\r\n                    alt4 = 3\r\n                    alt4 = self.dfa4.predict(self.input)\r\n                    if alt4 == 1:\r\n                        # Eval.g:64:5: a= module\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_module_in_import_stmt209)\r\n                        a = self.module()\r\n\r\n                        self._state.following.pop()\r\n\r\n                        #action start\r\n                        self.cpy.op_import(a, None)\r\n                        #action end\r\n\r\n\r\n\r\n                    elif alt4 == 2:\r\n                        # Eval.g:66:5: b= module '.*'\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_module_in_import_stmt222)\r\n                        b = self.module()\r\n\r\n                        self._state.following.pop()\r\n\r\n                        self.match(self.input, 87, self.FOLLOW_87_in_import_stmt224)\r\n\r\n                        #action start\r\n                        self.cpy.op_import(b, '*')\r\n                        #action end\r\n\r\n\r\n\r\n                    else:\r\n                        if cnt4 >= 1:\r\n                            break #loop4\r\n\r\n                        eee = EarlyExitException(4, self.input)\r\n                        raise eee\r\n\r\n                    cnt4 += 1\r\n\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"import_stmt\"\r\n\r\n\r\n\r\n    # $ANTLR start \"exec_stmt\"\r\n    # Eval.g:72:1: exec_stmt : ^( EXEC_STMT exec_list ) ;\r\n    def exec_stmt(self, ):\r\n        exec_list1 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:73:2: ( ^( EXEC_STMT exec_list ) )\r\n                # Eval.g:73:4: ^( EXEC_STMT exec_list )\r\n                pass \r\n                self.match(self.input, EXEC_STMT, self.FOLLOW_EXEC_STMT_in_exec_stmt250)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_exec_list_in_exec_stmt252)\r\n                exec_list1 = self.exec_list()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                self.cpy.stmt(exec_list1)\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"exec_stmt\"\r\n\r\n\r\n\r\n    # $ANTLR start \"exec_expr\"\r\n    # Eval.g:76:1: exec_expr returns [text] : ( member_expr | ^( ASSIGN member_expr op= ( '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '^=' | '|=' ) expr ) | ^( POST_INC member_expr ) | ^( POST_DEC member_expr ) | ^( PRE_INC member_expr ) | ^( PRE_DEC member_expr ) );\r\n    def exec_expr(self, ):\r\n        text = None\r\n\r\n\r\n        op = None\r\n        member_expr2 = None\r\n\r\n        member_expr3 = None\r\n\r\n        expr4 = None\r\n\r\n        member_expr5 = None\r\n\r\n        member_expr6 = None\r\n\r\n        member_expr7 = None\r\n\r\n        member_expr8 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:77:2: ( member_expr | ^( ASSIGN member_expr op= ( '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '^=' | '|=' ) expr ) | ^( POST_INC member_expr ) | ^( POST_DEC member_expr ) | ^( PRE_INC member_expr ) | ^( PRE_DEC member_expr ) )\r\n                alt5 = 6\r\n                LA5 = self.input.LA(1)\r\n                if LA5 == MEMBER:\r\n                    alt5 = 1\r\n                elif LA5 == ASSIGN:\r\n                    alt5 = 2\r\n                elif LA5 == POST_INC:\r\n                    alt5 = 3\r\n                elif LA5 == POST_DEC:\r\n                    alt5 = 4\r\n                elif LA5 == PRE_INC:\r\n                    alt5 = 5\r\n                elif LA5 == PRE_DEC:\r\n                    alt5 = 6\r\n                else:\r\n                    nvae = NoViableAltException(\"\", 5, 0, self.input)\r\n\r\n                    raise nvae\r\n\r\n\r\n                if alt5 == 1:\r\n                    # Eval.g:77:4: member_expr\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_member_expr_in_exec_expr270)\r\n                    member_expr2 = self.member_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = member_expr2\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt5 == 2:\r\n                    # Eval.g:79:4: ^( ASSIGN member_expr op= ( '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '^=' | '|=' ) expr )\r\n                    pass \r\n                    self.match(self.input, ASSIGN, self.FOLLOW_ASSIGN_in_exec_expr280)\r\n\r\n                    self.match(self.input, DOWN, None)\r\n                    self._state.following.append(self.FOLLOW_member_expr_in_exec_expr282)\r\n                    member_expr3 = self.member_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    op = self.input.LT(1)\r\n\r\n                    if self.input.LA(1) == 71 or self.input.LA(1) == 74 or self.input.LA(1) == 78 or self.input.LA(1) == 81 or self.input.LA(1) == 85 or self.input.LA(1) == 90 or self.input.LA(1) == 95 or self.input.LA(1) == 103 or self.input.LA(1) == 134:\r\n                        self.input.consume()\r\n                        self._state.errorRecovery = False\r\n\r\n\r\n                    else:\r\n                        mse = MismatchedSetException(None, self.input)\r\n                        raise mse\r\n\r\n\r\n\r\n                    self._state.following.append(self.FOLLOW_expr_in_exec_expr306)\r\n                    expr4 = self.expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n                    #action start\r\n                    text = self.cpy.op_assign(member_expr3, expr4, op.text)\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt5 == 3:\r\n                    # Eval.g:81:4: ^( POST_INC member_expr )\r\n                    pass \r\n                    self.match(self.input, POST_INC, self.FOLLOW_POST_INC_in_exec_expr317)\r\n\r\n                    self.match(self.input, DOWN, None)\r\n                    self._state.following.append(self.FOLLOW_member_expr_in_exec_expr319)\r\n                    member_expr5 = self.member_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n                    #action start\r\n                    text = self.cpy.op_inc(member_expr5)\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt5 == 4:\r\n                    # Eval.g:83:4: ^( POST_DEC member_expr )\r\n                    pass \r\n                    self.match(self.input, POST_DEC, self.FOLLOW_POST_DEC_in_exec_expr330)\r\n\r\n                    self.match(self.input, DOWN, None)\r\n                    self._state.following.append(self.FOLLOW_member_expr_in_exec_expr332)\r\n                    member_expr6 = self.member_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n                    #action start\r\n                    text = self.cpy.op_dec(member_expr6)\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt5 == 5:\r\n                    # Eval.g:85:4: ^( PRE_INC member_expr )\r\n                    pass \r\n                    self.match(self.input, PRE_INC, self.FOLLOW_PRE_INC_in_exec_expr343)\r\n\r\n                    self.match(self.input, DOWN, None)\r\n                    self._state.following.append(self.FOLLOW_member_expr_in_exec_expr345)\r\n                    member_expr7 = self.member_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n                    #action start\r\n                    text = self.cpy.op_inc(member_expr7)\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt5 == 6:\r\n                    # Eval.g:87:4: ^( PRE_DEC member_expr )\r\n                    pass \r\n                    self.match(self.input, PRE_DEC, self.FOLLOW_PRE_DEC_in_exec_expr356)\r\n\r\n                    self.match(self.input, DOWN, None)\r\n                    self._state.following.append(self.FOLLOW_member_expr_in_exec_expr358)\r\n                    member_expr8 = self.member_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n                    #action start\r\n                    text = self.cpy.op_dec(member_expr8)\r\n                    #action end\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"exec_expr\"\r\n\r\n\r\n\r\n    # $ANTLR start \"exec_list\"\r\n    # Eval.g:90:1: exec_list returns [text] : ^( EXEC_LIST ( exec_expr )+ ) ;\r\n    def exec_list(self, ):\r\n        text = None\r\n\r\n\r\n        exec_expr9 = None\r\n\r\n\r\n        ps = []\r\n        try:\r\n            try:\r\n                # Eval.g:92:2: ( ^( EXEC_LIST ( exec_expr )+ ) )\r\n                # Eval.g:92:4: ^( EXEC_LIST ( exec_expr )+ )\r\n                pass \r\n                self.match(self.input, EXEC_LIST, self.FOLLOW_EXEC_LIST_in_exec_list382)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                # Eval.g:92:16: ( exec_expr )+\r\n                cnt6 = 0\r\n                while True: #loop6\r\n                    alt6 = 2\r\n                    LA6_0 = self.input.LA(1)\r\n\r\n                    if (LA6_0 == ASSIGN or LA6_0 == MEMBER or (POST_DEC <= LA6_0 <= PRE_INC)) :\r\n                        alt6 = 1\r\n\r\n\r\n                    if alt6 == 1:\r\n                        # Eval.g:92:17: exec_expr\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_exec_expr_in_exec_list385)\r\n                        exec_expr9 = self.exec_expr()\r\n\r\n                        self._state.following.pop()\r\n\r\n                        #action start\r\n                        ps.append(exec_expr9)\r\n                        #action end\r\n\r\n\r\n\r\n                    else:\r\n                        if cnt6 >= 1:\r\n                            break #loop6\r\n\r\n                        eee = EarlyExitException(6, self.input)\r\n                        raise eee\r\n\r\n                    cnt6 += 1\r\n\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                text = ', '.join(ps)\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"exec_list\"\r\n\r\n\r\n\r\n    # $ANTLR start \"printf_stmt\"\r\n    # Eval.g:96:1: printf_stmt : ^( PRINTF expr ( expr_list )? ) ;\r\n    def printf_stmt(self, ):\r\n        expr10 = None\r\n\r\n        expr_list11 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:97:2: ( ^( PRINTF expr ( expr_list )? ) )\r\n                # Eval.g:97:4: ^( PRINTF expr ( expr_list )? )\r\n                pass \r\n                self.match(self.input, PRINTF, self.FOLLOW_PRINTF_in_printf_stmt408)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_printf_stmt410)\r\n                expr10 = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                # Eval.g:97:18: ( expr_list )?\r\n                alt7 = 2\r\n                LA7_0 = self.input.LA(1)\r\n\r\n                if (LA7_0 == EXPR_LIST) :\r\n                    alt7 = 1\r\n                if alt7 == 1:\r\n                    # Eval.g:97:18: expr_list\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_expr_list_in_printf_stmt412)\r\n                    expr_list11 = self.expr_list()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                self.cpy.op_printf(expr10, expr_list11)\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"printf_stmt\"\r\n\r\n\r\n\r\n    # $ANTLR start \"print_stmt\"\r\n    # Eval.g:100:1: print_stmt : ^( PRINT expr_list ) ;\r\n    def print_stmt(self, ):\r\n        expr_list12 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:101:2: ( ^( PRINT expr_list ) )\r\n                # Eval.g:101:4: ^( PRINT expr_list )\r\n                pass \r\n                self.match(self.input, PRINT, self.FOLLOW_PRINT_in_print_stmt429)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_list_in_print_stmt431)\r\n                expr_list12 = self.expr_list()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                self.cpy.op_print(expr_list12)\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"print_stmt\"\r\n\r\n\r\n\r\n    # $ANTLR start \"break_stmt\"\r\n    # Eval.g:107:1: break_stmt : BREAK ;\r\n    def break_stmt(self, ):\r\n        try:\r\n            try:\r\n                # Eval.g:108:2: ( BREAK )\r\n                # Eval.g:108:4: BREAK\r\n                pass \r\n                self.match(self.input, BREAK, self.FOLLOW_BREAK_in_break_stmt451)\r\n\r\n                #action start\r\n                self.cpy.op_break()\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"break_stmt\"\r\n\r\n\r\n\r\n    # $ANTLR start \"continue_stmt\"\r\n    # Eval.g:111:1: continue_stmt : CONTINUE ;\r\n    def continue_stmt(self, ):\r\n        try:\r\n            try:\r\n                # Eval.g:112:2: ( CONTINUE )\r\n                # Eval.g:112:4: CONTINUE\r\n                pass \r\n                self.match(self.input, CONTINUE, self.FOLLOW_CONTINUE_in_continue_stmt465)\r\n\r\n                #action start\r\n                self.cpy.op_continue()\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"continue_stmt\"\r\n\r\n\r\n\r\n    # $ANTLR start \"return_stmt\"\r\n    # Eval.g:115:1: return_stmt : ^( RETURN ( expr )? ) ;\r\n    def return_stmt(self, ):\r\n        expr13 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:116:2: ( ^( RETURN ( expr )? ) )\r\n                # Eval.g:116:4: ^( RETURN ( expr )? )\r\n                pass \r\n                self.match(self.input, RETURN, self.FOLLOW_RETURN_in_return_stmt480)\r\n\r\n                if self.input.LA(1) == DOWN:\r\n                    self.match(self.input, DOWN, None)\r\n                    # Eval.g:116:13: ( expr )?\r\n                    alt8 = 2\r\n                    LA8_0 = self.input.LA(1)\r\n\r\n                    if (LA8_0 == ARRAY or LA8_0 == BOOL or LA8_0 == FLOAT or LA8_0 == INT or LA8_0 == MEMBER or (NEGATIVE <= LA8_0 <= NEW) or (NULL <= LA8_0 <= OBJECT) or (SPRINTF <= LA8_0 <= STRING) or (68 <= LA8_0 <= 70) or (72 <= LA8_0 <= 73) or LA8_0 == 77 or LA8_0 == 79 or LA8_0 == 83 or LA8_0 == 89 or (93 <= LA8_0 <= 94) or LA8_0 == 96 or (98 <= LA8_0 <= 99) or LA8_0 == 102 or LA8_0 == 133 or LA8_0 == 135) :\r\n                        alt8 = 1\r\n                    if alt8 == 1:\r\n                        # Eval.g:116:13: expr\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_expr_in_return_stmt482)\r\n                        expr13 = self.expr()\r\n\r\n                        self._state.following.pop()\r\n\r\n\r\n\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n\r\n                #action start\r\n                self.cpy.op_return(expr13)\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"return_stmt\"\r\n\r\n\r\n\r\n    # $ANTLR start \"if_stmt\"\r\n    # Eval.g:121:1: if_stmt : if_clause ( else_if_clause )* ( else_clause )? ;\r\n    def if_stmt(self, ):\r\n              \r\n        self.cpy.if_enter()\r\n        \t\r\n        try:\r\n            try:\r\n                # Eval.g:128:2: ( if_clause ( else_if_clause )* ( else_clause )? )\r\n                # Eval.g:128:4: if_clause ( else_if_clause )* ( else_clause )?\r\n                pass \r\n                self._state.following.append(self.FOLLOW_if_clause_in_if_stmt510)\r\n                self.if_clause()\r\n\r\n                self._state.following.pop()\r\n\r\n                # Eval.g:128:14: ( else_if_clause )*\r\n                while True: #loop9\r\n                    alt9 = 2\r\n                    LA9_0 = self.input.LA(1)\r\n\r\n                    if (LA9_0 == ELSE_IF) :\r\n                        alt9 = 1\r\n\r\n\r\n                    if alt9 == 1:\r\n                        # Eval.g:128:14: else_if_clause\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_else_if_clause_in_if_stmt512)\r\n                        self.else_if_clause()\r\n\r\n                        self._state.following.pop()\r\n\r\n\r\n                    else:\r\n                        break #loop9\r\n\r\n\r\n                # Eval.g:128:30: ( else_clause )?\r\n                alt10 = 2\r\n                LA10_0 = self.input.LA(1)\r\n\r\n                if (LA10_0 == ELSE) :\r\n                    alt10 = 1\r\n                if alt10 == 1:\r\n                    # Eval.g:128:30: else_clause\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_else_clause_in_if_stmt515)\r\n                    self.else_clause()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n\r\n\r\n\r\n\r\n                #action start\r\n                       \r\n                self.cpy.if_leave()\r\n                \t\r\n                #action end\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"if_stmt\"\r\n\r\n\r\n\r\n    # $ANTLR start \"if_clause\"\r\n    # Eval.g:130:1: if_clause : ^( IF expr block ) ;\r\n    def if_clause(self, ):\r\n        expr14 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:131:2: ( ^( IF expr block ) )\r\n                # Eval.g:131:4: ^( IF expr block )\r\n                pass \r\n                self.match(self.input, IF, self.FOLLOW_IF_in_if_clause527)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_if_clause529)\r\n                expr14 = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                #action start\r\n                self.cpy.op_if(expr14)\r\n                #action end\r\n\r\n\r\n                self._state.following.append(self.FOLLOW_block_in_if_clause533)\r\n                self.block()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"if_clause\"\r\n\r\n\r\n\r\n    # $ANTLR start \"else_if_clause\"\r\n    # Eval.g:133:1: else_if_clause : ^( ELSE_IF if_clause ) ;\r\n    def else_if_clause(self, ):\r\n        try:\r\n            try:\r\n                # Eval.g:134:2: ( ^( ELSE_IF if_clause ) )\r\n                # Eval.g:134:4: ^( ELSE_IF if_clause )\r\n                pass \r\n                self.match(self.input, ELSE_IF, self.FOLLOW_ELSE_IF_in_else_if_clause545)\r\n\r\n                #action start\r\n                self.cpy.op_else_if()\r\n                #action end\r\n\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_if_clause_in_else_if_clause549)\r\n                self.if_clause()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"else_if_clause\"\r\n\r\n\r\n\r\n    # $ANTLR start \"else_clause\"\r\n    # Eval.g:136:1: else_clause : ^( ELSE block ) ;\r\n    def else_clause(self, ):\r\n        try:\r\n            try:\r\n                # Eval.g:137:2: ( ^( ELSE block ) )\r\n                # Eval.g:137:4: ^( ELSE block )\r\n                pass \r\n                self.match(self.input, ELSE, self.FOLLOW_ELSE_in_else_clause561)\r\n\r\n                #action start\r\n                self.cpy.op_else()\r\n                #action end\r\n\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_block_in_else_clause565)\r\n                self.block()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"else_clause\"\r\n\r\n\r\n\r\n    # $ANTLR start \"while_stmt\"\r\n    # Eval.g:141:1: while_stmt : ^( WHILE expr block ) ;\r\n    def while_stmt(self, ):\r\n        expr15 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:142:2: ( ^( WHILE expr block ) )\r\n                # Eval.g:142:4: ^( WHILE expr block )\r\n                pass \r\n                self.match(self.input, WHILE, self.FOLLOW_WHILE_in_while_stmt579)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_while_stmt581)\r\n                expr15 = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                #action start\r\n                self.cpy.op_while(expr15)\r\n                #action end\r\n\r\n\r\n                self._state.following.append(self.FOLLOW_block_in_while_stmt585)\r\n                self.block()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"while_stmt\"\r\n\r\n\r\n\r\n    # $ANTLR start \"do_while_stmt\"\r\n    # Eval.g:145:1: do_while_stmt : ^( DO_WHILE block expr ) ;\r\n    def do_while_stmt(self, ):\r\n        expr16 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:146:2: ( ^( DO_WHILE block expr ) )\r\n                # Eval.g:146:4: ^( DO_WHILE block expr )\r\n                pass \r\n                self.match(self.input, DO_WHILE, self.FOLLOW_DO_WHILE_in_do_while_stmt598)\r\n\r\n                #action start\r\n                self.cpy.op_do_while_enter()\r\n                #action end\r\n\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_block_in_do_while_stmt604)\r\n                self.block()\r\n\r\n                self._state.following.pop()\r\n\r\n                self._state.following.append(self.FOLLOW_expr_in_do_while_stmt608)\r\n                expr16 = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                #action start\r\n                self.cpy.op_do_while_leave(expr16)\r\n                #action end\r\n\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"do_while_stmt\"\r\n\r\n\r\n\r\n    # $ANTLR start \"switch_stmt\"\r\n    # Eval.g:153:1: switch_stmt : ^( SWITCH expr case_block ) ;\r\n    def switch_stmt(self, ):\r\n        expr17 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:154:2: ( ^( SWITCH expr case_block ) )\r\n                # Eval.g:154:4: ^( SWITCH expr case_block )\r\n                pass \r\n                self.match(self.input, SWITCH, self.FOLLOW_SWITCH_in_switch_stmt627)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_switch_stmt629)\r\n                expr17 = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                #action start\r\n                self.cpy.op_switch_enter(expr17)\r\n                #action end\r\n\r\n\r\n                self._state.following.append(self.FOLLOW_case_block_in_switch_stmt633)\r\n                self.case_block()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                self.cpy.op_switch_leave()\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"switch_stmt\"\r\n\r\n\r\n\r\n    # $ANTLR start \"case_block\"\r\n    # Eval.g:157:1: case_block : '{' ( case_clause )+ ( default_clause )? '}' ;\r\n    def case_block(self, ):\r\n        try:\r\n            try:\r\n                # Eval.g:158:2: ( '{' ( case_clause )+ ( default_clause )? '}' )\r\n                # Eval.g:158:4: '{' ( case_clause )+ ( default_clause )? '}'\r\n                pass \r\n                self.match(self.input, 132, self.FOLLOW_132_in_case_block648)\r\n\r\n                # Eval.g:158:8: ( case_clause )+\r\n                cnt11 = 0\r\n                while True: #loop11\r\n                    alt11 = 2\r\n                    LA11_0 = self.input.LA(1)\r\n\r\n                    if (LA11_0 == CASE) :\r\n                        alt11 = 1\r\n\r\n\r\n                    if alt11 == 1:\r\n                        # Eval.g:158:9: case_clause\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_case_clause_in_case_block651)\r\n                        self.case_clause()\r\n\r\n                        self._state.following.pop()\r\n\r\n\r\n                    else:\r\n                        if cnt11 >= 1:\r\n                            break #loop11\r\n\r\n                        eee = EarlyExitException(11, self.input)\r\n                        raise eee\r\n\r\n                    cnt11 += 1\r\n\r\n\r\n                # Eval.g:158:23: ( default_clause )?\r\n                alt12 = 2\r\n                LA12_0 = self.input.LA(1)\r\n\r\n                if (LA12_0 == DEFAULT) :\r\n                    alt12 = 1\r\n                if alt12 == 1:\r\n                    # Eval.g:158:24: default_clause\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_default_clause_in_case_block656)\r\n                    self.default_clause()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n\r\n\r\n                self.match(self.input, 136, self.FOLLOW_136_in_case_block660)\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"case_block\"\r\n\r\n\r\n\r\n    # $ANTLR start \"case_clause\"\r\n    # Eval.g:160:1: case_clause : ^( CASE ( case_test )+ ( stmt )* break_stmt ) ;\r\n    def case_clause(self, ):\r\n        self.cpy.op_case_enter()\r\n        try:\r\n            try:\r\n                # Eval.g:162:2: ( ^( CASE ( case_test )+ ( stmt )* break_stmt ) )\r\n                # Eval.g:162:4: ^( CASE ( case_test )+ ( stmt )* break_stmt )\r\n                pass \r\n                self.match(self.input, CASE, self.FOLLOW_CASE_in_case_clause676)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                # Eval.g:162:11: ( case_test )+\r\n                cnt13 = 0\r\n                while True: #loop13\r\n                    alt13 = 2\r\n                    LA13_0 = self.input.LA(1)\r\n\r\n                    if (LA13_0 == CASE) :\r\n                        alt13 = 1\r\n\r\n\r\n                    if alt13 == 1:\r\n                        # Eval.g:162:11: case_test\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_case_test_in_case_clause678)\r\n                        self.case_test()\r\n\r\n                        self._state.following.pop()\r\n\r\n\r\n                    else:\r\n                        if cnt13 >= 1:\r\n                            break #loop13\r\n\r\n                        eee = EarlyExitException(13, self.input)\r\n                        raise eee\r\n\r\n                    cnt13 += 1\r\n\r\n\r\n                #action start\r\n                self.cpy.op_case()\r\n                #action end\r\n\r\n\r\n                # Eval.g:162:43: ( stmt )*\r\n                while True: #loop14\r\n                    alt14 = 2\r\n                    LA14_0 = self.input.LA(1)\r\n\r\n                    if (LA14_0 == BREAK) :\r\n                        LA14_1 = self.input.LA(2)\r\n\r\n                        if (LA14_1 == BREAK or LA14_1 == CLASS or LA14_1 == CONTINUE or LA14_1 == DO_WHILE or LA14_1 == EXEC_STMT or (FOR <= LA14_1 <= FUNCTION) or (IF <= LA14_1 <= IMPORT) or (PRINT <= LA14_1 <= RETURN) or (SWITCH <= LA14_1 <= TRY) or LA14_1 == WHILE) :\r\n                            alt14 = 1\r\n\r\n\r\n                    elif (LA14_0 == CLASS or LA14_0 == CONTINUE or LA14_0 == DO_WHILE or LA14_0 == EXEC_STMT or (FOR <= LA14_0 <= FUNCTION) or (IF <= LA14_0 <= IMPORT) or (PRINT <= LA14_0 <= RETURN) or (SWITCH <= LA14_0 <= TRY) or LA14_0 == WHILE) :\r\n                        alt14 = 1\r\n\r\n\r\n                    if alt14 == 1:\r\n                        # Eval.g:162:43: stmt\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_stmt_in_case_clause683)\r\n                        self.stmt()\r\n\r\n                        self._state.following.pop()\r\n\r\n\r\n                    else:\r\n                        break #loop14\r\n\r\n\r\n                self._state.following.append(self.FOLLOW_break_stmt_in_case_clause686)\r\n                self.break_stmt()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                self.cpy.op_case_leave()\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"case_clause\"\r\n\r\n\r\n\r\n    # $ANTLR start \"case_test\"\r\n    # Eval.g:165:1: case_test : ^( CASE expr ) ;\r\n    def case_test(self, ):\r\n        expr18 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:166:2: ( ^( CASE expr ) )\r\n                # Eval.g:166:4: ^( CASE expr )\r\n                pass \r\n                self.match(self.input, CASE, self.FOLLOW_CASE_in_case_test702)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_case_test704)\r\n                expr18 = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                self.cpy.op_case_test(expr18)\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"case_test\"\r\n\r\n\r\n\r\n    # $ANTLR start \"default_clause\"\r\n    # Eval.g:169:1: default_clause : ^( DEFAULT ( stmt )* ) ;\r\n    def default_clause(self, ):\r\n              \r\n        self.cpy.op_default_enter()\r\n        \t\r\n        try:\r\n            try:\r\n                # Eval.g:173:2: ( ^( DEFAULT ( stmt )* ) )\r\n                # Eval.g:173:4: ^( DEFAULT ( stmt )* )\r\n                pass \r\n                self.match(self.input, DEFAULT, self.FOLLOW_DEFAULT_in_default_clause725)\r\n\r\n                if self.input.LA(1) == DOWN:\r\n                    self.match(self.input, DOWN, None)\r\n                    # Eval.g:173:14: ( stmt )*\r\n                    while True: #loop15\r\n                        alt15 = 2\r\n                        LA15_0 = self.input.LA(1)\r\n\r\n                        if (LA15_0 == BREAK or LA15_0 == CLASS or LA15_0 == CONTINUE or LA15_0 == DO_WHILE or LA15_0 == EXEC_STMT or (FOR <= LA15_0 <= FUNCTION) or (IF <= LA15_0 <= IMPORT) or (PRINT <= LA15_0 <= RETURN) or (SWITCH <= LA15_0 <= TRY) or LA15_0 == WHILE) :\r\n                            alt15 = 1\r\n\r\n\r\n                        if alt15 == 1:\r\n                            # Eval.g:173:14: stmt\r\n                            pass \r\n                            self._state.following.append(self.FOLLOW_stmt_in_default_clause727)\r\n                            self.stmt()\r\n\r\n                            self._state.following.pop()\r\n\r\n\r\n                        else:\r\n                            break #loop15\r\n\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n\r\n                #action start\r\n                self.cpy.op_default_leave()\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"default_clause\"\r\n\r\n\r\n\r\n    # $ANTLR start \"for_stmt\"\r\n    # Eval.g:178:1: for_stmt : ^( FOR (a= exec_list )? expr block (b= exec_list )? ) ;\r\n    def for_stmt(self, ):\r\n        a = None\r\n\r\n        b = None\r\n\r\n        expr19 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:179:2: ( ^( FOR (a= exec_list )? expr block (b= exec_list )? ) )\r\n                # Eval.g:179:4: ^( FOR (a= exec_list )? expr block (b= exec_list )? )\r\n                pass \r\n                self.match(self.input, FOR, self.FOLLOW_FOR_in_for_stmt746)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                # Eval.g:179:10: (a= exec_list )?\r\n                alt16 = 2\r\n                LA16_0 = self.input.LA(1)\r\n\r\n                if (LA16_0 == EXEC_LIST) :\r\n                    alt16 = 1\r\n                if alt16 == 1:\r\n                    # Eval.g:179:11: a= exec_list\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_exec_list_in_for_stmt751)\r\n                    a = self.exec_list()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    self.cpy.stmt(a)\r\n                    #action end\r\n\r\n\r\n\r\n\r\n\r\n                self._state.following.append(self.FOLLOW_expr_in_for_stmt759)\r\n                expr19 = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                #action start\r\n                self.cpy.op_while(expr19)\r\n                #action end\r\n\r\n\r\n                self._state.following.append(self.FOLLOW_block_in_for_stmt765)\r\n                self.block()\r\n\r\n                self._state.following.pop()\r\n\r\n                #action start\r\n                self.cpy.block_enter()\r\n                #action end\r\n\r\n\r\n                # Eval.g:183:3: (b= exec_list )?\r\n                alt17 = 2\r\n                LA17_0 = self.input.LA(1)\r\n\r\n                if (LA17_0 == EXEC_LIST) :\r\n                    alt17 = 1\r\n                if alt17 == 1:\r\n                    # Eval.g:183:4: b= exec_list\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_exec_list_in_for_stmt776)\r\n                    b = self.exec_list()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    self.cpy.stmt(b)\r\n                    #action end\r\n\r\n\r\n\r\n\r\n\r\n                #action start\r\n                self.cpy.block_leave()\r\n                #action end\r\n\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"for_stmt\"\r\n\r\n\r\n\r\n    # $ANTLR start \"foreach_stmt\"\r\n    # Eval.g:188:1: foreach_stmt : ^( FOREACH expr ( ^( EACH k= ID v= each_val ) | ^( EACH v= each_val ) ) block ) ;\r\n    def foreach_stmt(self, ):\r\n        k = None\r\n        v = None\r\n\r\n        expr20 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:189:2: ( ^( FOREACH expr ( ^( EACH k= ID v= each_val ) | ^( EACH v= each_val ) ) block ) )\r\n                # Eval.g:189:4: ^( FOREACH expr ( ^( EACH k= ID v= each_val ) | ^( EACH v= each_val ) ) block )\r\n                pass \r\n                self.match(self.input, FOREACH, self.FOLLOW_FOREACH_in_foreach_stmt800)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_foreach_stmt802)\r\n                expr20 = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                # Eval.g:190:3: ( ^( EACH k= ID v= each_val ) | ^( EACH v= each_val ) )\r\n                alt18 = 2\r\n                LA18_0 = self.input.LA(1)\r\n\r\n                if (LA18_0 == EACH) :\r\n                    LA18_1 = self.input.LA(2)\r\n\r\n                    if (LA18_1 == 2) :\r\n                        LA18_2 = self.input.LA(3)\r\n\r\n                        if (LA18_2 == ID) :\r\n                            alt18 = 1\r\n                        elif (LA18_2 == EACH_VAL) :\r\n                            alt18 = 2\r\n                        else:\r\n                            nvae = NoViableAltException(\"\", 18, 2, self.input)\r\n\r\n                            raise nvae\r\n\r\n\r\n                    else:\r\n                        nvae = NoViableAltException(\"\", 18, 1, self.input)\r\n\r\n                        raise nvae\r\n\r\n\r\n                else:\r\n                    nvae = NoViableAltException(\"\", 18, 0, self.input)\r\n\r\n                    raise nvae\r\n\r\n\r\n                if alt18 == 1:\r\n                    # Eval.g:190:5: ^( EACH k= ID v= each_val )\r\n                    pass \r\n                    self.match(self.input, EACH, self.FOLLOW_EACH_in_foreach_stmt809)\r\n\r\n                    self.match(self.input, DOWN, None)\r\n                    k = self.match(self.input, ID, self.FOLLOW_ID_in_foreach_stmt813)\r\n\r\n                    self._state.following.append(self.FOLLOW_each_val_in_foreach_stmt817)\r\n                    v = self.each_val()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n                    #action start\r\n                    self.cpy.op_foreach(expr20, k.text, v)\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt18 == 2:\r\n                    # Eval.g:192:5: ^( EACH v= each_val )\r\n                    pass \r\n                    self.match(self.input, EACH, self.FOLLOW_EACH_in_foreach_stmt830)\r\n\r\n                    self.match(self.input, DOWN, None)\r\n                    self._state.following.append(self.FOLLOW_each_val_in_foreach_stmt834)\r\n                    v = self.each_val()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n                    #action start\r\n                    self.cpy.op_foreach(expr20, None, v)\r\n                    #action end\r\n\r\n\r\n\r\n\r\n\r\n                self._state.following.append(self.FOLLOW_block_in_foreach_stmt848)\r\n                self.block()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"foreach_stmt\"\r\n\r\n\r\n\r\n    # $ANTLR start \"each_val\"\r\n    # Eval.g:198:1: each_val returns [text] : ^( EACH_VAL ( ID )+ ) ;\r\n    def each_val(self, ):\r\n        text = None\r\n\r\n\r\n        ID21 = None\r\n\r\n        ps = []\r\n        try:\r\n            try:\r\n                # Eval.g:200:2: ( ^( EACH_VAL ( ID )+ ) )\r\n                # Eval.g:200:4: ^( EACH_VAL ( ID )+ )\r\n                pass \r\n                self.match(self.input, EACH_VAL, self.FOLLOW_EACH_VAL_in_each_val871)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                # Eval.g:200:15: ( ID )+\r\n                cnt19 = 0\r\n                while True: #loop19\r\n                    alt19 = 2\r\n                    LA19_0 = self.input.LA(1)\r\n\r\n                    if (LA19_0 == ID) :\r\n                        alt19 = 1\r\n\r\n\r\n                    if alt19 == 1:\r\n                        # Eval.g:200:16: ID\r\n                        pass \r\n                        ID21 = self.match(self.input, ID, self.FOLLOW_ID_in_each_val874)\r\n\r\n                        #action start\r\n                        ps.append(ID21.text)\r\n                        #action end\r\n\r\n\r\n\r\n                    else:\r\n                        if cnt19 >= 1:\r\n                            break #loop19\r\n\r\n                        eee = EarlyExitException(19, self.input)\r\n                        raise eee\r\n\r\n                    cnt19 += 1\r\n\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                text = ','.join(ps)\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"each_val\"\r\n\r\n\r\n\r\n    # $ANTLR start \"throw_stmt\"\r\n    # Eval.g:205:1: throw_stmt : ^( THROW expr ) ;\r\n    def throw_stmt(self, ):\r\n        expr22 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:206:2: ( ^( THROW expr ) )\r\n                # Eval.g:206:4: ^( THROW expr )\r\n                pass \r\n                self.match(self.input, THROW, self.FOLLOW_THROW_in_throw_stmt897)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_throw_stmt899)\r\n                expr22 = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                self.cpy.op_throw(expr22)\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"throw_stmt\"\r\n\r\n\r\n\r\n    # $ANTLR start \"try_stmt\"\r\n    # Eval.g:209:1: try_stmt : ^( TRY block ( catch_clause )+ ( finally_clause )? ) ;\r\n    def try_stmt(self, ):\r\n        self.cpy.op_try()\r\n        try:\r\n            try:\r\n                # Eval.g:211:2: ( ^( TRY block ( catch_clause )+ ( finally_clause )? ) )\r\n                # Eval.g:211:4: ^( TRY block ( catch_clause )+ ( finally_clause )? )\r\n                pass \r\n                self.match(self.input, TRY, self.FOLLOW_TRY_in_try_stmt920)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_block_in_try_stmt922)\r\n                self.block()\r\n\r\n                self._state.following.pop()\r\n\r\n                # Eval.g:211:16: ( catch_clause )+\r\n                cnt20 = 0\r\n                while True: #loop20\r\n                    alt20 = 2\r\n                    LA20_0 = self.input.LA(1)\r\n\r\n                    if (LA20_0 == CATCH) :\r\n                        alt20 = 1\r\n\r\n\r\n                    if alt20 == 1:\r\n                        # Eval.g:211:16: catch_clause\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_catch_clause_in_try_stmt924)\r\n                        self.catch_clause()\r\n\r\n                        self._state.following.pop()\r\n\r\n\r\n                    else:\r\n                        if cnt20 >= 1:\r\n                            break #loop20\r\n\r\n                        eee = EarlyExitException(20, self.input)\r\n                        raise eee\r\n\r\n                    cnt20 += 1\r\n\r\n\r\n                # Eval.g:211:30: ( finally_clause )?\r\n                alt21 = 2\r\n                LA21_0 = self.input.LA(1)\r\n\r\n                if (LA21_0 == FINALLY) :\r\n                    alt21 = 1\r\n                if alt21 == 1:\r\n                    # Eval.g:211:30: finally_clause\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_finally_clause_in_try_stmt927)\r\n                    self.finally_clause()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"try_stmt\"\r\n\r\n\r\n\r\n    # $ANTLR start \"catch_clause\"\r\n    # Eval.g:213:1: catch_clause : ^( CATCH module ( ID )? block ) ;\r\n    def catch_clause(self, ):\r\n        ID24 = None\r\n        module23 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:214:2: ( ^( CATCH module ( ID )? block ) )\r\n                # Eval.g:214:4: ^( CATCH module ( ID )? block )\r\n                pass \r\n                self.match(self.input, CATCH, self.FOLLOW_CATCH_in_catch_clause940)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_module_in_catch_clause942)\r\n                module23 = self.module()\r\n\r\n                self._state.following.pop()\r\n\r\n                # Eval.g:214:19: ( ID )?\r\n                alt22 = 2\r\n                LA22_0 = self.input.LA(1)\r\n\r\n                if (LA22_0 == ID) :\r\n                    alt22 = 1\r\n                if alt22 == 1:\r\n                    # Eval.g:214:19: ID\r\n                    pass \r\n                    ID24 = self.match(self.input, ID, self.FOLLOW_ID_in_catch_clause944)\r\n\r\n\r\n\r\n\r\n                #action start\r\n                self.cpy.op_catch(module23, ID24.text)\r\n                #action end\r\n\r\n\r\n                self._state.following.append(self.FOLLOW_block_in_catch_clause953)\r\n                self.block()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"catch_clause\"\r\n\r\n\r\n\r\n    # $ANTLR start \"finally_clause\"\r\n    # Eval.g:218:1: finally_clause : ^( FINALLY block ) ;\r\n    def finally_clause(self, ):\r\n        self.cpy.op_finally()\r\n        try:\r\n            try:\r\n                # Eval.g:220:2: ( ^( FINALLY block ) )\r\n                # Eval.g:220:4: ^( FINALLY block )\r\n                pass \r\n                self.match(self.input, FINALLY, self.FOLLOW_FINALLY_in_finally_clause970)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_block_in_finally_clause972)\r\n                self.block()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"finally_clause\"\r\n\r\n\r\n\r\n    # $ANTLR start \"func_decl\"\r\n    # Eval.g:224:1: func_decl : ^( FUNCTION ID params block ) ;\r\n    def func_decl(self, ):\r\n        ID25 = None\r\n        params26 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:225:2: ( ^( FUNCTION ID params block ) )\r\n                # Eval.g:225:4: ^( FUNCTION ID params block )\r\n                pass \r\n                self.match(self.input, FUNCTION, self.FOLLOW_FUNCTION_in_func_decl986)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                ID25 = self.match(self.input, ID, self.FOLLOW_ID_in_func_decl988)\r\n\r\n                self._state.following.append(self.FOLLOW_params_in_func_decl990)\r\n                params26 = self.params()\r\n\r\n                self._state.following.pop()\r\n\r\n                #action start\r\n                self.cpy.op_function(ID25.text, params26)\r\n                #action end\r\n\r\n\r\n                self._state.following.append(self.FOLLOW_block_in_func_decl998)\r\n                self.block()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"func_decl\"\r\n\r\n\r\n\r\n    # $ANTLR start \"params\"\r\n    # Eval.g:230:1: params returns [text] : ^( PARAMS ( param_decl )* ) ;\r\n    def params(self, ):\r\n        text = None\r\n\r\n\r\n        param_decl27 = None\r\n\r\n\r\n        ps = []\r\n        try:\r\n            try:\r\n                # Eval.g:232:2: ( ^( PARAMS ( param_decl )* ) )\r\n                # Eval.g:232:4: ^( PARAMS ( param_decl )* )\r\n                pass \r\n                self.match(self.input, PARAMS, self.FOLLOW_PARAMS_in_params1021)\r\n\r\n                if self.input.LA(1) == DOWN:\r\n                    self.match(self.input, DOWN, None)\r\n                    # Eval.g:232:13: ( param_decl )*\r\n                    while True: #loop23\r\n                        alt23 = 2\r\n                        LA23_0 = self.input.LA(1)\r\n\r\n                        if (LA23_0 == ID) :\r\n                            alt23 = 1\r\n\r\n\r\n                        if alt23 == 1:\r\n                            # Eval.g:232:14: param_decl\r\n                            pass \r\n                            self._state.following.append(self.FOLLOW_param_decl_in_params1024)\r\n                            param_decl27 = self.param_decl()\r\n\r\n                            self._state.following.pop()\r\n\r\n                            #action start\r\n                            ps.append(param_decl27)\r\n                            #action end\r\n\r\n\r\n\r\n                        else:\r\n                            break #loop23\r\n\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n\r\n                #action start\r\n                text = ', '.join(ps)\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"params\"\r\n\r\n\r\n\r\n    # $ANTLR start \"param_decl\"\r\n    # Eval.g:235:1: param_decl returns [text] : ID ( '=' atom )? ;\r\n    def param_decl(self, ):\r\n        text = None\r\n\r\n\r\n        ID28 = None\r\n        atom29 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:236:2: ( ID ( '=' atom )? )\r\n                # Eval.g:236:4: ID ( '=' atom )?\r\n                pass \r\n                ID28 = self.match(self.input, ID, self.FOLLOW_ID_in_param_decl1048)\r\n\r\n                #action start\r\n                text = ID28.text\r\n                #action end\r\n\r\n\r\n                # Eval.g:238:3: ( '=' atom )?\r\n                alt24 = 2\r\n                LA24_0 = self.input.LA(1)\r\n\r\n                if (LA24_0 == 95) :\r\n                    alt24 = 1\r\n                if alt24 == 1:\r\n                    # Eval.g:238:4: '=' atom\r\n                    pass \r\n                    self.match(self.input, 95, self.FOLLOW_95_in_param_decl1057)\r\n\r\n                    self._state.following.append(self.FOLLOW_atom_in_param_decl1059)\r\n                    atom29 = self.atom()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text += ('=' + atom29)\r\n                    #action end\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"param_decl\"\r\n\r\n\r\n\r\n    # $ANTLR start \"class_decl\"\r\n    # Eval.g:244:1: class_decl : ( ^( CLASS a= ID ( class_element )* ) | ^( CLASS b= ID c= ID ( class_element )* ) );\r\n    def class_decl(self, ):\r\n        a = None\r\n        b = None\r\n        c = None\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:246:2: ( ^( CLASS a= ID ( class_element )* ) | ^( CLASS b= ID c= ID ( class_element )* ) )\r\n                alt27 = 2\r\n                LA27_0 = self.input.LA(1)\r\n\r\n                if (LA27_0 == CLASS) :\r\n                    LA27_1 = self.input.LA(2)\r\n\r\n                    if (LA27_1 == 2) :\r\n                        LA27_2 = self.input.LA(3)\r\n\r\n                        if (LA27_2 == ID) :\r\n                            LA27_3 = self.input.LA(4)\r\n\r\n                            if (LA27_3 == ID) :\r\n                                alt27 = 2\r\n                            elif (LA27_3 == 3 or LA27_3 == CONSTRUCTOR or LA27_3 == FUNCTION or LA27_3 == VAR) :\r\n                                alt27 = 1\r\n                            else:\r\n                                nvae = NoViableAltException(\"\", 27, 3, self.input)\r\n\r\n                                raise nvae\r\n\r\n\r\n                        else:\r\n                            nvae = NoViableAltException(\"\", 27, 2, self.input)\r\n\r\n                            raise nvae\r\n\r\n\r\n                    else:\r\n                        nvae = NoViableAltException(\"\", 27, 1, self.input)\r\n\r\n                        raise nvae\r\n\r\n\r\n                else:\r\n                    nvae = NoViableAltException(\"\", 27, 0, self.input)\r\n\r\n                    raise nvae\r\n\r\n\r\n                if alt27 == 1:\r\n                    # Eval.g:246:4: ^( CLASS a= ID ( class_element )* )\r\n                    pass \r\n                    self.match(self.input, CLASS, self.FOLLOW_CLASS_in_class_decl1087)\r\n\r\n                    self.match(self.input, DOWN, None)\r\n                    a = self.match(self.input, ID, self.FOLLOW_ID_in_class_decl1091)\r\n\r\n                    #action start\r\n                    self.cpy.op_class_enter(a.text, None)\r\n                    #action end\r\n\r\n\r\n                    # Eval.g:248:3: ( class_element )*\r\n                    while True: #loop25\r\n                        alt25 = 2\r\n                        LA25_0 = self.input.LA(1)\r\n\r\n                        if (LA25_0 == CONSTRUCTOR or LA25_0 == FUNCTION or LA25_0 == VAR) :\r\n                            alt25 = 1\r\n\r\n\r\n                        if alt25 == 1:\r\n                            # Eval.g:248:3: class_element\r\n                            pass \r\n                            self._state.following.append(self.FOLLOW_class_element_in_class_decl1100)\r\n                            self.class_element()\r\n\r\n                            self._state.following.pop()\r\n\r\n\r\n                        else:\r\n                            break #loop25\r\n\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n\r\n                elif alt27 == 2:\r\n                    # Eval.g:249:4: ^( CLASS b= ID c= ID ( class_element )* )\r\n                    pass \r\n                    self.match(self.input, CLASS, self.FOLLOW_CLASS_in_class_decl1108)\r\n\r\n                    self.match(self.input, DOWN, None)\r\n                    b = self.match(self.input, ID, self.FOLLOW_ID_in_class_decl1112)\r\n\r\n                    c = self.match(self.input, ID, self.FOLLOW_ID_in_class_decl1116)\r\n\r\n                    #action start\r\n                    self.cpy.op_class_enter(b.text, c.text)\r\n                    #action end\r\n\r\n\r\n                    # Eval.g:251:3: ( class_element )*\r\n                    while True: #loop26\r\n                        alt26 = 2\r\n                        LA26_0 = self.input.LA(1)\r\n\r\n                        if (LA26_0 == CONSTRUCTOR or LA26_0 == FUNCTION or LA26_0 == VAR) :\r\n                            alt26 = 1\r\n\r\n\r\n                        if alt26 == 1:\r\n                            # Eval.g:251:3: class_element\r\n                            pass \r\n                            self._state.following.append(self.FOLLOW_class_element_in_class_decl1125)\r\n                            self.class_element()\r\n\r\n                            self._state.following.pop()\r\n\r\n\r\n                        else:\r\n                            break #loop26\r\n\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n\r\n                #action start\r\n                self.cpy.op_class_leave()\r\n                #action end\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"class_decl\"\r\n\r\n\r\n\r\n    # $ANTLR start \"class_element\"\r\n    # Eval.g:253:1: class_element : ( var_def | constructor | func_decl );\r\n    def class_element(self, ):\r\n        try:\r\n            try:\r\n                # Eval.g:254:2: ( var_def | constructor | func_decl )\r\n                alt28 = 3\r\n                LA28 = self.input.LA(1)\r\n                if LA28 == VAR:\r\n                    alt28 = 1\r\n                elif LA28 == CONSTRUCTOR:\r\n                    alt28 = 2\r\n                elif LA28 == FUNCTION:\r\n                    alt28 = 3\r\n                else:\r\n                    nvae = NoViableAltException(\"\", 28, 0, self.input)\r\n\r\n                    raise nvae\r\n\r\n\r\n                if alt28 == 1:\r\n                    # Eval.g:254:4: var_def\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_var_def_in_class_element1137)\r\n                    self.var_def()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt28 == 2:\r\n                    # Eval.g:254:14: constructor\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_constructor_in_class_element1141)\r\n                    self.constructor()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n                elif alt28 == 3:\r\n                    # Eval.g:254:28: func_decl\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_func_decl_in_class_element1145)\r\n                    self.func_decl()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"class_element\"\r\n\r\n\r\n\r\n    # $ANTLR start \"var_def\"\r\n    # Eval.g:256:1: var_def : ( ^( VAR ID ( expr )? ) | ^( VAR 'static' ID ( expr )? ) );\r\n    def var_def(self, ):\r\n        ID30 = None\r\n        ID32 = None\r\n        expr31 = None\r\n\r\n        expr33 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:257:2: ( ^( VAR ID ( expr )? ) | ^( VAR 'static' ID ( expr )? ) )\r\n                alt31 = 2\r\n                LA31_0 = self.input.LA(1)\r\n\r\n                if (LA31_0 == VAR) :\r\n                    LA31_1 = self.input.LA(2)\r\n\r\n                    if (LA31_1 == 2) :\r\n                        LA31_2 = self.input.LA(3)\r\n\r\n                        if (LA31_2 == ID) :\r\n                            alt31 = 1\r\n                        elif (LA31_2 == 127) :\r\n                            alt31 = 2\r\n                        else:\r\n                            nvae = NoViableAltException(\"\", 31, 2, self.input)\r\n\r\n                            raise nvae\r\n\r\n\r\n                    else:\r\n                        nvae = NoViableAltException(\"\", 31, 1, self.input)\r\n\r\n                        raise nvae\r\n\r\n\r\n                else:\r\n                    nvae = NoViableAltException(\"\", 31, 0, self.input)\r\n\r\n                    raise nvae\r\n\r\n\r\n                if alt31 == 1:\r\n                    # Eval.g:257:4: ^( VAR ID ( expr )? )\r\n                    pass \r\n                    self.match(self.input, VAR, self.FOLLOW_VAR_in_var_def1156)\r\n\r\n                    self.match(self.input, DOWN, None)\r\n                    ID30 = self.match(self.input, ID, self.FOLLOW_ID_in_var_def1158)\r\n\r\n                    # Eval.g:257:13: ( expr )?\r\n                    alt29 = 2\r\n                    LA29_0 = self.input.LA(1)\r\n\r\n                    if (LA29_0 == ARRAY or LA29_0 == BOOL or LA29_0 == FLOAT or LA29_0 == INT or LA29_0 == MEMBER or (NEGATIVE <= LA29_0 <= NEW) or (NULL <= LA29_0 <= OBJECT) or (SPRINTF <= LA29_0 <= STRING) or (68 <= LA29_0 <= 70) or (72 <= LA29_0 <= 73) or LA29_0 == 77 or LA29_0 == 79 or LA29_0 == 83 or LA29_0 == 89 or (93 <= LA29_0 <= 94) or LA29_0 == 96 or (98 <= LA29_0 <= 99) or LA29_0 == 102 or LA29_0 == 133 or LA29_0 == 135) :\r\n                        alt29 = 1\r\n                    if alt29 == 1:\r\n                        # Eval.g:257:13: expr\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_expr_in_var_def1160)\r\n                        expr31 = self.expr()\r\n\r\n                        self._state.following.pop()\r\n\r\n\r\n\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n                    #action start\r\n                    self.cpy.op_var_def(False, ID30.text, expr31)\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt31 == 2:\r\n                    # Eval.g:259:4: ^( VAR 'static' ID ( expr )? )\r\n                    pass \r\n                    self.match(self.input, VAR, self.FOLLOW_VAR_in_var_def1172)\r\n\r\n                    self.match(self.input, DOWN, None)\r\n                    self.match(self.input, 127, self.FOLLOW_127_in_var_def1174)\r\n\r\n                    ID32 = self.match(self.input, ID, self.FOLLOW_ID_in_var_def1176)\r\n\r\n                    # Eval.g:259:22: ( expr )?\r\n                    alt30 = 2\r\n                    LA30_0 = self.input.LA(1)\r\n\r\n                    if (LA30_0 == ARRAY or LA30_0 == BOOL or LA30_0 == FLOAT or LA30_0 == INT or LA30_0 == MEMBER or (NEGATIVE <= LA30_0 <= NEW) or (NULL <= LA30_0 <= OBJECT) or (SPRINTF <= LA30_0 <= STRING) or (68 <= LA30_0 <= 70) or (72 <= LA30_0 <= 73) or LA30_0 == 77 or LA30_0 == 79 or LA30_0 == 83 or LA30_0 == 89 or (93 <= LA30_0 <= 94) or LA30_0 == 96 or (98 <= LA30_0 <= 99) or LA30_0 == 102 or LA30_0 == 133 or LA30_0 == 135) :\r\n                        alt30 = 1\r\n                    if alt30 == 1:\r\n                        # Eval.g:259:22: expr\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_expr_in_var_def1178)\r\n                        expr33 = self.expr()\r\n\r\n                        self._state.following.pop()\r\n\r\n\r\n\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n                    #action start\r\n                    self.cpy.op_var_def(True, ID32.text, expr33)\r\n                    #action end\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"var_def\"\r\n\r\n\r\n\r\n    # $ANTLR start \"constructor\"\r\n    # Eval.g:262:1: constructor : ^( CONSTRUCTOR params block ) ;\r\n    def constructor(self, ):\r\n        params34 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:263:2: ( ^( CONSTRUCTOR params block ) )\r\n                # Eval.g:263:4: ^( CONSTRUCTOR params block )\r\n                pass \r\n                self.match(self.input, CONSTRUCTOR, self.FOLLOW_CONSTRUCTOR_in_constructor1195)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_params_in_constructor1197)\r\n                params34 = self.params()\r\n\r\n                self._state.following.pop()\r\n\r\n                #action start\r\n                self.cpy.op_construct(params34)\r\n                #action end\r\n\r\n\r\n                self._state.following.append(self.FOLLOW_block_in_constructor1205)\r\n                self.block()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return \r\n\r\n    # $ANTLR end \"constructor\"\r\n\r\n\r\n\r\n    # $ANTLR start \"module\"\r\n    # Eval.g:270:1: module returns [text] : ^( MODULE ( ID )+ ) ;\r\n    def module(self, ):\r\n        text = None\r\n\r\n\r\n        ID35 = None\r\n\r\n        ps = []\r\n        try:\r\n            try:\r\n                # Eval.g:272:2: ( ^( MODULE ( ID )+ ) )\r\n                # Eval.g:272:4: ^( MODULE ( ID )+ )\r\n                pass \r\n                self.match(self.input, MODULE, self.FOLLOW_MODULE_in_module1229)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                # Eval.g:272:13: ( ID )+\r\n                cnt32 = 0\r\n                while True: #loop32\r\n                    alt32 = 2\r\n                    LA32_0 = self.input.LA(1)\r\n\r\n                    if (LA32_0 == ID) :\r\n                        alt32 = 1\r\n\r\n\r\n                    if alt32 == 1:\r\n                        # Eval.g:272:14: ID\r\n                        pass \r\n                        ID35 = self.match(self.input, ID, self.FOLLOW_ID_in_module1232)\r\n\r\n                        #action start\r\n                        ps.append(ID35.text)\r\n                        #action end\r\n\r\n\r\n\r\n                    else:\r\n                        if cnt32 >= 1:\r\n                            break #loop32\r\n\r\n                        eee = EarlyExitException(32, self.input)\r\n                        raise eee\r\n\r\n                    cnt32 += 1\r\n\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                text = '.'.join(ps)\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"module\"\r\n\r\n\r\n\r\n    # $ANTLR start \"member_expr\"\r\n    # Eval.g:276:1: member_expr returns [text] : ^( MEMBER ( primary )+ ) ;\r\n    def member_expr(self, ):\r\n        text = None\r\n\r\n\r\n        primary36 = None\r\n\r\n\r\n        ps = []\r\n        try:\r\n            try:\r\n                # Eval.g:278:2: ( ^( MEMBER ( primary )+ ) )\r\n                # Eval.g:278:4: ^( MEMBER ( primary )+ )\r\n                pass \r\n                self.match(self.input, MEMBER, self.FOLLOW_MEMBER_in_member_expr1263)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                # Eval.g:278:13: ( primary )+\r\n                cnt33 = 0\r\n                while True: #loop33\r\n                    alt33 = 2\r\n                    LA33_0 = self.input.LA(1)\r\n\r\n                    if (LA33_0 == ID) :\r\n                        alt33 = 1\r\n\r\n\r\n                    if alt33 == 1:\r\n                        # Eval.g:278:14: primary\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_primary_in_member_expr1266)\r\n                        primary36 = self.primary()\r\n\r\n                        self._state.following.pop()\r\n\r\n                        #action start\r\n                        ps.append(primary36)\r\n                        #action end\r\n\r\n\r\n\r\n                    else:\r\n                        if cnt33 >= 1:\r\n                            break #loop33\r\n\r\n                        eee = EarlyExitException(33, self.input)\r\n                        raise eee\r\n\r\n                    cnt33 += 1\r\n\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                text = '.'.join(ps)\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"member_expr\"\r\n\r\n\r\n\r\n    # $ANTLR start \"primary\"\r\n    # Eval.g:281:1: primary returns [text] : ID ( index_expr )* ( call_expr )? ;\r\n    def primary(self, ):\r\n        text = None\r\n\r\n\r\n        ID39 = None\r\n        index_expr37 = None\r\n\r\n        call_expr38 = None\r\n\r\n\r\n        a=''\r\n        try:\r\n            try:\r\n                # Eval.g:283:2: ( ID ( index_expr )* ( call_expr )? )\r\n                # Eval.g:283:4: ID ( index_expr )* ( call_expr )?\r\n                pass \r\n                ID39 = self.match(self.input, ID, self.FOLLOW_ID_in_primary1295)\r\n\r\n                # Eval.g:283:7: ( index_expr )*\r\n                while True: #loop34\r\n                    alt34 = 2\r\n                    LA34_0 = self.input.LA(1)\r\n\r\n                    if (LA34_0 == INDEX or LA34_0 == SLICE) :\r\n                        alt34 = 1\r\n\r\n\r\n                    if alt34 == 1:\r\n                        # Eval.g:283:8: index_expr\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_index_expr_in_primary1298)\r\n                        index_expr37 = self.index_expr()\r\n\r\n                        self._state.following.pop()\r\n\r\n                        #action start\r\n                        a += index_expr37\r\n                        #action end\r\n\r\n\r\n\r\n                    else:\r\n                        break #loop34\r\n\r\n\r\n                # Eval.g:284:3: ( call_expr )?\r\n                alt35 = 2\r\n                LA35_0 = self.input.LA(1)\r\n\r\n                if (LA35_0 == CALL) :\r\n                    alt35 = 1\r\n                if alt35 == 1:\r\n                    # Eval.g:284:3: call_expr\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_call_expr_in_primary1305)\r\n                    call_expr38 = self.call_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n\r\n\r\n                #action start\r\n                  \r\n                b = call_expr38\r\n                if b == None: b = ''\r\n                text = ID39.text + a + b\r\n                \t\t\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"primary\"\r\n\r\n\r\n\r\n    # $ANTLR start \"call_expr\"\r\n    # Eval.g:291:1: call_expr returns [text] : ^( CALL ( expr_list )? ) ;\r\n    def call_expr(self, ):\r\n        text = None\r\n\r\n\r\n        expr_list40 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:292:2: ( ^( CALL ( expr_list )? ) )\r\n                # Eval.g:292:4: ^( CALL ( expr_list )? )\r\n                pass \r\n                self.match(self.input, CALL, self.FOLLOW_CALL_in_call_expr1324)\r\n\r\n                if self.input.LA(1) == DOWN:\r\n                    self.match(self.input, DOWN, None)\r\n                    # Eval.g:292:11: ( expr_list )?\r\n                    alt36 = 2\r\n                    LA36_0 = self.input.LA(1)\r\n\r\n                    if (LA36_0 == EXPR_LIST) :\r\n                        alt36 = 1\r\n                    if alt36 == 1:\r\n                        # Eval.g:292:11: expr_list\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_expr_list_in_call_expr1326)\r\n                        expr_list40 = self.expr_list()\r\n\r\n                        self._state.following.pop()\r\n\r\n\r\n\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n\r\n                #action start\r\n                  \r\n                s = expr_list40\r\n                if s == None: s = ''\r\n                text = '(' + s + ')'\r\n                \t\t\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"call_expr\"\r\n\r\n\r\n\r\n    # $ANTLR start \"index_expr\"\r\n    # Eval.g:299:1: index_expr returns [text] : ( ^( INDEX expr ) | ^( SLICE a= expr (b= expr )? ) );\r\n    def index_expr(self, ):\r\n        text = None\r\n\r\n\r\n        a = None\r\n\r\n        b = None\r\n\r\n        expr41 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:300:2: ( ^( INDEX expr ) | ^( SLICE a= expr (b= expr )? ) )\r\n                alt38 = 2\r\n                LA38_0 = self.input.LA(1)\r\n\r\n                if (LA38_0 == INDEX) :\r\n                    alt38 = 1\r\n                elif (LA38_0 == SLICE) :\r\n                    alt38 = 2\r\n                else:\r\n                    nvae = NoViableAltException(\"\", 38, 0, self.input)\r\n\r\n                    raise nvae\r\n\r\n\r\n                if alt38 == 1:\r\n                    # Eval.g:300:4: ^( INDEX expr )\r\n                    pass \r\n                    self.match(self.input, INDEX, self.FOLLOW_INDEX_in_index_expr1346)\r\n\r\n                    self.match(self.input, DOWN, None)\r\n                    self._state.following.append(self.FOLLOW_expr_in_index_expr1348)\r\n                    expr41 = self.expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n                    #action start\r\n                    text = '[' + expr41 + ']'\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt38 == 2:\r\n                    # Eval.g:302:4: ^( SLICE a= expr (b= expr )? )\r\n                    pass \r\n                    self.match(self.input, SLICE, self.FOLLOW_SLICE_in_index_expr1359)\r\n\r\n                    self.match(self.input, DOWN, None)\r\n                    self._state.following.append(self.FOLLOW_expr_in_index_expr1363)\r\n                    a = self.expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    # Eval.g:302:20: (b= expr )?\r\n                    alt37 = 2\r\n                    LA37_0 = self.input.LA(1)\r\n\r\n                    if (LA37_0 == ARRAY or LA37_0 == BOOL or LA37_0 == FLOAT or LA37_0 == INT or LA37_0 == MEMBER or (NEGATIVE <= LA37_0 <= NEW) or (NULL <= LA37_0 <= OBJECT) or (SPRINTF <= LA37_0 <= STRING) or (68 <= LA37_0 <= 70) or (72 <= LA37_0 <= 73) or LA37_0 == 77 or LA37_0 == 79 or LA37_0 == 83 or LA37_0 == 89 or (93 <= LA37_0 <= 94) or LA37_0 == 96 or (98 <= LA37_0 <= 99) or LA37_0 == 102 or LA37_0 == 133 or LA37_0 == 135) :\r\n                        alt37 = 1\r\n                    if alt37 == 1:\r\n                        # Eval.g:302:20: b= expr\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_expr_in_index_expr1367)\r\n                        b = self.expr()\r\n\r\n                        self._state.following.pop()\r\n\r\n\r\n\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n                    #action start\r\n                      \r\n                    s = b\r\n                    if s == None: s = ''\r\n                    text = '[%s : %s]' %(a, s)\r\n                    \t\t\r\n                    #action end\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"index_expr\"\r\n\r\n\r\n\r\n    # $ANTLR start \"expr_list\"\r\n    # Eval.g:311:1: expr_list returns [text] : ^( EXPR_LIST ( expr )+ ) ;\r\n    def expr_list(self, ):\r\n        text = None\r\n\r\n\r\n        expr42 = None\r\n\r\n\r\n        ps = []\r\n        try:\r\n            try:\r\n                # Eval.g:313:2: ( ^( EXPR_LIST ( expr )+ ) )\r\n                # Eval.g:313:4: ^( EXPR_LIST ( expr )+ )\r\n                pass \r\n                self.match(self.input, EXPR_LIST, self.FOLLOW_EXPR_LIST_in_expr_list1394)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                # Eval.g:313:16: ( expr )+\r\n                cnt39 = 0\r\n                while True: #loop39\r\n                    alt39 = 2\r\n                    LA39_0 = self.input.LA(1)\r\n\r\n                    if (LA39_0 == ARRAY or LA39_0 == BOOL or LA39_0 == FLOAT or LA39_0 == INT or LA39_0 == MEMBER or (NEGATIVE <= LA39_0 <= NEW) or (NULL <= LA39_0 <= OBJECT) or (SPRINTF <= LA39_0 <= STRING) or (68 <= LA39_0 <= 70) or (72 <= LA39_0 <= 73) or LA39_0 == 77 or LA39_0 == 79 or LA39_0 == 83 or LA39_0 == 89 or (93 <= LA39_0 <= 94) or LA39_0 == 96 or (98 <= LA39_0 <= 99) or LA39_0 == 102 or LA39_0 == 133 or LA39_0 == 135) :\r\n                        alt39 = 1\r\n\r\n\r\n                    if alt39 == 1:\r\n                        # Eval.g:313:17: expr\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_expr_in_expr_list1397)\r\n                        expr42 = self.expr()\r\n\r\n                        self._state.following.pop()\r\n\r\n                        #action start\r\n                        ps.append(expr42)\r\n                        #action end\r\n\r\n\r\n\r\n                    else:\r\n                        if cnt39 >= 1:\r\n                            break #loop39\r\n\r\n                        eee = EarlyExitException(39, self.input)\r\n                        raise eee\r\n\r\n                    cnt39 += 1\r\n\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                  \r\n                text = ', '.join(ps)\r\n                \t\t\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"expr_list\"\r\n\r\n\r\n\r\n    # $ANTLR start \"expr\"\r\n    # Eval.g:319:1: expr returns [text] : (a= relation_expr |a= logic_or_expr |a= logic_and_expr |a= bitwise_or_expr |a= bitwise_xor_expr |a= bitwise_and_expr |a= add_expr |a= mul_expr |a= not_expr |a= negative_expr |a= atom );\r\n    def expr(self, ):\r\n        text = None\r\n\r\n\r\n        a = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:320:2: (a= relation_expr |a= logic_or_expr |a= logic_and_expr |a= bitwise_or_expr |a= bitwise_xor_expr |a= bitwise_and_expr |a= add_expr |a= mul_expr |a= not_expr |a= negative_expr |a= atom )\r\n                alt40 = 11\r\n                LA40 = self.input.LA(1)\r\n                if LA40 == 69 or LA40 == 93 or LA40 == 94 or LA40 == 96 or LA40 == 98 or LA40 == 99:\r\n                    alt40 = 1\r\n                elif LA40 == 135:\r\n                    alt40 = 2\r\n                elif LA40 == 72:\r\n                    alt40 = 3\r\n                elif LA40 == 133:\r\n                    alt40 = 4\r\n                elif LA40 == 102:\r\n                    alt40 = 5\r\n                elif LA40 == 73:\r\n                    alt40 = 6\r\n                elif LA40 == 79 or LA40 == 83:\r\n                    alt40 = 7\r\n                elif LA40 == 70 or LA40 == 77 or LA40 == 89:\r\n                    alt40 = 8\r\n                elif LA40 == 68:\r\n                    alt40 = 9\r\n                elif LA40 == NEGATIVE:\r\n                    alt40 = 10\r\n                elif LA40 == ARRAY or LA40 == BOOL or LA40 == FLOAT or LA40 == INT or LA40 == MEMBER or LA40 == NEW or LA40 == NULL or LA40 == OBJECT or LA40 == SPRINTF or LA40 == STRING:\r\n                    alt40 = 11\r\n                else:\r\n                    nvae = NoViableAltException(\"\", 40, 0, self.input)\r\n\r\n                    raise nvae\r\n\r\n\r\n                if alt40 == 1:\r\n                    # Eval.g:320:4: a= relation_expr\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_relation_expr_in_expr1423)\r\n                    a = self.relation_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt40 == 2:\r\n                    # Eval.g:321:4: a= logic_or_expr\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_logic_or_expr_in_expr1432)\r\n                    a = self.logic_or_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt40 == 3:\r\n                    # Eval.g:322:4: a= logic_and_expr\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_logic_and_expr_in_expr1441)\r\n                    a = self.logic_and_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt40 == 4:\r\n                    # Eval.g:323:4: a= bitwise_or_expr\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_bitwise_or_expr_in_expr1450)\r\n                    a = self.bitwise_or_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt40 == 5:\r\n                    # Eval.g:324:4: a= bitwise_xor_expr\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_bitwise_xor_expr_in_expr1459)\r\n                    a = self.bitwise_xor_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt40 == 6:\r\n                    # Eval.g:325:4: a= bitwise_and_expr\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_bitwise_and_expr_in_expr1468)\r\n                    a = self.bitwise_and_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt40 == 7:\r\n                    # Eval.g:326:4: a= add_expr\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_add_expr_in_expr1477)\r\n                    a = self.add_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt40 == 8:\r\n                    # Eval.g:327:4: a= mul_expr\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_mul_expr_in_expr1487)\r\n                    a = self.mul_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt40 == 9:\r\n                    # Eval.g:328:4: a= not_expr\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_not_expr_in_expr1497)\r\n                    a = self.not_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt40 == 10:\r\n                    # Eval.g:329:4: a= negative_expr\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_negative_expr_in_expr1507)\r\n                    a = self.negative_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt40 == 11:\r\n                    # Eval.g:330:4: a= atom\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_atom_in_expr1516)\r\n                    a = self.atom()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"expr\"\r\n\r\n\r\n\r\n    # $ANTLR start \"logic_or_expr\"\r\n    # Eval.g:332:1: logic_or_expr returns [text] : ^( '||' b= expr c= expr ) ;\r\n    def logic_or_expr(self, ):\r\n        text = None\r\n\r\n\r\n        b = None\r\n\r\n        c = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:333:2: ( ^( '||' b= expr c= expr ) )\r\n                # Eval.g:333:4: ^( '||' b= expr c= expr )\r\n                pass \r\n                self.match(self.input, 135, self.FOLLOW_135_in_logic_or_expr1534)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_logic_or_expr1538)\r\n                b = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self._state.following.append(self.FOLLOW_expr_in_logic_or_expr1542)\r\n                c = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                text = '(' + b + ' or ' + c + ')'\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"logic_or_expr\"\r\n\r\n\r\n\r\n    # $ANTLR start \"logic_and_expr\"\r\n    # Eval.g:336:1: logic_and_expr returns [text] : ^( '&&' b= expr c= expr ) ;\r\n    def logic_and_expr(self, ):\r\n        text = None\r\n\r\n\r\n        b = None\r\n\r\n        c = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:337:2: ( ^( '&&' b= expr c= expr ) )\r\n                # Eval.g:337:4: ^( '&&' b= expr c= expr )\r\n                pass \r\n                self.match(self.input, 72, self.FOLLOW_72_in_logic_and_expr1561)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_logic_and_expr1565)\r\n                b = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self._state.following.append(self.FOLLOW_expr_in_logic_and_expr1569)\r\n                c = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                text = b + ' and ' + c\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"logic_and_expr\"\r\n\r\n\r\n\r\n    # $ANTLR start \"bitwise_or_expr\"\r\n    # Eval.g:340:1: bitwise_or_expr returns [text] : ^( '|' b= expr c= expr ) ;\r\n    def bitwise_or_expr(self, ):\r\n        text = None\r\n\r\n\r\n        b = None\r\n\r\n        c = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:341:2: ( ^( '|' b= expr c= expr ) )\r\n                # Eval.g:341:4: ^( '|' b= expr c= expr )\r\n                pass \r\n                self.match(self.input, 133, self.FOLLOW_133_in_bitwise_or_expr1588)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_bitwise_or_expr1592)\r\n                b = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self._state.following.append(self.FOLLOW_expr_in_bitwise_or_expr1596)\r\n                c = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                text = b + ' | ' + c\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"bitwise_or_expr\"\r\n\r\n\r\n\r\n    # $ANTLR start \"bitwise_xor_expr\"\r\n    # Eval.g:344:1: bitwise_xor_expr returns [text] : ^( '^' b= expr c= expr ) ;\r\n    def bitwise_xor_expr(self, ):\r\n        text = None\r\n\r\n\r\n        b = None\r\n\r\n        c = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:345:2: ( ^( '^' b= expr c= expr ) )\r\n                # Eval.g:345:4: ^( '^' b= expr c= expr )\r\n                pass \r\n                self.match(self.input, 102, self.FOLLOW_102_in_bitwise_xor_expr1615)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_bitwise_xor_expr1619)\r\n                b = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self._state.following.append(self.FOLLOW_expr_in_bitwise_xor_expr1623)\r\n                c = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                text = b + ' ^ ' + c\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"bitwise_xor_expr\"\r\n\r\n\r\n\r\n    # $ANTLR start \"bitwise_and_expr\"\r\n    # Eval.g:348:1: bitwise_and_expr returns [text] : ^( '&' b= expr c= expr ) ;\r\n    def bitwise_and_expr(self, ):\r\n        text = None\r\n\r\n\r\n        b = None\r\n\r\n        c = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:349:2: ( ^( '&' b= expr c= expr ) )\r\n                # Eval.g:349:4: ^( '&' b= expr c= expr )\r\n                pass \r\n                self.match(self.input, 73, self.FOLLOW_73_in_bitwise_and_expr1642)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_bitwise_and_expr1646)\r\n                b = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self._state.following.append(self.FOLLOW_expr_in_bitwise_and_expr1650)\r\n                c = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                text = b + ' & ' + c\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"bitwise_and_expr\"\r\n\r\n\r\n\r\n    # $ANTLR start \"relation_expr\"\r\n    # Eval.g:352:1: relation_expr returns [text] : ^(op= ( '<' | '>' | '<=' | '>=' | '==' | '!=' ) b= expr c= expr ) ;\r\n    def relation_expr(self, ):\r\n        text = None\r\n\r\n\r\n        op = None\r\n        b = None\r\n\r\n        c = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:353:2: ( ^(op= ( '<' | '>' | '<=' | '>=' | '==' | '!=' ) b= expr c= expr ) )\r\n                # Eval.g:353:4: ^(op= ( '<' | '>' | '<=' | '>=' | '==' | '!=' ) b= expr c= expr )\r\n                pass \r\n                op = self.input.LT(1)\r\n\r\n                if self.input.LA(1) == 69 or (93 <= self.input.LA(1) <= 94) or self.input.LA(1) == 96 or (98 <= self.input.LA(1) <= 99):\r\n                    self.input.consume()\r\n                    self._state.errorRecovery = False\r\n\r\n\r\n                else:\r\n                    mse = MismatchedSetException(None, self.input)\r\n                    raise mse\r\n\r\n\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_relation_expr1687)\r\n                b = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self._state.following.append(self.FOLLOW_expr_in_relation_expr1691)\r\n                c = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                text = b + op.text + c\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"relation_expr\"\r\n\r\n\r\n\r\n    # $ANTLR start \"add_expr\"\r\n    # Eval.g:356:1: add_expr returns [text] : ^(op= ( '+' | '-' ) b= expr c= expr ) ;\r\n    def add_expr(self, ):\r\n        text = None\r\n\r\n\r\n        op = None\r\n        b = None\r\n\r\n        c = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:357:2: ( ^(op= ( '+' | '-' ) b= expr c= expr ) )\r\n                # Eval.g:357:4: ^(op= ( '+' | '-' ) b= expr c= expr )\r\n                pass \r\n                op = self.input.LT(1)\r\n\r\n                if self.input.LA(1) == 79 or self.input.LA(1) == 83:\r\n                    self.input.consume()\r\n                    self._state.errorRecovery = False\r\n\r\n\r\n                else:\r\n                    mse = MismatchedSetException(None, self.input)\r\n                    raise mse\r\n\r\n\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_add_expr1720)\r\n                b = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self._state.following.append(self.FOLLOW_expr_in_add_expr1724)\r\n                c = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                text = '(' + b + ' ' + op.text + ' ' + c + ')'\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"add_expr\"\r\n\r\n\r\n\r\n    # $ANTLR start \"mul_expr\"\r\n    # Eval.g:360:1: mul_expr returns [text] : ^(op= ( '*' | '/' | '%' ) b= expr c= expr ) ;\r\n    def mul_expr(self, ):\r\n        text = None\r\n\r\n\r\n        op = None\r\n        b = None\r\n\r\n        c = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:361:2: ( ^(op= ( '*' | '/' | '%' ) b= expr c= expr ) )\r\n                # Eval.g:361:4: ^(op= ( '*' | '/' | '%' ) b= expr c= expr )\r\n                pass \r\n                op = self.input.LT(1)\r\n\r\n                if self.input.LA(1) == 70 or self.input.LA(1) == 77 or self.input.LA(1) == 89:\r\n                    self.input.consume()\r\n                    self._state.errorRecovery = False\r\n\r\n\r\n                else:\r\n                    mse = MismatchedSetException(None, self.input)\r\n                    raise mse\r\n\r\n\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_mul_expr1755)\r\n                b = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self._state.following.append(self.FOLLOW_expr_in_mul_expr1759)\r\n                c = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                text = b + ' ' + op.text + ' ' + c\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"mul_expr\"\r\n\r\n\r\n\r\n    # $ANTLR start \"not_expr\"\r\n    # Eval.g:364:1: not_expr returns [text] : ^( '!' a= expr ) ;\r\n    def not_expr(self, ):\r\n        text = None\r\n\r\n\r\n        a = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:365:2: ( ^( '!' a= expr ) )\r\n                # Eval.g:365:4: ^( '!' a= expr )\r\n                pass \r\n                self.match(self.input, 68, self.FOLLOW_68_in_not_expr1778)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_not_expr1782)\r\n                a = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                text = 'not (' + a + ')'\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"not_expr\"\r\n\r\n\r\n\r\n    # $ANTLR start \"negative_expr\"\r\n    # Eval.g:368:1: negative_expr returns [text] : ^( NEGATIVE a= expr ) ;\r\n    def negative_expr(self, ):\r\n        text = None\r\n\r\n\r\n        a = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:369:2: ( ^( NEGATIVE a= expr ) )\r\n                # Eval.g:369:4: ^( NEGATIVE a= expr )\r\n                pass \r\n                self.match(self.input, NEGATIVE, self.FOLLOW_NEGATIVE_in_negative_expr1801)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_negative_expr1805)\r\n                a = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                text = '- (' + a + ')'\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"negative_expr\"\r\n\r\n\r\n\r\n    # $ANTLR start \"sprintf\"\r\n    # Eval.g:374:1: sprintf returns [text] : ^( SPRINTF expr (a= expr_list )? ) ;\r\n    def sprintf(self, ):\r\n        text = None\r\n\r\n\r\n        a = None\r\n\r\n        expr43 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:375:2: ( ^( SPRINTF expr (a= expr_list )? ) )\r\n                # Eval.g:375:4: ^( SPRINTF expr (a= expr_list )? )\r\n                pass \r\n                self.match(self.input, SPRINTF, self.FOLLOW_SPRINTF_in_sprintf1826)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_expr_in_sprintf1828)\r\n                expr43 = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                # Eval.g:375:20: (a= expr_list )?\r\n                alt41 = 2\r\n                LA41_0 = self.input.LA(1)\r\n\r\n                if (LA41_0 == EXPR_LIST) :\r\n                    alt41 = 1\r\n                if alt41 == 1:\r\n                    # Eval.g:375:20: a= expr_list\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_expr_list_in_sprintf1832)\r\n                    a = self.expr_list()\r\n\r\n                    self._state.following.pop()\r\n\r\n\r\n\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                  \r\n                s = a\r\n                if not s: s=''\r\n                text = expr43 + '%(' + s + ')'\r\n                \t\t\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"sprintf\"\r\n\r\n\r\n\r\n    # $ANTLR start \"new_clause\"\r\n    # Eval.g:383:1: new_clause returns [text] : ^( NEW module call_expr ) ;\r\n    def new_clause(self, ):\r\n        text = None\r\n\r\n\r\n        module44 = None\r\n\r\n        call_expr45 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:384:2: ( ^( NEW module call_expr ) )\r\n                # Eval.g:384:4: ^( NEW module call_expr )\r\n                pass \r\n                self.match(self.input, NEW, self.FOLLOW_NEW_in_new_clause1853)\r\n\r\n                self.match(self.input, DOWN, None)\r\n                self._state.following.append(self.FOLLOW_module_in_new_clause1855)\r\n                module44 = self.module()\r\n\r\n                self._state.following.pop()\r\n\r\n                self._state.following.append(self.FOLLOW_call_expr_in_new_clause1857)\r\n                call_expr45 = self.call_expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                self.match(self.input, UP, None)\r\n\r\n\r\n                #action start\r\n                text = module44 + call_expr45\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"new_clause\"\r\n\r\n\r\n\r\n    # $ANTLR start \"array_decl\"\r\n    # Eval.g:388:1: array_decl returns [text] : ^( ARRAY ( expr_list )? ) ;\r\n    def array_decl(self, ):\r\n        text = None\r\n\r\n\r\n        expr_list46 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:389:2: ( ^( ARRAY ( expr_list )? ) )\r\n                # Eval.g:389:4: ^( ARRAY ( expr_list )? )\r\n                pass \r\n                self.match(self.input, ARRAY, self.FOLLOW_ARRAY_in_array_decl1877)\r\n\r\n                if self.input.LA(1) == DOWN:\r\n                    self.match(self.input, DOWN, None)\r\n                    # Eval.g:389:12: ( expr_list )?\r\n                    alt42 = 2\r\n                    LA42_0 = self.input.LA(1)\r\n\r\n                    if (LA42_0 == EXPR_LIST) :\r\n                        alt42 = 1\r\n                    if alt42 == 1:\r\n                        # Eval.g:389:12: expr_list\r\n                        pass \r\n                        self._state.following.append(self.FOLLOW_expr_list_in_array_decl1879)\r\n                        expr_list46 = self.expr_list()\r\n\r\n                        self._state.following.pop()\r\n\r\n\r\n\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n\r\n                #action start\r\n                  \r\n                s = expr_list46\r\n                if s == None: s = ''\r\n                text = '[' + s + ']'\r\n                \t\t\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"array_decl\"\r\n\r\n\r\n\r\n    # $ANTLR start \"object_decl\"\r\n    # Eval.g:396:1: object_decl returns [text] : ^( OBJECT ( property )* ) ;\r\n    def object_decl(self, ):\r\n        text = None\r\n\r\n\r\n        property47 = None\r\n\r\n\r\n        s = ''\r\n        try:\r\n            try:\r\n                # Eval.g:398:2: ( ^( OBJECT ( property )* ) )\r\n                # Eval.g:398:4: ^( OBJECT ( property )* )\r\n                pass \r\n                self.match(self.input, OBJECT, self.FOLLOW_OBJECT_in_object_decl1904)\r\n\r\n                if self.input.LA(1) == DOWN:\r\n                    self.match(self.input, DOWN, None)\r\n                    # Eval.g:398:13: ( property )*\r\n                    while True: #loop43\r\n                        alt43 = 2\r\n                        LA43_0 = self.input.LA(1)\r\n\r\n                        if (LA43_0 == ID or LA43_0 == INT or LA43_0 == STRING) :\r\n                            alt43 = 1\r\n\r\n\r\n                        if alt43 == 1:\r\n                            # Eval.g:398:14: property\r\n                            pass \r\n                            self._state.following.append(self.FOLLOW_property_in_object_decl1907)\r\n                            property47 = self.property()\r\n\r\n                            self._state.following.pop()\r\n\r\n                            #action start\r\n                            s += property47\r\n                            #action end\r\n\r\n\r\n\r\n                        else:\r\n                            break #loop43\r\n\r\n\r\n                    self.match(self.input, UP, None)\r\n\r\n\r\n\r\n                #action start\r\n                text = '{' + s + '}'\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"object_decl\"\r\n\r\n\r\n\r\n    # $ANTLR start \"property\"\r\n    # Eval.g:401:1: property returns [text] : a= ( ID | STRING | INT ) ':' expr ;\r\n    def property(self, ):\r\n        text = None\r\n\r\n\r\n        a = None\r\n        expr48 = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:402:2: (a= ( ID | STRING | INT ) ':' expr )\r\n                # Eval.g:402:4: a= ( ID | STRING | INT ) ':' expr\r\n                pass \r\n                a = self.input.LT(1)\r\n\r\n                if self.input.LA(1) == ID or self.input.LA(1) == INT or self.input.LA(1) == STRING:\r\n                    self.input.consume()\r\n                    self._state.errorRecovery = False\r\n\r\n\r\n                else:\r\n                    mse = MismatchedSetException(None, self.input)\r\n                    raise mse\r\n\r\n\r\n\r\n                self.match(self.input, 91, self.FOLLOW_91_in_property1944)\r\n\r\n                self._state.following.append(self.FOLLOW_expr_in_property1946)\r\n                expr48 = self.expr()\r\n\r\n                self._state.following.pop()\r\n\r\n                #action start\r\n                text = a.text + ': ' + expr48 + ','\r\n                #action end\r\n\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"property\"\r\n\r\n\r\n\r\n    # $ANTLR start \"atom\"\r\n    # Eval.g:407:1: atom returns [text] : (a= literal |a= member_expr |a= new_clause |a= array_decl |a= object_decl |a= sprintf );\r\n    def atom(self, ):\r\n        text = None\r\n\r\n\r\n        a = None\r\n\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:408:2: (a= literal |a= member_expr |a= new_clause |a= array_decl |a= object_decl |a= sprintf )\r\n                alt44 = 6\r\n                LA44 = self.input.LA(1)\r\n                if LA44 == BOOL or LA44 == FLOAT or LA44 == INT or LA44 == NULL or LA44 == STRING:\r\n                    alt44 = 1\r\n                elif LA44 == MEMBER:\r\n                    alt44 = 2\r\n                elif LA44 == NEW:\r\n                    alt44 = 3\r\n                elif LA44 == ARRAY:\r\n                    alt44 = 4\r\n                elif LA44 == OBJECT:\r\n                    alt44 = 5\r\n                elif LA44 == SPRINTF:\r\n                    alt44 = 6\r\n                else:\r\n                    nvae = NoViableAltException(\"\", 44, 0, self.input)\r\n\r\n                    raise nvae\r\n\r\n\r\n                if alt44 == 1:\r\n                    # Eval.g:408:4: a= literal\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_literal_in_atom1967)\r\n                    a = self.literal()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt44 == 2:\r\n                    # Eval.g:409:4: a= member_expr\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_member_expr_in_atom1977)\r\n                    a = self.member_expr()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt44 == 3:\r\n                    # Eval.g:410:4: a= new_clause\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_new_clause_in_atom1986)\r\n                    a = self.new_clause()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt44 == 4:\r\n                    # Eval.g:411:4: a= array_decl\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_array_decl_in_atom1995)\r\n                    a = self.array_decl()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt44 == 5:\r\n                    # Eval.g:412:4: a= object_decl\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_object_decl_in_atom2004)\r\n                    a = self.object_decl()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt44 == 6:\r\n                    # Eval.g:413:4: a= sprintf\r\n                    pass \r\n                    self._state.following.append(self.FOLLOW_sprintf_in_atom2013)\r\n                    a = self.sprintf()\r\n\r\n                    self._state.following.pop()\r\n\r\n                    #action start\r\n                    text = a\r\n                    #action end\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"atom\"\r\n\r\n\r\n\r\n    # $ANTLR start \"literal\"\r\n    # Eval.g:415:1: literal returns [text] : ( NULL | BOOL | INT | FLOAT | STRING );\r\n    def literal(self, ):\r\n        text = None\r\n\r\n\r\n        BOOL49 = None\r\n        INT50 = None\r\n        FLOAT51 = None\r\n        STRING52 = None\r\n\r\n        try:\r\n            try:\r\n                # Eval.g:416:2: ( NULL | BOOL | INT | FLOAT | STRING )\r\n                alt45 = 5\r\n                LA45 = self.input.LA(1)\r\n                if LA45 == NULL:\r\n                    alt45 = 1\r\n                elif LA45 == BOOL:\r\n                    alt45 = 2\r\n                elif LA45 == INT:\r\n                    alt45 = 3\r\n                elif LA45 == FLOAT:\r\n                    alt45 = 4\r\n                elif LA45 == STRING:\r\n                    alt45 = 5\r\n                else:\r\n                    nvae = NoViableAltException(\"\", 45, 0, self.input)\r\n\r\n                    raise nvae\r\n\r\n\r\n                if alt45 == 1:\r\n                    # Eval.g:416:4: NULL\r\n                    pass \r\n                    self.match(self.input, NULL, self.FOLLOW_NULL_in_literal2029)\r\n\r\n                    #action start\r\n                    text = 'None'\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt45 == 2:\r\n                    # Eval.g:417:4: BOOL\r\n                    pass \r\n                    BOOL49 = self.match(self.input, BOOL, self.FOLLOW_BOOL_in_literal2036)\r\n\r\n                    #action start\r\n                    text = BOOL49.text.capitalize()\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt45 == 3:\r\n                    # Eval.g:418:4: INT\r\n                    pass \r\n                    INT50 = self.match(self.input, INT, self.FOLLOW_INT_in_literal2043)\r\n\r\n                    #action start\r\n                    text = INT50.text\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt45 == 4:\r\n                    # Eval.g:419:4: FLOAT\r\n                    pass \r\n                    FLOAT51 = self.match(self.input, FLOAT, self.FOLLOW_FLOAT_in_literal2050)\r\n\r\n                    #action start\r\n                    text = FLOAT51.text\r\n                    #action end\r\n\r\n\r\n\r\n                elif alt45 == 5:\r\n                    # Eval.g:420:4: STRING\r\n                    pass \r\n                    STRING52 = self.match(self.input, STRING, self.FOLLOW_STRING_in_literal2057)\r\n\r\n                    #action start\r\n                    text = STRING52.text\r\n                    #action end\r\n\r\n\r\n\r\n\r\n            except RecognitionException, re:\r\n                self.reportError(re)\r\n                self.recover(self.input, re)\r\n\r\n        finally:\r\n            pass\r\n        return text\r\n\r\n    # $ANTLR end \"literal\"\r\n\r\n\r\n\r\n    # lookup tables for DFA #4\r\n\r\n    DFA4_eot = DFA.unpack(\r\n        u\"\\10\\uffff\"\r\n        )\r\n\r\n    DFA4_eof = DFA.unpack(\r\n        u\"\\10\\uffff\"\r\n        )\r\n\r\n    DFA4_min = DFA.unpack(\r\n        u\"\\1\\3\\1\\uffff\\1\\2\\1\\42\\2\\3\\2\\uffff\"\r\n        )\r\n\r\n    DFA4_max = DFA.unpack(\r\n        u\"\\1\\52\\1\\uffff\\1\\2\\2\\42\\1\\127\\2\\uffff\"\r\n        )\r\n\r\n    DFA4_accept = DFA.unpack(\r\n        u\"\\1\\uffff\\1\\3\\4\\uffff\\1\\1\\1\\2\"\r\n        )\r\n\r\n    DFA4_special = DFA.unpack(\r\n        u\"\\10\\uffff\"\r\n        )\r\n\r\n\r\n    DFA4_transition = [\r\n        DFA.unpack(u\"\\1\\1\\46\\uffff\\1\\2\"),\r\n        DFA.unpack(u\"\"),\r\n        DFA.unpack(u\"\\1\\3\"),\r\n        DFA.unpack(u\"\\1\\4\"),\r\n        DFA.unpack(u\"\\1\\5\\36\\uffff\\1\\4\"),\r\n        DFA.unpack(u\"\\1\\6\\46\\uffff\\1\\6\\54\\uffff\\1\\7\"),\r\n        DFA.unpack(u\"\"),\r\n        DFA.unpack(u\"\")\r\n    ]\r\n\r\n    # class definition for DFA #4\r\n\r\n    class DFA4(DFA):\r\n        pass\r\n\r\n\r\n \r\n\r\n    FOLLOW_stmt_in_prog69 = frozenset([1, 9, 13, 16, 20, 27, 31, 32, 33, 36, 37, 55, 56, 57, 62, 63, 64, 66])\r\n    FOLLOW_import_stmt_in_stmt81 = frozenset([1])\r\n    FOLLOW_exec_stmt_in_stmt86 = frozenset([1])\r\n    FOLLOW_print_stmt_in_stmt91 = frozenset([1])\r\n    FOLLOW_printf_stmt_in_stmt95 = frozenset([1])\r\n    FOLLOW_break_stmt_in_stmt100 = frozenset([1])\r\n    FOLLOW_continue_stmt_in_stmt105 = frozenset([1])\r\n    FOLLOW_return_stmt_in_stmt110 = frozenset([1])\r\n    FOLLOW_if_stmt_in_stmt115 = frozenset([1])\r\n    FOLLOW_while_stmt_in_stmt120 = frozenset([1])\r\n    FOLLOW_do_while_stmt_in_stmt125 = frozenset([1])\r\n    FOLLOW_switch_stmt_in_stmt130 = frozenset([1])\r\n    FOLLOW_throw_stmt_in_stmt135 = frozenset([1])\r\n    FOLLOW_try_stmt_in_stmt140 = frozenset([1])\r\n    FOLLOW_func_decl_in_stmt145 = frozenset([1])\r\n    FOLLOW_class_decl_in_stmt150 = frozenset([1])\r\n    FOLLOW_for_stmt_in_stmt155 = frozenset([1])\r\n    FOLLOW_foreach_stmt_in_stmt160 = frozenset([1])\r\n    FOLLOW_BLOCK_in_block185 = frozenset([2])\r\n    FOLLOW_stmt_in_block187 = frozenset([3, 9, 13, 16, 20, 27, 31, 32, 33, 36, 37, 55, 56, 57, 62, 63, 64, 66])\r\n    FOLLOW_IMPORT_in_import_stmt201 = frozenset([2])\r\n    FOLLOW_module_in_import_stmt209 = frozenset([3, 42])\r\n    FOLLOW_module_in_import_stmt222 = frozenset([87])\r\n    FOLLOW_87_in_import_stmt224 = frozenset([3, 42])\r\n    FOLLOW_EXEC_STMT_in_exec_stmt250 = frozenset([2])\r\n    FOLLOW_exec_list_in_exec_stmt252 = frozenset([3])\r\n    FOLLOW_member_expr_in_exec_expr270 = frozenset([1])\r\n    FOLLOW_ASSIGN_in_exec_expr280 = frozenset([2])\r\n    FOLLOW_member_expr_in_exec_expr282 = frozenset([71, 74, 78, 81, 85, 90, 95, 103, 134])\r\n    FOLLOW_set_in_exec_expr286 = frozenset([5, 8, 30, 39, 41, 43, 44, 47, 48, 60, 61, 68, 69, 70, 72, 73, 77, 79, 83, 89, 93, 94, 96, 98, 99, 102, 133, 135])\r\n    FOLLOW_expr_in_exec_expr306 = frozenset([3])\r\n    FOLLOW_POST_INC_in_exec_expr317 = frozenset([2])\r\n    FOLLOW_member_expr_in_exec_expr319 = frozenset([3])\r\n    FOLLOW_POST_DEC_in_exec_expr330 = frozenset([2])\r\n    FOLLOW_member_expr_in_exec_expr332 = frozenset([3])\r\n    FOLLOW_PRE_INC_in_exec_expr343 = frozenset([2])\r\n    FOLLOW_member_expr_in_exec_expr345 = frozenset([3])\r\n    FOLLOW_PRE_DEC_in_exec_expr356 = frozenset([2])\r\n    FOLLOW_member_expr_in_exec_expr358 = frozenset([3])\r\n    FOLLOW_EXEC_LIST_in_exec_list382 = frozenset([2])\r\n    FOLLOW_exec_expr_in_exec_list385 = frozenset([3, 6, 41, 51, 52, 53, 54])\r\n    FOLLOW_PRINTF_in_printf_stmt408 = frozenset([2])\r\n    FOLLOW_expr_in_printf_stmt410 = frozenset([3, 28])\r\n    FOLLOW_expr_list_in_printf_stmt412 = frozenset([3])\r\n    FOLLOW_PRINT_in_print_stmt429 = frozenset([2])\r\n    FOLLOW_expr_list_in_print_stmt431 = frozenset([3])\r\n    FOLLOW_BREAK_in_break_stmt451 = frozenset([1])\r\n    FOLLOW_CONTINUE_in_continue_stmt465 = frozenset([1])\r\n    FOLLOW_RETURN_in_return_stmt480 = frozenset([2])\r\n    FOLLOW_expr_in_return_stmt482 = frozenset([3])\r\n    FOLLOW_if_clause_in_if_stmt510 = frozenset([1, 23, 24])\r\n    FOLLOW_else_if_clause_in_if_stmt512 = frozenset([1, 23, 24])\r\n    FOLLOW_else_clause_in_if_stmt515 = frozenset([1])\r\n    FOLLOW_IF_in_if_clause527 = frozenset([2])\r\n    FOLLOW_expr_in_if_clause529 = frozenset([7])\r\n    FOLLOW_block_in_if_clause533 = frozenset([3])\r\n    FOLLOW_ELSE_IF_in_else_if_clause545 = frozenset([2])\r\n    FOLLOW_if_clause_in_else_if_clause549 = frozenset([3])\r\n    FOLLOW_ELSE_in_else_clause561 = frozenset([2])\r\n    FOLLOW_block_in_else_clause565 = frozenset([3])\r\n    FOLLOW_WHILE_in_while_stmt579 = frozenset([2])\r\n    FOLLOW_expr_in_while_stmt581 = frozenset([7])\r\n    FOLLOW_block_in_while_stmt585 = frozenset([3])\r\n    FOLLOW_DO_WHILE_in_do_while_stmt598 = frozenset([2])\r\n    FOLLOW_block_in_do_while_stmt604 = frozenset([5, 8, 30, 39, 41, 43, 44, 47, 48, 60, 61, 68, 69, 70, 72, 73, 77, 79, 83, 89, 93, 94, 96, 98, 99, 102, 133, 135])\r\n    FOLLOW_expr_in_do_while_stmt608 = frozenset([3])\r\n    FOLLOW_SWITCH_in_switch_stmt627 = frozenset([2])\r\n    FOLLOW_expr_in_switch_stmt629 = frozenset([132])\r\n    FOLLOW_case_block_in_switch_stmt633 = frozenset([3])\r\n    FOLLOW_132_in_case_block648 = frozenset([11])\r\n    FOLLOW_case_clause_in_case_block651 = frozenset([11, 17, 136])\r\n    FOLLOW_default_clause_in_case_block656 = frozenset([136])\r\n    FOLLOW_136_in_case_block660 = frozenset([1])\r\n    FOLLOW_CASE_in_case_clause676 = frozenset([2])\r\n    FOLLOW_case_test_in_case_clause678 = frozenset([9, 11, 13, 16, 20, 27, 31, 32, 33, 36, 37, 55, 56, 57, 62, 63, 64, 66])\r\n    FOLLOW_stmt_in_case_clause683 = frozenset([9, 13, 16, 20, 27, 31, 32, 33, 36, 37, 55, 56, 57, 62, 63, 64, 66])\r\n    FOLLOW_break_stmt_in_case_clause686 = frozenset([3])\r\n    FOLLOW_CASE_in_case_test702 = frozenset([2])\r\n    FOLLOW_expr_in_case_test704 = frozenset([3])\r\n    FOLLOW_DEFAULT_in_default_clause725 = frozenset([2])\r\n    FOLLOW_stmt_in_default_clause727 = frozenset([3, 9, 13, 16, 20, 27, 31, 32, 33, 36, 37, 55, 56, 57, 62, 63, 64, 66])\r\n    FOLLOW_FOR_in_for_stmt746 = frozenset([2])\r\n    FOLLOW_exec_list_in_for_stmt751 = frozenset([5, 8, 30, 39, 41, 43, 44, 47, 48, 60, 61, 68, 69, 70, 72, 73, 77, 79, 83, 89, 93, 94, 96, 98, 99, 102, 133, 135])\r\n    FOLLOW_expr_in_for_stmt759 = frozenset([7])\r\n    FOLLOW_block_in_for_stmt765 = frozenset([3, 26])\r\n    FOLLOW_exec_list_in_for_stmt776 = frozenset([3])\r\n    FOLLOW_FOREACH_in_foreach_stmt800 = frozenset([2])\r\n    FOLLOW_expr_in_foreach_stmt802 = frozenset([21])\r\n    FOLLOW_EACH_in_foreach_stmt809 = frozenset([2])\r\n    FOLLOW_ID_in_foreach_stmt813 = frozenset([22])\r\n    FOLLOW_each_val_in_foreach_stmt817 = frozenset([3])\r\n    FOLLOW_EACH_in_foreach_stmt830 = frozenset([2])\r\n    FOLLOW_each_val_in_foreach_stmt834 = frozenset([3])\r\n    FOLLOW_block_in_foreach_stmt848 = frozenset([3])\r\n    FOLLOW_EACH_VAL_in_each_val871 = frozenset([2])\r\n    FOLLOW_ID_in_each_val874 = frozenset([3, 34])\r\n    FOLLOW_THROW_in_throw_stmt897 = frozenset([2])\r\n    FOLLOW_expr_in_throw_stmt899 = frozenset([3])\r\n    FOLLOW_TRY_in_try_stmt920 = frozenset([2])\r\n    FOLLOW_block_in_try_stmt922 = frozenset([12])\r\n    FOLLOW_catch_clause_in_try_stmt924 = frozenset([3, 12, 29])\r\n    FOLLOW_finally_clause_in_try_stmt927 = frozenset([3])\r\n    FOLLOW_CATCH_in_catch_clause940 = frozenset([2])\r\n    FOLLOW_module_in_catch_clause942 = frozenset([7, 34])\r\n    FOLLOW_ID_in_catch_clause944 = frozenset([7])\r\n    FOLLOW_block_in_catch_clause953 = frozenset([3])\r\n    FOLLOW_FINALLY_in_finally_clause970 = frozenset([2])\r\n    FOLLOW_block_in_finally_clause972 = frozenset([3])\r\n    FOLLOW_FUNCTION_in_func_decl986 = frozenset([2])\r\n    FOLLOW_ID_in_func_decl988 = frozenset([50])\r\n    FOLLOW_params_in_func_decl990 = frozenset([7])\r\n    FOLLOW_block_in_func_decl998 = frozenset([3])\r\n    FOLLOW_PARAMS_in_params1021 = frozenset([2])\r\n    FOLLOW_param_decl_in_params1024 = frozenset([3, 34])\r\n    FOLLOW_ID_in_param_decl1048 = frozenset([1, 95])\r\n    FOLLOW_95_in_param_decl1057 = frozenset([5, 8, 30, 39, 41, 44, 47, 48, 60, 61])\r\n    FOLLOW_atom_in_param_decl1059 = frozenset([1])\r\n    FOLLOW_CLASS_in_class_decl1087 = frozenset([2])\r\n    FOLLOW_ID_in_class_decl1091 = frozenset([3, 15, 33, 65])\r\n    FOLLOW_class_element_in_class_decl1100 = frozenset([3, 15, 33, 65])\r\n    FOLLOW_CLASS_in_class_decl1108 = frozenset([2])\r\n    FOLLOW_ID_in_class_decl1112 = frozenset([34])\r\n    FOLLOW_ID_in_class_decl1116 = frozenset([3, 15, 33, 65])\r\n    FOLLOW_class_element_in_class_decl1125 = frozenset([3, 15, 33, 65])\r\n    FOLLOW_var_def_in_class_element1137 = frozenset([1])\r\n    FOLLOW_constructor_in_class_element1141 = frozenset([1])\r\n    FOLLOW_func_decl_in_class_element1145 = frozenset([1])\r\n    FOLLOW_VAR_in_var_def1156 = frozenset([2])\r\n    FOLLOW_ID_in_var_def1158 = frozenset([3, 5, 8, 30, 39, 41, 43, 44, 47, 48, 60, 61, 68, 69, 70, 72, 73, 77, 79, 83, 89, 93, 94, 96, 98, 99, 102, 133, 135])\r\n    FOLLOW_expr_in_var_def1160 = frozenset([3])\r\n    FOLLOW_VAR_in_var_def1172 = frozenset([2])\r\n    FOLLOW_127_in_var_def1174 = frozenset([34])\r\n    FOLLOW_ID_in_var_def1176 = frozenset([3, 5, 8, 30, 39, 41, 43, 44, 47, 48, 60, 61, 68, 69, 70, 72, 73, 77, 79, 83, 89, 93, 94, 96, 98, 99, 102, 133, 135])\r\n    FOLLOW_expr_in_var_def1178 = frozenset([3])\r\n    FOLLOW_CONSTRUCTOR_in_constructor1195 = frozenset([2])\r\n    FOLLOW_params_in_constructor1197 = frozenset([7])\r\n    FOLLOW_block_in_constructor1205 = frozenset([3])\r\n    FOLLOW_MODULE_in_module1229 = frozenset([2])\r\n    FOLLOW_ID_in_module1232 = frozenset([3, 34])\r\n    FOLLOW_MEMBER_in_member_expr1263 = frozenset([2])\r\n    FOLLOW_primary_in_member_expr1266 = frozenset([3, 34])\r\n    FOLLOW_ID_in_primary1295 = frozenset([1, 10, 38, 59])\r\n    FOLLOW_index_expr_in_primary1298 = frozenset([1, 10, 38, 59])\r\n    FOLLOW_call_expr_in_primary1305 = frozenset([1])\r\n    FOLLOW_CALL_in_call_expr1324 = frozenset([2])\r\n    FOLLOW_expr_list_in_call_expr1326 = frozenset([3])\r\n    FOLLOW_INDEX_in_index_expr1346 = frozenset([2])\r\n    FOLLOW_expr_in_index_expr1348 = frozenset([3])\r\n    FOLLOW_SLICE_in_index_expr1359 = frozenset([2])\r\n    FOLLOW_expr_in_index_expr1363 = frozenset([3, 5, 8, 30, 39, 41, 43, 44, 47, 48, 60, 61, 68, 69, 70, 72, 73, 77, 79, 83, 89, 93, 94, 96, 98, 99, 102, 133, 135])\r\n    FOLLOW_expr_in_index_expr1367 = frozenset([3])\r\n    FOLLOW_EXPR_LIST_in_expr_list1394 = frozenset([2])\r\n    FOLLOW_expr_in_expr_list1397 = frozenset([3, 5, 8, 30, 39, 41, 43, 44, 47, 48, 60, 61, 68, 69, 70, 72, 73, 77, 79, 83, 89, 93, 94, 96, 98, 99, 102, 133, 135])\r\n    FOLLOW_relation_expr_in_expr1423 = frozenset([1])\r\n    FOLLOW_logic_or_expr_in_expr1432 = frozenset([1])\r\n    FOLLOW_logic_and_expr_in_expr1441 = frozenset([1])\r\n    FOLLOW_bitwise_or_expr_in_expr1450 = frozenset([1])\r\n    FOLLOW_bitwise_xor_expr_in_expr1459 = frozenset([1])\r\n    FOLLOW_bitwise_and_expr_in_expr1468 = frozenset([1])\r\n    FOLLOW_add_expr_in_expr1477 = frozenset([1])\r\n    FOLLOW_mul_expr_in_expr1487 = frozenset([1])\r\n    FOLLOW_not_expr_in_expr1497 = frozenset([1])\r\n    FOLLOW_negative_expr_in_expr1507 = frozenset([1])\r\n    FOLLOW_atom_in_expr1516 = frozenset([1])\r\n    FOLLOW_135_in_logic_or_expr1534 = frozenset([2])\r\n    FOLLOW_expr_in_logic_or_expr1538 = frozenset([5, 8, 30, 39, 41, 43, 44, 47, 48, 60, 61, 68, 69, 70, 72, 73, 77, 79, 83, 89, 93, 94, 96, 98, 99, 102, 133, 135])\r\n    FOLLOW_expr_in_logic_or_expr1542 = frozenset([3])\r\n    FOLLOW_72_in_logic_and_expr1561 = frozenset([2])\r\n    FOLLOW_expr_in_logic_and_expr1565 = frozenset([5, 8, 30, 39, 41, 43, 44, 47, 48, 60, 61, 68, 69, 70, 72, 73, 77, 79, 83, 89, 93, 94, 96, 98, 99, 102, 133, 135])\r\n    FOLLOW_expr_in_logic_and_expr1569 = frozenset([3])\r\n    FOLLOW_133_in_bitwise_or_expr1588 = frozenset([2])\r\n    FOLLOW_expr_in_bitwise_or_expr1592 = frozenset([5, 8, 30, 39, 41, 43, 44, 47, 48, 60, 61, 68, 69, 70, 72, 73, 77, 79, 83, 89, 93, 94, 96, 98, 99, 102, 133, 135])\r\n    FOLLOW_expr_in_bitwise_or_expr1596 = frozenset([3])\r\n    FOLLOW_102_in_bitwise_xor_expr1615 = frozenset([2])\r\n    FOLLOW_expr_in_bitwise_xor_expr1619 = frozenset([5, 8, 30, 39, 41, 43, 44, 47, 48, 60, 61, 68, 69, 70, 72, 73, 77, 79, 83, 89, 93, 94, 96, 98, 99, 102, 133, 135])\r\n    FOLLOW_expr_in_bitwise_xor_expr1623 = frozenset([3])\r\n    FOLLOW_73_in_bitwise_and_expr1642 = frozenset([2])\r\n    FOLLOW_expr_in_bitwise_and_expr1646 = frozenset([5, 8, 30, 39, 41, 43, 44, 47, 48, 60, 61, 68, 69, 70, 72, 73, 77, 79, 83, 89, 93, 94, 96, 98, 99, 102, 133, 135])\r\n    FOLLOW_expr_in_bitwise_and_expr1650 = frozenset([3])\r\n    FOLLOW_set_in_relation_expr1671 = frozenset([2])\r\n    FOLLOW_expr_in_relation_expr1687 = frozenset([5, 8, 30, 39, 41, 43, 44, 47, 48, 60, 61, 68, 69, 70, 72, 73, 77, 79, 83, 89, 93, 94, 96, 98, 99, 102, 133, 135])\r\n    FOLLOW_expr_in_relation_expr1691 = frozenset([3])\r\n    FOLLOW_set_in_add_expr1712 = frozenset([2])\r\n    FOLLOW_expr_in_add_expr1720 = frozenset([5, 8, 30, 39, 41, 43, 44, 47, 48, 60, 61, 68, 69, 70, 72, 73, 77, 79, 83, 89, 93, 94, 96, 98, 99, 102, 133, 135])\r\n    FOLLOW_expr_in_add_expr1724 = frozenset([3])\r\n    FOLLOW_set_in_mul_expr1745 = frozenset([2])\r\n    FOLLOW_expr_in_mul_expr1755 = frozenset([5, 8, 30, 39, 41, 43, 44, 47, 48, 60, 61, 68, 69, 70, 72, 73, 77, 79, 83, 89, 93, 94, 96, 98, 99, 102, 133, 135])\r\n    FOLLOW_expr_in_mul_expr1759 = frozenset([3])\r\n    FOLLOW_68_in_not_expr1778 = frozenset([2])\r\n    FOLLOW_expr_in_not_expr1782 = frozenset([3])\r\n    FOLLOW_NEGATIVE_in_negative_expr1801 = frozenset([2])\r\n    FOLLOW_expr_in_negative_expr1805 = frozenset([3])\r\n    FOLLOW_SPRINTF_in_sprintf1826 = frozenset([2])\r\n    FOLLOW_expr_in_sprintf1828 = frozenset([3, 28])\r\n    FOLLOW_expr_list_in_sprintf1832 = frozenset([3])\r\n    FOLLOW_NEW_in_new_clause1853 = frozenset([2])\r\n    FOLLOW_module_in_new_clause1855 = frozenset([10])\r\n    FOLLOW_call_expr_in_new_clause1857 = frozenset([3])\r\n    FOLLOW_ARRAY_in_array_decl1877 = frozenset([2])\r\n    FOLLOW_expr_list_in_array_decl1879 = frozenset([3])\r\n    FOLLOW_OBJECT_in_object_decl1904 = frozenset([2])\r\n    FOLLOW_property_in_object_decl1907 = frozenset([3, 34, 39, 61])\r\n    FOLLOW_set_in_property1932 = frozenset([91])\r\n    FOLLOW_91_in_property1944 = frozenset([5, 8, 30, 39, 41, 43, 44, 47, 48, 60, 61, 68, 69, 70, 72, 73, 77, 79, 83, 89, 93, 94, 96, 98, 99, 102, 133, 135])\r\n    FOLLOW_expr_in_property1946 = frozenset([1])\r\n    FOLLOW_literal_in_atom1967 = frozenset([1])\r\n    FOLLOW_member_expr_in_atom1977 = frozenset([1])\r\n    FOLLOW_new_clause_in_atom1986 = frozenset([1])\r\n    FOLLOW_array_decl_in_atom1995 = frozenset([1])\r\n    FOLLOW_object_decl_in_atom2004 = frozenset([1])\r\n    FOLLOW_sprintf_in_atom2013 = frozenset([1])\r\n    FOLLOW_NULL_in_literal2029 = frozenset([1])\r\n    FOLLOW_BOOL_in_literal2036 = frozenset([1])\r\n    FOLLOW_INT_in_literal2043 = frozenset([1])\r\n    FOLLOW_FLOAT_in_literal2050 = frozenset([1])\r\n    FOLLOW_STRING_in_literal2057 = frozenset([1])\r\n\r\n\r\n\r\ndef main(argv, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr):\r\n    from antlr3.main import WalkerMain\r\n    main = WalkerMain(Eval)\r\n\r\n    main.stdin = stdin\r\n    main.stdout = stdout\r\n    main.stderr = stderr\r\n    main.execute(argv)\r\n\r\n\r\n\r\nif __name__ == '__main__':\r\n    main(sys.argv)\r\n"
  },
  {
    "path": "deps/cpy/Expr.g",
    "content": "/********************************\r\n * Author: ideawu\r\n * Link: http://www.ideawu.net/\r\n ********************************/\r\n\r\ngrammar Expr;\r\n\r\noptions {\r\n\tlanguage=Python;\r\n\toutput=AST;\r\n\tASTLabelType=CommonTree;\r\n}\r\n\r\ntokens{\r\n\tNOP; EMPTY_LINE; ID_LIST;\r\n\tNEW; THROW; TRY; CATCH; FINALLY;\r\n\tPRINT; PRINTF; SPRINTF;\r\n\tCALL; BLOCK; EXPR_LIST;\r\n\tIMPORT; MEMBER; MODULE;\r\n\tARRAY; INDEX; SLICE; OBJECT;\r\n\tCLASS; FUNCTION; PARAMS;\r\n\tPRE_INC; PRE_DEC; POST_INC; POST_DEC;\r\n\tIF; ELSE; ELSE_IF; WHILE; DO_WHILE;\r\n\tSWITCH; CASE; DEFAULT;\r\n\tBREAK; CONTINUE; RETURN;\r\n\tFOR; FOREACH; EACH; EACH_VAL;\r\n\tCLASS; VAR; CONSTRUCTOR;\r\n\tASSIGN; OP_ASSIGN;\r\n\tEXEC_STMT; EXEC_LIST;\r\n\tNEGATIVE;\r\n}\r\n\r\nprog\r\n\t: EOF -> NOP\r\n\t| stmt*\r\n\t;\r\n\r\nstmt\r\n\t: ';' ->\r\n\t| exec_stmt\r\n\t| import_stmt\r\n\t| print_stmt | printf_stmt\r\n\t| break_stmt\r\n\t| continue_stmt\r\n\t| return_stmt\r\n\t| if_stmt\r\n\t| while_stmt\r\n\t| do_while_stmt\r\n\t| switch_stmt\r\n\t| for_stmt\r\n\t| foreach_stmt\r\n\t| throw_stmt\r\n\t| try_stmt\r\n\t| func_decl\r\n\t| class_decl\r\n\t;\r\n\r\n/***** statements *****/\r\nblock\r\n\t: '{' stmt* '}'\r\n\t\t-> ^(BLOCK stmt*)\r\n\t;\r\n\r\nimport_stmt\r\n\t: 'import' module_path (',' module_path)* ';'\r\n\t\t-> ^(IMPORT module_path+)\r\n\t;\r\nmodule_path\r\n\t: module\r\n\t| module '.*'\r\n\t;\r\n\r\nprintf_stmt\r\n\t: 'printf' '(' expr (',' expr_list)? ')' ';'\r\n\t\t-> ^(PRINTF expr expr_list?)\r\n\t;\r\n// echo: no newline\r\nprint_stmt\r\n\t//: ('print')  expr (',' expr)* ';'\r\n\t//\t-> ^(PRINT expr+)\r\n\t: ('print') expr_list ';'\r\n\t\t-> ^(PRINT expr_list)\r\n\t;\r\n\r\nbreak_stmt\r\n\t: 'break' ';'\r\n\t\t-> BREAK\r\n\t;\r\ncontinue_stmt\r\n\t: 'continue' ';'\r\n\t\t-> CONTINUE\r\n\t;\r\nreturn_stmt\r\n\t: 'return' expr? ';'\r\n\t\t-> ^(RETURN expr?)\r\n\t;\r\n\r\nif_stmt\r\n\t: if_clause else_if_clause* else_clause?\r\n\t;\r\nif_clause\r\n\t: 'if' '(' expr ')' block\r\n\t\t-> ^(IF expr block)\r\n\t;\r\nelse_if_clause\r\n\t: 'else' if_clause\r\n\t\t-> ^(ELSE_IF if_clause)\r\n\t;\r\nelse_clause\r\n\t: 'else' block\r\n\t\t-> ^(ELSE block)\r\n\t;\r\n\r\nwhile_stmt\r\n\t: 'while' '(' expr ')' block\r\n\t\t-> ^(WHILE expr block)\r\n\t;\r\n\r\ndo_while_stmt\r\n\t: 'do' block 'while' '(' expr ')' ';'\r\n\t\t-> ^(DO_WHILE block expr)\r\n\t;\r\n\r\nswitch_stmt\r\n\t: 'switch' '(' expr ')' case_block\r\n\t\t-> ^(SWITCH expr case_block)\r\n\t;\r\ncase_block\r\n\t: '{' (case_clause)+ (default_clause)? '}'\r\n\t;\r\ncase_clause\r\n\t: case_test+ stmt* break_stmt\r\n\t\t-> ^(CASE case_test+ stmt* break_stmt)\r\n\t;\r\ncase_test\r\n\t: 'case' expr ':'\r\n\t\t-> ^(CASE expr)\r\n\t;\r\ndefault_clause\r\n\t: 'default' ':' stmt*\r\n\t\t-> ^(DEFAULT stmt*)\r\n\t;\r\n\r\nfor_stmt\r\n\t: 'for' '(' a=exec_list? ';' expr ';' b=exec_list? ')' block\r\n\t\t-> ^(FOR $a? expr block $b?)\r\n\t;\r\n// for in 是一种 trackback 结构, 而 foreach as 不是\r\nforeach_stmt\r\n\t: 'foreach' '(' expr 'as' each ')' block\r\n\t\t-> ^(FOREACH expr each block)\r\n\t;\r\neach\r\n\t: each_val\r\n\t\t-> ^(EACH each_val)\r\n\t| ID '=>' each_val\r\n\t\t-> ^(EACH ID each_val)\r\n\t;\r\neach_val\r\n\t: ID (',' ID)*\r\n\t\t-> ^(EACH_VAL ID+)\r\n\t;\r\n\r\n\r\nthrow_stmt\r\n\t: 'throw' expr ';'\r\n\t\t-> ^(THROW expr)\r\n\t;\r\ntry_stmt\r\n\t: 'try' block catch_clause+ finally_clause?\r\n\t\t-> ^(TRY block catch_clause+ finally_clause?)\r\n\t;\r\ncatch_clause\r\n\t: 'catch' '(' module ID? ')' block\r\n\t\t-> ^(CATCH module ID? block)\r\n\t;\r\nfinally_clause\r\n\t: 'finally' block\r\n\t\t-> ^(FINALLY block)\r\n\t;\r\n\r\n\r\nfunc_decl\r\n\t: 'function' ID params block\r\n\t\t-> ^(FUNCTION ID params block)\r\n\t;\r\nparams\r\n\t: '(' param_decl? (',' param_decl)* ')'\r\n\t\t-> ^(PARAMS param_decl*)\r\n\t;\r\nparam_decl\r\n\t: ID ('=' atom)?\r\n\t;\r\n\r\nclass_decl\r\n\t: 'class' ID ('extends' ID)?\r\n\t\t'{' class_element* '}'\r\n\t\t-> ^(CLASS ID ID? class_element*)\r\n\t;\r\nclass_element\r\n\t: var_def | constructor | func_decl\r\n\t;\r\nvar_def\r\n\t: 'public' ID ('=' expr)? ';'\r\n\t\t-> ^(VAR ID expr?)\r\n\t| 'public' 'static' ID ('=' expr)? ';'\r\n\t\t-> ^(VAR 'static' ID expr?)\r\n\t;\r\nconstructor\r\n\t: 'function' 'init' params block\r\n\t\t-> ^(CONSTRUCTOR params block)\r\n\t;\r\n\r\n\r\n\r\n/***** expressions *****/\r\nmember_expr\r\n\t: primary ('.' primary)*\r\n\t\t-> ^(MEMBER primary+)\r\n\t;\r\nprimary\r\n\t: ID index_expr* call_expr?\r\n\t;\r\ncall_expr\r\n\t: '(' expr_list? ')'\r\n\t\t-> ^(CALL expr_list?)\r\n\t;\r\nindex_expr\r\n\toptions{\r\n\t\tbacktrack = true;\r\n\t}\r\n\t: '[' expr ']'\r\n\t\t-> ^(INDEX expr)\r\n\t| '[' expr '..' expr? ']'\r\n\t\t-> ^(SLICE expr expr?)\r\n\t;\r\n\r\n\r\nexec_list\r\n\t: exec_expr (',' exec_expr)*\r\n\t\t-> ^(EXEC_LIST exec_expr+)\r\n\t;\r\nmember_list\r\n\t: member_expr (',' member_expr)*\r\n\t;\r\nexec_expr\r\n\t: member_expr\r\n\t\t(assign_op expr\r\n\t\t\t-> ^(ASSIGN member_expr assign_op expr)\r\n\t\t| '++'\r\n\t\t\t-> ^(POST_INC member_expr)\r\n\t\t| '--'\r\n\t\t\t-> ^(POST_DEC member_expr)\r\n\t\t|\r\n\t\t\t-> member_expr\r\n\t\t)\r\n\t| '++' member_expr\r\n\t\t-> ^(PRE_INC member_expr)\r\n\t| '--' member_expr\r\n\t\t-> ^(PRE_DEC member_expr)\r\n\t;\r\nassign_op\r\n\t: '='|'+='|'-='|'*='|'/='|'%='|'&='|'^='|'|='\r\n\t;\r\nexec_stmt\r\n\t: exec_list ';'\r\n\t\t-> ^(EXEC_STMT exec_list)\r\n\t;\r\n\r\n\r\n\r\nexpr_list\r\n\t: expr (',' expr)* ','?\r\n\t\t-> ^(EXPR_LIST expr+)\r\n\t;\r\nexpr\r\n\t: logic_or_expr\r\n\t;\r\nlogic_or_expr\r\n\t: logic_and_expr ('||'^ logic_and_expr)*\r\n\t;\r\nlogic_and_expr\r\n\t: bitwise_or_expr ('&&'^ bitwise_or_expr)*\r\n\t;\r\nbitwise_or_expr\r\n\t: bitwise_xor_expr ('|'^ bitwise_xor_expr)*\r\n\t;\r\nbitwise_xor_expr\r\n\t: bitwise_and_expr ('^'^ bitwise_and_expr)*\r\n\t;\r\nbitwise_and_expr\r\n\t: relation_expr ('&'^ relation_expr)*\r\n\t;\r\nrelation_expr\r\n\t: add_expr (('<'|'>'|'<='|'>='|'=='|'!=')^ add_expr)?\r\n\t;\r\nadd_expr\r\n\t: mul_expr (('+'|'-')^ mul_expr)*\r\n\t;\r\nmul_expr\r\n\t: not_expr (('*'|'/'|'%')^ not_expr)*\r\n\t;\r\nnot_expr\r\n\t: op='!'? negative_expr\r\n\t\t-> {$op != None}?\r\n\t\t\t^('!' negative_expr)\r\n\t\t\t-> negative_expr\r\n\t;\r\nnegative_expr\r\n\t: (op='-')? atom\r\n\t\t-> {$op != None}?\r\n\t\t\t^(NEGATIVE atom)\r\n\t\t\t-> atom\r\n\t;\r\n\r\natom\r\n\t: literal\r\n\t| member_expr\r\n\t| array_decl\r\n\t| object_decl\r\n\t| new_clause\r\n\t| sprintf\r\n\t| '(' expr ')' -> expr\r\n\t;\r\nliteral\r\n\t: BOOL | NULL | INT | FLOAT | STRING\r\n\t;\r\n\r\nnew_clause\r\n\t: 'new' module call_expr\r\n\t\t-> ^(NEW module call_expr)\r\n\t;\r\nmodule\r\n\t: ID ('.' ID)*\r\n\t\t-> ^(MODULE ID+)\r\n\t;\r\n\r\n\r\narray_decl\r\n\t: '[' expr_list? ']'\r\n\t\t-> ^(ARRAY expr_list?)\r\n\t;\r\n\r\nobject_decl\r\n\t: '{' property? (',' property)* ','? '}'\r\n\t\t-> ^(OBJECT property*)\r\n\t;\r\nproperty\r\n\t: (ID | STRING | INT) ':' expr\r\n\t;\r\n\r\n\r\nsprintf\r\n\t: 'sprintf' '(' expr (',' expr_list)? ')'\r\n\t\t-> ^(SPRINTF expr expr_list?)\r\n\t;\r\n\r\n/***** tokens *****/\r\n\r\nNULL\r\n\t: 'null'\r\n\t;\r\nBOOL\r\n\t: 'true' | 'false'\r\n\t;\r\nID\r\n\t: (ALPHA | '_' | '$') (ALPHA | '_' | DIGIT)*\r\n\t;\r\n\r\nINT\r\n\t: DIGIT+\r\n\t;\r\nFLOAT\r\n\t: INT '.' DIGIT*\r\n\t;\r\nfragment ALPHA\r\n\t: 'a'..'z' |'A'..'Z'\r\n\t;\r\nfragment DIGIT\r\n\t: '0'..'9'\r\n\t;\r\n// TODO: 字符串拼接 \"$a$b\"\r\nSTRING\r\n\t: '\"' DOUBLE_QUOTE_CHARS* '\"'\r\n\t| '\\'' SINGLE_QUOTE_CHARS* '\\''\r\n\t;\r\nfragment DOUBLE_QUOTE_CHARS\r\n\t: ~('\"')\r\n\t// 应该是 '\\\\\"' 吧?\r\n\t| '\\\\' '\"'\r\n\t;\r\nfragment SINGLE_QUOTE_CHARS\r\n\t: ~('\\'')\r\n\t| '\\\\' '\\''\r\n\t;\r\n\r\nfragment NEWLINE\r\n\t: '\\r'? '\\n'\r\n\t;\r\n\r\nWS\r\n\t: (' '|'\\t'|'\\r'|'\\n')+ {$channel=HIDDEN;}\r\n\t;\r\nCOMMENT\r\n\t: '/*' (options {greedy=false;}:.)* '*/' {$channel=HIDDEN;}\r\n\t;\r\nLINECOMMENT\r\n\t: ('//'|'#') ~('\\r'|'\\n')* NEWLINE {$channel=HIDDEN;}\r\n\t;\r\n\r\n"
  },
  {
    "path": "deps/cpy/ExprLexer.py",
    "content": "# $ANTLR 3.5 Expr.g 2013-04-12 19:22:24\n\nimport sys\nfrom antlr3 import *\nfrom antlr3.compat import set, frozenset\n\n\n\n# for convenience in actions\nHIDDEN = BaseRecognizer.HIDDEN\n\n# token types\nEOF=-1\nT__68=68\nT__69=69\nT__70=70\nT__71=71\nT__72=72\nT__73=73\nT__74=74\nT__75=75\nT__76=76\nT__77=77\nT__78=78\nT__79=79\nT__80=80\nT__81=81\nT__82=82\nT__83=83\nT__84=84\nT__85=85\nT__86=86\nT__87=87\nT__88=88\nT__89=89\nT__90=90\nT__91=91\nT__92=92\nT__93=93\nT__94=94\nT__95=95\nT__96=96\nT__97=97\nT__98=98\nT__99=99\nT__100=100\nT__101=101\nT__102=102\nT__103=103\nT__104=104\nT__105=105\nT__106=106\nT__107=107\nT__108=108\nT__109=109\nT__110=110\nT__111=111\nT__112=112\nT__113=113\nT__114=114\nT__115=115\nT__116=116\nT__117=117\nT__118=118\nT__119=119\nT__120=120\nT__121=121\nT__122=122\nT__123=123\nT__124=124\nT__125=125\nT__126=126\nT__127=127\nT__128=128\nT__129=129\nT__130=130\nT__131=131\nT__132=132\nT__133=133\nT__134=134\nT__135=135\nT__136=136\nALPHA=4\nARRAY=5\nASSIGN=6\nBLOCK=7\nBOOL=8\nBREAK=9\nCALL=10\nCASE=11\nCATCH=12\nCLASS=13\nCOMMENT=14\nCONSTRUCTOR=15\nCONTINUE=16\nDEFAULT=17\nDIGIT=18\nDOUBLE_QUOTE_CHARS=19\nDO_WHILE=20\nEACH=21\nEACH_VAL=22\nELSE=23\nELSE_IF=24\nEMPTY_LINE=25\nEXEC_LIST=26\nEXEC_STMT=27\nEXPR_LIST=28\nFINALLY=29\nFLOAT=30\nFOR=31\nFOREACH=32\nFUNCTION=33\nID=34\nID_LIST=35\nIF=36\nIMPORT=37\nINDEX=38\nINT=39\nLINECOMMENT=40\nMEMBER=41\nMODULE=42\nNEGATIVE=43\nNEW=44\nNEWLINE=45\nNOP=46\nNULL=47\nOBJECT=48\nOP_ASSIGN=49\nPARAMS=50\nPOST_DEC=51\nPOST_INC=52\nPRE_DEC=53\nPRE_INC=54\nPRINT=55\nPRINTF=56\nRETURN=57\nSINGLE_QUOTE_CHARS=58\nSLICE=59\nSPRINTF=60\nSTRING=61\nSWITCH=62\nTHROW=63\nTRY=64\nVAR=65\nWHILE=66\nWS=67\n\n\nclass ExprLexer(Lexer):\n\n    grammarFileName = \"Expr.g\"\n    api_version = 1\n\n    def __init__(self, input=None, state=None):\n        if state is None:\n            state = RecognizerSharedState()\n        super(ExprLexer, self).__init__(input, state)\n\n        self.delegates = []\n\n        self.dfa15 = self.DFA15(\n            self, 15,\n            eot = self.DFA15_eot,\n            eof = self.DFA15_eof,\n            min = self.DFA15_min,\n            max = self.DFA15_max,\n            accept = self.DFA15_accept,\n            special = self.DFA15_special,\n            transition = self.DFA15_transition\n            )\n\n\n\n\n\n\n    # $ANTLR start \"T__68\"\n    def mT__68(self, ):\n        try:\n            _type = T__68\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:7:7: ( '!' )\n            # Expr.g:7:9: '!'\n            pass \n            self.match(33)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__68\"\n\n\n\n    # $ANTLR start \"T__69\"\n    def mT__69(self, ):\n        try:\n            _type = T__69\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:8:7: ( '!=' )\n            # Expr.g:8:9: '!='\n            pass \n            self.match(\"!=\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__69\"\n\n\n\n    # $ANTLR start \"T__70\"\n    def mT__70(self, ):\n        try:\n            _type = T__70\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:9:7: ( '%' )\n            # Expr.g:9:9: '%'\n            pass \n            self.match(37)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__70\"\n\n\n\n    # $ANTLR start \"T__71\"\n    def mT__71(self, ):\n        try:\n            _type = T__71\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:10:7: ( '%=' )\n            # Expr.g:10:9: '%='\n            pass \n            self.match(\"%=\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__71\"\n\n\n\n    # $ANTLR start \"T__72\"\n    def mT__72(self, ):\n        try:\n            _type = T__72\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:11:7: ( '&&' )\n            # Expr.g:11:9: '&&'\n            pass \n            self.match(\"&&\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__72\"\n\n\n\n    # $ANTLR start \"T__73\"\n    def mT__73(self, ):\n        try:\n            _type = T__73\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:12:7: ( '&' )\n            # Expr.g:12:9: '&'\n            pass \n            self.match(38)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__73\"\n\n\n\n    # $ANTLR start \"T__74\"\n    def mT__74(self, ):\n        try:\n            _type = T__74\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:13:7: ( '&=' )\n            # Expr.g:13:9: '&='\n            pass \n            self.match(\"&=\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__74\"\n\n\n\n    # $ANTLR start \"T__75\"\n    def mT__75(self, ):\n        try:\n            _type = T__75\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:14:7: ( '(' )\n            # Expr.g:14:9: '('\n            pass \n            self.match(40)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__75\"\n\n\n\n    # $ANTLR start \"T__76\"\n    def mT__76(self, ):\n        try:\n            _type = T__76\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:15:7: ( ')' )\n            # Expr.g:15:9: ')'\n            pass \n            self.match(41)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__76\"\n\n\n\n    # $ANTLR start \"T__77\"\n    def mT__77(self, ):\n        try:\n            _type = T__77\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:16:7: ( '*' )\n            # Expr.g:16:9: '*'\n            pass \n            self.match(42)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__77\"\n\n\n\n    # $ANTLR start \"T__78\"\n    def mT__78(self, ):\n        try:\n            _type = T__78\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:17:7: ( '*=' )\n            # Expr.g:17:9: '*='\n            pass \n            self.match(\"*=\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__78\"\n\n\n\n    # $ANTLR start \"T__79\"\n    def mT__79(self, ):\n        try:\n            _type = T__79\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:18:7: ( '+' )\n            # Expr.g:18:9: '+'\n            pass \n            self.match(43)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__79\"\n\n\n\n    # $ANTLR start \"T__80\"\n    def mT__80(self, ):\n        try:\n            _type = T__80\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:19:7: ( '++' )\n            # Expr.g:19:9: '++'\n            pass \n            self.match(\"++\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__80\"\n\n\n\n    # $ANTLR start \"T__81\"\n    def mT__81(self, ):\n        try:\n            _type = T__81\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:20:7: ( '+=' )\n            # Expr.g:20:9: '+='\n            pass \n            self.match(\"+=\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__81\"\n\n\n\n    # $ANTLR start \"T__82\"\n    def mT__82(self, ):\n        try:\n            _type = T__82\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:21:7: ( ',' )\n            # Expr.g:21:9: ','\n            pass \n            self.match(44)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__82\"\n\n\n\n    # $ANTLR start \"T__83\"\n    def mT__83(self, ):\n        try:\n            _type = T__83\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:22:7: ( '-' )\n            # Expr.g:22:9: '-'\n            pass \n            self.match(45)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__83\"\n\n\n\n    # $ANTLR start \"T__84\"\n    def mT__84(self, ):\n        try:\n            _type = T__84\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:23:7: ( '--' )\n            # Expr.g:23:9: '--'\n            pass \n            self.match(\"--\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__84\"\n\n\n\n    # $ANTLR start \"T__85\"\n    def mT__85(self, ):\n        try:\n            _type = T__85\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:24:7: ( '-=' )\n            # Expr.g:24:9: '-='\n            pass \n            self.match(\"-=\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__85\"\n\n\n\n    # $ANTLR start \"T__86\"\n    def mT__86(self, ):\n        try:\n            _type = T__86\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:25:7: ( '.' )\n            # Expr.g:25:9: '.'\n            pass \n            self.match(46)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__86\"\n\n\n\n    # $ANTLR start \"T__87\"\n    def mT__87(self, ):\n        try:\n            _type = T__87\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:26:7: ( '.*' )\n            # Expr.g:26:9: '.*'\n            pass \n            self.match(\".*\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__87\"\n\n\n\n    # $ANTLR start \"T__88\"\n    def mT__88(self, ):\n        try:\n            _type = T__88\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:27:7: ( '..' )\n            # Expr.g:27:9: '..'\n            pass \n            self.match(\"..\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__88\"\n\n\n\n    # $ANTLR start \"T__89\"\n    def mT__89(self, ):\n        try:\n            _type = T__89\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:28:7: ( '/' )\n            # Expr.g:28:9: '/'\n            pass \n            self.match(47)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__89\"\n\n\n\n    # $ANTLR start \"T__90\"\n    def mT__90(self, ):\n        try:\n            _type = T__90\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:29:7: ( '/=' )\n            # Expr.g:29:9: '/='\n            pass \n            self.match(\"/=\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__90\"\n\n\n\n    # $ANTLR start \"T__91\"\n    def mT__91(self, ):\n        try:\n            _type = T__91\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:30:7: ( ':' )\n            # Expr.g:30:9: ':'\n            pass \n            self.match(58)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__91\"\n\n\n\n    # $ANTLR start \"T__92\"\n    def mT__92(self, ):\n        try:\n            _type = T__92\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:31:7: ( ';' )\n            # Expr.g:31:9: ';'\n            pass \n            self.match(59)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__92\"\n\n\n\n    # $ANTLR start \"T__93\"\n    def mT__93(self, ):\n        try:\n            _type = T__93\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:32:7: ( '<' )\n            # Expr.g:32:9: '<'\n            pass \n            self.match(60)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__93\"\n\n\n\n    # $ANTLR start \"T__94\"\n    def mT__94(self, ):\n        try:\n            _type = T__94\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:33:7: ( '<=' )\n            # Expr.g:33:9: '<='\n            pass \n            self.match(\"<=\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__94\"\n\n\n\n    # $ANTLR start \"T__95\"\n    def mT__95(self, ):\n        try:\n            _type = T__95\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:34:7: ( '=' )\n            # Expr.g:34:9: '='\n            pass \n            self.match(61)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__95\"\n\n\n\n    # $ANTLR start \"T__96\"\n    def mT__96(self, ):\n        try:\n            _type = T__96\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:35:7: ( '==' )\n            # Expr.g:35:9: '=='\n            pass \n            self.match(\"==\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__96\"\n\n\n\n    # $ANTLR start \"T__97\"\n    def mT__97(self, ):\n        try:\n            _type = T__97\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:36:7: ( '=>' )\n            # Expr.g:36:9: '=>'\n            pass \n            self.match(\"=>\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__97\"\n\n\n\n    # $ANTLR start \"T__98\"\n    def mT__98(self, ):\n        try:\n            _type = T__98\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:37:7: ( '>' )\n            # Expr.g:37:9: '>'\n            pass \n            self.match(62)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__98\"\n\n\n\n    # $ANTLR start \"T__99\"\n    def mT__99(self, ):\n        try:\n            _type = T__99\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:38:7: ( '>=' )\n            # Expr.g:38:9: '>='\n            pass \n            self.match(\">=\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__99\"\n\n\n\n    # $ANTLR start \"T__100\"\n    def mT__100(self, ):\n        try:\n            _type = T__100\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:39:8: ( '[' )\n            # Expr.g:39:10: '['\n            pass \n            self.match(91)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__100\"\n\n\n\n    # $ANTLR start \"T__101\"\n    def mT__101(self, ):\n        try:\n            _type = T__101\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:40:8: ( ']' )\n            # Expr.g:40:10: ']'\n            pass \n            self.match(93)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__101\"\n\n\n\n    # $ANTLR start \"T__102\"\n    def mT__102(self, ):\n        try:\n            _type = T__102\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:41:8: ( '^' )\n            # Expr.g:41:10: '^'\n            pass \n            self.match(94)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__102\"\n\n\n\n    # $ANTLR start \"T__103\"\n    def mT__103(self, ):\n        try:\n            _type = T__103\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:42:8: ( '^=' )\n            # Expr.g:42:10: '^='\n            pass \n            self.match(\"^=\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__103\"\n\n\n\n    # $ANTLR start \"T__104\"\n    def mT__104(self, ):\n        try:\n            _type = T__104\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:43:8: ( 'as' )\n            # Expr.g:43:10: 'as'\n            pass \n            self.match(\"as\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__104\"\n\n\n\n    # $ANTLR start \"T__105\"\n    def mT__105(self, ):\n        try:\n            _type = T__105\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:44:8: ( 'break' )\n            # Expr.g:44:10: 'break'\n            pass \n            self.match(\"break\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__105\"\n\n\n\n    # $ANTLR start \"T__106\"\n    def mT__106(self, ):\n        try:\n            _type = T__106\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:45:8: ( 'case' )\n            # Expr.g:45:10: 'case'\n            pass \n            self.match(\"case\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__106\"\n\n\n\n    # $ANTLR start \"T__107\"\n    def mT__107(self, ):\n        try:\n            _type = T__107\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:46:8: ( 'catch' )\n            # Expr.g:46:10: 'catch'\n            pass \n            self.match(\"catch\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__107\"\n\n\n\n    # $ANTLR start \"T__108\"\n    def mT__108(self, ):\n        try:\n            _type = T__108\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:47:8: ( 'class' )\n            # Expr.g:47:10: 'class'\n            pass \n            self.match(\"class\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__108\"\n\n\n\n    # $ANTLR start \"T__109\"\n    def mT__109(self, ):\n        try:\n            _type = T__109\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:48:8: ( 'continue' )\n            # Expr.g:48:10: 'continue'\n            pass \n            self.match(\"continue\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__109\"\n\n\n\n    # $ANTLR start \"T__110\"\n    def mT__110(self, ):\n        try:\n            _type = T__110\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:49:8: ( 'default' )\n            # Expr.g:49:10: 'default'\n            pass \n            self.match(\"default\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__110\"\n\n\n\n    # $ANTLR start \"T__111\"\n    def mT__111(self, ):\n        try:\n            _type = T__111\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:50:8: ( 'do' )\n            # Expr.g:50:10: 'do'\n            pass \n            self.match(\"do\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__111\"\n\n\n\n    # $ANTLR start \"T__112\"\n    def mT__112(self, ):\n        try:\n            _type = T__112\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:51:8: ( 'else' )\n            # Expr.g:51:10: 'else'\n            pass \n            self.match(\"else\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__112\"\n\n\n\n    # $ANTLR start \"T__113\"\n    def mT__113(self, ):\n        try:\n            _type = T__113\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:52:8: ( 'extends' )\n            # Expr.g:52:10: 'extends'\n            pass \n            self.match(\"extends\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__113\"\n\n\n\n    # $ANTLR start \"T__114\"\n    def mT__114(self, ):\n        try:\n            _type = T__114\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:53:8: ( 'finally' )\n            # Expr.g:53:10: 'finally'\n            pass \n            self.match(\"finally\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__114\"\n\n\n\n    # $ANTLR start \"T__115\"\n    def mT__115(self, ):\n        try:\n            _type = T__115\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:54:8: ( 'for' )\n            # Expr.g:54:10: 'for'\n            pass \n            self.match(\"for\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__115\"\n\n\n\n    # $ANTLR start \"T__116\"\n    def mT__116(self, ):\n        try:\n            _type = T__116\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:55:8: ( 'foreach' )\n            # Expr.g:55:10: 'foreach'\n            pass \n            self.match(\"foreach\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__116\"\n\n\n\n    # $ANTLR start \"T__117\"\n    def mT__117(self, ):\n        try:\n            _type = T__117\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:56:8: ( 'function' )\n            # Expr.g:56:10: 'function'\n            pass \n            self.match(\"function\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__117\"\n\n\n\n    # $ANTLR start \"T__118\"\n    def mT__118(self, ):\n        try:\n            _type = T__118\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:57:8: ( 'if' )\n            # Expr.g:57:10: 'if'\n            pass \n            self.match(\"if\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__118\"\n\n\n\n    # $ANTLR start \"T__119\"\n    def mT__119(self, ):\n        try:\n            _type = T__119\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:58:8: ( 'import' )\n            # Expr.g:58:10: 'import'\n            pass \n            self.match(\"import\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__119\"\n\n\n\n    # $ANTLR start \"T__120\"\n    def mT__120(self, ):\n        try:\n            _type = T__120\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:59:8: ( 'init' )\n            # Expr.g:59:10: 'init'\n            pass \n            self.match(\"init\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__120\"\n\n\n\n    # $ANTLR start \"T__121\"\n    def mT__121(self, ):\n        try:\n            _type = T__121\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:60:8: ( 'new' )\n            # Expr.g:60:10: 'new'\n            pass \n            self.match(\"new\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__121\"\n\n\n\n    # $ANTLR start \"T__122\"\n    def mT__122(self, ):\n        try:\n            _type = T__122\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:61:8: ( 'print' )\n            # Expr.g:61:10: 'print'\n            pass \n            self.match(\"print\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__122\"\n\n\n\n    # $ANTLR start \"T__123\"\n    def mT__123(self, ):\n        try:\n            _type = T__123\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:62:8: ( 'printf' )\n            # Expr.g:62:10: 'printf'\n            pass \n            self.match(\"printf\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__123\"\n\n\n\n    # $ANTLR start \"T__124\"\n    def mT__124(self, ):\n        try:\n            _type = T__124\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:63:8: ( 'public' )\n            # Expr.g:63:10: 'public'\n            pass \n            self.match(\"public\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__124\"\n\n\n\n    # $ANTLR start \"T__125\"\n    def mT__125(self, ):\n        try:\n            _type = T__125\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:64:8: ( 'return' )\n            # Expr.g:64:10: 'return'\n            pass \n            self.match(\"return\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__125\"\n\n\n\n    # $ANTLR start \"T__126\"\n    def mT__126(self, ):\n        try:\n            _type = T__126\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:65:8: ( 'sprintf' )\n            # Expr.g:65:10: 'sprintf'\n            pass \n            self.match(\"sprintf\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__126\"\n\n\n\n    # $ANTLR start \"T__127\"\n    def mT__127(self, ):\n        try:\n            _type = T__127\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:66:8: ( 'static' )\n            # Expr.g:66:10: 'static'\n            pass \n            self.match(\"static\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__127\"\n\n\n\n    # $ANTLR start \"T__128\"\n    def mT__128(self, ):\n        try:\n            _type = T__128\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:67:8: ( 'switch' )\n            # Expr.g:67:10: 'switch'\n            pass \n            self.match(\"switch\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__128\"\n\n\n\n    # $ANTLR start \"T__129\"\n    def mT__129(self, ):\n        try:\n            _type = T__129\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:68:8: ( 'throw' )\n            # Expr.g:68:10: 'throw'\n            pass \n            self.match(\"throw\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__129\"\n\n\n\n    # $ANTLR start \"T__130\"\n    def mT__130(self, ):\n        try:\n            _type = T__130\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:69:8: ( 'try' )\n            # Expr.g:69:10: 'try'\n            pass \n            self.match(\"try\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__130\"\n\n\n\n    # $ANTLR start \"T__131\"\n    def mT__131(self, ):\n        try:\n            _type = T__131\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:70:8: ( 'while' )\n            # Expr.g:70:10: 'while'\n            pass \n            self.match(\"while\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__131\"\n\n\n\n    # $ANTLR start \"T__132\"\n    def mT__132(self, ):\n        try:\n            _type = T__132\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:71:8: ( '{' )\n            # Expr.g:71:10: '{'\n            pass \n            self.match(123)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__132\"\n\n\n\n    # $ANTLR start \"T__133\"\n    def mT__133(self, ):\n        try:\n            _type = T__133\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:72:8: ( '|' )\n            # Expr.g:72:10: '|'\n            pass \n            self.match(124)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__133\"\n\n\n\n    # $ANTLR start \"T__134\"\n    def mT__134(self, ):\n        try:\n            _type = T__134\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:73:8: ( '|=' )\n            # Expr.g:73:10: '|='\n            pass \n            self.match(\"|=\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__134\"\n\n\n\n    # $ANTLR start \"T__135\"\n    def mT__135(self, ):\n        try:\n            _type = T__135\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:74:8: ( '||' )\n            # Expr.g:74:10: '||'\n            pass \n            self.match(\"||\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__135\"\n\n\n\n    # $ANTLR start \"T__136\"\n    def mT__136(self, ):\n        try:\n            _type = T__136\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:75:8: ( '}' )\n            # Expr.g:75:10: '}'\n            pass \n            self.match(125)\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"T__136\"\n\n\n\n    # $ANTLR start \"NULL\"\n    def mNULL(self, ):\n        try:\n            _type = NULL\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:363:2: ( 'null' )\n            # Expr.g:363:4: 'null'\n            pass \n            self.match(\"null\")\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"NULL\"\n\n\n\n    # $ANTLR start \"BOOL\"\n    def mBOOL(self, ):\n        try:\n            _type = BOOL\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:364:2: ( 'true' | 'false' )\n            alt1 = 2\n            LA1_0 = self.input.LA(1)\n\n            if (LA1_0 == 116) :\n                alt1 = 1\n            elif (LA1_0 == 102) :\n                alt1 = 2\n            else:\n                nvae = NoViableAltException(\"\", 1, 0, self.input)\n\n                raise nvae\n\n\n            if alt1 == 1:\n                # Expr.g:364:4: 'true'\n                pass \n                self.match(\"true\")\n\n\n\n            elif alt1 == 2:\n                # Expr.g:364:13: 'false'\n                pass \n                self.match(\"false\")\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"BOOL\"\n\n\n\n    # $ANTLR start \"ID\"\n    def mID(self, ):\n        try:\n            _type = ID\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:367:2: ( ( ALPHA | '_' | '$' ) ( ALPHA | '_' | DIGIT )* )\n            # Expr.g:367:4: ( ALPHA | '_' | '$' ) ( ALPHA | '_' | DIGIT )*\n            pass \n            if self.input.LA(1) == 36 or (65 <= self.input.LA(1) <= 90) or self.input.LA(1) == 95 or (97 <= self.input.LA(1) <= 122):\n                self.input.consume()\n            else:\n                mse = MismatchedSetException(None, self.input)\n                self.recover(mse)\n                raise mse\n\n\n\n            # Expr.g:367:24: ( ALPHA | '_' | DIGIT )*\n            while True: #loop2\n                alt2 = 2\n                LA2_0 = self.input.LA(1)\n\n                if ((48 <= LA2_0 <= 57) or (65 <= LA2_0 <= 90) or LA2_0 == 95 or (97 <= LA2_0 <= 122)) :\n                    alt2 = 1\n\n\n                if alt2 == 1:\n                    # Expr.g:\n                    pass \n                    if (48 <= self.input.LA(1) <= 57) or (65 <= self.input.LA(1) <= 90) or self.input.LA(1) == 95 or (97 <= self.input.LA(1) <= 122):\n                        self.input.consume()\n                    else:\n                        mse = MismatchedSetException(None, self.input)\n                        self.recover(mse)\n                        raise mse\n\n\n\n\n                else:\n                    break #loop2\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"ID\"\n\n\n\n    # $ANTLR start \"INT\"\n    def mINT(self, ):\n        try:\n            _type = INT\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:371:2: ( ( DIGIT )+ )\n            # Expr.g:371:4: ( DIGIT )+\n            pass \n            # Expr.g:371:4: ( DIGIT )+\n            cnt3 = 0\n            while True: #loop3\n                alt3 = 2\n                LA3_0 = self.input.LA(1)\n\n                if ((48 <= LA3_0 <= 57)) :\n                    alt3 = 1\n\n\n                if alt3 == 1:\n                    # Expr.g:\n                    pass \n                    if (48 <= self.input.LA(1) <= 57):\n                        self.input.consume()\n                    else:\n                        mse = MismatchedSetException(None, self.input)\n                        self.recover(mse)\n                        raise mse\n\n\n\n\n                else:\n                    if cnt3 >= 1:\n                        break #loop3\n\n                    eee = EarlyExitException(3, self.input)\n                    raise eee\n\n                cnt3 += 1\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"INT\"\n\n\n\n    # $ANTLR start \"FLOAT\"\n    def mFLOAT(self, ):\n        try:\n            _type = FLOAT\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:374:2: ( INT '.' ( DIGIT )* )\n            # Expr.g:374:4: INT '.' ( DIGIT )*\n            pass \n            self.mINT()\n\n\n            self.match(46)\n\n            # Expr.g:374:12: ( DIGIT )*\n            while True: #loop4\n                alt4 = 2\n                LA4_0 = self.input.LA(1)\n\n                if ((48 <= LA4_0 <= 57)) :\n                    alt4 = 1\n\n\n                if alt4 == 1:\n                    # Expr.g:\n                    pass \n                    if (48 <= self.input.LA(1) <= 57):\n                        self.input.consume()\n                    else:\n                        mse = MismatchedSetException(None, self.input)\n                        self.recover(mse)\n                        raise mse\n\n\n\n\n                else:\n                    break #loop4\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"FLOAT\"\n\n\n\n    # $ANTLR start \"ALPHA\"\n    def mALPHA(self, ):\n        try:\n            # Expr.g:377:2: ( 'a' .. 'z' | 'A' .. 'Z' )\n            # Expr.g:\n            pass \n            if (65 <= self.input.LA(1) <= 90) or (97 <= self.input.LA(1) <= 122):\n                self.input.consume()\n            else:\n                mse = MismatchedSetException(None, self.input)\n                self.recover(mse)\n                raise mse\n\n\n\n\n\n\n        finally:\n            pass\n\n    # $ANTLR end \"ALPHA\"\n\n\n\n    # $ANTLR start \"DIGIT\"\n    def mDIGIT(self, ):\n        try:\n            # Expr.g:380:2: ( '0' .. '9' )\n            # Expr.g:\n            pass \n            if (48 <= self.input.LA(1) <= 57):\n                self.input.consume()\n            else:\n                mse = MismatchedSetException(None, self.input)\n                self.recover(mse)\n                raise mse\n\n\n\n\n\n\n        finally:\n            pass\n\n    # $ANTLR end \"DIGIT\"\n\n\n\n    # $ANTLR start \"STRING\"\n    def mSTRING(self, ):\n        try:\n            _type = STRING\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:384:2: ( '\\\"' ( DOUBLE_QUOTE_CHARS )* '\\\"' | '\\\\'' ( SINGLE_QUOTE_CHARS )* '\\\\'' )\n            alt7 = 2\n            LA7_0 = self.input.LA(1)\n\n            if (LA7_0 == 34) :\n                alt7 = 1\n            elif (LA7_0 == 39) :\n                alt7 = 2\n            else:\n                nvae = NoViableAltException(\"\", 7, 0, self.input)\n\n                raise nvae\n\n\n            if alt7 == 1:\n                # Expr.g:384:4: '\\\"' ( DOUBLE_QUOTE_CHARS )* '\\\"'\n                pass \n                self.match(34)\n\n                # Expr.g:384:8: ( DOUBLE_QUOTE_CHARS )*\n                while True: #loop5\n                    alt5 = 2\n                    LA5_0 = self.input.LA(1)\n\n                    if ((0 <= LA5_0 <= 33) or (35 <= LA5_0 <= 65535)) :\n                        alt5 = 1\n\n\n                    if alt5 == 1:\n                        # Expr.g:384:8: DOUBLE_QUOTE_CHARS\n                        pass \n                        self.mDOUBLE_QUOTE_CHARS()\n\n\n\n                    else:\n                        break #loop5\n\n\n                self.match(34)\n\n\n            elif alt7 == 2:\n                # Expr.g:385:4: '\\\\'' ( SINGLE_QUOTE_CHARS )* '\\\\''\n                pass \n                self.match(39)\n\n                # Expr.g:385:9: ( SINGLE_QUOTE_CHARS )*\n                while True: #loop6\n                    alt6 = 2\n                    LA6_0 = self.input.LA(1)\n\n                    if ((0 <= LA6_0 <= 38) or (40 <= LA6_0 <= 65535)) :\n                        alt6 = 1\n\n\n                    if alt6 == 1:\n                        # Expr.g:385:9: SINGLE_QUOTE_CHARS\n                        pass \n                        self.mSINGLE_QUOTE_CHARS()\n\n\n\n                    else:\n                        break #loop6\n\n\n                self.match(39)\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"STRING\"\n\n\n\n    # $ANTLR start \"DOUBLE_QUOTE_CHARS\"\n    def mDOUBLE_QUOTE_CHARS(self, ):\n        try:\n            # Expr.g:388:2: (~ ( '\\\"' ) | '\\\\\\\\' '\\\"' | '\\\\\\\\' '\\\\\\\\' )\n            alt8 = 3\n            LA8_0 = self.input.LA(1)\n\n            if (LA8_0 == 92) :\n                LA8 = self.input.LA(2)\n                if LA8 == 34:\n                    alt8 = 2\n                elif LA8 == 92:\n                    alt8 = 3\n                else:\n                    alt8 = 1\n\n            elif ((0 <= LA8_0 <= 33) or (35 <= LA8_0 <= 91) or (93 <= LA8_0 <= 65535)) :\n                alt8 = 1\n            else:\n                nvae = NoViableAltException(\"\", 8, 0, self.input)\n\n                raise nvae\n\n\n            if alt8 == 1:\n                # Expr.g:388:4: ~ ( '\\\"' )\n                pass \n                if (0 <= self.input.LA(1) <= 33) or (35 <= self.input.LA(1) <= 65535):\n                    self.input.consume()\n                else:\n                    mse = MismatchedSetException(None, self.input)\n                    self.recover(mse)\n                    raise mse\n\n\n\n\n            elif alt8 == 2:\n                # Expr.g:390:4: '\\\\\\\\' '\\\"'\n                pass \n                self.match(92)\n\n                self.match(34)\n\n\n            elif alt8 == 3:\n                # Expr.g:391:4: '\\\\\\\\' '\\\\\\\\'\n                pass \n                self.match(92)\n\n                self.match(92)\n\n\n\n        finally:\n            pass\n\n    # $ANTLR end \"DOUBLE_QUOTE_CHARS\"\n\n\n\n    # $ANTLR start \"SINGLE_QUOTE_CHARS\"\n    def mSINGLE_QUOTE_CHARS(self, ):\n        try:\n            # Expr.g:394:2: (~ ( '\\\\'' ) | '\\\\\\\\' '\\\\'' | '\\\\\\\\' '\\\\\\\\' )\n            alt9 = 3\n            LA9_0 = self.input.LA(1)\n\n            if (LA9_0 == 92) :\n                LA9 = self.input.LA(2)\n                if LA9 == 39:\n                    alt9 = 2\n                elif LA9 == 92:\n                    alt9 = 3\n                else:\n                    alt9 = 1\n\n            elif ((0 <= LA9_0 <= 38) or (40 <= LA9_0 <= 91) or (93 <= LA9_0 <= 65535)) :\n                alt9 = 1\n            else:\n                nvae = NoViableAltException(\"\", 9, 0, self.input)\n\n                raise nvae\n\n\n            if alt9 == 1:\n                # Expr.g:394:4: ~ ( '\\\\'' )\n                pass \n                if (0 <= self.input.LA(1) <= 38) or (40 <= self.input.LA(1) <= 65535):\n                    self.input.consume()\n                else:\n                    mse = MismatchedSetException(None, self.input)\n                    self.recover(mse)\n                    raise mse\n\n\n\n\n            elif alt9 == 2:\n                # Expr.g:395:4: '\\\\\\\\' '\\\\''\n                pass \n                self.match(92)\n\n                self.match(39)\n\n\n            elif alt9 == 3:\n                # Expr.g:396:4: '\\\\\\\\' '\\\\\\\\'\n                pass \n                self.match(92)\n\n                self.match(92)\n\n\n\n        finally:\n            pass\n\n    # $ANTLR end \"SINGLE_QUOTE_CHARS\"\n\n\n\n    # $ANTLR start \"NEWLINE\"\n    def mNEWLINE(self, ):\n        try:\n            # Expr.g:400:2: ( ( '\\\\r' )? '\\\\n' )\n            # Expr.g:400:4: ( '\\\\r' )? '\\\\n'\n            pass \n            # Expr.g:400:4: ( '\\\\r' )?\n            alt10 = 2\n            LA10_0 = self.input.LA(1)\n\n            if (LA10_0 == 13) :\n                alt10 = 1\n            if alt10 == 1:\n                # Expr.g:400:4: '\\\\r'\n                pass \n                self.match(13)\n\n\n\n\n            self.match(10)\n\n\n\n\n        finally:\n            pass\n\n    # $ANTLR end \"NEWLINE\"\n\n\n\n    # $ANTLR start \"WS\"\n    def mWS(self, ):\n        try:\n            _type = WS\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:404:2: ( ( ' ' | '\\\\t' | '\\\\r' | '\\\\n' )+ )\n            # Expr.g:404:4: ( ' ' | '\\\\t' | '\\\\r' | '\\\\n' )+\n            pass \n            # Expr.g:404:4: ( ' ' | '\\\\t' | '\\\\r' | '\\\\n' )+\n            cnt11 = 0\n            while True: #loop11\n                alt11 = 2\n                LA11_0 = self.input.LA(1)\n\n                if ((9 <= LA11_0 <= 10) or LA11_0 == 13 or LA11_0 == 32) :\n                    alt11 = 1\n\n\n                if alt11 == 1:\n                    # Expr.g:\n                    pass \n                    if (9 <= self.input.LA(1) <= 10) or self.input.LA(1) == 13 or self.input.LA(1) == 32:\n                        self.input.consume()\n                    else:\n                        mse = MismatchedSetException(None, self.input)\n                        self.recover(mse)\n                        raise mse\n\n\n\n\n                else:\n                    if cnt11 >= 1:\n                        break #loop11\n\n                    eee = EarlyExitException(11, self.input)\n                    raise eee\n\n                cnt11 += 1\n\n\n            #action start\n            _channel=HIDDEN;\n            #action end\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"WS\"\n\n\n\n    # $ANTLR start \"COMMENT\"\n    def mCOMMENT(self, ):\n        try:\n            _type = COMMENT\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:407:2: ( '/*' ( options {greedy=false; } : . )* '*/' )\n            # Expr.g:407:4: '/*' ( options {greedy=false; } : . )* '*/'\n            pass \n            self.match(\"/*\")\n\n\n            # Expr.g:407:9: ( options {greedy=false; } : . )*\n            while True: #loop12\n                alt12 = 2\n                LA12_0 = self.input.LA(1)\n\n                if (LA12_0 == 42) :\n                    LA12_1 = self.input.LA(2)\n\n                    if (LA12_1 == 47) :\n                        alt12 = 2\n                    elif ((0 <= LA12_1 <= 46) or (48 <= LA12_1 <= 65535)) :\n                        alt12 = 1\n\n\n                elif ((0 <= LA12_0 <= 41) or (43 <= LA12_0 <= 65535)) :\n                    alt12 = 1\n\n\n                if alt12 == 1:\n                    # Expr.g:407:34: .\n                    pass \n                    self.matchAny()\n\n\n                else:\n                    break #loop12\n\n\n            self.match(\"*/\")\n\n\n            #action start\n            _channel=HIDDEN;\n            #action end\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"COMMENT\"\n\n\n\n    # $ANTLR start \"LINECOMMENT\"\n    def mLINECOMMENT(self, ):\n        try:\n            _type = LINECOMMENT\n            _channel = DEFAULT_CHANNEL\n\n            # Expr.g:410:2: ( ( '//' | '#' ) (~ ( '\\\\r' | '\\\\n' ) )* NEWLINE )\n            # Expr.g:410:4: ( '//' | '#' ) (~ ( '\\\\r' | '\\\\n' ) )* NEWLINE\n            pass \n            # Expr.g:410:4: ( '//' | '#' )\n            alt13 = 2\n            LA13_0 = self.input.LA(1)\n\n            if (LA13_0 == 47) :\n                alt13 = 1\n            elif (LA13_0 == 35) :\n                alt13 = 2\n            else:\n                nvae = NoViableAltException(\"\", 13, 0, self.input)\n\n                raise nvae\n\n\n            if alt13 == 1:\n                # Expr.g:410:5: '//'\n                pass \n                self.match(\"//\")\n\n\n\n            elif alt13 == 2:\n                # Expr.g:410:10: '#'\n                pass \n                self.match(35)\n\n\n\n\n            # Expr.g:410:15: (~ ( '\\\\r' | '\\\\n' ) )*\n            while True: #loop14\n                alt14 = 2\n                LA14_0 = self.input.LA(1)\n\n                if ((0 <= LA14_0 <= 9) or (11 <= LA14_0 <= 12) or (14 <= LA14_0 <= 65535)) :\n                    alt14 = 1\n\n\n                if alt14 == 1:\n                    # Expr.g:\n                    pass \n                    if (0 <= self.input.LA(1) <= 9) or (11 <= self.input.LA(1) <= 12) or (14 <= self.input.LA(1) <= 65535):\n                        self.input.consume()\n                    else:\n                        mse = MismatchedSetException(None, self.input)\n                        self.recover(mse)\n                        raise mse\n\n\n\n\n                else:\n                    break #loop14\n\n\n            self.mNEWLINE()\n\n\n            #action start\n            _channel=HIDDEN;\n            #action end\n\n\n\n\n            self._state.type = _type\n            self._state.channel = _channel\n        finally:\n            pass\n\n    # $ANTLR end \"LINECOMMENT\"\n\n\n\n    def mTokens(self):\n        # Expr.g:1:8: ( T__68 | T__69 | T__70 | T__71 | T__72 | T__73 | T__74 | T__75 | T__76 | T__77 | T__78 | T__79 | T__80 | T__81 | T__82 | T__83 | T__84 | T__85 | T__86 | T__87 | T__88 | T__89 | T__90 | T__91 | T__92 | T__93 | T__94 | T__95 | T__96 | T__97 | T__98 | T__99 | T__100 | T__101 | T__102 | T__103 | T__104 | T__105 | T__106 | T__107 | T__108 | T__109 | T__110 | T__111 | T__112 | T__113 | T__114 | T__115 | T__116 | T__117 | T__118 | T__119 | T__120 | T__121 | T__122 | T__123 | T__124 | T__125 | T__126 | T__127 | T__128 | T__129 | T__130 | T__131 | T__132 | T__133 | T__134 | T__135 | T__136 | NULL | BOOL | ID | INT | FLOAT | STRING | WS | COMMENT | LINECOMMENT )\n        alt15 = 78\n        alt15 = self.dfa15.predict(self.input)\n        if alt15 == 1:\n            # Expr.g:1:10: T__68\n            pass \n            self.mT__68()\n\n\n\n        elif alt15 == 2:\n            # Expr.g:1:16: T__69\n            pass \n            self.mT__69()\n\n\n\n        elif alt15 == 3:\n            # Expr.g:1:22: T__70\n            pass \n            self.mT__70()\n\n\n\n        elif alt15 == 4:\n            # Expr.g:1:28: T__71\n            pass \n            self.mT__71()\n\n\n\n        elif alt15 == 5:\n            # Expr.g:1:34: T__72\n            pass \n            self.mT__72()\n\n\n\n        elif alt15 == 6:\n            # Expr.g:1:40: T__73\n            pass \n            self.mT__73()\n\n\n\n        elif alt15 == 7:\n            # Expr.g:1:46: T__74\n            pass \n            self.mT__74()\n\n\n\n        elif alt15 == 8:\n            # Expr.g:1:52: T__75\n            pass \n            self.mT__75()\n\n\n\n        elif alt15 == 9:\n            # Expr.g:1:58: T__76\n            pass \n            self.mT__76()\n\n\n\n        elif alt15 == 10:\n            # Expr.g:1:64: T__77\n            pass \n            self.mT__77()\n\n\n\n        elif alt15 == 11:\n            # Expr.g:1:70: T__78\n            pass \n            self.mT__78()\n\n\n\n        elif alt15 == 12:\n            # Expr.g:1:76: T__79\n            pass \n            self.mT__79()\n\n\n\n        elif alt15 == 13:\n            # Expr.g:1:82: T__80\n            pass \n            self.mT__80()\n\n\n\n        elif alt15 == 14:\n            # Expr.g:1:88: T__81\n            pass \n            self.mT__81()\n\n\n\n        elif alt15 == 15:\n            # Expr.g:1:94: T__82\n            pass \n            self.mT__82()\n\n\n\n        elif alt15 == 16:\n            # Expr.g:1:100: T__83\n            pass \n            self.mT__83()\n\n\n\n        elif alt15 == 17:\n            # Expr.g:1:106: T__84\n            pass \n            self.mT__84()\n\n\n\n        elif alt15 == 18:\n            # Expr.g:1:112: T__85\n            pass \n            self.mT__85()\n\n\n\n        elif alt15 == 19:\n            # Expr.g:1:118: T__86\n            pass \n            self.mT__86()\n\n\n\n        elif alt15 == 20:\n            # Expr.g:1:124: T__87\n            pass \n            self.mT__87()\n\n\n\n        elif alt15 == 21:\n            # Expr.g:1:130: T__88\n            pass \n            self.mT__88()\n\n\n\n        elif alt15 == 22:\n            # Expr.g:1:136: T__89\n            pass \n            self.mT__89()\n\n\n\n        elif alt15 == 23:\n            # Expr.g:1:142: T__90\n            pass \n            self.mT__90()\n\n\n\n        elif alt15 == 24:\n            # Expr.g:1:148: T__91\n            pass \n            self.mT__91()\n\n\n\n        elif alt15 == 25:\n            # Expr.g:1:154: T__92\n            pass \n            self.mT__92()\n\n\n\n        elif alt15 == 26:\n            # Expr.g:1:160: T__93\n            pass \n            self.mT__93()\n\n\n\n        elif alt15 == 27:\n            # Expr.g:1:166: T__94\n            pass \n            self.mT__94()\n\n\n\n        elif alt15 == 28:\n            # Expr.g:1:172: T__95\n            pass \n            self.mT__95()\n\n\n\n        elif alt15 == 29:\n            # Expr.g:1:178: T__96\n            pass \n            self.mT__96()\n\n\n\n        elif alt15 == 30:\n            # Expr.g:1:184: T__97\n            pass \n            self.mT__97()\n\n\n\n        elif alt15 == 31:\n            # Expr.g:1:190: T__98\n            pass \n            self.mT__98()\n\n\n\n        elif alt15 == 32:\n            # Expr.g:1:196: T__99\n            pass \n            self.mT__99()\n\n\n\n        elif alt15 == 33:\n            # Expr.g:1:202: T__100\n            pass \n            self.mT__100()\n\n\n\n        elif alt15 == 34:\n            # Expr.g:1:209: T__101\n            pass \n            self.mT__101()\n\n\n\n        elif alt15 == 35:\n            # Expr.g:1:216: T__102\n            pass \n            self.mT__102()\n\n\n\n        elif alt15 == 36:\n            # Expr.g:1:223: T__103\n            pass \n            self.mT__103()\n\n\n\n        elif alt15 == 37:\n            # Expr.g:1:230: T__104\n            pass \n            self.mT__104()\n\n\n\n        elif alt15 == 38:\n            # Expr.g:1:237: T__105\n            pass \n            self.mT__105()\n\n\n\n        elif alt15 == 39:\n            # Expr.g:1:244: T__106\n            pass \n            self.mT__106()\n\n\n\n        elif alt15 == 40:\n            # Expr.g:1:251: T__107\n            pass \n            self.mT__107()\n\n\n\n        elif alt15 == 41:\n            # Expr.g:1:258: T__108\n            pass \n            self.mT__108()\n\n\n\n        elif alt15 == 42:\n            # Expr.g:1:265: T__109\n            pass \n            self.mT__109()\n\n\n\n        elif alt15 == 43:\n            # Expr.g:1:272: T__110\n            pass \n            self.mT__110()\n\n\n\n        elif alt15 == 44:\n            # Expr.g:1:279: T__111\n            pass \n            self.mT__111()\n\n\n\n        elif alt15 == 45:\n            # Expr.g:1:286: T__112\n            pass \n            self.mT__112()\n\n\n\n        elif alt15 == 46:\n            # Expr.g:1:293: T__113\n            pass \n            self.mT__113()\n\n\n\n        elif alt15 == 47:\n            # Expr.g:1:300: T__114\n            pass \n            self.mT__114()\n\n\n\n        elif alt15 == 48:\n            # Expr.g:1:307: T__115\n            pass \n            self.mT__115()\n\n\n\n        elif alt15 == 49:\n            # Expr.g:1:314: T__116\n            pass \n            self.mT__116()\n\n\n\n        elif alt15 == 50:\n            # Expr.g:1:321: T__117\n            pass \n            self.mT__117()\n\n\n\n        elif alt15 == 51:\n            # Expr.g:1:328: T__118\n            pass \n            self.mT__118()\n\n\n\n        elif alt15 == 52:\n            # Expr.g:1:335: T__119\n            pass \n            self.mT__119()\n\n\n\n        elif alt15 == 53:\n            # Expr.g:1:342: T__120\n            pass \n            self.mT__120()\n\n\n\n        elif alt15 == 54:\n            # Expr.g:1:349: T__121\n            pass \n            self.mT__121()\n\n\n\n        elif alt15 == 55:\n            # Expr.g:1:356: T__122\n            pass \n            self.mT__122()\n\n\n\n        elif alt15 == 56:\n            # Expr.g:1:363: T__123\n            pass \n            self.mT__123()\n\n\n\n        elif alt15 == 57:\n            # Expr.g:1:370: T__124\n            pass \n            self.mT__124()\n\n\n\n        elif alt15 == 58:\n            # Expr.g:1:377: T__125\n            pass \n            self.mT__125()\n\n\n\n        elif alt15 == 59:\n            # Expr.g:1:384: T__126\n            pass \n            self.mT__126()\n\n\n\n        elif alt15 == 60:\n            # Expr.g:1:391: T__127\n            pass \n            self.mT__127()\n\n\n\n        elif alt15 == 61:\n            # Expr.g:1:398: T__128\n            pass \n            self.mT__128()\n\n\n\n        elif alt15 == 62:\n            # Expr.g:1:405: T__129\n            pass \n            self.mT__129()\n\n\n\n        elif alt15 == 63:\n            # Expr.g:1:412: T__130\n            pass \n            self.mT__130()\n\n\n\n        elif alt15 == 64:\n            # Expr.g:1:419: T__131\n            pass \n            self.mT__131()\n\n\n\n        elif alt15 == 65:\n            # Expr.g:1:426: T__132\n            pass \n            self.mT__132()\n\n\n\n        elif alt15 == 66:\n            # Expr.g:1:433: T__133\n            pass \n            self.mT__133()\n\n\n\n        elif alt15 == 67:\n            # Expr.g:1:440: T__134\n            pass \n            self.mT__134()\n\n\n\n        elif alt15 == 68:\n            # Expr.g:1:447: T__135\n            pass \n            self.mT__135()\n\n\n\n        elif alt15 == 69:\n            # Expr.g:1:454: T__136\n            pass \n            self.mT__136()\n\n\n\n        elif alt15 == 70:\n            # Expr.g:1:461: NULL\n            pass \n            self.mNULL()\n\n\n\n        elif alt15 == 71:\n            # Expr.g:1:466: BOOL\n            pass \n            self.mBOOL()\n\n\n\n        elif alt15 == 72:\n            # Expr.g:1:471: ID\n            pass \n            self.mID()\n\n\n\n        elif alt15 == 73:\n            # Expr.g:1:474: INT\n            pass \n            self.mINT()\n\n\n\n        elif alt15 == 74:\n            # Expr.g:1:478: FLOAT\n            pass \n            self.mFLOAT()\n\n\n\n        elif alt15 == 75:\n            # Expr.g:1:484: STRING\n            pass \n            self.mSTRING()\n\n\n\n        elif alt15 == 76:\n            # Expr.g:1:491: WS\n            pass \n            self.mWS()\n\n\n\n        elif alt15 == 77:\n            # Expr.g:1:494: COMMENT\n            pass \n            self.mCOMMENT()\n\n\n\n        elif alt15 == 78:\n            # Expr.g:1:502: LINECOMMENT\n            pass \n            self.mLINECOMMENT()\n\n\n\n\n\n\n\n\n    # lookup tables for DFA #15\n\n    DFA15_eot = DFA.unpack(\n        u\"\\1\\uffff\\1\\52\\1\\54\\1\\57\\2\\uffff\\1\\61\\1\\64\\1\\uffff\\1\\67\\1\\72\\1\\75\"\n        u\"\\2\\uffff\\1\\77\\1\\102\\1\\104\\2\\uffff\\1\\106\\15\\44\\1\\uffff\\1\\144\\2\\uffff\"\n        u\"\\1\\145\\41\\uffff\\1\\147\\5\\44\\1\\156\\6\\44\\1\\165\\15\\44\\6\\uffff\\6\\44\"\n        u\"\\1\\uffff\\3\\44\\1\\u008e\\2\\44\\1\\uffff\\2\\44\\1\\u0093\\10\\44\\1\\u009c\\3\"\n        u\"\\44\\1\\u00a0\\4\\44\\1\\u00a5\\3\\44\\1\\uffff\\3\\44\\1\\u00ac\\1\\uffff\\1\\u00ad\"\n        u\"\\7\\44\\1\\uffff\\1\\u00b5\\1\\44\\1\\u00b7\\1\\uffff\\1\\u00b8\\1\\u00b9\\2\\44\"\n        u\"\\1\\uffff\\4\\44\\1\\u00b5\\1\\44\\2\\uffff\\1\\u00c2\\5\\44\\1\\u00c8\\1\\uffff\"\n        u\"\\1\\u00c9\\3\\uffff\\6\\44\\1\\u00d0\\1\\u00d1\\1\\uffff\\1\\u00d2\\1\\u00d3\\1\"\n        u\"\\44\\1\\u00d5\\1\\u00d6\\2\\uffff\\1\\44\\1\\u00d8\\1\\u00d9\\1\\u00da\\1\\u00db\"\n        u\"\\1\\44\\4\\uffff\\1\\u00dd\\2\\uffff\\1\\u00de\\4\\uffff\\1\\u00df\\3\\uffff\"\n        )\n\n    DFA15_eof = DFA.unpack(\n        u\"\\u00e0\\uffff\"\n        )\n\n    DFA15_min = DFA.unpack(\n        u\"\\1\\11\\2\\75\\1\\46\\2\\uffff\\1\\75\\1\\53\\1\\uffff\\1\\55\\2\\52\\2\\uffff\\3\\75\"\n        u\"\\2\\uffff\\1\\75\\1\\163\\1\\162\\1\\141\\1\\145\\1\\154\\1\\141\\1\\146\\1\\145\\1\"\n        u\"\\162\\1\\145\\1\\160\\2\\150\\1\\uffff\\1\\75\\2\\uffff\\1\\56\\41\\uffff\\1\\60\"\n        u\"\\1\\145\\1\\163\\1\\141\\1\\156\\1\\146\\1\\60\\1\\163\\1\\164\\1\\156\\1\\162\\1\\156\"\n        u\"\\1\\154\\1\\60\\1\\160\\1\\151\\1\\167\\1\\154\\1\\151\\1\\142\\1\\164\\1\\162\\1\\141\"\n        u\"\\1\\151\\1\\162\\1\\165\\1\\151\\6\\uffff\\1\\141\\1\\145\\1\\143\\1\\163\\1\\164\"\n        u\"\\1\\141\\1\\uffff\\2\\145\\1\\141\\1\\60\\1\\143\\1\\163\\1\\uffff\\1\\157\\1\\164\"\n        u\"\\1\\60\\1\\154\\1\\156\\1\\154\\1\\165\\1\\151\\2\\164\\1\\157\\1\\60\\1\\145\\1\\154\"\n        u\"\\1\\153\\1\\60\\1\\150\\1\\163\\1\\151\\1\\165\\1\\60\\1\\156\\1\\154\\1\\141\\1\\uffff\"\n        u\"\\1\\164\\1\\145\\1\\162\\1\\60\\1\\uffff\\1\\60\\1\\164\\1\\151\\1\\162\\1\\156\\1\"\n        u\"\\151\\1\\143\\1\\167\\1\\uffff\\1\\60\\1\\145\\1\\60\\1\\uffff\\2\\60\\1\\156\\1\\154\"\n        u\"\\1\\uffff\\1\\144\\1\\154\\1\\143\\1\\151\\1\\60\\1\\164\\2\\uffff\\1\\60\\1\\143\"\n        u\"\\1\\156\\1\\164\\1\\143\\1\\150\\1\\60\\1\\uffff\\1\\60\\3\\uffff\\1\\165\\1\\164\"\n        u\"\\1\\163\\1\\171\\1\\150\\1\\157\\2\\60\\1\\uffff\\2\\60\\1\\146\\2\\60\\2\\uffff\\1\"\n        u\"\\145\\4\\60\\1\\156\\4\\uffff\\1\\60\\2\\uffff\\1\\60\\4\\uffff\\1\\60\\3\\uffff\"\n        )\n\n    DFA15_max = DFA.unpack(\n        u\"\\1\\175\\3\\75\\2\\uffff\\2\\75\\1\\uffff\\1\\75\\1\\56\\1\\75\\2\\uffff\\1\\75\\1\"\n        u\"\\76\\1\\75\\2\\uffff\\1\\75\\1\\163\\1\\162\\2\\157\\1\\170\\1\\165\\1\\156\\2\\165\"\n        u\"\\1\\145\\1\\167\\1\\162\\1\\150\\1\\uffff\\1\\174\\2\\uffff\\1\\71\\41\\uffff\\1\"\n        u\"\\172\\1\\145\\1\\164\\1\\141\\1\\156\\1\\146\\1\\172\\1\\163\\1\\164\\1\\156\\1\\162\"\n        u\"\\1\\156\\1\\154\\1\\172\\1\\160\\1\\151\\1\\167\\1\\154\\1\\151\\1\\142\\1\\164\\1\"\n        u\"\\162\\1\\141\\1\\151\\1\\162\\1\\171\\1\\151\\6\\uffff\\1\\141\\1\\145\\1\\143\\1\"\n        u\"\\163\\1\\164\\1\\141\\1\\uffff\\2\\145\\1\\141\\1\\172\\1\\143\\1\\163\\1\\uffff\"\n        u\"\\1\\157\\1\\164\\1\\172\\1\\154\\1\\156\\1\\154\\1\\165\\1\\151\\2\\164\\1\\157\\1\"\n        u\"\\172\\1\\145\\1\\154\\1\\153\\1\\172\\1\\150\\1\\163\\1\\151\\1\\165\\1\\172\\1\\156\"\n        u\"\\1\\154\\1\\141\\1\\uffff\\1\\164\\1\\145\\1\\162\\1\\172\\1\\uffff\\1\\172\\1\\164\"\n        u\"\\1\\151\\1\\162\\1\\156\\1\\151\\1\\143\\1\\167\\1\\uffff\\1\\172\\1\\145\\1\\172\"\n        u\"\\1\\uffff\\2\\172\\1\\156\\1\\154\\1\\uffff\\1\\144\\1\\154\\1\\143\\1\\151\\1\\172\"\n        u\"\\1\\164\\2\\uffff\\1\\172\\1\\143\\1\\156\\1\\164\\1\\143\\1\\150\\1\\172\\1\\uffff\"\n        u\"\\1\\172\\3\\uffff\\1\\165\\1\\164\\1\\163\\1\\171\\1\\150\\1\\157\\2\\172\\1\\uffff\"\n        u\"\\2\\172\\1\\146\\2\\172\\2\\uffff\\1\\145\\4\\172\\1\\156\\4\\uffff\\1\\172\\2\\uffff\"\n        u\"\\1\\172\\4\\uffff\\1\\172\\3\\uffff\"\n        )\n\n    DFA15_accept = DFA.unpack(\n        u\"\\4\\uffff\\1\\10\\1\\11\\2\\uffff\\1\\17\\3\\uffff\\1\\30\\1\\31\\3\\uffff\\1\\41\"\n        u\"\\1\\42\\16\\uffff\\1\\101\\1\\uffff\\1\\105\\1\\110\\1\\uffff\\1\\113\\1\\114\\1\"\n        u\"\\116\\1\\2\\1\\1\\1\\4\\1\\3\\1\\5\\1\\7\\1\\6\\1\\13\\1\\12\\1\\15\\1\\16\\1\\14\\1\\21\"\n        u\"\\1\\22\\1\\20\\1\\24\\1\\25\\1\\23\\1\\27\\1\\115\\1\\26\\1\\33\\1\\32\\1\\35\\1\\36\\1\"\n        u\"\\34\\1\\40\\1\\37\\1\\44\\1\\43\\33\\uffff\\1\\103\\1\\104\\1\\102\\1\\111\\1\\112\"\n        u\"\\1\\45\\6\\uffff\\1\\54\\6\\uffff\\1\\63\\30\\uffff\\1\\60\\4\\uffff\\1\\66\\10\\uffff\"\n        u\"\\1\\77\\3\\uffff\\1\\47\\4\\uffff\\1\\55\\6\\uffff\\1\\65\\1\\106\\7\\uffff\\1\\107\"\n        u\"\\1\\uffff\\1\\46\\1\\50\\1\\51\\10\\uffff\\1\\67\\5\\uffff\\1\\76\\1\\100\\6\\uffff\"\n        u\"\\1\\64\\1\\70\\1\\71\\1\\72\\1\\uffff\\1\\74\\1\\75\\1\\uffff\\1\\53\\1\\56\\1\\57\\1\"\n        u\"\\61\\1\\uffff\\1\\73\\1\\52\\1\\62\"\n        )\n\n    DFA15_special = DFA.unpack(\n        u\"\\u00e0\\uffff\"\n        )\n\n\n    DFA15_transition = [\n        DFA.unpack(u\"\\2\\47\\2\\uffff\\1\\47\\22\\uffff\\1\\47\\1\\1\\1\\46\\1\\50\\1\\44\"\n        u\"\\1\\2\\1\\3\\1\\46\\1\\4\\1\\5\\1\\6\\1\\7\\1\\10\\1\\11\\1\\12\\1\\13\\12\\45\\1\\14\\1\"\n        u\"\\15\\1\\16\\1\\17\\1\\20\\2\\uffff\\32\\44\\1\\21\\1\\uffff\\1\\22\\1\\23\\1\\44\\1\"\n        u\"\\uffff\\1\\24\\1\\25\\1\\26\\1\\27\\1\\30\\1\\31\\2\\44\\1\\32\\4\\44\\1\\33\\1\\44\\1\"\n        u\"\\34\\1\\44\\1\\35\\1\\36\\1\\37\\2\\44\\1\\40\\3\\44\\1\\41\\1\\42\\1\\43\"),\n        DFA.unpack(u\"\\1\\51\"),\n        DFA.unpack(u\"\\1\\53\"),\n        DFA.unpack(u\"\\1\\55\\26\\uffff\\1\\56\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\1\\60\"),\n        DFA.unpack(u\"\\1\\62\\21\\uffff\\1\\63\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\1\\65\\17\\uffff\\1\\66\"),\n        DFA.unpack(u\"\\1\\70\\3\\uffff\\1\\71\"),\n        DFA.unpack(u\"\\1\\74\\4\\uffff\\1\\50\\15\\uffff\\1\\73\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\1\\76\"),\n        DFA.unpack(u\"\\1\\100\\1\\101\"),\n        DFA.unpack(u\"\\1\\103\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\1\\105\"),\n        DFA.unpack(u\"\\1\\107\"),\n        DFA.unpack(u\"\\1\\110\"),\n        DFA.unpack(u\"\\1\\111\\12\\uffff\\1\\112\\2\\uffff\\1\\113\"),\n        DFA.unpack(u\"\\1\\114\\11\\uffff\\1\\115\"),\n        DFA.unpack(u\"\\1\\116\\13\\uffff\\1\\117\"),\n        DFA.unpack(u\"\\1\\123\\7\\uffff\\1\\120\\5\\uffff\\1\\121\\5\\uffff\\1\\122\"),\n        DFA.unpack(u\"\\1\\124\\6\\uffff\\1\\125\\1\\126\"),\n        DFA.unpack(u\"\\1\\127\\17\\uffff\\1\\130\"),\n        DFA.unpack(u\"\\1\\131\\2\\uffff\\1\\132\"),\n        DFA.unpack(u\"\\1\\133\"),\n        DFA.unpack(u\"\\1\\134\\3\\uffff\\1\\135\\2\\uffff\\1\\136\"),\n        DFA.unpack(u\"\\1\\137\\11\\uffff\\1\\140\"),\n        DFA.unpack(u\"\\1\\141\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\1\\142\\76\\uffff\\1\\143\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\1\\146\\1\\uffff\\12\\45\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\1\\150\"),\n        DFA.unpack(u\"\\1\\151\\1\\152\"),\n        DFA.unpack(u\"\\1\\153\"),\n        DFA.unpack(u\"\\1\\154\"),\n        DFA.unpack(u\"\\1\\155\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\1\\157\"),\n        DFA.unpack(u\"\\1\\160\"),\n        DFA.unpack(u\"\\1\\161\"),\n        DFA.unpack(u\"\\1\\162\"),\n        DFA.unpack(u\"\\1\\163\"),\n        DFA.unpack(u\"\\1\\164\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\1\\166\"),\n        DFA.unpack(u\"\\1\\167\"),\n        DFA.unpack(u\"\\1\\170\"),\n        DFA.unpack(u\"\\1\\171\"),\n        DFA.unpack(u\"\\1\\172\"),\n        DFA.unpack(u\"\\1\\173\"),\n        DFA.unpack(u\"\\1\\174\"),\n        DFA.unpack(u\"\\1\\175\"),\n        DFA.unpack(u\"\\1\\176\"),\n        DFA.unpack(u\"\\1\\177\"),\n        DFA.unpack(u\"\\1\\u0080\"),\n        DFA.unpack(u\"\\1\\u0082\\3\\uffff\\1\\u0081\"),\n        DFA.unpack(u\"\\1\\u0083\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\1\\u0084\"),\n        DFA.unpack(u\"\\1\\u0085\"),\n        DFA.unpack(u\"\\1\\u0086\"),\n        DFA.unpack(u\"\\1\\u0087\"),\n        DFA.unpack(u\"\\1\\u0088\"),\n        DFA.unpack(u\"\\1\\u0089\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\1\\u008a\"),\n        DFA.unpack(u\"\\1\\u008b\"),\n        DFA.unpack(u\"\\1\\u008c\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\4\\44\\1\\u008d\"\n        u\"\\25\\44\"),\n        DFA.unpack(u\"\\1\\u008f\"),\n        DFA.unpack(u\"\\1\\u0090\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\1\\u0091\"),\n        DFA.unpack(u\"\\1\\u0092\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\1\\u0094\"),\n        DFA.unpack(u\"\\1\\u0095\"),\n        DFA.unpack(u\"\\1\\u0096\"),\n        DFA.unpack(u\"\\1\\u0097\"),\n        DFA.unpack(u\"\\1\\u0098\"),\n        DFA.unpack(u\"\\1\\u0099\"),\n        DFA.unpack(u\"\\1\\u009a\"),\n        DFA.unpack(u\"\\1\\u009b\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\1\\u009d\"),\n        DFA.unpack(u\"\\1\\u009e\"),\n        DFA.unpack(u\"\\1\\u009f\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\1\\u00a1\"),\n        DFA.unpack(u\"\\1\\u00a2\"),\n        DFA.unpack(u\"\\1\\u00a3\"),\n        DFA.unpack(u\"\\1\\u00a4\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\1\\u00a6\"),\n        DFA.unpack(u\"\\1\\u00a7\"),\n        DFA.unpack(u\"\\1\\u00a8\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\1\\u00a9\"),\n        DFA.unpack(u\"\\1\\u00aa\"),\n        DFA.unpack(u\"\\1\\u00ab\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\1\\u00ae\"),\n        DFA.unpack(u\"\\1\\u00af\"),\n        DFA.unpack(u\"\\1\\u00b0\"),\n        DFA.unpack(u\"\\1\\u00b1\"),\n        DFA.unpack(u\"\\1\\u00b2\"),\n        DFA.unpack(u\"\\1\\u00b3\"),\n        DFA.unpack(u\"\\1\\u00b4\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\1\\u00b6\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\1\\u00ba\"),\n        DFA.unpack(u\"\\1\\u00bb\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\1\\u00bc\"),\n        DFA.unpack(u\"\\1\\u00bd\"),\n        DFA.unpack(u\"\\1\\u00be\"),\n        DFA.unpack(u\"\\1\\u00bf\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\1\\u00c0\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\5\\44\\1\\u00c1\"\n        u\"\\24\\44\"),\n        DFA.unpack(u\"\\1\\u00c3\"),\n        DFA.unpack(u\"\\1\\u00c4\"),\n        DFA.unpack(u\"\\1\\u00c5\"),\n        DFA.unpack(u\"\\1\\u00c6\"),\n        DFA.unpack(u\"\\1\\u00c7\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\1\\u00ca\"),\n        DFA.unpack(u\"\\1\\u00cb\"),\n        DFA.unpack(u\"\\1\\u00cc\"),\n        DFA.unpack(u\"\\1\\u00cd\"),\n        DFA.unpack(u\"\\1\\u00ce\"),\n        DFA.unpack(u\"\\1\\u00cf\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\1\\u00d4\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\1\\u00d7\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\\1\\u00dc\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\12\\44\\7\\uffff\\32\\44\\4\\uffff\\1\\44\\1\\uffff\\32\\44\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\")\n    ]\n\n    # class definition for DFA #15\n\n    class DFA15(DFA):\n        pass\n\n\n \n\n\n\ndef main(argv, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr):\n    from antlr3.main import LexerMain\n    main = LexerMain(ExprLexer)\n\n    main.stdin = stdin\n    main.stdout = stdout\n    main.stderr = stderr\n    main.execute(argv)\n\n\n\nif __name__ == '__main__':\n    main(sys.argv)\n"
  },
  {
    "path": "deps/cpy/ExprParser.py",
    "content": "# $ANTLR 3.5 Expr.g 2013-04-12 19:22:24\n\nimport sys\nfrom antlr3 import *\nfrom antlr3.compat import set, frozenset\n\nfrom antlr3.tree import *\n\n\n\n\n# for convenience in actions\nHIDDEN = BaseRecognizer.HIDDEN\n\n# token types\nEOF=-1\nT__68=68\nT__69=69\nT__70=70\nT__71=71\nT__72=72\nT__73=73\nT__74=74\nT__75=75\nT__76=76\nT__77=77\nT__78=78\nT__79=79\nT__80=80\nT__81=81\nT__82=82\nT__83=83\nT__84=84\nT__85=85\nT__86=86\nT__87=87\nT__88=88\nT__89=89\nT__90=90\nT__91=91\nT__92=92\nT__93=93\nT__94=94\nT__95=95\nT__96=96\nT__97=97\nT__98=98\nT__99=99\nT__100=100\nT__101=101\nT__102=102\nT__103=103\nT__104=104\nT__105=105\nT__106=106\nT__107=107\nT__108=108\nT__109=109\nT__110=110\nT__111=111\nT__112=112\nT__113=113\nT__114=114\nT__115=115\nT__116=116\nT__117=117\nT__118=118\nT__119=119\nT__120=120\nT__121=121\nT__122=122\nT__123=123\nT__124=124\nT__125=125\nT__126=126\nT__127=127\nT__128=128\nT__129=129\nT__130=130\nT__131=131\nT__132=132\nT__133=133\nT__134=134\nT__135=135\nT__136=136\nALPHA=4\nARRAY=5\nASSIGN=6\nBLOCK=7\nBOOL=8\nBREAK=9\nCALL=10\nCASE=11\nCATCH=12\nCLASS=13\nCOMMENT=14\nCONSTRUCTOR=15\nCONTINUE=16\nDEFAULT=17\nDIGIT=18\nDOUBLE_QUOTE_CHARS=19\nDO_WHILE=20\nEACH=21\nEACH_VAL=22\nELSE=23\nELSE_IF=24\nEMPTY_LINE=25\nEXEC_LIST=26\nEXEC_STMT=27\nEXPR_LIST=28\nFINALLY=29\nFLOAT=30\nFOR=31\nFOREACH=32\nFUNCTION=33\nID=34\nID_LIST=35\nIF=36\nIMPORT=37\nINDEX=38\nINT=39\nLINECOMMENT=40\nMEMBER=41\nMODULE=42\nNEGATIVE=43\nNEW=44\nNEWLINE=45\nNOP=46\nNULL=47\nOBJECT=48\nOP_ASSIGN=49\nPARAMS=50\nPOST_DEC=51\nPOST_INC=52\nPRE_DEC=53\nPRE_INC=54\nPRINT=55\nPRINTF=56\nRETURN=57\nSINGLE_QUOTE_CHARS=58\nSLICE=59\nSPRINTF=60\nSTRING=61\nSWITCH=62\nTHROW=63\nTRY=64\nVAR=65\nWHILE=66\nWS=67\n\n# token names\ntokenNames = [\n    \"<invalid>\", \"<EOR>\", \"<DOWN>\", \"<UP>\",\n    \"ALPHA\", \"ARRAY\", \"ASSIGN\", \"BLOCK\", \"BOOL\", \"BREAK\", \"CALL\", \"CASE\", \n    \"CATCH\", \"CLASS\", \"COMMENT\", \"CONSTRUCTOR\", \"CONTINUE\", \"DEFAULT\", \"DIGIT\", \n    \"DOUBLE_QUOTE_CHARS\", \"DO_WHILE\", \"EACH\", \"EACH_VAL\", \"ELSE\", \"ELSE_IF\", \n    \"EMPTY_LINE\", \"EXEC_LIST\", \"EXEC_STMT\", \"EXPR_LIST\", \"FINALLY\", \"FLOAT\", \n    \"FOR\", \"FOREACH\", \"FUNCTION\", \"ID\", \"ID_LIST\", \"IF\", \"IMPORT\", \"INDEX\", \n    \"INT\", \"LINECOMMENT\", \"MEMBER\", \"MODULE\", \"NEGATIVE\", \"NEW\", \"NEWLINE\", \n    \"NOP\", \"NULL\", \"OBJECT\", \"OP_ASSIGN\", \"PARAMS\", \"POST_DEC\", \"POST_INC\", \n    \"PRE_DEC\", \"PRE_INC\", \"PRINT\", \"PRINTF\", \"RETURN\", \"SINGLE_QUOTE_CHARS\", \n    \"SLICE\", \"SPRINTF\", \"STRING\", \"SWITCH\", \"THROW\", \"TRY\", \"VAR\", \"WHILE\", \n    \"WS\", \"'!'\", \"'!='\", \"'%'\", \"'%='\", \"'&&'\", \"'&'\", \"'&='\", \"'('\", \"')'\", \n    \"'*'\", \"'*='\", \"'+'\", \"'++'\", \"'+='\", \"','\", \"'-'\", \"'--'\", \"'-='\", \n    \"'.'\", \"'.*'\", \"'..'\", \"'/'\", \"'/='\", \"':'\", \"';'\", \"'<'\", \"'<='\", \"'='\", \n    \"'=='\", \"'=>'\", \"'>'\", \"'>='\", \"'['\", \"']'\", \"'^'\", \"'^='\", \"'as'\", \n    \"'break'\", \"'case'\", \"'catch'\", \"'class'\", \"'continue'\", \"'default'\", \n    \"'do'\", \"'else'\", \"'extends'\", \"'finally'\", \"'for'\", \"'foreach'\", \"'function'\", \n    \"'if'\", \"'import'\", \"'init'\", \"'new'\", \"'print'\", \"'printf'\", \"'public'\", \n    \"'return'\", \"'sprintf'\", \"'static'\", \"'switch'\", \"'throw'\", \"'try'\", \n    \"'while'\", \"'{'\", \"'|'\", \"'|='\", \"'||'\", \"'}'\"\n]\n\n\n\n\nclass ExprParser(Parser):\n    grammarFileName = \"Expr.g\"\n    api_version = 1\n    tokenNames = tokenNames\n\n    def __init__(self, input, state=None, *args, **kwargs):\n        if state is None:\n            state = RecognizerSharedState()\n\n        super(ExprParser, self).__init__(input, state, *args, **kwargs)\n\n        self.dfa6 = self.DFA6(\n            self, 6,\n            eot = self.DFA6_eot,\n            eof = self.DFA6_eof,\n            min = self.DFA6_min,\n            max = self.DFA6_max,\n            accept = self.DFA6_accept,\n            special = self.DFA6_special,\n            transition = self.DFA6_transition\n            )\n\n\n\n\n        self.delegates = []\n\n\tself._adaptor = None\n\tself.adaptor = CommonTreeAdaptor()\n\n\n\n    def getTreeAdaptor(self):\n        return self._adaptor\n\n    def setTreeAdaptor(self, adaptor):\n        self._adaptor = adaptor\n\n    adaptor = property(getTreeAdaptor, setTreeAdaptor)\n\n\n    class prog_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.prog_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"prog\"\n    # Expr.g:33:1: prog : ( EOF -> NOP | ( stmt )* );\n    def prog(self, ):\n        retval = self.prog_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        EOF1 = None\n        stmt2 = None\n\n        EOF1_tree = None\n        stream_EOF = RewriteRuleTokenStream(self._adaptor, \"token EOF\")\n\n        try:\n            try:\n                # Expr.g:34:2: ( EOF -> NOP | ( stmt )* )\n                alt2 = 2\n                LA2_0 = self.input.LA(1)\n\n                if (LA2_0 == EOF) :\n                    LA2_1 = self.input.LA(2)\n\n                    if (LA2_1 == EOF) :\n                        alt2 = 1\n                    else:\n                        if self._state.backtracking > 0:\n                            raise BacktrackingFailed\n\n\n                        nvae = NoViableAltException(\"\", 2, 1, self.input)\n\n                        raise nvae\n\n\n                elif (LA2_0 == ID or LA2_0 == 80 or LA2_0 == 84 or LA2_0 == 92 or LA2_0 == 105 or (108 <= LA2_0 <= 109) or LA2_0 == 111 or (115 <= LA2_0 <= 119) or (122 <= LA2_0 <= 123) or LA2_0 == 125 or (128 <= LA2_0 <= 131)) :\n                    alt2 = 2\n                else:\n                    if self._state.backtracking > 0:\n                        raise BacktrackingFailed\n\n\n                    nvae = NoViableAltException(\"\", 2, 0, self.input)\n\n                    raise nvae\n\n\n                if alt2 == 1:\n                    # Expr.g:34:4: EOF\n                    pass \n                    EOF1 = self.match(self.input, EOF, self.FOLLOW_EOF_in_prog211) \n                    if self._state.backtracking == 0:\n                        stream_EOF.add(EOF1)\n\n\n                    # AST Rewrite\n                    # elements: \n                    # token labels: \n                    # rule labels: retval\n                    # token list labels: \n                    # rule list labels: \n                    # wildcard labels: \n                    if self._state.backtracking == 0:\n                        retval.tree = root_0\n                        if retval is not None:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                        else:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                        root_0 = self._adaptor.nil()\n                        # 34:8: -> NOP\n                        self._adaptor.addChild(root_0, \n                        self._adaptor.createFromType(NOP, \"NOP\")\n                        )\n\n\n\n\n                        retval.tree = root_0\n\n\n\n\n                elif alt2 == 2:\n                    # Expr.g:35:4: ( stmt )*\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    # Expr.g:35:4: ( stmt )*\n                    while True: #loop1\n                        alt1 = 2\n                        LA1_0 = self.input.LA(1)\n\n                        if (LA1_0 == ID or LA1_0 == 80 or LA1_0 == 84 or LA1_0 == 92 or LA1_0 == 105 or (108 <= LA1_0 <= 109) or LA1_0 == 111 or (115 <= LA1_0 <= 119) or (122 <= LA1_0 <= 123) or LA1_0 == 125 or (128 <= LA1_0 <= 131)) :\n                            alt1 = 1\n\n\n                        if alt1 == 1:\n                            # Expr.g:35:4: stmt\n                            pass \n                            self._state.following.append(self.FOLLOW_stmt_in_prog220)\n                            stmt2 = self.stmt()\n\n                            self._state.following.pop()\n                            if self._state.backtracking == 0:\n                                self._adaptor.addChild(root_0, stmt2.tree)\n\n\n\n                        else:\n                            break #loop1\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"prog\"\n\n\n    class stmt_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.stmt_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"stmt\"\n    # Expr.g:38:1: stmt : ( ';' ->| exec_stmt | import_stmt | print_stmt | printf_stmt | break_stmt | continue_stmt | return_stmt | if_stmt | while_stmt | do_while_stmt | switch_stmt | for_stmt | foreach_stmt | throw_stmt | try_stmt | func_decl | class_decl );\n    def stmt(self, ):\n        retval = self.stmt_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal3 = None\n        exec_stmt4 = None\n        import_stmt5 = None\n        print_stmt6 = None\n        printf_stmt7 = None\n        break_stmt8 = None\n        continue_stmt9 = None\n        return_stmt10 = None\n        if_stmt11 = None\n        while_stmt12 = None\n        do_while_stmt13 = None\n        switch_stmt14 = None\n        for_stmt15 = None\n        foreach_stmt16 = None\n        throw_stmt17 = None\n        try_stmt18 = None\n        func_decl19 = None\n        class_decl20 = None\n\n        char_literal3_tree = None\n        stream_92 = RewriteRuleTokenStream(self._adaptor, \"token 92\")\n\n        try:\n            try:\n                # Expr.g:39:2: ( ';' ->| exec_stmt | import_stmt | print_stmt | printf_stmt | break_stmt | continue_stmt | return_stmt | if_stmt | while_stmt | do_while_stmt | switch_stmt | for_stmt | foreach_stmt | throw_stmt | try_stmt | func_decl | class_decl )\n                alt3 = 18\n                LA3 = self.input.LA(1)\n                if LA3 == 92:\n                    alt3 = 1\n                elif LA3 == ID or LA3 == 80 or LA3 == 84:\n                    alt3 = 2\n                elif LA3 == 119:\n                    alt3 = 3\n                elif LA3 == 122:\n                    alt3 = 4\n                elif LA3 == 123:\n                    alt3 = 5\n                elif LA3 == 105:\n                    alt3 = 6\n                elif LA3 == 109:\n                    alt3 = 7\n                elif LA3 == 125:\n                    alt3 = 8\n                elif LA3 == 118:\n                    alt3 = 9\n                elif LA3 == 131:\n                    alt3 = 10\n                elif LA3 == 111:\n                    alt3 = 11\n                elif LA3 == 128:\n                    alt3 = 12\n                elif LA3 == 115:\n                    alt3 = 13\n                elif LA3 == 116:\n                    alt3 = 14\n                elif LA3 == 129:\n                    alt3 = 15\n                elif LA3 == 130:\n                    alt3 = 16\n                elif LA3 == 117:\n                    alt3 = 17\n                elif LA3 == 108:\n                    alt3 = 18\n                else:\n                    if self._state.backtracking > 0:\n                        raise BacktrackingFailed\n\n\n                    nvae = NoViableAltException(\"\", 3, 0, self.input)\n\n                    raise nvae\n\n\n                if alt3 == 1:\n                    # Expr.g:39:4: ';'\n                    pass \n                    char_literal3 = self.match(self.input, 92, self.FOLLOW_92_in_stmt232) \n                    if self._state.backtracking == 0:\n                        stream_92.add(char_literal3)\n\n\n                    # AST Rewrite\n                    # elements: \n                    # token labels: \n                    # rule labels: retval\n                    # token list labels: \n                    # rule list labels: \n                    # wildcard labels: \n                    if self._state.backtracking == 0:\n                        retval.tree = root_0\n                        if retval is not None:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                        else:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                        root_0 = self._adaptor.nil()\n                        # 39:8: ->\n                        root_0 = None\n\n\n\n                        retval.tree = root_0\n\n\n\n\n                elif alt3 == 2:\n                    # Expr.g:40:4: exec_stmt\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_exec_stmt_in_stmt239)\n                    exec_stmt4 = self.exec_stmt()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, exec_stmt4.tree)\n\n\n\n                elif alt3 == 3:\n                    # Expr.g:41:4: import_stmt\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_import_stmt_in_stmt244)\n                    import_stmt5 = self.import_stmt()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, import_stmt5.tree)\n\n\n\n                elif alt3 == 4:\n                    # Expr.g:42:4: print_stmt\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_print_stmt_in_stmt249)\n                    print_stmt6 = self.print_stmt()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, print_stmt6.tree)\n\n\n\n                elif alt3 == 5:\n                    # Expr.g:42:17: printf_stmt\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_printf_stmt_in_stmt253)\n                    printf_stmt7 = self.printf_stmt()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, printf_stmt7.tree)\n\n\n\n                elif alt3 == 6:\n                    # Expr.g:43:4: break_stmt\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_break_stmt_in_stmt258)\n                    break_stmt8 = self.break_stmt()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, break_stmt8.tree)\n\n\n\n                elif alt3 == 7:\n                    # Expr.g:44:4: continue_stmt\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_continue_stmt_in_stmt263)\n                    continue_stmt9 = self.continue_stmt()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, continue_stmt9.tree)\n\n\n\n                elif alt3 == 8:\n                    # Expr.g:45:4: return_stmt\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_return_stmt_in_stmt268)\n                    return_stmt10 = self.return_stmt()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, return_stmt10.tree)\n\n\n\n                elif alt3 == 9:\n                    # Expr.g:46:4: if_stmt\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_if_stmt_in_stmt273)\n                    if_stmt11 = self.if_stmt()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, if_stmt11.tree)\n\n\n\n                elif alt3 == 10:\n                    # Expr.g:47:4: while_stmt\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_while_stmt_in_stmt278)\n                    while_stmt12 = self.while_stmt()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, while_stmt12.tree)\n\n\n\n                elif alt3 == 11:\n                    # Expr.g:48:4: do_while_stmt\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_do_while_stmt_in_stmt283)\n                    do_while_stmt13 = self.do_while_stmt()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, do_while_stmt13.tree)\n\n\n\n                elif alt3 == 12:\n                    # Expr.g:49:4: switch_stmt\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_switch_stmt_in_stmt288)\n                    switch_stmt14 = self.switch_stmt()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, switch_stmt14.tree)\n\n\n\n                elif alt3 == 13:\n                    # Expr.g:50:4: for_stmt\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_for_stmt_in_stmt293)\n                    for_stmt15 = self.for_stmt()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, for_stmt15.tree)\n\n\n\n                elif alt3 == 14:\n                    # Expr.g:51:4: foreach_stmt\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_foreach_stmt_in_stmt298)\n                    foreach_stmt16 = self.foreach_stmt()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, foreach_stmt16.tree)\n\n\n\n                elif alt3 == 15:\n                    # Expr.g:52:4: throw_stmt\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_throw_stmt_in_stmt303)\n                    throw_stmt17 = self.throw_stmt()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, throw_stmt17.tree)\n\n\n\n                elif alt3 == 16:\n                    # Expr.g:53:4: try_stmt\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_try_stmt_in_stmt308)\n                    try_stmt18 = self.try_stmt()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, try_stmt18.tree)\n\n\n\n                elif alt3 == 17:\n                    # Expr.g:54:4: func_decl\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_func_decl_in_stmt313)\n                    func_decl19 = self.func_decl()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, func_decl19.tree)\n\n\n\n                elif alt3 == 18:\n                    # Expr.g:55:4: class_decl\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_class_decl_in_stmt318)\n                    class_decl20 = self.class_decl()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, class_decl20.tree)\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"stmt\"\n\n\n    class block_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.block_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"block\"\n    # Expr.g:59:1: block : '{' ( stmt )* '}' -> ^( BLOCK ( stmt )* ) ;\n    def block(self, ):\n        retval = self.block_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal21 = None\n        char_literal23 = None\n        stmt22 = None\n\n        char_literal21_tree = None\n        char_literal23_tree = None\n        stream_132 = RewriteRuleTokenStream(self._adaptor, \"token 132\")\n        stream_136 = RewriteRuleTokenStream(self._adaptor, \"token 136\")\n        stream_stmt = RewriteRuleSubtreeStream(self._adaptor, \"rule stmt\")\n        try:\n            try:\n                # Expr.g:60:2: ( '{' ( stmt )* '}' -> ^( BLOCK ( stmt )* ) )\n                # Expr.g:60:4: '{' ( stmt )* '}'\n                pass \n                char_literal21 = self.match(self.input, 132, self.FOLLOW_132_in_block331) \n                if self._state.backtracking == 0:\n                    stream_132.add(char_literal21)\n\n\n                # Expr.g:60:8: ( stmt )*\n                while True: #loop4\n                    alt4 = 2\n                    LA4_0 = self.input.LA(1)\n\n                    if (LA4_0 == ID or LA4_0 == 80 or LA4_0 == 84 or LA4_0 == 92 or LA4_0 == 105 or (108 <= LA4_0 <= 109) or LA4_0 == 111 or (115 <= LA4_0 <= 119) or (122 <= LA4_0 <= 123) or LA4_0 == 125 or (128 <= LA4_0 <= 131)) :\n                        alt4 = 1\n\n\n                    if alt4 == 1:\n                        # Expr.g:60:8: stmt\n                        pass \n                        self._state.following.append(self.FOLLOW_stmt_in_block333)\n                        stmt22 = self.stmt()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_stmt.add(stmt22.tree)\n\n\n\n                    else:\n                        break #loop4\n\n\n                char_literal23 = self.match(self.input, 136, self.FOLLOW_136_in_block336) \n                if self._state.backtracking == 0:\n                    stream_136.add(char_literal23)\n\n\n                # AST Rewrite\n                # elements: stmt\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 61:3: -> ^( BLOCK ( stmt )* )\n                    # Expr.g:61:6: ^( BLOCK ( stmt )* )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(BLOCK, \"BLOCK\")\n                    , root_1)\n\n                    # Expr.g:61:14: ( stmt )*\n                    while stream_stmt.hasNext():\n                        self._adaptor.addChild(root_1, stream_stmt.nextTree())\n\n\n                    stream_stmt.reset();\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"block\"\n\n\n    class import_stmt_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.import_stmt_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"import_stmt\"\n    # Expr.g:64:1: import_stmt : 'import' module_path ( ',' module_path )* ';' -> ^( IMPORT ( module_path )+ ) ;\n    def import_stmt(self, ):\n        retval = self.import_stmt_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal24 = None\n        char_literal26 = None\n        char_literal28 = None\n        module_path25 = None\n        module_path27 = None\n\n        string_literal24_tree = None\n        char_literal26_tree = None\n        char_literal28_tree = None\n        stream_92 = RewriteRuleTokenStream(self._adaptor, \"token 92\")\n        stream_82 = RewriteRuleTokenStream(self._adaptor, \"token 82\")\n        stream_119 = RewriteRuleTokenStream(self._adaptor, \"token 119\")\n        stream_module_path = RewriteRuleSubtreeStream(self._adaptor, \"rule module_path\")\n        try:\n            try:\n                # Expr.g:65:2: ( 'import' module_path ( ',' module_path )* ';' -> ^( IMPORT ( module_path )+ ) )\n                # Expr.g:65:4: 'import' module_path ( ',' module_path )* ';'\n                pass \n                string_literal24 = self.match(self.input, 119, self.FOLLOW_119_in_import_stmt358) \n                if self._state.backtracking == 0:\n                    stream_119.add(string_literal24)\n\n\n                self._state.following.append(self.FOLLOW_module_path_in_import_stmt360)\n                module_path25 = self.module_path()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_module_path.add(module_path25.tree)\n\n\n                # Expr.g:65:25: ( ',' module_path )*\n                while True: #loop5\n                    alt5 = 2\n                    LA5_0 = self.input.LA(1)\n\n                    if (LA5_0 == 82) :\n                        alt5 = 1\n\n\n                    if alt5 == 1:\n                        # Expr.g:65:26: ',' module_path\n                        pass \n                        char_literal26 = self.match(self.input, 82, self.FOLLOW_82_in_import_stmt363) \n                        if self._state.backtracking == 0:\n                            stream_82.add(char_literal26)\n\n\n                        self._state.following.append(self.FOLLOW_module_path_in_import_stmt365)\n                        module_path27 = self.module_path()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_module_path.add(module_path27.tree)\n\n\n\n                    else:\n                        break #loop5\n\n\n                char_literal28 = self.match(self.input, 92, self.FOLLOW_92_in_import_stmt369) \n                if self._state.backtracking == 0:\n                    stream_92.add(char_literal28)\n\n\n                # AST Rewrite\n                # elements: module_path\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 66:3: -> ^( IMPORT ( module_path )+ )\n                    # Expr.g:66:6: ^( IMPORT ( module_path )+ )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(IMPORT, \"IMPORT\")\n                    , root_1)\n\n                    # Expr.g:66:15: ( module_path )+\n                    if not (stream_module_path.hasNext()):\n                        raise RewriteEarlyExitException()\n\n                    while stream_module_path.hasNext():\n                        self._adaptor.addChild(root_1, stream_module_path.nextTree())\n\n\n                    stream_module_path.reset()\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"import_stmt\"\n\n\n    class module_path_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.module_path_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"module_path\"\n    # Expr.g:68:1: module_path : ( module | module '.*' );\n    def module_path(self, ):\n        retval = self.module_path_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal31 = None\n        module29 = None\n        module30 = None\n\n        string_literal31_tree = None\n\n        try:\n            try:\n                # Expr.g:69:2: ( module | module '.*' )\n                alt6 = 2\n                alt6 = self.dfa6.predict(self.input)\n                if alt6 == 1:\n                    # Expr.g:69:4: module\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_module_in_module_path390)\n                    module29 = self.module()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, module29.tree)\n\n\n\n                elif alt6 == 2:\n                    # Expr.g:70:4: module '.*'\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_module_in_module_path395)\n                    module30 = self.module()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, module30.tree)\n\n\n                    string_literal31 = self.match(self.input, 87, self.FOLLOW_87_in_module_path397)\n                    if self._state.backtracking == 0:\n                        string_literal31_tree = self._adaptor.createWithPayload(string_literal31)\n                        self._adaptor.addChild(root_0, string_literal31_tree)\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"module_path\"\n\n\n    class printf_stmt_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.printf_stmt_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"printf_stmt\"\n    # Expr.g:73:1: printf_stmt : 'printf' '(' expr ( ',' expr_list )? ')' ';' -> ^( PRINTF expr ( expr_list )? ) ;\n    def printf_stmt(self, ):\n        retval = self.printf_stmt_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal32 = None\n        char_literal33 = None\n        char_literal35 = None\n        char_literal37 = None\n        char_literal38 = None\n        expr34 = None\n        expr_list36 = None\n\n        string_literal32_tree = None\n        char_literal33_tree = None\n        char_literal35_tree = None\n        char_literal37_tree = None\n        char_literal38_tree = None\n        stream_92 = RewriteRuleTokenStream(self._adaptor, \"token 92\")\n        stream_123 = RewriteRuleTokenStream(self._adaptor, \"token 123\")\n        stream_82 = RewriteRuleTokenStream(self._adaptor, \"token 82\")\n        stream_75 = RewriteRuleTokenStream(self._adaptor, \"token 75\")\n        stream_76 = RewriteRuleTokenStream(self._adaptor, \"token 76\")\n        stream_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule expr\")\n        stream_expr_list = RewriteRuleSubtreeStream(self._adaptor, \"rule expr_list\")\n        try:\n            try:\n                # Expr.g:74:2: ( 'printf' '(' expr ( ',' expr_list )? ')' ';' -> ^( PRINTF expr ( expr_list )? ) )\n                # Expr.g:74:4: 'printf' '(' expr ( ',' expr_list )? ')' ';'\n                pass \n                string_literal32 = self.match(self.input, 123, self.FOLLOW_123_in_printf_stmt408) \n                if self._state.backtracking == 0:\n                    stream_123.add(string_literal32)\n\n\n                char_literal33 = self.match(self.input, 75, self.FOLLOW_75_in_printf_stmt410) \n                if self._state.backtracking == 0:\n                    stream_75.add(char_literal33)\n\n\n                self._state.following.append(self.FOLLOW_expr_in_printf_stmt412)\n                expr34 = self.expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_expr.add(expr34.tree)\n\n\n                # Expr.g:74:22: ( ',' expr_list )?\n                alt7 = 2\n                LA7_0 = self.input.LA(1)\n\n                if (LA7_0 == 82) :\n                    alt7 = 1\n                if alt7 == 1:\n                    # Expr.g:74:23: ',' expr_list\n                    pass \n                    char_literal35 = self.match(self.input, 82, self.FOLLOW_82_in_printf_stmt415) \n                    if self._state.backtracking == 0:\n                        stream_82.add(char_literal35)\n\n\n                    self._state.following.append(self.FOLLOW_expr_list_in_printf_stmt417)\n                    expr_list36 = self.expr_list()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_expr_list.add(expr_list36.tree)\n\n\n\n\n\n                char_literal37 = self.match(self.input, 76, self.FOLLOW_76_in_printf_stmt421) \n                if self._state.backtracking == 0:\n                    stream_76.add(char_literal37)\n\n\n                char_literal38 = self.match(self.input, 92, self.FOLLOW_92_in_printf_stmt423) \n                if self._state.backtracking == 0:\n                    stream_92.add(char_literal38)\n\n\n                # AST Rewrite\n                # elements: expr_list, expr\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 75:3: -> ^( PRINTF expr ( expr_list )? )\n                    # Expr.g:75:6: ^( PRINTF expr ( expr_list )? )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(PRINTF, \"PRINTF\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n                    # Expr.g:75:20: ( expr_list )?\n                    if stream_expr_list.hasNext():\n                        self._adaptor.addChild(root_1, stream_expr_list.nextTree())\n\n\n                    stream_expr_list.reset();\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"printf_stmt\"\n\n\n    class print_stmt_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.print_stmt_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"print_stmt\"\n    # Expr.g:78:1: print_stmt : ( 'print' ) expr_list ';' -> ^( PRINT expr_list ) ;\n    def print_stmt(self, ):\n        retval = self.print_stmt_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal39 = None\n        char_literal41 = None\n        expr_list40 = None\n\n        string_literal39_tree = None\n        char_literal41_tree = None\n        stream_122 = RewriteRuleTokenStream(self._adaptor, \"token 122\")\n        stream_92 = RewriteRuleTokenStream(self._adaptor, \"token 92\")\n        stream_expr_list = RewriteRuleSubtreeStream(self._adaptor, \"rule expr_list\")\n        try:\n            try:\n                # Expr.g:81:2: ( ( 'print' ) expr_list ';' -> ^( PRINT expr_list ) )\n                # Expr.g:81:4: ( 'print' ) expr_list ';'\n                pass \n                # Expr.g:81:4: ( 'print' )\n                # Expr.g:81:5: 'print'\n                pass \n                string_literal39 = self.match(self.input, 122, self.FOLLOW_122_in_print_stmt452) \n                if self._state.backtracking == 0:\n                    stream_122.add(string_literal39)\n\n\n\n\n\n                self._state.following.append(self.FOLLOW_expr_list_in_print_stmt455)\n                expr_list40 = self.expr_list()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_expr_list.add(expr_list40.tree)\n\n\n                char_literal41 = self.match(self.input, 92, self.FOLLOW_92_in_print_stmt457) \n                if self._state.backtracking == 0:\n                    stream_92.add(char_literal41)\n\n\n                # AST Rewrite\n                # elements: expr_list\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 82:3: -> ^( PRINT expr_list )\n                    # Expr.g:82:6: ^( PRINT expr_list )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(PRINT, \"PRINT\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_expr_list.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"print_stmt\"\n\n\n    class break_stmt_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.break_stmt_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"break_stmt\"\n    # Expr.g:85:1: break_stmt : 'break' ';' -> BREAK ;\n    def break_stmt(self, ):\n        retval = self.break_stmt_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal42 = None\n        char_literal43 = None\n\n        string_literal42_tree = None\n        char_literal43_tree = None\n        stream_92 = RewriteRuleTokenStream(self._adaptor, \"token 92\")\n        stream_105 = RewriteRuleTokenStream(self._adaptor, \"token 105\")\n\n        try:\n            try:\n                # Expr.g:86:2: ( 'break' ';' -> BREAK )\n                # Expr.g:86:4: 'break' ';'\n                pass \n                string_literal42 = self.match(self.input, 105, self.FOLLOW_105_in_break_stmt478) \n                if self._state.backtracking == 0:\n                    stream_105.add(string_literal42)\n\n\n                char_literal43 = self.match(self.input, 92, self.FOLLOW_92_in_break_stmt480) \n                if self._state.backtracking == 0:\n                    stream_92.add(char_literal43)\n\n\n                # AST Rewrite\n                # elements: \n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 87:3: -> BREAK\n                    self._adaptor.addChild(root_0, \n                    self._adaptor.createFromType(BREAK, \"BREAK\")\n                    )\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"break_stmt\"\n\n\n    class continue_stmt_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.continue_stmt_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"continue_stmt\"\n    # Expr.g:89:1: continue_stmt : 'continue' ';' -> CONTINUE ;\n    def continue_stmt(self, ):\n        retval = self.continue_stmt_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal44 = None\n        char_literal45 = None\n\n        string_literal44_tree = None\n        char_literal45_tree = None\n        stream_109 = RewriteRuleTokenStream(self._adaptor, \"token 109\")\n        stream_92 = RewriteRuleTokenStream(self._adaptor, \"token 92\")\n\n        try:\n            try:\n                # Expr.g:90:2: ( 'continue' ';' -> CONTINUE )\n                # Expr.g:90:4: 'continue' ';'\n                pass \n                string_literal44 = self.match(self.input, 109, self.FOLLOW_109_in_continue_stmt496) \n                if self._state.backtracking == 0:\n                    stream_109.add(string_literal44)\n\n\n                char_literal45 = self.match(self.input, 92, self.FOLLOW_92_in_continue_stmt498) \n                if self._state.backtracking == 0:\n                    stream_92.add(char_literal45)\n\n\n                # AST Rewrite\n                # elements: \n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 91:3: -> CONTINUE\n                    self._adaptor.addChild(root_0, \n                    self._adaptor.createFromType(CONTINUE, \"CONTINUE\")\n                    )\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"continue_stmt\"\n\n\n    class return_stmt_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.return_stmt_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"return_stmt\"\n    # Expr.g:93:1: return_stmt : 'return' ( expr )? ';' -> ^( RETURN ( expr )? ) ;\n    def return_stmt(self, ):\n        retval = self.return_stmt_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal46 = None\n        char_literal48 = None\n        expr47 = None\n\n        string_literal46_tree = None\n        char_literal48_tree = None\n        stream_125 = RewriteRuleTokenStream(self._adaptor, \"token 125\")\n        stream_92 = RewriteRuleTokenStream(self._adaptor, \"token 92\")\n        stream_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule expr\")\n        try:\n            try:\n                # Expr.g:94:2: ( 'return' ( expr )? ';' -> ^( RETURN ( expr )? ) )\n                # Expr.g:94:4: 'return' ( expr )? ';'\n                pass \n                string_literal46 = self.match(self.input, 125, self.FOLLOW_125_in_return_stmt514) \n                if self._state.backtracking == 0:\n                    stream_125.add(string_literal46)\n\n\n                # Expr.g:94:13: ( expr )?\n                alt8 = 2\n                LA8_0 = self.input.LA(1)\n\n                if (LA8_0 == BOOL or LA8_0 == FLOAT or LA8_0 == ID or LA8_0 == INT or LA8_0 == NULL or LA8_0 == STRING or LA8_0 == 68 or LA8_0 == 75 or LA8_0 == 83 or LA8_0 == 100 or LA8_0 == 121 or LA8_0 == 126 or LA8_0 == 132) :\n                    alt8 = 1\n                if alt8 == 1:\n                    # Expr.g:94:13: expr\n                    pass \n                    self._state.following.append(self.FOLLOW_expr_in_return_stmt516)\n                    expr47 = self.expr()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_expr.add(expr47.tree)\n\n\n\n\n\n                char_literal48 = self.match(self.input, 92, self.FOLLOW_92_in_return_stmt519) \n                if self._state.backtracking == 0:\n                    stream_92.add(char_literal48)\n\n\n                # AST Rewrite\n                # elements: expr\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 95:3: -> ^( RETURN ( expr )? )\n                    # Expr.g:95:6: ^( RETURN ( expr )? )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(RETURN, \"RETURN\")\n                    , root_1)\n\n                    # Expr.g:95:15: ( expr )?\n                    if stream_expr.hasNext():\n                        self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n\n                    stream_expr.reset();\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"return_stmt\"\n\n\n    class if_stmt_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.if_stmt_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"if_stmt\"\n    # Expr.g:98:1: if_stmt : if_clause ( else_if_clause )* ( else_clause )? ;\n    def if_stmt(self, ):\n        retval = self.if_stmt_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        if_clause49 = None\n        else_if_clause50 = None\n        else_clause51 = None\n\n\n        try:\n            try:\n                # Expr.g:99:2: ( if_clause ( else_if_clause )* ( else_clause )? )\n                # Expr.g:99:4: if_clause ( else_if_clause )* ( else_clause )?\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                self._state.following.append(self.FOLLOW_if_clause_in_if_stmt541)\n                if_clause49 = self.if_clause()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    self._adaptor.addChild(root_0, if_clause49.tree)\n\n\n                # Expr.g:99:14: ( else_if_clause )*\n                while True: #loop9\n                    alt9 = 2\n                    LA9_0 = self.input.LA(1)\n\n                    if (LA9_0 == 112) :\n                        LA9_1 = self.input.LA(2)\n\n                        if (LA9_1 == 118) :\n                            alt9 = 1\n\n\n\n\n                    if alt9 == 1:\n                        # Expr.g:99:14: else_if_clause\n                        pass \n                        self._state.following.append(self.FOLLOW_else_if_clause_in_if_stmt543)\n                        else_if_clause50 = self.else_if_clause()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            self._adaptor.addChild(root_0, else_if_clause50.tree)\n\n\n\n                    else:\n                        break #loop9\n\n\n                # Expr.g:99:30: ( else_clause )?\n                alt10 = 2\n                LA10_0 = self.input.LA(1)\n\n                if (LA10_0 == 112) :\n                    alt10 = 1\n                if alt10 == 1:\n                    # Expr.g:99:30: else_clause\n                    pass \n                    self._state.following.append(self.FOLLOW_else_clause_in_if_stmt546)\n                    else_clause51 = self.else_clause()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, else_clause51.tree)\n\n\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"if_stmt\"\n\n\n    class if_clause_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.if_clause_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"if_clause\"\n    # Expr.g:101:1: if_clause : 'if' '(' expr ')' block -> ^( IF expr block ) ;\n    def if_clause(self, ):\n        retval = self.if_clause_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal52 = None\n        char_literal53 = None\n        char_literal55 = None\n        expr54 = None\n        block56 = None\n\n        string_literal52_tree = None\n        char_literal53_tree = None\n        char_literal55_tree = None\n        stream_75 = RewriteRuleTokenStream(self._adaptor, \"token 75\")\n        stream_118 = RewriteRuleTokenStream(self._adaptor, \"token 118\")\n        stream_76 = RewriteRuleTokenStream(self._adaptor, \"token 76\")\n        stream_block = RewriteRuleSubtreeStream(self._adaptor, \"rule block\")\n        stream_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule expr\")\n        try:\n            try:\n                # Expr.g:102:2: ( 'if' '(' expr ')' block -> ^( IF expr block ) )\n                # Expr.g:102:4: 'if' '(' expr ')' block\n                pass \n                string_literal52 = self.match(self.input, 118, self.FOLLOW_118_in_if_clause557) \n                if self._state.backtracking == 0:\n                    stream_118.add(string_literal52)\n\n\n                char_literal53 = self.match(self.input, 75, self.FOLLOW_75_in_if_clause559) \n                if self._state.backtracking == 0:\n                    stream_75.add(char_literal53)\n\n\n                self._state.following.append(self.FOLLOW_expr_in_if_clause561)\n                expr54 = self.expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_expr.add(expr54.tree)\n\n\n                char_literal55 = self.match(self.input, 76, self.FOLLOW_76_in_if_clause563) \n                if self._state.backtracking == 0:\n                    stream_76.add(char_literal55)\n\n\n                self._state.following.append(self.FOLLOW_block_in_if_clause565)\n                block56 = self.block()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_block.add(block56.tree)\n\n\n                # AST Rewrite\n                # elements: block, expr\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 103:3: -> ^( IF expr block )\n                    # Expr.g:103:6: ^( IF expr block )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(IF, \"IF\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n                    self._adaptor.addChild(root_1, stream_block.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"if_clause\"\n\n\n    class else_if_clause_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.else_if_clause_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"else_if_clause\"\n    # Expr.g:105:1: else_if_clause : 'else' if_clause -> ^( ELSE_IF if_clause ) ;\n    def else_if_clause(self, ):\n        retval = self.else_if_clause_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal57 = None\n        if_clause58 = None\n\n        string_literal57_tree = None\n        stream_112 = RewriteRuleTokenStream(self._adaptor, \"token 112\")\n        stream_if_clause = RewriteRuleSubtreeStream(self._adaptor, \"rule if_clause\")\n        try:\n            try:\n                # Expr.g:106:2: ( 'else' if_clause -> ^( ELSE_IF if_clause ) )\n                # Expr.g:106:4: 'else' if_clause\n                pass \n                string_literal57 = self.match(self.input, 112, self.FOLLOW_112_in_else_if_clause587) \n                if self._state.backtracking == 0:\n                    stream_112.add(string_literal57)\n\n\n                self._state.following.append(self.FOLLOW_if_clause_in_else_if_clause589)\n                if_clause58 = self.if_clause()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_if_clause.add(if_clause58.tree)\n\n\n                # AST Rewrite\n                # elements: if_clause\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 107:3: -> ^( ELSE_IF if_clause )\n                    # Expr.g:107:6: ^( ELSE_IF if_clause )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(ELSE_IF, \"ELSE_IF\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_if_clause.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"else_if_clause\"\n\n\n    class else_clause_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.else_clause_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"else_clause\"\n    # Expr.g:109:1: else_clause : 'else' block -> ^( ELSE block ) ;\n    def else_clause(self, ):\n        retval = self.else_clause_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal59 = None\n        block60 = None\n\n        string_literal59_tree = None\n        stream_112 = RewriteRuleTokenStream(self._adaptor, \"token 112\")\n        stream_block = RewriteRuleSubtreeStream(self._adaptor, \"rule block\")\n        try:\n            try:\n                # Expr.g:110:2: ( 'else' block -> ^( ELSE block ) )\n                # Expr.g:110:4: 'else' block\n                pass \n                string_literal59 = self.match(self.input, 112, self.FOLLOW_112_in_else_clause609) \n                if self._state.backtracking == 0:\n                    stream_112.add(string_literal59)\n\n\n                self._state.following.append(self.FOLLOW_block_in_else_clause611)\n                block60 = self.block()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_block.add(block60.tree)\n\n\n                # AST Rewrite\n                # elements: block\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 111:3: -> ^( ELSE block )\n                    # Expr.g:111:6: ^( ELSE block )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(ELSE, \"ELSE\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_block.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"else_clause\"\n\n\n    class while_stmt_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.while_stmt_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"while_stmt\"\n    # Expr.g:114:1: while_stmt : 'while' '(' expr ')' block -> ^( WHILE expr block ) ;\n    def while_stmt(self, ):\n        retval = self.while_stmt_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal61 = None\n        char_literal62 = None\n        char_literal64 = None\n        expr63 = None\n        block65 = None\n\n        string_literal61_tree = None\n        char_literal62_tree = None\n        char_literal64_tree = None\n        stream_131 = RewriteRuleTokenStream(self._adaptor, \"token 131\")\n        stream_75 = RewriteRuleTokenStream(self._adaptor, \"token 75\")\n        stream_76 = RewriteRuleTokenStream(self._adaptor, \"token 76\")\n        stream_block = RewriteRuleSubtreeStream(self._adaptor, \"rule block\")\n        stream_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule expr\")\n        try:\n            try:\n                # Expr.g:115:2: ( 'while' '(' expr ')' block -> ^( WHILE expr block ) )\n                # Expr.g:115:4: 'while' '(' expr ')' block\n                pass \n                string_literal61 = self.match(self.input, 131, self.FOLLOW_131_in_while_stmt632) \n                if self._state.backtracking == 0:\n                    stream_131.add(string_literal61)\n\n\n                char_literal62 = self.match(self.input, 75, self.FOLLOW_75_in_while_stmt634) \n                if self._state.backtracking == 0:\n                    stream_75.add(char_literal62)\n\n\n                self._state.following.append(self.FOLLOW_expr_in_while_stmt636)\n                expr63 = self.expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_expr.add(expr63.tree)\n\n\n                char_literal64 = self.match(self.input, 76, self.FOLLOW_76_in_while_stmt638) \n                if self._state.backtracking == 0:\n                    stream_76.add(char_literal64)\n\n\n                self._state.following.append(self.FOLLOW_block_in_while_stmt640)\n                block65 = self.block()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_block.add(block65.tree)\n\n\n                # AST Rewrite\n                # elements: expr, block\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 116:3: -> ^( WHILE expr block )\n                    # Expr.g:116:6: ^( WHILE expr block )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(WHILE, \"WHILE\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n                    self._adaptor.addChild(root_1, stream_block.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"while_stmt\"\n\n\n    class do_while_stmt_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.do_while_stmt_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"do_while_stmt\"\n    # Expr.g:119:1: do_while_stmt : 'do' block 'while' '(' expr ')' ';' -> ^( DO_WHILE block expr ) ;\n    def do_while_stmt(self, ):\n        retval = self.do_while_stmt_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal66 = None\n        string_literal68 = None\n        char_literal69 = None\n        char_literal71 = None\n        char_literal72 = None\n        block67 = None\n        expr70 = None\n\n        string_literal66_tree = None\n        string_literal68_tree = None\n        char_literal69_tree = None\n        char_literal71_tree = None\n        char_literal72_tree = None\n        stream_92 = RewriteRuleTokenStream(self._adaptor, \"token 92\")\n        stream_111 = RewriteRuleTokenStream(self._adaptor, \"token 111\")\n        stream_131 = RewriteRuleTokenStream(self._adaptor, \"token 131\")\n        stream_75 = RewriteRuleTokenStream(self._adaptor, \"token 75\")\n        stream_76 = RewriteRuleTokenStream(self._adaptor, \"token 76\")\n        stream_block = RewriteRuleSubtreeStream(self._adaptor, \"rule block\")\n        stream_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule expr\")\n        try:\n            try:\n                # Expr.g:120:2: ( 'do' block 'while' '(' expr ')' ';' -> ^( DO_WHILE block expr ) )\n                # Expr.g:120:4: 'do' block 'while' '(' expr ')' ';'\n                pass \n                string_literal66 = self.match(self.input, 111, self.FOLLOW_111_in_do_while_stmt663) \n                if self._state.backtracking == 0:\n                    stream_111.add(string_literal66)\n\n\n                self._state.following.append(self.FOLLOW_block_in_do_while_stmt665)\n                block67 = self.block()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_block.add(block67.tree)\n\n\n                string_literal68 = self.match(self.input, 131, self.FOLLOW_131_in_do_while_stmt667) \n                if self._state.backtracking == 0:\n                    stream_131.add(string_literal68)\n\n\n                char_literal69 = self.match(self.input, 75, self.FOLLOW_75_in_do_while_stmt669) \n                if self._state.backtracking == 0:\n                    stream_75.add(char_literal69)\n\n\n                self._state.following.append(self.FOLLOW_expr_in_do_while_stmt671)\n                expr70 = self.expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_expr.add(expr70.tree)\n\n\n                char_literal71 = self.match(self.input, 76, self.FOLLOW_76_in_do_while_stmt673) \n                if self._state.backtracking == 0:\n                    stream_76.add(char_literal71)\n\n\n                char_literal72 = self.match(self.input, 92, self.FOLLOW_92_in_do_while_stmt675) \n                if self._state.backtracking == 0:\n                    stream_92.add(char_literal72)\n\n\n                # AST Rewrite\n                # elements: expr, block\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 121:3: -> ^( DO_WHILE block expr )\n                    # Expr.g:121:6: ^( DO_WHILE block expr )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(DO_WHILE, \"DO_WHILE\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_block.nextTree())\n\n                    self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"do_while_stmt\"\n\n\n    class switch_stmt_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.switch_stmt_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"switch_stmt\"\n    # Expr.g:124:1: switch_stmt : 'switch' '(' expr ')' case_block -> ^( SWITCH expr case_block ) ;\n    def switch_stmt(self, ):\n        retval = self.switch_stmt_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal73 = None\n        char_literal74 = None\n        char_literal76 = None\n        expr75 = None\n        case_block77 = None\n\n        string_literal73_tree = None\n        char_literal74_tree = None\n        char_literal76_tree = None\n        stream_128 = RewriteRuleTokenStream(self._adaptor, \"token 128\")\n        stream_75 = RewriteRuleTokenStream(self._adaptor, \"token 75\")\n        stream_76 = RewriteRuleTokenStream(self._adaptor, \"token 76\")\n        stream_case_block = RewriteRuleSubtreeStream(self._adaptor, \"rule case_block\")\n        stream_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule expr\")\n        try:\n            try:\n                # Expr.g:125:2: ( 'switch' '(' expr ')' case_block -> ^( SWITCH expr case_block ) )\n                # Expr.g:125:4: 'switch' '(' expr ')' case_block\n                pass \n                string_literal73 = self.match(self.input, 128, self.FOLLOW_128_in_switch_stmt698) \n                if self._state.backtracking == 0:\n                    stream_128.add(string_literal73)\n\n\n                char_literal74 = self.match(self.input, 75, self.FOLLOW_75_in_switch_stmt700) \n                if self._state.backtracking == 0:\n                    stream_75.add(char_literal74)\n\n\n                self._state.following.append(self.FOLLOW_expr_in_switch_stmt702)\n                expr75 = self.expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_expr.add(expr75.tree)\n\n\n                char_literal76 = self.match(self.input, 76, self.FOLLOW_76_in_switch_stmt704) \n                if self._state.backtracking == 0:\n                    stream_76.add(char_literal76)\n\n\n                self._state.following.append(self.FOLLOW_case_block_in_switch_stmt706)\n                case_block77 = self.case_block()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_case_block.add(case_block77.tree)\n\n\n                # AST Rewrite\n                # elements: case_block, expr\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 126:3: -> ^( SWITCH expr case_block )\n                    # Expr.g:126:6: ^( SWITCH expr case_block )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(SWITCH, \"SWITCH\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n                    self._adaptor.addChild(root_1, stream_case_block.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"switch_stmt\"\n\n\n    class case_block_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.case_block_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"case_block\"\n    # Expr.g:128:1: case_block : '{' ( case_clause )+ ( default_clause )? '}' ;\n    def case_block(self, ):\n        retval = self.case_block_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal78 = None\n        char_literal81 = None\n        case_clause79 = None\n        default_clause80 = None\n\n        char_literal78_tree = None\n        char_literal81_tree = None\n\n        try:\n            try:\n                # Expr.g:129:2: ( '{' ( case_clause )+ ( default_clause )? '}' )\n                # Expr.g:129:4: '{' ( case_clause )+ ( default_clause )? '}'\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                char_literal78 = self.match(self.input, 132, self.FOLLOW_132_in_case_block728)\n                if self._state.backtracking == 0:\n                    char_literal78_tree = self._adaptor.createWithPayload(char_literal78)\n                    self._adaptor.addChild(root_0, char_literal78_tree)\n\n\n\n                # Expr.g:129:8: ( case_clause )+\n                cnt11 = 0\n                while True: #loop11\n                    alt11 = 2\n                    LA11_0 = self.input.LA(1)\n\n                    if (LA11_0 == 106) :\n                        alt11 = 1\n\n\n                    if alt11 == 1:\n                        # Expr.g:129:9: case_clause\n                        pass \n                        self._state.following.append(self.FOLLOW_case_clause_in_case_block731)\n                        case_clause79 = self.case_clause()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            self._adaptor.addChild(root_0, case_clause79.tree)\n\n\n\n                    else:\n                        if cnt11 >= 1:\n                            break #loop11\n\n                        if self._state.backtracking > 0:\n                            raise BacktrackingFailed\n\n\n                        eee = EarlyExitException(11, self.input)\n                        raise eee\n\n                    cnt11 += 1\n\n\n                # Expr.g:129:23: ( default_clause )?\n                alt12 = 2\n                LA12_0 = self.input.LA(1)\n\n                if (LA12_0 == 110) :\n                    alt12 = 1\n                if alt12 == 1:\n                    # Expr.g:129:24: default_clause\n                    pass \n                    self._state.following.append(self.FOLLOW_default_clause_in_case_block736)\n                    default_clause80 = self.default_clause()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, default_clause80.tree)\n\n\n\n\n\n                char_literal81 = self.match(self.input, 136, self.FOLLOW_136_in_case_block740)\n                if self._state.backtracking == 0:\n                    char_literal81_tree = self._adaptor.createWithPayload(char_literal81)\n                    self._adaptor.addChild(root_0, char_literal81_tree)\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"case_block\"\n\n\n    class case_clause_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.case_clause_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"case_clause\"\n    # Expr.g:131:1: case_clause : ( case_test )+ ( stmt )* break_stmt -> ^( CASE ( case_test )+ ( stmt )* break_stmt ) ;\n    def case_clause(self, ):\n        retval = self.case_clause_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        case_test82 = None\n        stmt83 = None\n        break_stmt84 = None\n\n        stream_case_test = RewriteRuleSubtreeStream(self._adaptor, \"rule case_test\")\n        stream_stmt = RewriteRuleSubtreeStream(self._adaptor, \"rule stmt\")\n        stream_break_stmt = RewriteRuleSubtreeStream(self._adaptor, \"rule break_stmt\")\n        try:\n            try:\n                # Expr.g:132:2: ( ( case_test )+ ( stmt )* break_stmt -> ^( CASE ( case_test )+ ( stmt )* break_stmt ) )\n                # Expr.g:132:4: ( case_test )+ ( stmt )* break_stmt\n                pass \n                # Expr.g:132:4: ( case_test )+\n                cnt13 = 0\n                while True: #loop13\n                    alt13 = 2\n                    LA13_0 = self.input.LA(1)\n\n                    if (LA13_0 == 106) :\n                        alt13 = 1\n\n\n                    if alt13 == 1:\n                        # Expr.g:132:4: case_test\n                        pass \n                        self._state.following.append(self.FOLLOW_case_test_in_case_clause750)\n                        case_test82 = self.case_test()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_case_test.add(case_test82.tree)\n\n\n\n                    else:\n                        if cnt13 >= 1:\n                            break #loop13\n\n                        if self._state.backtracking > 0:\n                            raise BacktrackingFailed\n\n\n                        eee = EarlyExitException(13, self.input)\n                        raise eee\n\n                    cnt13 += 1\n\n\n                # Expr.g:132:15: ( stmt )*\n                while True: #loop14\n                    alt14 = 2\n                    LA14_0 = self.input.LA(1)\n\n                    if (LA14_0 == 105) :\n                        LA14_1 = self.input.LA(2)\n\n                        if (LA14_1 == 92) :\n                            LA14_3 = self.input.LA(3)\n\n                            if (LA14_3 == ID or LA14_3 == 80 or LA14_3 == 84 or LA14_3 == 92 or LA14_3 == 105 or (108 <= LA14_3 <= 109) or LA14_3 == 111 or (115 <= LA14_3 <= 119) or (122 <= LA14_3 <= 123) or LA14_3 == 125 or (128 <= LA14_3 <= 131)) :\n                                alt14 = 1\n\n\n\n\n                    elif (LA14_0 == ID or LA14_0 == 80 or LA14_0 == 84 or LA14_0 == 92 or (108 <= LA14_0 <= 109) or LA14_0 == 111 or (115 <= LA14_0 <= 119) or (122 <= LA14_0 <= 123) or LA14_0 == 125 or (128 <= LA14_0 <= 131)) :\n                        alt14 = 1\n\n\n                    if alt14 == 1:\n                        # Expr.g:132:15: stmt\n                        pass \n                        self._state.following.append(self.FOLLOW_stmt_in_case_clause753)\n                        stmt83 = self.stmt()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_stmt.add(stmt83.tree)\n\n\n\n                    else:\n                        break #loop14\n\n\n                self._state.following.append(self.FOLLOW_break_stmt_in_case_clause756)\n                break_stmt84 = self.break_stmt()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_break_stmt.add(break_stmt84.tree)\n\n\n                # AST Rewrite\n                # elements: stmt, case_test, break_stmt\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 133:3: -> ^( CASE ( case_test )+ ( stmt )* break_stmt )\n                    # Expr.g:133:6: ^( CASE ( case_test )+ ( stmt )* break_stmt )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(CASE, \"CASE\")\n                    , root_1)\n\n                    # Expr.g:133:13: ( case_test )+\n                    if not (stream_case_test.hasNext()):\n                        raise RewriteEarlyExitException()\n\n                    while stream_case_test.hasNext():\n                        self._adaptor.addChild(root_1, stream_case_test.nextTree())\n\n\n                    stream_case_test.reset()\n\n                    # Expr.g:133:24: ( stmt )*\n                    while stream_stmt.hasNext():\n                        self._adaptor.addChild(root_1, stream_stmt.nextTree())\n\n\n                    stream_stmt.reset();\n\n                    self._adaptor.addChild(root_1, stream_break_stmt.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"case_clause\"\n\n\n    class case_test_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.case_test_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"case_test\"\n    # Expr.g:135:1: case_test : 'case' expr ':' -> ^( CASE expr ) ;\n    def case_test(self, ):\n        retval = self.case_test_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal85 = None\n        char_literal87 = None\n        expr86 = None\n\n        string_literal85_tree = None\n        char_literal87_tree = None\n        stream_91 = RewriteRuleTokenStream(self._adaptor, \"token 91\")\n        stream_106 = RewriteRuleTokenStream(self._adaptor, \"token 106\")\n        stream_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule expr\")\n        try:\n            try:\n                # Expr.g:136:2: ( 'case' expr ':' -> ^( CASE expr ) )\n                # Expr.g:136:4: 'case' expr ':'\n                pass \n                string_literal85 = self.match(self.input, 106, self.FOLLOW_106_in_case_test782) \n                if self._state.backtracking == 0:\n                    stream_106.add(string_literal85)\n\n\n                self._state.following.append(self.FOLLOW_expr_in_case_test784)\n                expr86 = self.expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_expr.add(expr86.tree)\n\n\n                char_literal87 = self.match(self.input, 91, self.FOLLOW_91_in_case_test786) \n                if self._state.backtracking == 0:\n                    stream_91.add(char_literal87)\n\n\n                # AST Rewrite\n                # elements: expr\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 137:3: -> ^( CASE expr )\n                    # Expr.g:137:6: ^( CASE expr )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(CASE, \"CASE\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"case_test\"\n\n\n    class default_clause_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.default_clause_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"default_clause\"\n    # Expr.g:139:1: default_clause : 'default' ':' ( stmt )* -> ^( DEFAULT ( stmt )* ) ;\n    def default_clause(self, ):\n        retval = self.default_clause_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal88 = None\n        char_literal89 = None\n        stmt90 = None\n\n        string_literal88_tree = None\n        char_literal89_tree = None\n        stream_110 = RewriteRuleTokenStream(self._adaptor, \"token 110\")\n        stream_91 = RewriteRuleTokenStream(self._adaptor, \"token 91\")\n        stream_stmt = RewriteRuleSubtreeStream(self._adaptor, \"rule stmt\")\n        try:\n            try:\n                # Expr.g:140:2: ( 'default' ':' ( stmt )* -> ^( DEFAULT ( stmt )* ) )\n                # Expr.g:140:4: 'default' ':' ( stmt )*\n                pass \n                string_literal88 = self.match(self.input, 110, self.FOLLOW_110_in_default_clause806) \n                if self._state.backtracking == 0:\n                    stream_110.add(string_literal88)\n\n\n                char_literal89 = self.match(self.input, 91, self.FOLLOW_91_in_default_clause808) \n                if self._state.backtracking == 0:\n                    stream_91.add(char_literal89)\n\n\n                # Expr.g:140:18: ( stmt )*\n                while True: #loop15\n                    alt15 = 2\n                    LA15_0 = self.input.LA(1)\n\n                    if (LA15_0 == ID or LA15_0 == 80 or LA15_0 == 84 or LA15_0 == 92 or LA15_0 == 105 or (108 <= LA15_0 <= 109) or LA15_0 == 111 or (115 <= LA15_0 <= 119) or (122 <= LA15_0 <= 123) or LA15_0 == 125 or (128 <= LA15_0 <= 131)) :\n                        alt15 = 1\n\n\n                    if alt15 == 1:\n                        # Expr.g:140:18: stmt\n                        pass \n                        self._state.following.append(self.FOLLOW_stmt_in_default_clause810)\n                        stmt90 = self.stmt()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_stmt.add(stmt90.tree)\n\n\n\n                    else:\n                        break #loop15\n\n\n                # AST Rewrite\n                # elements: stmt\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 141:3: -> ^( DEFAULT ( stmt )* )\n                    # Expr.g:141:6: ^( DEFAULT ( stmt )* )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(DEFAULT, \"DEFAULT\")\n                    , root_1)\n\n                    # Expr.g:141:16: ( stmt )*\n                    while stream_stmt.hasNext():\n                        self._adaptor.addChild(root_1, stream_stmt.nextTree())\n\n\n                    stream_stmt.reset();\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"default_clause\"\n\n\n    class for_stmt_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.for_stmt_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"for_stmt\"\n    # Expr.g:144:1: for_stmt : 'for' '(' (a= exec_list )? ';' expr ';' (b= exec_list )? ')' block -> ^( FOR ( $a)? expr block ( $b)? ) ;\n    def for_stmt(self, ):\n        retval = self.for_stmt_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal91 = None\n        char_literal92 = None\n        char_literal93 = None\n        char_literal95 = None\n        char_literal96 = None\n        a = None\n        b = None\n        expr94 = None\n        block97 = None\n\n        string_literal91_tree = None\n        char_literal92_tree = None\n        char_literal93_tree = None\n        char_literal95_tree = None\n        char_literal96_tree = None\n        stream_115 = RewriteRuleTokenStream(self._adaptor, \"token 115\")\n        stream_92 = RewriteRuleTokenStream(self._adaptor, \"token 92\")\n        stream_75 = RewriteRuleTokenStream(self._adaptor, \"token 75\")\n        stream_76 = RewriteRuleTokenStream(self._adaptor, \"token 76\")\n        stream_block = RewriteRuleSubtreeStream(self._adaptor, \"rule block\")\n        stream_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule expr\")\n        stream_exec_list = RewriteRuleSubtreeStream(self._adaptor, \"rule exec_list\")\n        try:\n            try:\n                # Expr.g:145:2: ( 'for' '(' (a= exec_list )? ';' expr ';' (b= exec_list )? ')' block -> ^( FOR ( $a)? expr block ( $b)? ) )\n                # Expr.g:145:4: 'for' '(' (a= exec_list )? ';' expr ';' (b= exec_list )? ')' block\n                pass \n                string_literal91 = self.match(self.input, 115, self.FOLLOW_115_in_for_stmt833) \n                if self._state.backtracking == 0:\n                    stream_115.add(string_literal91)\n\n\n                char_literal92 = self.match(self.input, 75, self.FOLLOW_75_in_for_stmt835) \n                if self._state.backtracking == 0:\n                    stream_75.add(char_literal92)\n\n\n                # Expr.g:145:15: (a= exec_list )?\n                alt16 = 2\n                LA16_0 = self.input.LA(1)\n\n                if (LA16_0 == ID or LA16_0 == 80 or LA16_0 == 84) :\n                    alt16 = 1\n                if alt16 == 1:\n                    # Expr.g:145:15: a= exec_list\n                    pass \n                    self._state.following.append(self.FOLLOW_exec_list_in_for_stmt839)\n                    a = self.exec_list()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_exec_list.add(a.tree)\n\n\n\n\n\n                char_literal93 = self.match(self.input, 92, self.FOLLOW_92_in_for_stmt842) \n                if self._state.backtracking == 0:\n                    stream_92.add(char_literal93)\n\n\n                self._state.following.append(self.FOLLOW_expr_in_for_stmt844)\n                expr94 = self.expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_expr.add(expr94.tree)\n\n\n                char_literal95 = self.match(self.input, 92, self.FOLLOW_92_in_for_stmt846) \n                if self._state.backtracking == 0:\n                    stream_92.add(char_literal95)\n\n\n                # Expr.g:145:41: (b= exec_list )?\n                alt17 = 2\n                LA17_0 = self.input.LA(1)\n\n                if (LA17_0 == ID or LA17_0 == 80 or LA17_0 == 84) :\n                    alt17 = 1\n                if alt17 == 1:\n                    # Expr.g:145:41: b= exec_list\n                    pass \n                    self._state.following.append(self.FOLLOW_exec_list_in_for_stmt850)\n                    b = self.exec_list()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_exec_list.add(b.tree)\n\n\n\n\n\n                char_literal96 = self.match(self.input, 76, self.FOLLOW_76_in_for_stmt853) \n                if self._state.backtracking == 0:\n                    stream_76.add(char_literal96)\n\n\n                self._state.following.append(self.FOLLOW_block_in_for_stmt855)\n                block97 = self.block()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_block.add(block97.tree)\n\n\n                # AST Rewrite\n                # elements: expr, block, a, b\n                # token labels: \n                # rule labels: retval, b, a\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n                    if b is not None:\n                        stream_b = RewriteRuleSubtreeStream(self._adaptor, \"rule b\", b.tree)\n                    else:\n                        stream_b = RewriteRuleSubtreeStream(self._adaptor, \"token b\", None)\n\n                    if a is not None:\n                        stream_a = RewriteRuleSubtreeStream(self._adaptor, \"rule a\", a.tree)\n                    else:\n                        stream_a = RewriteRuleSubtreeStream(self._adaptor, \"token a\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 146:3: -> ^( FOR ( $a)? expr block ( $b)? )\n                    # Expr.g:146:6: ^( FOR ( $a)? expr block ( $b)? )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(FOR, \"FOR\")\n                    , root_1)\n\n                    # Expr.g:146:13: ( $a)?\n                    if stream_a.hasNext():\n                        self._adaptor.addChild(root_1, stream_a.nextTree())\n\n\n                    stream_a.reset();\n\n                    self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n                    self._adaptor.addChild(root_1, stream_block.nextTree())\n\n                    # Expr.g:146:28: ( $b)?\n                    if stream_b.hasNext():\n                        self._adaptor.addChild(root_1, stream_b.nextTree())\n\n\n                    stream_b.reset();\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"for_stmt\"\n\n\n    class foreach_stmt_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.foreach_stmt_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"foreach_stmt\"\n    # Expr.g:149:1: foreach_stmt : 'foreach' '(' expr 'as' each ')' block -> ^( FOREACH expr each block ) ;\n    def foreach_stmt(self, ):\n        retval = self.foreach_stmt_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal98 = None\n        char_literal99 = None\n        string_literal101 = None\n        char_literal103 = None\n        expr100 = None\n        each102 = None\n        block104 = None\n\n        string_literal98_tree = None\n        char_literal99_tree = None\n        string_literal101_tree = None\n        char_literal103_tree = None\n        stream_116 = RewriteRuleTokenStream(self._adaptor, \"token 116\")\n        stream_104 = RewriteRuleTokenStream(self._adaptor, \"token 104\")\n        stream_75 = RewriteRuleTokenStream(self._adaptor, \"token 75\")\n        stream_76 = RewriteRuleTokenStream(self._adaptor, \"token 76\")\n        stream_block = RewriteRuleSubtreeStream(self._adaptor, \"rule block\")\n        stream_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule expr\")\n        stream_each = RewriteRuleSubtreeStream(self._adaptor, \"rule each\")\n        try:\n            try:\n                # Expr.g:150:2: ( 'foreach' '(' expr 'as' each ')' block -> ^( FOREACH expr each block ) )\n                # Expr.g:150:4: 'foreach' '(' expr 'as' each ')' block\n                pass \n                string_literal98 = self.match(self.input, 116, self.FOLLOW_116_in_foreach_stmt886) \n                if self._state.backtracking == 0:\n                    stream_116.add(string_literal98)\n\n\n                char_literal99 = self.match(self.input, 75, self.FOLLOW_75_in_foreach_stmt888) \n                if self._state.backtracking == 0:\n                    stream_75.add(char_literal99)\n\n\n                self._state.following.append(self.FOLLOW_expr_in_foreach_stmt890)\n                expr100 = self.expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_expr.add(expr100.tree)\n\n\n                string_literal101 = self.match(self.input, 104, self.FOLLOW_104_in_foreach_stmt892) \n                if self._state.backtracking == 0:\n                    stream_104.add(string_literal101)\n\n\n                self._state.following.append(self.FOLLOW_each_in_foreach_stmt894)\n                each102 = self.each()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_each.add(each102.tree)\n\n\n                char_literal103 = self.match(self.input, 76, self.FOLLOW_76_in_foreach_stmt896) \n                if self._state.backtracking == 0:\n                    stream_76.add(char_literal103)\n\n\n                self._state.following.append(self.FOLLOW_block_in_foreach_stmt898)\n                block104 = self.block()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_block.add(block104.tree)\n\n\n                # AST Rewrite\n                # elements: expr, block, each\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 151:3: -> ^( FOREACH expr each block )\n                    # Expr.g:151:6: ^( FOREACH expr each block )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(FOREACH, \"FOREACH\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n                    self._adaptor.addChild(root_1, stream_each.nextTree())\n\n                    self._adaptor.addChild(root_1, stream_block.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"foreach_stmt\"\n\n\n    class each_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.each_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"each\"\n    # Expr.g:153:1: each : ( each_val -> ^( EACH each_val ) | ID '=>' each_val -> ^( EACH ID each_val ) );\n    def each(self, ):\n        retval = self.each_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        ID106 = None\n        string_literal107 = None\n        each_val105 = None\n        each_val108 = None\n\n        ID106_tree = None\n        string_literal107_tree = None\n        stream_97 = RewriteRuleTokenStream(self._adaptor, \"token 97\")\n        stream_ID = RewriteRuleTokenStream(self._adaptor, \"token ID\")\n        stream_each_val = RewriteRuleSubtreeStream(self._adaptor, \"rule each_val\")\n        try:\n            try:\n                # Expr.g:154:2: ( each_val -> ^( EACH each_val ) | ID '=>' each_val -> ^( EACH ID each_val ) )\n                alt18 = 2\n                LA18_0 = self.input.LA(1)\n\n                if (LA18_0 == ID) :\n                    LA18_1 = self.input.LA(2)\n\n                    if (LA18_1 == 97) :\n                        alt18 = 2\n                    elif (LA18_1 == 76 or LA18_1 == 82) :\n                        alt18 = 1\n                    else:\n                        if self._state.backtracking > 0:\n                            raise BacktrackingFailed\n\n\n                        nvae = NoViableAltException(\"\", 18, 1, self.input)\n\n                        raise nvae\n\n\n                else:\n                    if self._state.backtracking > 0:\n                        raise BacktrackingFailed\n\n\n                    nvae = NoViableAltException(\"\", 18, 0, self.input)\n\n                    raise nvae\n\n\n                if alt18 == 1:\n                    # Expr.g:154:4: each_val\n                    pass \n                    self._state.following.append(self.FOLLOW_each_val_in_each922)\n                    each_val105 = self.each_val()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_each_val.add(each_val105.tree)\n\n\n                    # AST Rewrite\n                    # elements: each_val\n                    # token labels: \n                    # rule labels: retval\n                    # token list labels: \n                    # rule list labels: \n                    # wildcard labels: \n                    if self._state.backtracking == 0:\n                        retval.tree = root_0\n                        if retval is not None:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                        else:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                        root_0 = self._adaptor.nil()\n                        # 155:3: -> ^( EACH each_val )\n                        # Expr.g:155:6: ^( EACH each_val )\n                        root_1 = self._adaptor.nil()\n                        root_1 = self._adaptor.becomeRoot(\n                        self._adaptor.createFromType(EACH, \"EACH\")\n                        , root_1)\n\n                        self._adaptor.addChild(root_1, stream_each_val.nextTree())\n\n                        self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                        retval.tree = root_0\n\n\n\n\n                elif alt18 == 2:\n                    # Expr.g:156:4: ID '=>' each_val\n                    pass \n                    ID106 = self.match(self.input, ID, self.FOLLOW_ID_in_each937) \n                    if self._state.backtracking == 0:\n                        stream_ID.add(ID106)\n\n\n                    string_literal107 = self.match(self.input, 97, self.FOLLOW_97_in_each939) \n                    if self._state.backtracking == 0:\n                        stream_97.add(string_literal107)\n\n\n                    self._state.following.append(self.FOLLOW_each_val_in_each941)\n                    each_val108 = self.each_val()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_each_val.add(each_val108.tree)\n\n\n                    # AST Rewrite\n                    # elements: each_val, ID\n                    # token labels: \n                    # rule labels: retval\n                    # token list labels: \n                    # rule list labels: \n                    # wildcard labels: \n                    if self._state.backtracking == 0:\n                        retval.tree = root_0\n                        if retval is not None:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                        else:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                        root_0 = self._adaptor.nil()\n                        # 157:3: -> ^( EACH ID each_val )\n                        # Expr.g:157:6: ^( EACH ID each_val )\n                        root_1 = self._adaptor.nil()\n                        root_1 = self._adaptor.becomeRoot(\n                        self._adaptor.createFromType(EACH, \"EACH\")\n                        , root_1)\n\n                        self._adaptor.addChild(root_1, \n                        stream_ID.nextNode()\n                        )\n\n                        self._adaptor.addChild(root_1, stream_each_val.nextTree())\n\n                        self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                        retval.tree = root_0\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"each\"\n\n\n    class each_val_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.each_val_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"each_val\"\n    # Expr.g:159:1: each_val : ID ( ',' ID )* -> ^( EACH_VAL ( ID )+ ) ;\n    def each_val(self, ):\n        retval = self.each_val_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        ID109 = None\n        char_literal110 = None\n        ID111 = None\n\n        ID109_tree = None\n        char_literal110_tree = None\n        ID111_tree = None\n        stream_82 = RewriteRuleTokenStream(self._adaptor, \"token 82\")\n        stream_ID = RewriteRuleTokenStream(self._adaptor, \"token ID\")\n\n        try:\n            try:\n                # Expr.g:160:2: ( ID ( ',' ID )* -> ^( EACH_VAL ( ID )+ ) )\n                # Expr.g:160:4: ID ( ',' ID )*\n                pass \n                ID109 = self.match(self.input, ID, self.FOLLOW_ID_in_each_val963) \n                if self._state.backtracking == 0:\n                    stream_ID.add(ID109)\n\n\n                # Expr.g:160:7: ( ',' ID )*\n                while True: #loop19\n                    alt19 = 2\n                    LA19_0 = self.input.LA(1)\n\n                    if (LA19_0 == 82) :\n                        alt19 = 1\n\n\n                    if alt19 == 1:\n                        # Expr.g:160:8: ',' ID\n                        pass \n                        char_literal110 = self.match(self.input, 82, self.FOLLOW_82_in_each_val966) \n                        if self._state.backtracking == 0:\n                            stream_82.add(char_literal110)\n\n\n                        ID111 = self.match(self.input, ID, self.FOLLOW_ID_in_each_val968) \n                        if self._state.backtracking == 0:\n                            stream_ID.add(ID111)\n\n\n\n                    else:\n                        break #loop19\n\n\n                # AST Rewrite\n                # elements: ID\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 161:3: -> ^( EACH_VAL ( ID )+ )\n                    # Expr.g:161:6: ^( EACH_VAL ( ID )+ )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(EACH_VAL, \"EACH_VAL\")\n                    , root_1)\n\n                    # Expr.g:161:17: ( ID )+\n                    if not (stream_ID.hasNext()):\n                        raise RewriteEarlyExitException()\n\n                    while stream_ID.hasNext():\n                        self._adaptor.addChild(root_1, \n                        stream_ID.nextNode()\n                        )\n\n\n                    stream_ID.reset()\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"each_val\"\n\n\n    class throw_stmt_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.throw_stmt_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"throw_stmt\"\n    # Expr.g:165:1: throw_stmt : 'throw' expr ';' -> ^( THROW expr ) ;\n    def throw_stmt(self, ):\n        retval = self.throw_stmt_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal112 = None\n        char_literal114 = None\n        expr113 = None\n\n        string_literal112_tree = None\n        char_literal114_tree = None\n        stream_92 = RewriteRuleTokenStream(self._adaptor, \"token 92\")\n        stream_129 = RewriteRuleTokenStream(self._adaptor, \"token 129\")\n        stream_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule expr\")\n        try:\n            try:\n                # Expr.g:166:2: ( 'throw' expr ';' -> ^( THROW expr ) )\n                # Expr.g:166:4: 'throw' expr ';'\n                pass \n                string_literal112 = self.match(self.input, 129, self.FOLLOW_129_in_throw_stmt993) \n                if self._state.backtracking == 0:\n                    stream_129.add(string_literal112)\n\n\n                self._state.following.append(self.FOLLOW_expr_in_throw_stmt995)\n                expr113 = self.expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_expr.add(expr113.tree)\n\n\n                char_literal114 = self.match(self.input, 92, self.FOLLOW_92_in_throw_stmt997) \n                if self._state.backtracking == 0:\n                    stream_92.add(char_literal114)\n\n\n                # AST Rewrite\n                # elements: expr\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 167:3: -> ^( THROW expr )\n                    # Expr.g:167:6: ^( THROW expr )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(THROW, \"THROW\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"throw_stmt\"\n\n\n    class try_stmt_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.try_stmt_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"try_stmt\"\n    # Expr.g:169:1: try_stmt : 'try' block ( catch_clause )+ ( finally_clause )? -> ^( TRY block ( catch_clause )+ ( finally_clause )? ) ;\n    def try_stmt(self, ):\n        retval = self.try_stmt_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal115 = None\n        block116 = None\n        catch_clause117 = None\n        finally_clause118 = None\n\n        string_literal115_tree = None\n        stream_130 = RewriteRuleTokenStream(self._adaptor, \"token 130\")\n        stream_catch_clause = RewriteRuleSubtreeStream(self._adaptor, \"rule catch_clause\")\n        stream_block = RewriteRuleSubtreeStream(self._adaptor, \"rule block\")\n        stream_finally_clause = RewriteRuleSubtreeStream(self._adaptor, \"rule finally_clause\")\n        try:\n            try:\n                # Expr.g:170:2: ( 'try' block ( catch_clause )+ ( finally_clause )? -> ^( TRY block ( catch_clause )+ ( finally_clause )? ) )\n                # Expr.g:170:4: 'try' block ( catch_clause )+ ( finally_clause )?\n                pass \n                string_literal115 = self.match(self.input, 130, self.FOLLOW_130_in_try_stmt1017) \n                if self._state.backtracking == 0:\n                    stream_130.add(string_literal115)\n\n\n                self._state.following.append(self.FOLLOW_block_in_try_stmt1019)\n                block116 = self.block()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_block.add(block116.tree)\n\n\n                # Expr.g:170:16: ( catch_clause )+\n                cnt20 = 0\n                while True: #loop20\n                    alt20 = 2\n                    LA20_0 = self.input.LA(1)\n\n                    if (LA20_0 == 107) :\n                        alt20 = 1\n\n\n                    if alt20 == 1:\n                        # Expr.g:170:16: catch_clause\n                        pass \n                        self._state.following.append(self.FOLLOW_catch_clause_in_try_stmt1021)\n                        catch_clause117 = self.catch_clause()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_catch_clause.add(catch_clause117.tree)\n\n\n\n                    else:\n                        if cnt20 >= 1:\n                            break #loop20\n\n                        if self._state.backtracking > 0:\n                            raise BacktrackingFailed\n\n\n                        eee = EarlyExitException(20, self.input)\n                        raise eee\n\n                    cnt20 += 1\n\n\n                # Expr.g:170:30: ( finally_clause )?\n                alt21 = 2\n                LA21_0 = self.input.LA(1)\n\n                if (LA21_0 == 114) :\n                    alt21 = 1\n                if alt21 == 1:\n                    # Expr.g:170:30: finally_clause\n                    pass \n                    self._state.following.append(self.FOLLOW_finally_clause_in_try_stmt1024)\n                    finally_clause118 = self.finally_clause()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_finally_clause.add(finally_clause118.tree)\n\n\n\n\n\n                # AST Rewrite\n                # elements: finally_clause, catch_clause, block\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 171:3: -> ^( TRY block ( catch_clause )+ ( finally_clause )? )\n                    # Expr.g:171:6: ^( TRY block ( catch_clause )+ ( finally_clause )? )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(TRY, \"TRY\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_block.nextTree())\n\n                    # Expr.g:171:18: ( catch_clause )+\n                    if not (stream_catch_clause.hasNext()):\n                        raise RewriteEarlyExitException()\n\n                    while stream_catch_clause.hasNext():\n                        self._adaptor.addChild(root_1, stream_catch_clause.nextTree())\n\n\n                    stream_catch_clause.reset()\n\n                    # Expr.g:171:32: ( finally_clause )?\n                    if stream_finally_clause.hasNext():\n                        self._adaptor.addChild(root_1, stream_finally_clause.nextTree())\n\n\n                    stream_finally_clause.reset();\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"try_stmt\"\n\n\n    class catch_clause_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.catch_clause_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"catch_clause\"\n    # Expr.g:173:1: catch_clause : 'catch' '(' module ( ID )? ')' block -> ^( CATCH module ( ID )? block ) ;\n    def catch_clause(self, ):\n        retval = self.catch_clause_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal119 = None\n        char_literal120 = None\n        ID122 = None\n        char_literal123 = None\n        module121 = None\n        block124 = None\n\n        string_literal119_tree = None\n        char_literal120_tree = None\n        ID122_tree = None\n        char_literal123_tree = None\n        stream_107 = RewriteRuleTokenStream(self._adaptor, \"token 107\")\n        stream_ID = RewriteRuleTokenStream(self._adaptor, \"token ID\")\n        stream_75 = RewriteRuleTokenStream(self._adaptor, \"token 75\")\n        stream_76 = RewriteRuleTokenStream(self._adaptor, \"token 76\")\n        stream_module = RewriteRuleSubtreeStream(self._adaptor, \"rule module\")\n        stream_block = RewriteRuleSubtreeStream(self._adaptor, \"rule block\")\n        try:\n            try:\n                # Expr.g:174:2: ( 'catch' '(' module ( ID )? ')' block -> ^( CATCH module ( ID )? block ) )\n                # Expr.g:174:4: 'catch' '(' module ( ID )? ')' block\n                pass \n                string_literal119 = self.match(self.input, 107, self.FOLLOW_107_in_catch_clause1051) \n                if self._state.backtracking == 0:\n                    stream_107.add(string_literal119)\n\n\n                char_literal120 = self.match(self.input, 75, self.FOLLOW_75_in_catch_clause1053) \n                if self._state.backtracking == 0:\n                    stream_75.add(char_literal120)\n\n\n                self._state.following.append(self.FOLLOW_module_in_catch_clause1055)\n                module121 = self.module()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_module.add(module121.tree)\n\n\n                # Expr.g:174:23: ( ID )?\n                alt22 = 2\n                LA22_0 = self.input.LA(1)\n\n                if (LA22_0 == ID) :\n                    alt22 = 1\n                if alt22 == 1:\n                    # Expr.g:174:23: ID\n                    pass \n                    ID122 = self.match(self.input, ID, self.FOLLOW_ID_in_catch_clause1057) \n                    if self._state.backtracking == 0:\n                        stream_ID.add(ID122)\n\n\n\n\n\n                char_literal123 = self.match(self.input, 76, self.FOLLOW_76_in_catch_clause1060) \n                if self._state.backtracking == 0:\n                    stream_76.add(char_literal123)\n\n\n                self._state.following.append(self.FOLLOW_block_in_catch_clause1062)\n                block124 = self.block()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_block.add(block124.tree)\n\n\n                # AST Rewrite\n                # elements: block, ID, module\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 175:3: -> ^( CATCH module ( ID )? block )\n                    # Expr.g:175:6: ^( CATCH module ( ID )? block )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(CATCH, \"CATCH\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_module.nextTree())\n\n                    # Expr.g:175:21: ( ID )?\n                    if stream_ID.hasNext():\n                        self._adaptor.addChild(root_1, \n                        stream_ID.nextNode()\n                        )\n\n\n                    stream_ID.reset();\n\n                    self._adaptor.addChild(root_1, stream_block.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"catch_clause\"\n\n\n    class finally_clause_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.finally_clause_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"finally_clause\"\n    # Expr.g:177:1: finally_clause : 'finally' block -> ^( FINALLY block ) ;\n    def finally_clause(self, ):\n        retval = self.finally_clause_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal125 = None\n        block126 = None\n\n        string_literal125_tree = None\n        stream_114 = RewriteRuleTokenStream(self._adaptor, \"token 114\")\n        stream_block = RewriteRuleSubtreeStream(self._adaptor, \"rule block\")\n        try:\n            try:\n                # Expr.g:178:2: ( 'finally' block -> ^( FINALLY block ) )\n                # Expr.g:178:4: 'finally' block\n                pass \n                string_literal125 = self.match(self.input, 114, self.FOLLOW_114_in_finally_clause1087) \n                if self._state.backtracking == 0:\n                    stream_114.add(string_literal125)\n\n\n                self._state.following.append(self.FOLLOW_block_in_finally_clause1089)\n                block126 = self.block()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_block.add(block126.tree)\n\n\n                # AST Rewrite\n                # elements: block\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 179:3: -> ^( FINALLY block )\n                    # Expr.g:179:6: ^( FINALLY block )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(FINALLY, \"FINALLY\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_block.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"finally_clause\"\n\n\n    class func_decl_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.func_decl_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"func_decl\"\n    # Expr.g:183:1: func_decl : 'function' ID params block -> ^( FUNCTION ID params block ) ;\n    def func_decl(self, ):\n        retval = self.func_decl_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal127 = None\n        ID128 = None\n        params129 = None\n        block130 = None\n\n        string_literal127_tree = None\n        ID128_tree = None\n        stream_117 = RewriteRuleTokenStream(self._adaptor, \"token 117\")\n        stream_ID = RewriteRuleTokenStream(self._adaptor, \"token ID\")\n        stream_block = RewriteRuleSubtreeStream(self._adaptor, \"rule block\")\n        stream_params = RewriteRuleSubtreeStream(self._adaptor, \"rule params\")\n        try:\n            try:\n                # Expr.g:184:2: ( 'function' ID params block -> ^( FUNCTION ID params block ) )\n                # Expr.g:184:4: 'function' ID params block\n                pass \n                string_literal127 = self.match(self.input, 117, self.FOLLOW_117_in_func_decl1111) \n                if self._state.backtracking == 0:\n                    stream_117.add(string_literal127)\n\n\n                ID128 = self.match(self.input, ID, self.FOLLOW_ID_in_func_decl1113) \n                if self._state.backtracking == 0:\n                    stream_ID.add(ID128)\n\n\n                self._state.following.append(self.FOLLOW_params_in_func_decl1115)\n                params129 = self.params()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_params.add(params129.tree)\n\n\n                self._state.following.append(self.FOLLOW_block_in_func_decl1117)\n                block130 = self.block()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_block.add(block130.tree)\n\n\n                # AST Rewrite\n                # elements: block, ID, params\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 185:3: -> ^( FUNCTION ID params block )\n                    # Expr.g:185:6: ^( FUNCTION ID params block )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(FUNCTION, \"FUNCTION\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, \n                    stream_ID.nextNode()\n                    )\n\n                    self._adaptor.addChild(root_1, stream_params.nextTree())\n\n                    self._adaptor.addChild(root_1, stream_block.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"func_decl\"\n\n\n    class params_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.params_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"params\"\n    # Expr.g:187:1: params : '(' ( param_decl )? ( ',' param_decl )* ')' -> ^( PARAMS ( param_decl )* ) ;\n    def params(self, ):\n        retval = self.params_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal131 = None\n        char_literal133 = None\n        char_literal135 = None\n        param_decl132 = None\n        param_decl134 = None\n\n        char_literal131_tree = None\n        char_literal133_tree = None\n        char_literal135_tree = None\n        stream_82 = RewriteRuleTokenStream(self._adaptor, \"token 82\")\n        stream_75 = RewriteRuleTokenStream(self._adaptor, \"token 75\")\n        stream_76 = RewriteRuleTokenStream(self._adaptor, \"token 76\")\n        stream_param_decl = RewriteRuleSubtreeStream(self._adaptor, \"rule param_decl\")\n        try:\n            try:\n                # Expr.g:188:2: ( '(' ( param_decl )? ( ',' param_decl )* ')' -> ^( PARAMS ( param_decl )* ) )\n                # Expr.g:188:4: '(' ( param_decl )? ( ',' param_decl )* ')'\n                pass \n                char_literal131 = self.match(self.input, 75, self.FOLLOW_75_in_params1141) \n                if self._state.backtracking == 0:\n                    stream_75.add(char_literal131)\n\n\n                # Expr.g:188:8: ( param_decl )?\n                alt23 = 2\n                LA23_0 = self.input.LA(1)\n\n                if (LA23_0 == ID) :\n                    alt23 = 1\n                if alt23 == 1:\n                    # Expr.g:188:8: param_decl\n                    pass \n                    self._state.following.append(self.FOLLOW_param_decl_in_params1143)\n                    param_decl132 = self.param_decl()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_param_decl.add(param_decl132.tree)\n\n\n\n\n\n                # Expr.g:188:20: ( ',' param_decl )*\n                while True: #loop24\n                    alt24 = 2\n                    LA24_0 = self.input.LA(1)\n\n                    if (LA24_0 == 82) :\n                        alt24 = 1\n\n\n                    if alt24 == 1:\n                        # Expr.g:188:21: ',' param_decl\n                        pass \n                        char_literal133 = self.match(self.input, 82, self.FOLLOW_82_in_params1147) \n                        if self._state.backtracking == 0:\n                            stream_82.add(char_literal133)\n\n\n                        self._state.following.append(self.FOLLOW_param_decl_in_params1149)\n                        param_decl134 = self.param_decl()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_param_decl.add(param_decl134.tree)\n\n\n\n                    else:\n                        break #loop24\n\n\n                char_literal135 = self.match(self.input, 76, self.FOLLOW_76_in_params1153) \n                if self._state.backtracking == 0:\n                    stream_76.add(char_literal135)\n\n\n                # AST Rewrite\n                # elements: param_decl\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 189:3: -> ^( PARAMS ( param_decl )* )\n                    # Expr.g:189:6: ^( PARAMS ( param_decl )* )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(PARAMS, \"PARAMS\")\n                    , root_1)\n\n                    # Expr.g:189:15: ( param_decl )*\n                    while stream_param_decl.hasNext():\n                        self._adaptor.addChild(root_1, stream_param_decl.nextTree())\n\n\n                    stream_param_decl.reset();\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"params\"\n\n\n    class param_decl_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.param_decl_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"param_decl\"\n    # Expr.g:191:1: param_decl : ID ( '=' atom )? ;\n    def param_decl(self, ):\n        retval = self.param_decl_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        ID136 = None\n        char_literal137 = None\n        atom138 = None\n\n        ID136_tree = None\n        char_literal137_tree = None\n\n        try:\n            try:\n                # Expr.g:192:2: ( ID ( '=' atom )? )\n                # Expr.g:192:4: ID ( '=' atom )?\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                ID136 = self.match(self.input, ID, self.FOLLOW_ID_in_param_decl1174)\n                if self._state.backtracking == 0:\n                    ID136_tree = self._adaptor.createWithPayload(ID136)\n                    self._adaptor.addChild(root_0, ID136_tree)\n\n\n\n                # Expr.g:192:7: ( '=' atom )?\n                alt25 = 2\n                LA25_0 = self.input.LA(1)\n\n                if (LA25_0 == 95) :\n                    alt25 = 1\n                if alt25 == 1:\n                    # Expr.g:192:8: '=' atom\n                    pass \n                    char_literal137 = self.match(self.input, 95, self.FOLLOW_95_in_param_decl1177)\n                    if self._state.backtracking == 0:\n                        char_literal137_tree = self._adaptor.createWithPayload(char_literal137)\n                        self._adaptor.addChild(root_0, char_literal137_tree)\n\n\n\n                    self._state.following.append(self.FOLLOW_atom_in_param_decl1179)\n                    atom138 = self.atom()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, atom138.tree)\n\n\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"param_decl\"\n\n\n    class class_decl_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.class_decl_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"class_decl\"\n    # Expr.g:195:1: class_decl : 'class' ID ( 'extends' ID )? '{' ( class_element )* '}' -> ^( CLASS ID ( ID )? ( class_element )* ) ;\n    def class_decl(self, ):\n        retval = self.class_decl_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal139 = None\n        ID140 = None\n        string_literal141 = None\n        ID142 = None\n        char_literal143 = None\n        char_literal145 = None\n        class_element144 = None\n\n        string_literal139_tree = None\n        ID140_tree = None\n        string_literal141_tree = None\n        ID142_tree = None\n        char_literal143_tree = None\n        char_literal145_tree = None\n        stream_132 = RewriteRuleTokenStream(self._adaptor, \"token 132\")\n        stream_113 = RewriteRuleTokenStream(self._adaptor, \"token 113\")\n        stream_108 = RewriteRuleTokenStream(self._adaptor, \"token 108\")\n        stream_136 = RewriteRuleTokenStream(self._adaptor, \"token 136\")\n        stream_ID = RewriteRuleTokenStream(self._adaptor, \"token ID\")\n        stream_class_element = RewriteRuleSubtreeStream(self._adaptor, \"rule class_element\")\n        try:\n            try:\n                # Expr.g:196:2: ( 'class' ID ( 'extends' ID )? '{' ( class_element )* '}' -> ^( CLASS ID ( ID )? ( class_element )* ) )\n                # Expr.g:196:4: 'class' ID ( 'extends' ID )? '{' ( class_element )* '}'\n                pass \n                string_literal139 = self.match(self.input, 108, self.FOLLOW_108_in_class_decl1192) \n                if self._state.backtracking == 0:\n                    stream_108.add(string_literal139)\n\n\n                ID140 = self.match(self.input, ID, self.FOLLOW_ID_in_class_decl1194) \n                if self._state.backtracking == 0:\n                    stream_ID.add(ID140)\n\n\n                # Expr.g:196:15: ( 'extends' ID )?\n                alt26 = 2\n                LA26_0 = self.input.LA(1)\n\n                if (LA26_0 == 113) :\n                    alt26 = 1\n                if alt26 == 1:\n                    # Expr.g:196:16: 'extends' ID\n                    pass \n                    string_literal141 = self.match(self.input, 113, self.FOLLOW_113_in_class_decl1197) \n                    if self._state.backtracking == 0:\n                        stream_113.add(string_literal141)\n\n\n                    ID142 = self.match(self.input, ID, self.FOLLOW_ID_in_class_decl1199) \n                    if self._state.backtracking == 0:\n                        stream_ID.add(ID142)\n\n\n\n\n\n                char_literal143 = self.match(self.input, 132, self.FOLLOW_132_in_class_decl1205) \n                if self._state.backtracking == 0:\n                    stream_132.add(char_literal143)\n\n\n                # Expr.g:197:7: ( class_element )*\n                while True: #loop27\n                    alt27 = 2\n                    LA27_0 = self.input.LA(1)\n\n                    if (LA27_0 == 117 or LA27_0 == 124) :\n                        alt27 = 1\n\n\n                    if alt27 == 1:\n                        # Expr.g:197:7: class_element\n                        pass \n                        self._state.following.append(self.FOLLOW_class_element_in_class_decl1207)\n                        class_element144 = self.class_element()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_class_element.add(class_element144.tree)\n\n\n\n                    else:\n                        break #loop27\n\n\n                char_literal145 = self.match(self.input, 136, self.FOLLOW_136_in_class_decl1210) \n                if self._state.backtracking == 0:\n                    stream_136.add(char_literal145)\n\n\n                # AST Rewrite\n                # elements: ID, ID, class_element\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 198:3: -> ^( CLASS ID ( ID )? ( class_element )* )\n                    # Expr.g:198:6: ^( CLASS ID ( ID )? ( class_element )* )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(CLASS, \"CLASS\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, \n                    stream_ID.nextNode()\n                    )\n\n                    # Expr.g:198:17: ( ID )?\n                    if stream_ID.hasNext():\n                        self._adaptor.addChild(root_1, \n                        stream_ID.nextNode()\n                        )\n\n\n                    stream_ID.reset();\n\n                    # Expr.g:198:21: ( class_element )*\n                    while stream_class_element.hasNext():\n                        self._adaptor.addChild(root_1, stream_class_element.nextTree())\n\n\n                    stream_class_element.reset();\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"class_decl\"\n\n\n    class class_element_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.class_element_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"class_element\"\n    # Expr.g:200:1: class_element : ( var_def | constructor | func_decl );\n    def class_element(self, ):\n        retval = self.class_element_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        var_def146 = None\n        constructor147 = None\n        func_decl148 = None\n\n\n        try:\n            try:\n                # Expr.g:201:2: ( var_def | constructor | func_decl )\n                alt28 = 3\n                LA28_0 = self.input.LA(1)\n\n                if (LA28_0 == 124) :\n                    alt28 = 1\n                elif (LA28_0 == 117) :\n                    LA28_2 = self.input.LA(2)\n\n                    if (LA28_2 == 120) :\n                        alt28 = 2\n                    elif (LA28_2 == ID) :\n                        alt28 = 3\n                    else:\n                        if self._state.backtracking > 0:\n                            raise BacktrackingFailed\n\n\n                        nvae = NoViableAltException(\"\", 28, 2, self.input)\n\n                        raise nvae\n\n\n                else:\n                    if self._state.backtracking > 0:\n                        raise BacktrackingFailed\n\n\n                    nvae = NoViableAltException(\"\", 28, 0, self.input)\n\n                    raise nvae\n\n\n                if alt28 == 1:\n                    # Expr.g:201:4: var_def\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_var_def_in_class_element1236)\n                    var_def146 = self.var_def()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, var_def146.tree)\n\n\n\n                elif alt28 == 2:\n                    # Expr.g:201:14: constructor\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_constructor_in_class_element1240)\n                    constructor147 = self.constructor()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, constructor147.tree)\n\n\n\n                elif alt28 == 3:\n                    # Expr.g:201:28: func_decl\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_func_decl_in_class_element1244)\n                    func_decl148 = self.func_decl()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, func_decl148.tree)\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"class_element\"\n\n\n    class var_def_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.var_def_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"var_def\"\n    # Expr.g:203:1: var_def : ( 'public' ID ( '=' expr )? ';' -> ^( VAR ID ( expr )? ) | 'public' 'static' ID ( '=' expr )? ';' -> ^( VAR 'static' ID ( expr )? ) );\n    def var_def(self, ):\n        retval = self.var_def_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal149 = None\n        ID150 = None\n        char_literal151 = None\n        char_literal153 = None\n        string_literal154 = None\n        string_literal155 = None\n        ID156 = None\n        char_literal157 = None\n        char_literal159 = None\n        expr152 = None\n        expr158 = None\n\n        string_literal149_tree = None\n        ID150_tree = None\n        char_literal151_tree = None\n        char_literal153_tree = None\n        string_literal154_tree = None\n        string_literal155_tree = None\n        ID156_tree = None\n        char_literal157_tree = None\n        char_literal159_tree = None\n        stream_127 = RewriteRuleTokenStream(self._adaptor, \"token 127\")\n        stream_95 = RewriteRuleTokenStream(self._adaptor, \"token 95\")\n        stream_92 = RewriteRuleTokenStream(self._adaptor, \"token 92\")\n        stream_124 = RewriteRuleTokenStream(self._adaptor, \"token 124\")\n        stream_ID = RewriteRuleTokenStream(self._adaptor, \"token ID\")\n        stream_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule expr\")\n        try:\n            try:\n                # Expr.g:204:2: ( 'public' ID ( '=' expr )? ';' -> ^( VAR ID ( expr )? ) | 'public' 'static' ID ( '=' expr )? ';' -> ^( VAR 'static' ID ( expr )? ) )\n                alt31 = 2\n                LA31_0 = self.input.LA(1)\n\n                if (LA31_0 == 124) :\n                    LA31_1 = self.input.LA(2)\n\n                    if (LA31_1 == ID) :\n                        alt31 = 1\n                    elif (LA31_1 == 127) :\n                        alt31 = 2\n                    else:\n                        if self._state.backtracking > 0:\n                            raise BacktrackingFailed\n\n\n                        nvae = NoViableAltException(\"\", 31, 1, self.input)\n\n                        raise nvae\n\n\n                else:\n                    if self._state.backtracking > 0:\n                        raise BacktrackingFailed\n\n\n                    nvae = NoViableAltException(\"\", 31, 0, self.input)\n\n                    raise nvae\n\n\n                if alt31 == 1:\n                    # Expr.g:204:4: 'public' ID ( '=' expr )? ';'\n                    pass \n                    string_literal149 = self.match(self.input, 124, self.FOLLOW_124_in_var_def1254) \n                    if self._state.backtracking == 0:\n                        stream_124.add(string_literal149)\n\n\n                    ID150 = self.match(self.input, ID, self.FOLLOW_ID_in_var_def1256) \n                    if self._state.backtracking == 0:\n                        stream_ID.add(ID150)\n\n\n                    # Expr.g:204:16: ( '=' expr )?\n                    alt29 = 2\n                    LA29_0 = self.input.LA(1)\n\n                    if (LA29_0 == 95) :\n                        alt29 = 1\n                    if alt29 == 1:\n                        # Expr.g:204:17: '=' expr\n                        pass \n                        char_literal151 = self.match(self.input, 95, self.FOLLOW_95_in_var_def1259) \n                        if self._state.backtracking == 0:\n                            stream_95.add(char_literal151)\n\n\n                        self._state.following.append(self.FOLLOW_expr_in_var_def1261)\n                        expr152 = self.expr()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_expr.add(expr152.tree)\n\n\n\n\n\n                    char_literal153 = self.match(self.input, 92, self.FOLLOW_92_in_var_def1265) \n                    if self._state.backtracking == 0:\n                        stream_92.add(char_literal153)\n\n\n                    # AST Rewrite\n                    # elements: expr, ID\n                    # token labels: \n                    # rule labels: retval\n                    # token list labels: \n                    # rule list labels: \n                    # wildcard labels: \n                    if self._state.backtracking == 0:\n                        retval.tree = root_0\n                        if retval is not None:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                        else:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                        root_0 = self._adaptor.nil()\n                        # 205:3: -> ^( VAR ID ( expr )? )\n                        # Expr.g:205:6: ^( VAR ID ( expr )? )\n                        root_1 = self._adaptor.nil()\n                        root_1 = self._adaptor.becomeRoot(\n                        self._adaptor.createFromType(VAR, \"VAR\")\n                        , root_1)\n\n                        self._adaptor.addChild(root_1, \n                        stream_ID.nextNode()\n                        )\n\n                        # Expr.g:205:15: ( expr )?\n                        if stream_expr.hasNext():\n                            self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n\n                        stream_expr.reset();\n\n                        self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                        retval.tree = root_0\n\n\n\n\n                elif alt31 == 2:\n                    # Expr.g:206:4: 'public' 'static' ID ( '=' expr )? ';'\n                    pass \n                    string_literal154 = self.match(self.input, 124, self.FOLLOW_124_in_var_def1283) \n                    if self._state.backtracking == 0:\n                        stream_124.add(string_literal154)\n\n\n                    string_literal155 = self.match(self.input, 127, self.FOLLOW_127_in_var_def1285) \n                    if self._state.backtracking == 0:\n                        stream_127.add(string_literal155)\n\n\n                    ID156 = self.match(self.input, ID, self.FOLLOW_ID_in_var_def1287) \n                    if self._state.backtracking == 0:\n                        stream_ID.add(ID156)\n\n\n                    # Expr.g:206:25: ( '=' expr )?\n                    alt30 = 2\n                    LA30_0 = self.input.LA(1)\n\n                    if (LA30_0 == 95) :\n                        alt30 = 1\n                    if alt30 == 1:\n                        # Expr.g:206:26: '=' expr\n                        pass \n                        char_literal157 = self.match(self.input, 95, self.FOLLOW_95_in_var_def1290) \n                        if self._state.backtracking == 0:\n                            stream_95.add(char_literal157)\n\n\n                        self._state.following.append(self.FOLLOW_expr_in_var_def1292)\n                        expr158 = self.expr()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_expr.add(expr158.tree)\n\n\n\n\n\n                    char_literal159 = self.match(self.input, 92, self.FOLLOW_92_in_var_def1296) \n                    if self._state.backtracking == 0:\n                        stream_92.add(char_literal159)\n\n\n                    # AST Rewrite\n                    # elements: expr, ID, 127\n                    # token labels: \n                    # rule labels: retval\n                    # token list labels: \n                    # rule list labels: \n                    # wildcard labels: \n                    if self._state.backtracking == 0:\n                        retval.tree = root_0\n                        if retval is not None:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                        else:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                        root_0 = self._adaptor.nil()\n                        # 207:3: -> ^( VAR 'static' ID ( expr )? )\n                        # Expr.g:207:6: ^( VAR 'static' ID ( expr )? )\n                        root_1 = self._adaptor.nil()\n                        root_1 = self._adaptor.becomeRoot(\n                        self._adaptor.createFromType(VAR, \"VAR\")\n                        , root_1)\n\n                        self._adaptor.addChild(root_1, \n                        stream_127.nextNode()\n                        )\n\n                        self._adaptor.addChild(root_1, \n                        stream_ID.nextNode()\n                        )\n\n                        # Expr.g:207:24: ( expr )?\n                        if stream_expr.hasNext():\n                            self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n\n                        stream_expr.reset();\n\n                        self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                        retval.tree = root_0\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"var_def\"\n\n\n    class constructor_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.constructor_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"constructor\"\n    # Expr.g:209:1: constructor : 'function' 'init' params block -> ^( CONSTRUCTOR params block ) ;\n    def constructor(self, ):\n        retval = self.constructor_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal160 = None\n        string_literal161 = None\n        params162 = None\n        block163 = None\n\n        string_literal160_tree = None\n        string_literal161_tree = None\n        stream_117 = RewriteRuleTokenStream(self._adaptor, \"token 117\")\n        stream_120 = RewriteRuleTokenStream(self._adaptor, \"token 120\")\n        stream_block = RewriteRuleSubtreeStream(self._adaptor, \"rule block\")\n        stream_params = RewriteRuleSubtreeStream(self._adaptor, \"rule params\")\n        try:\n            try:\n                # Expr.g:210:2: ( 'function' 'init' params block -> ^( CONSTRUCTOR params block ) )\n                # Expr.g:210:4: 'function' 'init' params block\n                pass \n                string_literal160 = self.match(self.input, 117, self.FOLLOW_117_in_constructor1321) \n                if self._state.backtracking == 0:\n                    stream_117.add(string_literal160)\n\n\n                string_literal161 = self.match(self.input, 120, self.FOLLOW_120_in_constructor1323) \n                if self._state.backtracking == 0:\n                    stream_120.add(string_literal161)\n\n\n                self._state.following.append(self.FOLLOW_params_in_constructor1325)\n                params162 = self.params()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_params.add(params162.tree)\n\n\n                self._state.following.append(self.FOLLOW_block_in_constructor1327)\n                block163 = self.block()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_block.add(block163.tree)\n\n\n                # AST Rewrite\n                # elements: params, block\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 211:3: -> ^( CONSTRUCTOR params block )\n                    # Expr.g:211:6: ^( CONSTRUCTOR params block )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(CONSTRUCTOR, \"CONSTRUCTOR\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_params.nextTree())\n\n                    self._adaptor.addChild(root_1, stream_block.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"constructor\"\n\n\n    class member_expr_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.member_expr_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"member_expr\"\n    # Expr.g:217:1: member_expr : primary ( '.' primary )* -> ^( MEMBER ( primary )+ ) ;\n    def member_expr(self, ):\n        retval = self.member_expr_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal165 = None\n        primary164 = None\n        primary166 = None\n\n        char_literal165_tree = None\n        stream_86 = RewriteRuleTokenStream(self._adaptor, \"token 86\")\n        stream_primary = RewriteRuleSubtreeStream(self._adaptor, \"rule primary\")\n        try:\n            try:\n                # Expr.g:218:2: ( primary ( '.' primary )* -> ^( MEMBER ( primary )+ ) )\n                # Expr.g:218:4: primary ( '.' primary )*\n                pass \n                self._state.following.append(self.FOLLOW_primary_in_member_expr1354)\n                primary164 = self.primary()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_primary.add(primary164.tree)\n\n\n                # Expr.g:218:12: ( '.' primary )*\n                while True: #loop32\n                    alt32 = 2\n                    LA32_0 = self.input.LA(1)\n\n                    if (LA32_0 == 86) :\n                        alt32 = 1\n\n\n                    if alt32 == 1:\n                        # Expr.g:218:13: '.' primary\n                        pass \n                        char_literal165 = self.match(self.input, 86, self.FOLLOW_86_in_member_expr1357) \n                        if self._state.backtracking == 0:\n                            stream_86.add(char_literal165)\n\n\n                        self._state.following.append(self.FOLLOW_primary_in_member_expr1359)\n                        primary166 = self.primary()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_primary.add(primary166.tree)\n\n\n\n                    else:\n                        break #loop32\n\n\n                # AST Rewrite\n                # elements: primary\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 219:3: -> ^( MEMBER ( primary )+ )\n                    # Expr.g:219:6: ^( MEMBER ( primary )+ )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(MEMBER, \"MEMBER\")\n                    , root_1)\n\n                    # Expr.g:219:15: ( primary )+\n                    if not (stream_primary.hasNext()):\n                        raise RewriteEarlyExitException()\n\n                    while stream_primary.hasNext():\n                        self._adaptor.addChild(root_1, stream_primary.nextTree())\n\n\n                    stream_primary.reset()\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"member_expr\"\n\n\n    class primary_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.primary_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"primary\"\n    # Expr.g:221:1: primary : ID ( index_expr )* ( call_expr )? ;\n    def primary(self, ):\n        retval = self.primary_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        ID167 = None\n        index_expr168 = None\n        call_expr169 = None\n\n        ID167_tree = None\n\n        try:\n            try:\n                # Expr.g:222:2: ( ID ( index_expr )* ( call_expr )? )\n                # Expr.g:222:4: ID ( index_expr )* ( call_expr )?\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                ID167 = self.match(self.input, ID, self.FOLLOW_ID_in_primary1382)\n                if self._state.backtracking == 0:\n                    ID167_tree = self._adaptor.createWithPayload(ID167)\n                    self._adaptor.addChild(root_0, ID167_tree)\n\n\n\n                # Expr.g:222:7: ( index_expr )*\n                while True: #loop33\n                    alt33 = 2\n                    LA33_0 = self.input.LA(1)\n\n                    if (LA33_0 == 100) :\n                        alt33 = 1\n\n\n                    if alt33 == 1:\n                        # Expr.g:222:7: index_expr\n                        pass \n                        self._state.following.append(self.FOLLOW_index_expr_in_primary1384)\n                        index_expr168 = self.index_expr()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            self._adaptor.addChild(root_0, index_expr168.tree)\n\n\n\n                    else:\n                        break #loop33\n\n\n                # Expr.g:222:19: ( call_expr )?\n                alt34 = 2\n                LA34_0 = self.input.LA(1)\n\n                if (LA34_0 == 75) :\n                    alt34 = 1\n                if alt34 == 1:\n                    # Expr.g:222:19: call_expr\n                    pass \n                    self._state.following.append(self.FOLLOW_call_expr_in_primary1387)\n                    call_expr169 = self.call_expr()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, call_expr169.tree)\n\n\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"primary\"\n\n\n    class call_expr_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.call_expr_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"call_expr\"\n    # Expr.g:224:1: call_expr : '(' ( expr_list )? ')' -> ^( CALL ( expr_list )? ) ;\n    def call_expr(self, ):\n        retval = self.call_expr_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal170 = None\n        char_literal172 = None\n        expr_list171 = None\n\n        char_literal170_tree = None\n        char_literal172_tree = None\n        stream_75 = RewriteRuleTokenStream(self._adaptor, \"token 75\")\n        stream_76 = RewriteRuleTokenStream(self._adaptor, \"token 76\")\n        stream_expr_list = RewriteRuleSubtreeStream(self._adaptor, \"rule expr_list\")\n        try:\n            try:\n                # Expr.g:225:2: ( '(' ( expr_list )? ')' -> ^( CALL ( expr_list )? ) )\n                # Expr.g:225:4: '(' ( expr_list )? ')'\n                pass \n                char_literal170 = self.match(self.input, 75, self.FOLLOW_75_in_call_expr1398) \n                if self._state.backtracking == 0:\n                    stream_75.add(char_literal170)\n\n\n                # Expr.g:225:8: ( expr_list )?\n                alt35 = 2\n                LA35_0 = self.input.LA(1)\n\n                if (LA35_0 == BOOL or LA35_0 == FLOAT or LA35_0 == ID or LA35_0 == INT or LA35_0 == NULL or LA35_0 == STRING or LA35_0 == 68 or LA35_0 == 75 or LA35_0 == 83 or LA35_0 == 100 or LA35_0 == 121 or LA35_0 == 126 or LA35_0 == 132) :\n                    alt35 = 1\n                if alt35 == 1:\n                    # Expr.g:225:8: expr_list\n                    pass \n                    self._state.following.append(self.FOLLOW_expr_list_in_call_expr1400)\n                    expr_list171 = self.expr_list()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_expr_list.add(expr_list171.tree)\n\n\n\n\n\n                char_literal172 = self.match(self.input, 76, self.FOLLOW_76_in_call_expr1403) \n                if self._state.backtracking == 0:\n                    stream_76.add(char_literal172)\n\n\n                # AST Rewrite\n                # elements: expr_list\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 226:3: -> ^( CALL ( expr_list )? )\n                    # Expr.g:226:6: ^( CALL ( expr_list )? )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(CALL, \"CALL\")\n                    , root_1)\n\n                    # Expr.g:226:13: ( expr_list )?\n                    if stream_expr_list.hasNext():\n                        self._adaptor.addChild(root_1, stream_expr_list.nextTree())\n\n\n                    stream_expr_list.reset();\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"call_expr\"\n\n\n    class index_expr_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.index_expr_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"index_expr\"\n    # Expr.g:228:1: index_expr options {backtrack=true; } : ( '[' expr ']' -> ^( INDEX expr ) | '[' expr '..' ( expr )? ']' -> ^( SLICE expr ( expr )? ) );\n    def index_expr(self, ):\n        retval = self.index_expr_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal173 = None\n        char_literal175 = None\n        char_literal176 = None\n        string_literal178 = None\n        char_literal180 = None\n        expr174 = None\n        expr177 = None\n        expr179 = None\n\n        char_literal173_tree = None\n        char_literal175_tree = None\n        char_literal176_tree = None\n        string_literal178_tree = None\n        char_literal180_tree = None\n        stream_101 = RewriteRuleTokenStream(self._adaptor, \"token 101\")\n        stream_88 = RewriteRuleTokenStream(self._adaptor, \"token 88\")\n        stream_100 = RewriteRuleTokenStream(self._adaptor, \"token 100\")\n        stream_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule expr\")\n        try:\n            try:\n                # Expr.g:232:2: ( '[' expr ']' -> ^( INDEX expr ) | '[' expr '..' ( expr )? ']' -> ^( SLICE expr ( expr )? ) )\n                alt37 = 2\n                LA37_0 = self.input.LA(1)\n\n                if (LA37_0 == 100) :\n                    LA37_1 = self.input.LA(2)\n\n                    if (self.synpred1_Expr()) :\n                        alt37 = 1\n                    elif (True) :\n                        alt37 = 2\n                    else:\n                        if self._state.backtracking > 0:\n                            raise BacktrackingFailed\n\n\n                        nvae = NoViableAltException(\"\", 37, 1, self.input)\n\n                        raise nvae\n\n\n                else:\n                    if self._state.backtracking > 0:\n                        raise BacktrackingFailed\n\n\n                    nvae = NoViableAltException(\"\", 37, 0, self.input)\n\n                    raise nvae\n\n\n                if alt37 == 1:\n                    # Expr.g:232:4: '[' expr ']'\n                    pass \n                    char_literal173 = self.match(self.input, 100, self.FOLLOW_100_in_index_expr1439) \n                    if self._state.backtracking == 0:\n                        stream_100.add(char_literal173)\n\n\n                    self._state.following.append(self.FOLLOW_expr_in_index_expr1441)\n                    expr174 = self.expr()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_expr.add(expr174.tree)\n\n\n                    char_literal175 = self.match(self.input, 101, self.FOLLOW_101_in_index_expr1443) \n                    if self._state.backtracking == 0:\n                        stream_101.add(char_literal175)\n\n\n                    # AST Rewrite\n                    # elements: expr\n                    # token labels: \n                    # rule labels: retval\n                    # token list labels: \n                    # rule list labels: \n                    # wildcard labels: \n                    if self._state.backtracking == 0:\n                        retval.tree = root_0\n                        if retval is not None:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                        else:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                        root_0 = self._adaptor.nil()\n                        # 233:3: -> ^( INDEX expr )\n                        # Expr.g:233:6: ^( INDEX expr )\n                        root_1 = self._adaptor.nil()\n                        root_1 = self._adaptor.becomeRoot(\n                        self._adaptor.createFromType(INDEX, \"INDEX\")\n                        , root_1)\n\n                        self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n                        self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                        retval.tree = root_0\n\n\n\n\n                elif alt37 == 2:\n                    # Expr.g:234:4: '[' expr '..' ( expr )? ']'\n                    pass \n                    char_literal176 = self.match(self.input, 100, self.FOLLOW_100_in_index_expr1458) \n                    if self._state.backtracking == 0:\n                        stream_100.add(char_literal176)\n\n\n                    self._state.following.append(self.FOLLOW_expr_in_index_expr1460)\n                    expr177 = self.expr()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_expr.add(expr177.tree)\n\n\n                    string_literal178 = self.match(self.input, 88, self.FOLLOW_88_in_index_expr1462) \n                    if self._state.backtracking == 0:\n                        stream_88.add(string_literal178)\n\n\n                    # Expr.g:234:18: ( expr )?\n                    alt36 = 2\n                    LA36_0 = self.input.LA(1)\n\n                    if (LA36_0 == BOOL or LA36_0 == FLOAT or LA36_0 == ID or LA36_0 == INT or LA36_0 == NULL or LA36_0 == STRING or LA36_0 == 68 or LA36_0 == 75 or LA36_0 == 83 or LA36_0 == 100 or LA36_0 == 121 or LA36_0 == 126 or LA36_0 == 132) :\n                        alt36 = 1\n                    if alt36 == 1:\n                        # Expr.g:234:18: expr\n                        pass \n                        self._state.following.append(self.FOLLOW_expr_in_index_expr1464)\n                        expr179 = self.expr()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_expr.add(expr179.tree)\n\n\n\n\n\n                    char_literal180 = self.match(self.input, 101, self.FOLLOW_101_in_index_expr1467) \n                    if self._state.backtracking == 0:\n                        stream_101.add(char_literal180)\n\n\n                    # AST Rewrite\n                    # elements: expr, expr\n                    # token labels: \n                    # rule labels: retval\n                    # token list labels: \n                    # rule list labels: \n                    # wildcard labels: \n                    if self._state.backtracking == 0:\n                        retval.tree = root_0\n                        if retval is not None:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                        else:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                        root_0 = self._adaptor.nil()\n                        # 235:3: -> ^( SLICE expr ( expr )? )\n                        # Expr.g:235:6: ^( SLICE expr ( expr )? )\n                        root_1 = self._adaptor.nil()\n                        root_1 = self._adaptor.becomeRoot(\n                        self._adaptor.createFromType(SLICE, \"SLICE\")\n                        , root_1)\n\n                        self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n                        # Expr.g:235:19: ( expr )?\n                        if stream_expr.hasNext():\n                            self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n\n                        stream_expr.reset();\n\n                        self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                        retval.tree = root_0\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"index_expr\"\n\n\n    class exec_list_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.exec_list_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"exec_list\"\n    # Expr.g:239:1: exec_list : exec_expr ( ',' exec_expr )* -> ^( EXEC_LIST ( exec_expr )+ ) ;\n    def exec_list(self, ):\n        retval = self.exec_list_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal182 = None\n        exec_expr181 = None\n        exec_expr183 = None\n\n        char_literal182_tree = None\n        stream_82 = RewriteRuleTokenStream(self._adaptor, \"token 82\")\n        stream_exec_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule exec_expr\")\n        try:\n            try:\n                # Expr.g:240:2: ( exec_expr ( ',' exec_expr )* -> ^( EXEC_LIST ( exec_expr )+ ) )\n                # Expr.g:240:4: exec_expr ( ',' exec_expr )*\n                pass \n                self._state.following.append(self.FOLLOW_exec_expr_in_exec_list1492)\n                exec_expr181 = self.exec_expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_exec_expr.add(exec_expr181.tree)\n\n\n                # Expr.g:240:14: ( ',' exec_expr )*\n                while True: #loop38\n                    alt38 = 2\n                    LA38_0 = self.input.LA(1)\n\n                    if (LA38_0 == 82) :\n                        alt38 = 1\n\n\n                    if alt38 == 1:\n                        # Expr.g:240:15: ',' exec_expr\n                        pass \n                        char_literal182 = self.match(self.input, 82, self.FOLLOW_82_in_exec_list1495) \n                        if self._state.backtracking == 0:\n                            stream_82.add(char_literal182)\n\n\n                        self._state.following.append(self.FOLLOW_exec_expr_in_exec_list1497)\n                        exec_expr183 = self.exec_expr()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_exec_expr.add(exec_expr183.tree)\n\n\n\n                    else:\n                        break #loop38\n\n\n                # AST Rewrite\n                # elements: exec_expr\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 241:3: -> ^( EXEC_LIST ( exec_expr )+ )\n                    # Expr.g:241:6: ^( EXEC_LIST ( exec_expr )+ )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(EXEC_LIST, \"EXEC_LIST\")\n                    , root_1)\n\n                    # Expr.g:241:18: ( exec_expr )+\n                    if not (stream_exec_expr.hasNext()):\n                        raise RewriteEarlyExitException()\n\n                    while stream_exec_expr.hasNext():\n                        self._adaptor.addChild(root_1, stream_exec_expr.nextTree())\n\n\n                    stream_exec_expr.reset()\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"exec_list\"\n\n\n    class member_list_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.member_list_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"member_list\"\n    # Expr.g:243:1: member_list : member_expr ( ',' member_expr )* ;\n    def member_list(self, ):\n        retval = self.member_list_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal185 = None\n        member_expr184 = None\n        member_expr186 = None\n\n        char_literal185_tree = None\n\n        try:\n            try:\n                # Expr.g:244:2: ( member_expr ( ',' member_expr )* )\n                # Expr.g:244:4: member_expr ( ',' member_expr )*\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                self._state.following.append(self.FOLLOW_member_expr_in_member_list1520)\n                member_expr184 = self.member_expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    self._adaptor.addChild(root_0, member_expr184.tree)\n\n\n                # Expr.g:244:16: ( ',' member_expr )*\n                while True: #loop39\n                    alt39 = 2\n                    LA39_0 = self.input.LA(1)\n\n                    if (LA39_0 == 82) :\n                        alt39 = 1\n\n\n                    if alt39 == 1:\n                        # Expr.g:244:17: ',' member_expr\n                        pass \n                        char_literal185 = self.match(self.input, 82, self.FOLLOW_82_in_member_list1523)\n                        if self._state.backtracking == 0:\n                            char_literal185_tree = self._adaptor.createWithPayload(char_literal185)\n                            self._adaptor.addChild(root_0, char_literal185_tree)\n\n\n\n                        self._state.following.append(self.FOLLOW_member_expr_in_member_list1525)\n                        member_expr186 = self.member_expr()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            self._adaptor.addChild(root_0, member_expr186.tree)\n\n\n\n                    else:\n                        break #loop39\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"member_list\"\n\n\n    class exec_expr_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.exec_expr_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"exec_expr\"\n    # Expr.g:246:1: exec_expr : ( member_expr ( assign_op expr -> ^( ASSIGN member_expr assign_op expr ) | '++' -> ^( POST_INC member_expr ) | '--' -> ^( POST_DEC member_expr ) | -> member_expr ) | '++' member_expr -> ^( PRE_INC member_expr ) | '--' member_expr -> ^( PRE_DEC member_expr ) );\n    def exec_expr(self, ):\n        retval = self.exec_expr_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal190 = None\n        string_literal191 = None\n        string_literal192 = None\n        string_literal194 = None\n        member_expr187 = None\n        assign_op188 = None\n        expr189 = None\n        member_expr193 = None\n        member_expr195 = None\n\n        string_literal190_tree = None\n        string_literal191_tree = None\n        string_literal192_tree = None\n        string_literal194_tree = None\n        stream_80 = RewriteRuleTokenStream(self._adaptor, \"token 80\")\n        stream_84 = RewriteRuleTokenStream(self._adaptor, \"token 84\")\n        stream_member_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule member_expr\")\n        stream_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule expr\")\n        stream_assign_op = RewriteRuleSubtreeStream(self._adaptor, \"rule assign_op\")\n        try:\n            try:\n                # Expr.g:247:2: ( member_expr ( assign_op expr -> ^( ASSIGN member_expr assign_op expr ) | '++' -> ^( POST_INC member_expr ) | '--' -> ^( POST_DEC member_expr ) | -> member_expr ) | '++' member_expr -> ^( PRE_INC member_expr ) | '--' member_expr -> ^( PRE_DEC member_expr ) )\n                alt41 = 3\n                LA41 = self.input.LA(1)\n                if LA41 == ID:\n                    alt41 = 1\n                elif LA41 == 80:\n                    alt41 = 2\n                elif LA41 == 84:\n                    alt41 = 3\n                else:\n                    if self._state.backtracking > 0:\n                        raise BacktrackingFailed\n\n\n                    nvae = NoViableAltException(\"\", 41, 0, self.input)\n\n                    raise nvae\n\n\n                if alt41 == 1:\n                    # Expr.g:247:4: member_expr ( assign_op expr -> ^( ASSIGN member_expr assign_op expr ) | '++' -> ^( POST_INC member_expr ) | '--' -> ^( POST_DEC member_expr ) | -> member_expr )\n                    pass \n                    self._state.following.append(self.FOLLOW_member_expr_in_exec_expr1537)\n                    member_expr187 = self.member_expr()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_member_expr.add(member_expr187.tree)\n\n\n                    # Expr.g:248:3: ( assign_op expr -> ^( ASSIGN member_expr assign_op expr ) | '++' -> ^( POST_INC member_expr ) | '--' -> ^( POST_DEC member_expr ) | -> member_expr )\n                    alt40 = 4\n                    LA40 = self.input.LA(1)\n                    if LA40 == 71 or LA40 == 74 or LA40 == 78 or LA40 == 81 or LA40 == 85 or LA40 == 90 or LA40 == 95 or LA40 == 103 or LA40 == 134:\n                        alt40 = 1\n                    elif LA40 == 80:\n                        alt40 = 2\n                    elif LA40 == 84:\n                        alt40 = 3\n                    elif LA40 == 76 or LA40 == 82 or LA40 == 92:\n                        alt40 = 4\n                    else:\n                        if self._state.backtracking > 0:\n                            raise BacktrackingFailed\n\n\n                        nvae = NoViableAltException(\"\", 40, 0, self.input)\n\n                        raise nvae\n\n\n                    if alt40 == 1:\n                        # Expr.g:248:4: assign_op expr\n                        pass \n                        self._state.following.append(self.FOLLOW_assign_op_in_exec_expr1542)\n                        assign_op188 = self.assign_op()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_assign_op.add(assign_op188.tree)\n\n\n                        self._state.following.append(self.FOLLOW_expr_in_exec_expr1544)\n                        expr189 = self.expr()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_expr.add(expr189.tree)\n\n\n                        # AST Rewrite\n                        # elements: member_expr, expr, assign_op\n                        # token labels: \n                        # rule labels: retval\n                        # token list labels: \n                        # rule list labels: \n                        # wildcard labels: \n                        if self._state.backtracking == 0:\n                            retval.tree = root_0\n                            if retval is not None:\n                                stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                            else:\n                                stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                            root_0 = self._adaptor.nil()\n                            # 249:4: -> ^( ASSIGN member_expr assign_op expr )\n                            # Expr.g:249:7: ^( ASSIGN member_expr assign_op expr )\n                            root_1 = self._adaptor.nil()\n                            root_1 = self._adaptor.becomeRoot(\n                            self._adaptor.createFromType(ASSIGN, \"ASSIGN\")\n                            , root_1)\n\n                            self._adaptor.addChild(root_1, stream_member_expr.nextTree())\n\n                            self._adaptor.addChild(root_1, stream_assign_op.nextTree())\n\n                            self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n                            self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                            retval.tree = root_0\n\n\n\n\n                    elif alt40 == 2:\n                        # Expr.g:250:5: '++'\n                        pass \n                        string_literal190 = self.match(self.input, 80, self.FOLLOW_80_in_exec_expr1565) \n                        if self._state.backtracking == 0:\n                            stream_80.add(string_literal190)\n\n\n                        # AST Rewrite\n                        # elements: member_expr\n                        # token labels: \n                        # rule labels: retval\n                        # token list labels: \n                        # rule list labels: \n                        # wildcard labels: \n                        if self._state.backtracking == 0:\n                            retval.tree = root_0\n                            if retval is not None:\n                                stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                            else:\n                                stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                            root_0 = self._adaptor.nil()\n                            # 251:4: -> ^( POST_INC member_expr )\n                            # Expr.g:251:7: ^( POST_INC member_expr )\n                            root_1 = self._adaptor.nil()\n                            root_1 = self._adaptor.becomeRoot(\n                            self._adaptor.createFromType(POST_INC, \"POST_INC\")\n                            , root_1)\n\n                            self._adaptor.addChild(root_1, stream_member_expr.nextTree())\n\n                            self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                            retval.tree = root_0\n\n\n\n\n                    elif alt40 == 3:\n                        # Expr.g:252:5: '--'\n                        pass \n                        string_literal191 = self.match(self.input, 84, self.FOLLOW_84_in_exec_expr1582) \n                        if self._state.backtracking == 0:\n                            stream_84.add(string_literal191)\n\n\n                        # AST Rewrite\n                        # elements: member_expr\n                        # token labels: \n                        # rule labels: retval\n                        # token list labels: \n                        # rule list labels: \n                        # wildcard labels: \n                        if self._state.backtracking == 0:\n                            retval.tree = root_0\n                            if retval is not None:\n                                stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                            else:\n                                stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                            root_0 = self._adaptor.nil()\n                            # 253:4: -> ^( POST_DEC member_expr )\n                            # Expr.g:253:7: ^( POST_DEC member_expr )\n                            root_1 = self._adaptor.nil()\n                            root_1 = self._adaptor.becomeRoot(\n                            self._adaptor.createFromType(POST_DEC, \"POST_DEC\")\n                            , root_1)\n\n                            self._adaptor.addChild(root_1, stream_member_expr.nextTree())\n\n                            self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                            retval.tree = root_0\n\n\n\n\n                    elif alt40 == 4:\n                        # Expr.g:255:4: \n                        pass \n                        # AST Rewrite\n                        # elements: member_expr\n                        # token labels: \n                        # rule labels: retval\n                        # token list labels: \n                        # rule list labels: \n                        # wildcard labels: \n                        if self._state.backtracking == 0:\n                            retval.tree = root_0\n                            if retval is not None:\n                                stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                            else:\n                                stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                            root_0 = self._adaptor.nil()\n                            # 255:4: -> member_expr\n                            self._adaptor.addChild(root_0, stream_member_expr.nextTree())\n\n\n\n\n                            retval.tree = root_0\n\n\n\n\n\n\n\n                elif alt41 == 2:\n                    # Expr.g:257:4: '++' member_expr\n                    pass \n                    string_literal192 = self.match(self.input, 80, self.FOLLOW_80_in_exec_expr1613) \n                    if self._state.backtracking == 0:\n                        stream_80.add(string_literal192)\n\n\n                    self._state.following.append(self.FOLLOW_member_expr_in_exec_expr1615)\n                    member_expr193 = self.member_expr()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_member_expr.add(member_expr193.tree)\n\n\n                    # AST Rewrite\n                    # elements: member_expr\n                    # token labels: \n                    # rule labels: retval\n                    # token list labels: \n                    # rule list labels: \n                    # wildcard labels: \n                    if self._state.backtracking == 0:\n                        retval.tree = root_0\n                        if retval is not None:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                        else:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                        root_0 = self._adaptor.nil()\n                        # 258:3: -> ^( PRE_INC member_expr )\n                        # Expr.g:258:6: ^( PRE_INC member_expr )\n                        root_1 = self._adaptor.nil()\n                        root_1 = self._adaptor.becomeRoot(\n                        self._adaptor.createFromType(PRE_INC, \"PRE_INC\")\n                        , root_1)\n\n                        self._adaptor.addChild(root_1, stream_member_expr.nextTree())\n\n                        self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                        retval.tree = root_0\n\n\n\n\n                elif alt41 == 3:\n                    # Expr.g:259:4: '--' member_expr\n                    pass \n                    string_literal194 = self.match(self.input, 84, self.FOLLOW_84_in_exec_expr1630) \n                    if self._state.backtracking == 0:\n                        stream_84.add(string_literal194)\n\n\n                    self._state.following.append(self.FOLLOW_member_expr_in_exec_expr1632)\n                    member_expr195 = self.member_expr()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_member_expr.add(member_expr195.tree)\n\n\n                    # AST Rewrite\n                    # elements: member_expr\n                    # token labels: \n                    # rule labels: retval\n                    # token list labels: \n                    # rule list labels: \n                    # wildcard labels: \n                    if self._state.backtracking == 0:\n                        retval.tree = root_0\n                        if retval is not None:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                        else:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                        root_0 = self._adaptor.nil()\n                        # 260:3: -> ^( PRE_DEC member_expr )\n                        # Expr.g:260:6: ^( PRE_DEC member_expr )\n                        root_1 = self._adaptor.nil()\n                        root_1 = self._adaptor.becomeRoot(\n                        self._adaptor.createFromType(PRE_DEC, \"PRE_DEC\")\n                        , root_1)\n\n                        self._adaptor.addChild(root_1, stream_member_expr.nextTree())\n\n                        self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                        retval.tree = root_0\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"exec_expr\"\n\n\n    class assign_op_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.assign_op_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"assign_op\"\n    # Expr.g:262:1: assign_op : ( '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '^=' | '|=' );\n    def assign_op(self, ):\n        retval = self.assign_op_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        set196 = None\n\n        set196_tree = None\n\n        try:\n            try:\n                # Expr.g:263:2: ( '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '^=' | '|=' )\n                # Expr.g:\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                set196 = self.input.LT(1)\n\n                if self.input.LA(1) == 71 or self.input.LA(1) == 74 or self.input.LA(1) == 78 or self.input.LA(1) == 81 or self.input.LA(1) == 85 or self.input.LA(1) == 90 or self.input.LA(1) == 95 or self.input.LA(1) == 103 or self.input.LA(1) == 134:\n                    self.input.consume()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, self._adaptor.createWithPayload(set196))\n\n                    self._state.errorRecovery = False\n\n\n                else:\n                    if self._state.backtracking > 0:\n                        raise BacktrackingFailed\n\n\n                    mse = MismatchedSetException(None, self.input)\n                    raise mse\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"assign_op\"\n\n\n    class exec_stmt_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.exec_stmt_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"exec_stmt\"\n    # Expr.g:265:1: exec_stmt : exec_list ';' -> ^( EXEC_STMT exec_list ) ;\n    def exec_stmt(self, ):\n        retval = self.exec_stmt_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal198 = None\n        exec_list197 = None\n\n        char_literal198_tree = None\n        stream_92 = RewriteRuleTokenStream(self._adaptor, \"token 92\")\n        stream_exec_list = RewriteRuleSubtreeStream(self._adaptor, \"rule exec_list\")\n        try:\n            try:\n                # Expr.g:266:2: ( exec_list ';' -> ^( EXEC_STMT exec_list ) )\n                # Expr.g:266:4: exec_list ';'\n                pass \n                self._state.following.append(self.FOLLOW_exec_list_in_exec_stmt1678)\n                exec_list197 = self.exec_list()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_exec_list.add(exec_list197.tree)\n\n\n                char_literal198 = self.match(self.input, 92, self.FOLLOW_92_in_exec_stmt1680) \n                if self._state.backtracking == 0:\n                    stream_92.add(char_literal198)\n\n\n                # AST Rewrite\n                # elements: exec_list\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 267:3: -> ^( EXEC_STMT exec_list )\n                    # Expr.g:267:6: ^( EXEC_STMT exec_list )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(EXEC_STMT, \"EXEC_STMT\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_exec_list.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"exec_stmt\"\n\n\n    class expr_list_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.expr_list_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"expr_list\"\n    # Expr.g:272:1: expr_list : expr ( ',' expr )* ( ',' )? -> ^( EXPR_LIST ( expr )+ ) ;\n    def expr_list(self, ):\n        retval = self.expr_list_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal200 = None\n        char_literal202 = None\n        expr199 = None\n        expr201 = None\n\n        char_literal200_tree = None\n        char_literal202_tree = None\n        stream_82 = RewriteRuleTokenStream(self._adaptor, \"token 82\")\n        stream_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule expr\")\n        try:\n            try:\n                # Expr.g:273:2: ( expr ( ',' expr )* ( ',' )? -> ^( EXPR_LIST ( expr )+ ) )\n                # Expr.g:273:4: expr ( ',' expr )* ( ',' )?\n                pass \n                self._state.following.append(self.FOLLOW_expr_in_expr_list1703)\n                expr199 = self.expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_expr.add(expr199.tree)\n\n\n                # Expr.g:273:9: ( ',' expr )*\n                while True: #loop42\n                    alt42 = 2\n                    LA42_0 = self.input.LA(1)\n\n                    if (LA42_0 == 82) :\n                        LA42_1 = self.input.LA(2)\n\n                        if (LA42_1 == BOOL or LA42_1 == FLOAT or LA42_1 == ID or LA42_1 == INT or LA42_1 == NULL or LA42_1 == STRING or LA42_1 == 68 or LA42_1 == 75 or LA42_1 == 83 or LA42_1 == 100 or LA42_1 == 121 or LA42_1 == 126 or LA42_1 == 132) :\n                            alt42 = 1\n\n\n\n\n                    if alt42 == 1:\n                        # Expr.g:273:10: ',' expr\n                        pass \n                        char_literal200 = self.match(self.input, 82, self.FOLLOW_82_in_expr_list1706) \n                        if self._state.backtracking == 0:\n                            stream_82.add(char_literal200)\n\n\n                        self._state.following.append(self.FOLLOW_expr_in_expr_list1708)\n                        expr201 = self.expr()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_expr.add(expr201.tree)\n\n\n\n                    else:\n                        break #loop42\n\n\n                # Expr.g:273:21: ( ',' )?\n                alt43 = 2\n                LA43_0 = self.input.LA(1)\n\n                if (LA43_0 == 82) :\n                    alt43 = 1\n                if alt43 == 1:\n                    # Expr.g:273:21: ','\n                    pass \n                    char_literal202 = self.match(self.input, 82, self.FOLLOW_82_in_expr_list1712) \n                    if self._state.backtracking == 0:\n                        stream_82.add(char_literal202)\n\n\n\n\n\n                # AST Rewrite\n                # elements: expr\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 274:3: -> ^( EXPR_LIST ( expr )+ )\n                    # Expr.g:274:6: ^( EXPR_LIST ( expr )+ )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(EXPR_LIST, \"EXPR_LIST\")\n                    , root_1)\n\n                    # Expr.g:274:18: ( expr )+\n                    if not (stream_expr.hasNext()):\n                        raise RewriteEarlyExitException()\n\n                    while stream_expr.hasNext():\n                        self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n\n                    stream_expr.reset()\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"expr_list\"\n\n\n    class expr_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.expr_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"expr\"\n    # Expr.g:276:1: expr : logic_or_expr ;\n    def expr(self, ):\n        retval = self.expr_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        logic_or_expr203 = None\n\n\n        try:\n            try:\n                # Expr.g:277:2: ( logic_or_expr )\n                # Expr.g:277:4: logic_or_expr\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                self._state.following.append(self.FOLLOW_logic_or_expr_in_expr1734)\n                logic_or_expr203 = self.logic_or_expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    self._adaptor.addChild(root_0, logic_or_expr203.tree)\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"expr\"\n\n\n    class logic_or_expr_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.logic_or_expr_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"logic_or_expr\"\n    # Expr.g:279:1: logic_or_expr : logic_and_expr ( '||' ^ logic_and_expr )* ;\n    def logic_or_expr(self, ):\n        retval = self.logic_or_expr_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal205 = None\n        logic_and_expr204 = None\n        logic_and_expr206 = None\n\n        string_literal205_tree = None\n\n        try:\n            try:\n                # Expr.g:280:2: ( logic_and_expr ( '||' ^ logic_and_expr )* )\n                # Expr.g:280:4: logic_and_expr ( '||' ^ logic_and_expr )*\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                self._state.following.append(self.FOLLOW_logic_and_expr_in_logic_or_expr1744)\n                logic_and_expr204 = self.logic_and_expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    self._adaptor.addChild(root_0, logic_and_expr204.tree)\n\n\n                # Expr.g:280:19: ( '||' ^ logic_and_expr )*\n                while True: #loop44\n                    alt44 = 2\n                    LA44_0 = self.input.LA(1)\n\n                    if (LA44_0 == 135) :\n                        alt44 = 1\n\n\n                    if alt44 == 1:\n                        # Expr.g:280:20: '||' ^ logic_and_expr\n                        pass \n                        string_literal205 = self.match(self.input, 135, self.FOLLOW_135_in_logic_or_expr1747)\n                        if self._state.backtracking == 0:\n                            string_literal205_tree = self._adaptor.createWithPayload(string_literal205)\n                            root_0 = self._adaptor.becomeRoot(string_literal205_tree, root_0)\n\n\n\n                        self._state.following.append(self.FOLLOW_logic_and_expr_in_logic_or_expr1750)\n                        logic_and_expr206 = self.logic_and_expr()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            self._adaptor.addChild(root_0, logic_and_expr206.tree)\n\n\n\n                    else:\n                        break #loop44\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"logic_or_expr\"\n\n\n    class logic_and_expr_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.logic_and_expr_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"logic_and_expr\"\n    # Expr.g:282:1: logic_and_expr : bitwise_or_expr ( '&&' ^ bitwise_or_expr )* ;\n    def logic_and_expr(self, ):\n        retval = self.logic_and_expr_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal208 = None\n        bitwise_or_expr207 = None\n        bitwise_or_expr209 = None\n\n        string_literal208_tree = None\n\n        try:\n            try:\n                # Expr.g:283:2: ( bitwise_or_expr ( '&&' ^ bitwise_or_expr )* )\n                # Expr.g:283:4: bitwise_or_expr ( '&&' ^ bitwise_or_expr )*\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                self._state.following.append(self.FOLLOW_bitwise_or_expr_in_logic_and_expr1762)\n                bitwise_or_expr207 = self.bitwise_or_expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    self._adaptor.addChild(root_0, bitwise_or_expr207.tree)\n\n\n                # Expr.g:283:20: ( '&&' ^ bitwise_or_expr )*\n                while True: #loop45\n                    alt45 = 2\n                    LA45_0 = self.input.LA(1)\n\n                    if (LA45_0 == 72) :\n                        alt45 = 1\n\n\n                    if alt45 == 1:\n                        # Expr.g:283:21: '&&' ^ bitwise_or_expr\n                        pass \n                        string_literal208 = self.match(self.input, 72, self.FOLLOW_72_in_logic_and_expr1765)\n                        if self._state.backtracking == 0:\n                            string_literal208_tree = self._adaptor.createWithPayload(string_literal208)\n                            root_0 = self._adaptor.becomeRoot(string_literal208_tree, root_0)\n\n\n\n                        self._state.following.append(self.FOLLOW_bitwise_or_expr_in_logic_and_expr1768)\n                        bitwise_or_expr209 = self.bitwise_or_expr()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            self._adaptor.addChild(root_0, bitwise_or_expr209.tree)\n\n\n\n                    else:\n                        break #loop45\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"logic_and_expr\"\n\n\n    class bitwise_or_expr_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.bitwise_or_expr_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"bitwise_or_expr\"\n    # Expr.g:285:1: bitwise_or_expr : bitwise_xor_expr ( '|' ^ bitwise_xor_expr )* ;\n    def bitwise_or_expr(self, ):\n        retval = self.bitwise_or_expr_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal211 = None\n        bitwise_xor_expr210 = None\n        bitwise_xor_expr212 = None\n\n        char_literal211_tree = None\n\n        try:\n            try:\n                # Expr.g:286:2: ( bitwise_xor_expr ( '|' ^ bitwise_xor_expr )* )\n                # Expr.g:286:4: bitwise_xor_expr ( '|' ^ bitwise_xor_expr )*\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                self._state.following.append(self.FOLLOW_bitwise_xor_expr_in_bitwise_or_expr1780)\n                bitwise_xor_expr210 = self.bitwise_xor_expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    self._adaptor.addChild(root_0, bitwise_xor_expr210.tree)\n\n\n                # Expr.g:286:21: ( '|' ^ bitwise_xor_expr )*\n                while True: #loop46\n                    alt46 = 2\n                    LA46_0 = self.input.LA(1)\n\n                    if (LA46_0 == 133) :\n                        alt46 = 1\n\n\n                    if alt46 == 1:\n                        # Expr.g:286:22: '|' ^ bitwise_xor_expr\n                        pass \n                        char_literal211 = self.match(self.input, 133, self.FOLLOW_133_in_bitwise_or_expr1783)\n                        if self._state.backtracking == 0:\n                            char_literal211_tree = self._adaptor.createWithPayload(char_literal211)\n                            root_0 = self._adaptor.becomeRoot(char_literal211_tree, root_0)\n\n\n\n                        self._state.following.append(self.FOLLOW_bitwise_xor_expr_in_bitwise_or_expr1786)\n                        bitwise_xor_expr212 = self.bitwise_xor_expr()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            self._adaptor.addChild(root_0, bitwise_xor_expr212.tree)\n\n\n\n                    else:\n                        break #loop46\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"bitwise_or_expr\"\n\n\n    class bitwise_xor_expr_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.bitwise_xor_expr_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"bitwise_xor_expr\"\n    # Expr.g:288:1: bitwise_xor_expr : bitwise_and_expr ( '^' ^ bitwise_and_expr )* ;\n    def bitwise_xor_expr(self, ):\n        retval = self.bitwise_xor_expr_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal214 = None\n        bitwise_and_expr213 = None\n        bitwise_and_expr215 = None\n\n        char_literal214_tree = None\n\n        try:\n            try:\n                # Expr.g:289:2: ( bitwise_and_expr ( '^' ^ bitwise_and_expr )* )\n                # Expr.g:289:4: bitwise_and_expr ( '^' ^ bitwise_and_expr )*\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                self._state.following.append(self.FOLLOW_bitwise_and_expr_in_bitwise_xor_expr1798)\n                bitwise_and_expr213 = self.bitwise_and_expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    self._adaptor.addChild(root_0, bitwise_and_expr213.tree)\n\n\n                # Expr.g:289:21: ( '^' ^ bitwise_and_expr )*\n                while True: #loop47\n                    alt47 = 2\n                    LA47_0 = self.input.LA(1)\n\n                    if (LA47_0 == 102) :\n                        alt47 = 1\n\n\n                    if alt47 == 1:\n                        # Expr.g:289:22: '^' ^ bitwise_and_expr\n                        pass \n                        char_literal214 = self.match(self.input, 102, self.FOLLOW_102_in_bitwise_xor_expr1801)\n                        if self._state.backtracking == 0:\n                            char_literal214_tree = self._adaptor.createWithPayload(char_literal214)\n                            root_0 = self._adaptor.becomeRoot(char_literal214_tree, root_0)\n\n\n\n                        self._state.following.append(self.FOLLOW_bitwise_and_expr_in_bitwise_xor_expr1804)\n                        bitwise_and_expr215 = self.bitwise_and_expr()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            self._adaptor.addChild(root_0, bitwise_and_expr215.tree)\n\n\n\n                    else:\n                        break #loop47\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"bitwise_xor_expr\"\n\n\n    class bitwise_and_expr_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.bitwise_and_expr_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"bitwise_and_expr\"\n    # Expr.g:291:1: bitwise_and_expr : relation_expr ( '&' ^ relation_expr )* ;\n    def bitwise_and_expr(self, ):\n        retval = self.bitwise_and_expr_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal217 = None\n        relation_expr216 = None\n        relation_expr218 = None\n\n        char_literal217_tree = None\n\n        try:\n            try:\n                # Expr.g:292:2: ( relation_expr ( '&' ^ relation_expr )* )\n                # Expr.g:292:4: relation_expr ( '&' ^ relation_expr )*\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                self._state.following.append(self.FOLLOW_relation_expr_in_bitwise_and_expr1816)\n                relation_expr216 = self.relation_expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    self._adaptor.addChild(root_0, relation_expr216.tree)\n\n\n                # Expr.g:292:18: ( '&' ^ relation_expr )*\n                while True: #loop48\n                    alt48 = 2\n                    LA48_0 = self.input.LA(1)\n\n                    if (LA48_0 == 73) :\n                        alt48 = 1\n\n\n                    if alt48 == 1:\n                        # Expr.g:292:19: '&' ^ relation_expr\n                        pass \n                        char_literal217 = self.match(self.input, 73, self.FOLLOW_73_in_bitwise_and_expr1819)\n                        if self._state.backtracking == 0:\n                            char_literal217_tree = self._adaptor.createWithPayload(char_literal217)\n                            root_0 = self._adaptor.becomeRoot(char_literal217_tree, root_0)\n\n\n\n                        self._state.following.append(self.FOLLOW_relation_expr_in_bitwise_and_expr1822)\n                        relation_expr218 = self.relation_expr()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            self._adaptor.addChild(root_0, relation_expr218.tree)\n\n\n\n                    else:\n                        break #loop48\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"bitwise_and_expr\"\n\n\n    class relation_expr_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.relation_expr_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"relation_expr\"\n    # Expr.g:294:1: relation_expr : add_expr ( ( '<' | '>' | '<=' | '>=' | '==' | '!=' ) ^ add_expr )? ;\n    def relation_expr(self, ):\n        retval = self.relation_expr_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        set220 = None\n        add_expr219 = None\n        add_expr221 = None\n\n        set220_tree = None\n\n        try:\n            try:\n                # Expr.g:295:2: ( add_expr ( ( '<' | '>' | '<=' | '>=' | '==' | '!=' ) ^ add_expr )? )\n                # Expr.g:295:4: add_expr ( ( '<' | '>' | '<=' | '>=' | '==' | '!=' ) ^ add_expr )?\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                self._state.following.append(self.FOLLOW_add_expr_in_relation_expr1834)\n                add_expr219 = self.add_expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    self._adaptor.addChild(root_0, add_expr219.tree)\n\n\n                # Expr.g:295:13: ( ( '<' | '>' | '<=' | '>=' | '==' | '!=' ) ^ add_expr )?\n                alt49 = 2\n                LA49_0 = self.input.LA(1)\n\n                if (LA49_0 == 69 or (93 <= LA49_0 <= 94) or LA49_0 == 96 or (98 <= LA49_0 <= 99)) :\n                    alt49 = 1\n                if alt49 == 1:\n                    # Expr.g:295:14: ( '<' | '>' | '<=' | '>=' | '==' | '!=' ) ^ add_expr\n                    pass \n                    set220 = self.input.LT(1)\n\n                    set220 = self.input.LT(1)\n\n                    if self.input.LA(1) == 69 or (93 <= self.input.LA(1) <= 94) or self.input.LA(1) == 96 or (98 <= self.input.LA(1) <= 99):\n                        self.input.consume()\n                        if self._state.backtracking == 0:\n                            root_0 = self._adaptor.becomeRoot(self._adaptor.createWithPayload(set220), root_0)\n\n                        self._state.errorRecovery = False\n\n\n                    else:\n                        if self._state.backtracking > 0:\n                            raise BacktrackingFailed\n\n\n                        mse = MismatchedSetException(None, self.input)\n                        raise mse\n\n\n\n                    self._state.following.append(self.FOLLOW_add_expr_in_relation_expr1852)\n                    add_expr221 = self.add_expr()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, add_expr221.tree)\n\n\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"relation_expr\"\n\n\n    class add_expr_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.add_expr_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"add_expr\"\n    # Expr.g:297:1: add_expr : mul_expr ( ( '+' | '-' ) ^ mul_expr )* ;\n    def add_expr(self, ):\n        retval = self.add_expr_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        set223 = None\n        mul_expr222 = None\n        mul_expr224 = None\n\n        set223_tree = None\n\n        try:\n            try:\n                # Expr.g:298:2: ( mul_expr ( ( '+' | '-' ) ^ mul_expr )* )\n                # Expr.g:298:4: mul_expr ( ( '+' | '-' ) ^ mul_expr )*\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                self._state.following.append(self.FOLLOW_mul_expr_in_add_expr1864)\n                mul_expr222 = self.mul_expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    self._adaptor.addChild(root_0, mul_expr222.tree)\n\n\n                # Expr.g:298:13: ( ( '+' | '-' ) ^ mul_expr )*\n                while True: #loop50\n                    alt50 = 2\n                    LA50_0 = self.input.LA(1)\n\n                    if (LA50_0 == 79 or LA50_0 == 83) :\n                        alt50 = 1\n\n\n                    if alt50 == 1:\n                        # Expr.g:298:14: ( '+' | '-' ) ^ mul_expr\n                        pass \n                        set223 = self.input.LT(1)\n\n                        set223 = self.input.LT(1)\n\n                        if self.input.LA(1) == 79 or self.input.LA(1) == 83:\n                            self.input.consume()\n                            if self._state.backtracking == 0:\n                                root_0 = self._adaptor.becomeRoot(self._adaptor.createWithPayload(set223), root_0)\n\n                            self._state.errorRecovery = False\n\n\n                        else:\n                            if self._state.backtracking > 0:\n                                raise BacktrackingFailed\n\n\n                            mse = MismatchedSetException(None, self.input)\n                            raise mse\n\n\n\n                        self._state.following.append(self.FOLLOW_mul_expr_in_add_expr1874)\n                        mul_expr224 = self.mul_expr()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            self._adaptor.addChild(root_0, mul_expr224.tree)\n\n\n\n                    else:\n                        break #loop50\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"add_expr\"\n\n\n    class mul_expr_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.mul_expr_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"mul_expr\"\n    # Expr.g:300:1: mul_expr : not_expr ( ( '*' | '/' | '%' ) ^ not_expr )* ;\n    def mul_expr(self, ):\n        retval = self.mul_expr_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        set226 = None\n        not_expr225 = None\n        not_expr227 = None\n\n        set226_tree = None\n\n        try:\n            try:\n                # Expr.g:301:2: ( not_expr ( ( '*' | '/' | '%' ) ^ not_expr )* )\n                # Expr.g:301:4: not_expr ( ( '*' | '/' | '%' ) ^ not_expr )*\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                self._state.following.append(self.FOLLOW_not_expr_in_mul_expr1886)\n                not_expr225 = self.not_expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    self._adaptor.addChild(root_0, not_expr225.tree)\n\n\n                # Expr.g:301:13: ( ( '*' | '/' | '%' ) ^ not_expr )*\n                while True: #loop51\n                    alt51 = 2\n                    LA51_0 = self.input.LA(1)\n\n                    if (LA51_0 == 70 or LA51_0 == 77 or LA51_0 == 89) :\n                        alt51 = 1\n\n\n                    if alt51 == 1:\n                        # Expr.g:301:14: ( '*' | '/' | '%' ) ^ not_expr\n                        pass \n                        set226 = self.input.LT(1)\n\n                        set226 = self.input.LT(1)\n\n                        if self.input.LA(1) == 70 or self.input.LA(1) == 77 or self.input.LA(1) == 89:\n                            self.input.consume()\n                            if self._state.backtracking == 0:\n                                root_0 = self._adaptor.becomeRoot(self._adaptor.createWithPayload(set226), root_0)\n\n                            self._state.errorRecovery = False\n\n\n                        else:\n                            if self._state.backtracking > 0:\n                                raise BacktrackingFailed\n\n\n                            mse = MismatchedSetException(None, self.input)\n                            raise mse\n\n\n\n                        self._state.following.append(self.FOLLOW_not_expr_in_mul_expr1898)\n                        not_expr227 = self.not_expr()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            self._adaptor.addChild(root_0, not_expr227.tree)\n\n\n\n                    else:\n                        break #loop51\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"mul_expr\"\n\n\n    class not_expr_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.not_expr_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"not_expr\"\n    # Expr.g:303:1: not_expr : (op= '!' )? negative_expr -> {$op != None}? ^( '!' negative_expr ) -> negative_expr ;\n    def not_expr(self, ):\n        retval = self.not_expr_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        op = None\n        negative_expr228 = None\n\n        op_tree = None\n        stream_68 = RewriteRuleTokenStream(self._adaptor, \"token 68\")\n        stream_negative_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule negative_expr\")\n        try:\n            try:\n                # Expr.g:304:2: ( (op= '!' )? negative_expr -> {$op != None}? ^( '!' negative_expr ) -> negative_expr )\n                # Expr.g:304:4: (op= '!' )? negative_expr\n                pass \n                # Expr.g:304:6: (op= '!' )?\n                alt52 = 2\n                LA52_0 = self.input.LA(1)\n\n                if (LA52_0 == 68) :\n                    alt52 = 1\n                if alt52 == 1:\n                    # Expr.g:304:6: op= '!'\n                    pass \n                    op = self.match(self.input, 68, self.FOLLOW_68_in_not_expr1912) \n                    if self._state.backtracking == 0:\n                        stream_68.add(op)\n\n\n\n\n\n                self._state.following.append(self.FOLLOW_negative_expr_in_not_expr1915)\n                negative_expr228 = self.negative_expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_negative_expr.add(negative_expr228.tree)\n\n\n                # AST Rewrite\n                # elements: negative_expr, negative_expr, 68\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    if op != None:\n                        # 305:3: -> {$op != None}? ^( '!' negative_expr )\n                        # Expr.g:306:4: ^( '!' negative_expr )\n                        root_1 = self._adaptor.nil()\n                        root_1 = self._adaptor.becomeRoot(\n                        stream_68.nextNode()\n                        , root_1)\n\n                        self._adaptor.addChild(root_1, stream_negative_expr.nextTree())\n\n                        self._adaptor.addChild(root_0, root_1)\n\n\n\n                    else: \n                        # 307:4: -> negative_expr\n                        self._adaptor.addChild(root_0, stream_negative_expr.nextTree())\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"not_expr\"\n\n\n    class negative_expr_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.negative_expr_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"negative_expr\"\n    # Expr.g:309:1: negative_expr : (op= '-' )? atom -> {$op != None}? ^( NEGATIVE atom ) -> atom ;\n    def negative_expr(self, ):\n        retval = self.negative_expr_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        op = None\n        atom229 = None\n\n        op_tree = None\n        stream_83 = RewriteRuleTokenStream(self._adaptor, \"token 83\")\n        stream_atom = RewriteRuleSubtreeStream(self._adaptor, \"rule atom\")\n        try:\n            try:\n                # Expr.g:310:2: ( (op= '-' )? atom -> {$op != None}? ^( NEGATIVE atom ) -> atom )\n                # Expr.g:310:4: (op= '-' )? atom\n                pass \n                # Expr.g:310:4: (op= '-' )?\n                alt53 = 2\n                LA53_0 = self.input.LA(1)\n\n                if (LA53_0 == 83) :\n                    alt53 = 1\n                if alt53 == 1:\n                    # Expr.g:310:5: op= '-'\n                    pass \n                    op = self.match(self.input, 83, self.FOLLOW_83_in_negative_expr1950) \n                    if self._state.backtracking == 0:\n                        stream_83.add(op)\n\n\n\n\n\n                self._state.following.append(self.FOLLOW_atom_in_negative_expr1954)\n                atom229 = self.atom()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_atom.add(atom229.tree)\n\n\n                # AST Rewrite\n                # elements: atom, atom\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    if op != None:\n                        # 311:3: -> {$op != None}? ^( NEGATIVE atom )\n                        # Expr.g:312:4: ^( NEGATIVE atom )\n                        root_1 = self._adaptor.nil()\n                        root_1 = self._adaptor.becomeRoot(\n                        self._adaptor.createFromType(NEGATIVE, \"NEGATIVE\")\n                        , root_1)\n\n                        self._adaptor.addChild(root_1, stream_atom.nextTree())\n\n                        self._adaptor.addChild(root_0, root_1)\n\n\n\n                    else: \n                        # 313:4: -> atom\n                        self._adaptor.addChild(root_0, stream_atom.nextTree())\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"negative_expr\"\n\n\n    class atom_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.atom_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"atom\"\n    # Expr.g:316:1: atom : ( literal | member_expr | array_decl | object_decl | new_clause | sprintf | '(' expr ')' -> expr );\n    def atom(self, ):\n        retval = self.atom_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal236 = None\n        char_literal238 = None\n        literal230 = None\n        member_expr231 = None\n        array_decl232 = None\n        object_decl233 = None\n        new_clause234 = None\n        sprintf235 = None\n        expr237 = None\n\n        char_literal236_tree = None\n        char_literal238_tree = None\n        stream_75 = RewriteRuleTokenStream(self._adaptor, \"token 75\")\n        stream_76 = RewriteRuleTokenStream(self._adaptor, \"token 76\")\n        stream_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule expr\")\n        try:\n            try:\n                # Expr.g:317:2: ( literal | member_expr | array_decl | object_decl | new_clause | sprintf | '(' expr ')' -> expr )\n                alt54 = 7\n                LA54 = self.input.LA(1)\n                if LA54 == BOOL or LA54 == FLOAT or LA54 == INT or LA54 == NULL or LA54 == STRING:\n                    alt54 = 1\n                elif LA54 == ID:\n                    alt54 = 2\n                elif LA54 == 100:\n                    alt54 = 3\n                elif LA54 == 132:\n                    alt54 = 4\n                elif LA54 == 121:\n                    alt54 = 5\n                elif LA54 == 126:\n                    alt54 = 6\n                elif LA54 == 75:\n                    alt54 = 7\n                else:\n                    if self._state.backtracking > 0:\n                        raise BacktrackingFailed\n\n\n                    nvae = NoViableAltException(\"\", 54, 0, self.input)\n\n                    raise nvae\n\n\n                if alt54 == 1:\n                    # Expr.g:317:4: literal\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_literal_in_atom1987)\n                    literal230 = self.literal()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, literal230.tree)\n\n\n\n                elif alt54 == 2:\n                    # Expr.g:318:4: member_expr\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_member_expr_in_atom1992)\n                    member_expr231 = self.member_expr()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, member_expr231.tree)\n\n\n\n                elif alt54 == 3:\n                    # Expr.g:319:4: array_decl\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_array_decl_in_atom1997)\n                    array_decl232 = self.array_decl()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, array_decl232.tree)\n\n\n\n                elif alt54 == 4:\n                    # Expr.g:320:4: object_decl\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_object_decl_in_atom2002)\n                    object_decl233 = self.object_decl()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, object_decl233.tree)\n\n\n\n                elif alt54 == 5:\n                    # Expr.g:321:4: new_clause\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_new_clause_in_atom2007)\n                    new_clause234 = self.new_clause()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, new_clause234.tree)\n\n\n\n                elif alt54 == 6:\n                    # Expr.g:322:4: sprintf\n                    pass \n                    root_0 = self._adaptor.nil()\n\n\n                    self._state.following.append(self.FOLLOW_sprintf_in_atom2012)\n                    sprintf235 = self.sprintf()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, sprintf235.tree)\n\n\n\n                elif alt54 == 7:\n                    # Expr.g:323:4: '(' expr ')'\n                    pass \n                    char_literal236 = self.match(self.input, 75, self.FOLLOW_75_in_atom2017) \n                    if self._state.backtracking == 0:\n                        stream_75.add(char_literal236)\n\n\n                    self._state.following.append(self.FOLLOW_expr_in_atom2019)\n                    expr237 = self.expr()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_expr.add(expr237.tree)\n\n\n                    char_literal238 = self.match(self.input, 76, self.FOLLOW_76_in_atom2021) \n                    if self._state.backtracking == 0:\n                        stream_76.add(char_literal238)\n\n\n                    # AST Rewrite\n                    # elements: expr\n                    # token labels: \n                    # rule labels: retval\n                    # token list labels: \n                    # rule list labels: \n                    # wildcard labels: \n                    if self._state.backtracking == 0:\n                        retval.tree = root_0\n                        if retval is not None:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                        else:\n                            stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                        root_0 = self._adaptor.nil()\n                        # 323:17: -> expr\n                        self._adaptor.addChild(root_0, stream_expr.nextTree())\n\n\n\n\n                        retval.tree = root_0\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"atom\"\n\n\n    class literal_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.literal_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"literal\"\n    # Expr.g:325:1: literal : ( BOOL | NULL | INT | FLOAT | STRING );\n    def literal(self, ):\n        retval = self.literal_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        set239 = None\n\n        set239_tree = None\n\n        try:\n            try:\n                # Expr.g:326:2: ( BOOL | NULL | INT | FLOAT | STRING )\n                # Expr.g:\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                set239 = self.input.LT(1)\n\n                if self.input.LA(1) == BOOL or self.input.LA(1) == FLOAT or self.input.LA(1) == INT or self.input.LA(1) == NULL or self.input.LA(1) == STRING:\n                    self.input.consume()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, self._adaptor.createWithPayload(set239))\n\n                    self._state.errorRecovery = False\n\n\n                else:\n                    if self._state.backtracking > 0:\n                        raise BacktrackingFailed\n\n\n                    mse = MismatchedSetException(None, self.input)\n                    raise mse\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"literal\"\n\n\n    class new_clause_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.new_clause_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"new_clause\"\n    # Expr.g:329:1: new_clause : 'new' module call_expr -> ^( NEW module call_expr ) ;\n    def new_clause(self, ):\n        retval = self.new_clause_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal240 = None\n        module241 = None\n        call_expr242 = None\n\n        string_literal240_tree = None\n        stream_121 = RewriteRuleTokenStream(self._adaptor, \"token 121\")\n        stream_module = RewriteRuleSubtreeStream(self._adaptor, \"rule module\")\n        stream_call_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule call_expr\")\n        try:\n            try:\n                # Expr.g:330:2: ( 'new' module call_expr -> ^( NEW module call_expr ) )\n                # Expr.g:330:4: 'new' module call_expr\n                pass \n                string_literal240 = self.match(self.input, 121, self.FOLLOW_121_in_new_clause2062) \n                if self._state.backtracking == 0:\n                    stream_121.add(string_literal240)\n\n\n                self._state.following.append(self.FOLLOW_module_in_new_clause2064)\n                module241 = self.module()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_module.add(module241.tree)\n\n\n                self._state.following.append(self.FOLLOW_call_expr_in_new_clause2066)\n                call_expr242 = self.call_expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_call_expr.add(call_expr242.tree)\n\n\n                # AST Rewrite\n                # elements: module, call_expr\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 331:3: -> ^( NEW module call_expr )\n                    # Expr.g:331:6: ^( NEW module call_expr )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(NEW, \"NEW\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_module.nextTree())\n\n                    self._adaptor.addChild(root_1, stream_call_expr.nextTree())\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"new_clause\"\n\n\n    class module_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.module_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"module\"\n    # Expr.g:333:1: module : ID ( '.' ID )* -> ^( MODULE ( ID )+ ) ;\n    def module(self, ):\n        retval = self.module_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        ID243 = None\n        char_literal244 = None\n        ID245 = None\n\n        ID243_tree = None\n        char_literal244_tree = None\n        ID245_tree = None\n        stream_ID = RewriteRuleTokenStream(self._adaptor, \"token ID\")\n        stream_86 = RewriteRuleTokenStream(self._adaptor, \"token 86\")\n\n        try:\n            try:\n                # Expr.g:334:2: ( ID ( '.' ID )* -> ^( MODULE ( ID )+ ) )\n                # Expr.g:334:4: ID ( '.' ID )*\n                pass \n                ID243 = self.match(self.input, ID, self.FOLLOW_ID_in_module2088) \n                if self._state.backtracking == 0:\n                    stream_ID.add(ID243)\n\n\n                # Expr.g:334:7: ( '.' ID )*\n                while True: #loop55\n                    alt55 = 2\n                    LA55_0 = self.input.LA(1)\n\n                    if (LA55_0 == 86) :\n                        alt55 = 1\n\n\n                    if alt55 == 1:\n                        # Expr.g:334:8: '.' ID\n                        pass \n                        char_literal244 = self.match(self.input, 86, self.FOLLOW_86_in_module2091) \n                        if self._state.backtracking == 0:\n                            stream_86.add(char_literal244)\n\n\n                        ID245 = self.match(self.input, ID, self.FOLLOW_ID_in_module2093) \n                        if self._state.backtracking == 0:\n                            stream_ID.add(ID245)\n\n\n\n                    else:\n                        break #loop55\n\n\n                # AST Rewrite\n                # elements: ID\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 335:3: -> ^( MODULE ( ID )+ )\n                    # Expr.g:335:6: ^( MODULE ( ID )+ )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(MODULE, \"MODULE\")\n                    , root_1)\n\n                    # Expr.g:335:15: ( ID )+\n                    if not (stream_ID.hasNext()):\n                        raise RewriteEarlyExitException()\n\n                    while stream_ID.hasNext():\n                        self._adaptor.addChild(root_1, \n                        stream_ID.nextNode()\n                        )\n\n\n                    stream_ID.reset()\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"module\"\n\n\n    class array_decl_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.array_decl_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"array_decl\"\n    # Expr.g:339:1: array_decl : '[' ( expr_list )? ']' -> ^( ARRAY ( expr_list )? ) ;\n    def array_decl(self, ):\n        retval = self.array_decl_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal246 = None\n        char_literal248 = None\n        expr_list247 = None\n\n        char_literal246_tree = None\n        char_literal248_tree = None\n        stream_101 = RewriteRuleTokenStream(self._adaptor, \"token 101\")\n        stream_100 = RewriteRuleTokenStream(self._adaptor, \"token 100\")\n        stream_expr_list = RewriteRuleSubtreeStream(self._adaptor, \"rule expr_list\")\n        try:\n            try:\n                # Expr.g:340:2: ( '[' ( expr_list )? ']' -> ^( ARRAY ( expr_list )? ) )\n                # Expr.g:340:4: '[' ( expr_list )? ']'\n                pass \n                char_literal246 = self.match(self.input, 100, self.FOLLOW_100_in_array_decl2118) \n                if self._state.backtracking == 0:\n                    stream_100.add(char_literal246)\n\n\n                # Expr.g:340:8: ( expr_list )?\n                alt56 = 2\n                LA56_0 = self.input.LA(1)\n\n                if (LA56_0 == BOOL or LA56_0 == FLOAT or LA56_0 == ID or LA56_0 == INT or LA56_0 == NULL or LA56_0 == STRING or LA56_0 == 68 or LA56_0 == 75 or LA56_0 == 83 or LA56_0 == 100 or LA56_0 == 121 or LA56_0 == 126 or LA56_0 == 132) :\n                    alt56 = 1\n                if alt56 == 1:\n                    # Expr.g:340:8: expr_list\n                    pass \n                    self._state.following.append(self.FOLLOW_expr_list_in_array_decl2120)\n                    expr_list247 = self.expr_list()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_expr_list.add(expr_list247.tree)\n\n\n\n\n\n                char_literal248 = self.match(self.input, 101, self.FOLLOW_101_in_array_decl2123) \n                if self._state.backtracking == 0:\n                    stream_101.add(char_literal248)\n\n\n                # AST Rewrite\n                # elements: expr_list\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 341:3: -> ^( ARRAY ( expr_list )? )\n                    # Expr.g:341:6: ^( ARRAY ( expr_list )? )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(ARRAY, \"ARRAY\")\n                    , root_1)\n\n                    # Expr.g:341:14: ( expr_list )?\n                    if stream_expr_list.hasNext():\n                        self._adaptor.addChild(root_1, stream_expr_list.nextTree())\n\n\n                    stream_expr_list.reset();\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"array_decl\"\n\n\n    class object_decl_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.object_decl_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"object_decl\"\n    # Expr.g:344:1: object_decl : '{' ( property )? ( ',' property )* ( ',' )? '}' -> ^( OBJECT ( property )* ) ;\n    def object_decl(self, ):\n        retval = self.object_decl_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        char_literal249 = None\n        char_literal251 = None\n        char_literal253 = None\n        char_literal254 = None\n        property250 = None\n        property252 = None\n\n        char_literal249_tree = None\n        char_literal251_tree = None\n        char_literal253_tree = None\n        char_literal254_tree = None\n        stream_132 = RewriteRuleTokenStream(self._adaptor, \"token 132\")\n        stream_136 = RewriteRuleTokenStream(self._adaptor, \"token 136\")\n        stream_82 = RewriteRuleTokenStream(self._adaptor, \"token 82\")\n        stream_property = RewriteRuleSubtreeStream(self._adaptor, \"rule property\")\n        try:\n            try:\n                # Expr.g:345:2: ( '{' ( property )? ( ',' property )* ( ',' )? '}' -> ^( OBJECT ( property )* ) )\n                # Expr.g:345:4: '{' ( property )? ( ',' property )* ( ',' )? '}'\n                pass \n                char_literal249 = self.match(self.input, 132, self.FOLLOW_132_in_object_decl2145) \n                if self._state.backtracking == 0:\n                    stream_132.add(char_literal249)\n\n\n                # Expr.g:345:8: ( property )?\n                alt57 = 2\n                LA57_0 = self.input.LA(1)\n\n                if (LA57_0 == ID or LA57_0 == INT or LA57_0 == STRING) :\n                    alt57 = 1\n                if alt57 == 1:\n                    # Expr.g:345:8: property\n                    pass \n                    self._state.following.append(self.FOLLOW_property_in_object_decl2147)\n                    property250 = self.property()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_property.add(property250.tree)\n\n\n\n\n\n                # Expr.g:345:18: ( ',' property )*\n                while True: #loop58\n                    alt58 = 2\n                    LA58_0 = self.input.LA(1)\n\n                    if (LA58_0 == 82) :\n                        LA58_1 = self.input.LA(2)\n\n                        if (LA58_1 == ID or LA58_1 == INT or LA58_1 == STRING) :\n                            alt58 = 1\n\n\n\n\n                    if alt58 == 1:\n                        # Expr.g:345:19: ',' property\n                        pass \n                        char_literal251 = self.match(self.input, 82, self.FOLLOW_82_in_object_decl2151) \n                        if self._state.backtracking == 0:\n                            stream_82.add(char_literal251)\n\n\n                        self._state.following.append(self.FOLLOW_property_in_object_decl2153)\n                        property252 = self.property()\n\n                        self._state.following.pop()\n                        if self._state.backtracking == 0:\n                            stream_property.add(property252.tree)\n\n\n\n                    else:\n                        break #loop58\n\n\n                # Expr.g:345:34: ( ',' )?\n                alt59 = 2\n                LA59_0 = self.input.LA(1)\n\n                if (LA59_0 == 82) :\n                    alt59 = 1\n                if alt59 == 1:\n                    # Expr.g:345:34: ','\n                    pass \n                    char_literal253 = self.match(self.input, 82, self.FOLLOW_82_in_object_decl2157) \n                    if self._state.backtracking == 0:\n                        stream_82.add(char_literal253)\n\n\n\n\n\n                char_literal254 = self.match(self.input, 136, self.FOLLOW_136_in_object_decl2160) \n                if self._state.backtracking == 0:\n                    stream_136.add(char_literal254)\n\n\n                # AST Rewrite\n                # elements: property\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 346:3: -> ^( OBJECT ( property )* )\n                    # Expr.g:346:6: ^( OBJECT ( property )* )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(OBJECT, \"OBJECT\")\n                    , root_1)\n\n                    # Expr.g:346:15: ( property )*\n                    while stream_property.hasNext():\n                        self._adaptor.addChild(root_1, stream_property.nextTree())\n\n\n                    stream_property.reset();\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"object_decl\"\n\n\n    class property_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.property_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"property\"\n    # Expr.g:348:1: property : ( ID | STRING | INT ) ':' expr ;\n    def property(self, ):\n        retval = self.property_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        set255 = None\n        char_literal256 = None\n        expr257 = None\n\n        set255_tree = None\n        char_literal256_tree = None\n\n        try:\n            try:\n                # Expr.g:349:2: ( ( ID | STRING | INT ) ':' expr )\n                # Expr.g:349:4: ( ID | STRING | INT ) ':' expr\n                pass \n                root_0 = self._adaptor.nil()\n\n\n                set255 = self.input.LT(1)\n\n                if self.input.LA(1) == ID or self.input.LA(1) == INT or self.input.LA(1) == STRING:\n                    self.input.consume()\n                    if self._state.backtracking == 0:\n                        self._adaptor.addChild(root_0, self._adaptor.createWithPayload(set255))\n\n                    self._state.errorRecovery = False\n\n\n                else:\n                    if self._state.backtracking > 0:\n                        raise BacktrackingFailed\n\n\n                    mse = MismatchedSetException(None, self.input)\n                    raise mse\n\n\n\n                char_literal256 = self.match(self.input, 91, self.FOLLOW_91_in_property2193)\n                if self._state.backtracking == 0:\n                    char_literal256_tree = self._adaptor.createWithPayload(char_literal256)\n                    self._adaptor.addChild(root_0, char_literal256_tree)\n\n\n\n                self._state.following.append(self.FOLLOW_expr_in_property2195)\n                expr257 = self.expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    self._adaptor.addChild(root_0, expr257.tree)\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"property\"\n\n\n    class sprintf_return(ParserRuleReturnScope):\n        def __init__(self):\n            super(ExprParser.sprintf_return, self).__init__()\n\n            self.tree = None\n\n\n\n\n\n    # $ANTLR start \"sprintf\"\n    # Expr.g:353:1: sprintf : 'sprintf' '(' expr ( ',' expr_list )? ')' -> ^( SPRINTF expr ( expr_list )? ) ;\n    def sprintf(self, ):\n        retval = self.sprintf_return()\n        retval.start = self.input.LT(1)\n\n\n        root_0 = None\n\n        string_literal258 = None\n        char_literal259 = None\n        char_literal261 = None\n        char_literal263 = None\n        expr260 = None\n        expr_list262 = None\n\n        string_literal258_tree = None\n        char_literal259_tree = None\n        char_literal261_tree = None\n        char_literal263_tree = None\n        stream_126 = RewriteRuleTokenStream(self._adaptor, \"token 126\")\n        stream_82 = RewriteRuleTokenStream(self._adaptor, \"token 82\")\n        stream_75 = RewriteRuleTokenStream(self._adaptor, \"token 75\")\n        stream_76 = RewriteRuleTokenStream(self._adaptor, \"token 76\")\n        stream_expr = RewriteRuleSubtreeStream(self._adaptor, \"rule expr\")\n        stream_expr_list = RewriteRuleSubtreeStream(self._adaptor, \"rule expr_list\")\n        try:\n            try:\n                # Expr.g:354:2: ( 'sprintf' '(' expr ( ',' expr_list )? ')' -> ^( SPRINTF expr ( expr_list )? ) )\n                # Expr.g:354:4: 'sprintf' '(' expr ( ',' expr_list )? ')'\n                pass \n                string_literal258 = self.match(self.input, 126, self.FOLLOW_126_in_sprintf2207) \n                if self._state.backtracking == 0:\n                    stream_126.add(string_literal258)\n\n\n                char_literal259 = self.match(self.input, 75, self.FOLLOW_75_in_sprintf2209) \n                if self._state.backtracking == 0:\n                    stream_75.add(char_literal259)\n\n\n                self._state.following.append(self.FOLLOW_expr_in_sprintf2211)\n                expr260 = self.expr()\n\n                self._state.following.pop()\n                if self._state.backtracking == 0:\n                    stream_expr.add(expr260.tree)\n\n\n                # Expr.g:354:23: ( ',' expr_list )?\n                alt60 = 2\n                LA60_0 = self.input.LA(1)\n\n                if (LA60_0 == 82) :\n                    alt60 = 1\n                if alt60 == 1:\n                    # Expr.g:354:24: ',' expr_list\n                    pass \n                    char_literal261 = self.match(self.input, 82, self.FOLLOW_82_in_sprintf2214) \n                    if self._state.backtracking == 0:\n                        stream_82.add(char_literal261)\n\n\n                    self._state.following.append(self.FOLLOW_expr_list_in_sprintf2216)\n                    expr_list262 = self.expr_list()\n\n                    self._state.following.pop()\n                    if self._state.backtracking == 0:\n                        stream_expr_list.add(expr_list262.tree)\n\n\n\n\n\n                char_literal263 = self.match(self.input, 76, self.FOLLOW_76_in_sprintf2220) \n                if self._state.backtracking == 0:\n                    stream_76.add(char_literal263)\n\n\n                # AST Rewrite\n                # elements: expr_list, expr\n                # token labels: \n                # rule labels: retval\n                # token list labels: \n                # rule list labels: \n                # wildcard labels: \n                if self._state.backtracking == 0:\n                    retval.tree = root_0\n                    if retval is not None:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"rule retval\", retval.tree)\n                    else:\n                        stream_retval = RewriteRuleSubtreeStream(self._adaptor, \"token retval\", None)\n\n\n                    root_0 = self._adaptor.nil()\n                    # 355:3: -> ^( SPRINTF expr ( expr_list )? )\n                    # Expr.g:355:6: ^( SPRINTF expr ( expr_list )? )\n                    root_1 = self._adaptor.nil()\n                    root_1 = self._adaptor.becomeRoot(\n                    self._adaptor.createFromType(SPRINTF, \"SPRINTF\")\n                    , root_1)\n\n                    self._adaptor.addChild(root_1, stream_expr.nextTree())\n\n                    # Expr.g:355:21: ( expr_list )?\n                    if stream_expr_list.hasNext():\n                        self._adaptor.addChild(root_1, stream_expr_list.nextTree())\n\n\n                    stream_expr_list.reset();\n\n                    self._adaptor.addChild(root_0, root_1)\n\n\n\n\n                    retval.tree = root_0\n\n\n\n\n\n                retval.stop = self.input.LT(-1)\n\n\n                if self._state.backtracking == 0:\n                    retval.tree = self._adaptor.rulePostProcessing(root_0)\n                    self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)\n\n\n\n            except RecognitionException, re:\n                self.reportError(re)\n                self.recover(self.input, re)\n                retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)\n\n        finally:\n            pass\n        return retval\n\n    # $ANTLR end \"sprintf\"\n\n    # $ANTLR start \"synpred1_Expr\"\n    def synpred1_Expr_fragment(self, ):\n        # Expr.g:232:4: ( '[' expr ']' )\n        # Expr.g:232:4: '[' expr ']'\n        pass \n        root_0 = self._adaptor.nil()\n\n\n        self.match(self.input, 100, self.FOLLOW_100_in_synpred1_Expr1439)\n\n\n        self._state.following.append(self.FOLLOW_expr_in_synpred1_Expr1441)\n        self.expr()\n\n        self._state.following.pop()\n\n\n        self.match(self.input, 101, self.FOLLOW_101_in_synpred1_Expr1443)\n\n\n\n\n    # $ANTLR end \"synpred1_Expr\"\n\n\n\n\n    def synpred1_Expr(self):\n        self._state.backtracking += 1\n        start = self.input.mark()\n        try:\n            self.synpred1_Expr_fragment()\n        except BacktrackingFailed:\n            success = False\n        else:\n            success = True\n        self.input.rewind(start)\n        self._state.backtracking -= 1\n        return success\n\n\n\n    # lookup tables for DFA #6\n\n    DFA6_eot = DFA.unpack(\n        u\"\\6\\uffff\"\n        )\n\n    DFA6_eof = DFA.unpack(\n        u\"\\6\\uffff\"\n        )\n\n    DFA6_min = DFA.unpack(\n        u\"\\1\\42\\1\\122\\1\\42\\2\\uffff\\1\\122\"\n        )\n\n    DFA6_max = DFA.unpack(\n        u\"\\1\\42\\1\\134\\1\\42\\2\\uffff\\1\\134\"\n        )\n\n    DFA6_accept = DFA.unpack(\n        u\"\\3\\uffff\\1\\1\\1\\2\\1\\uffff\"\n        )\n\n    DFA6_special = DFA.unpack(\n        u\"\\6\\uffff\"\n        )\n\n\n    DFA6_transition = [\n        DFA.unpack(u\"\\1\\1\"),\n        DFA.unpack(u\"\\1\\3\\3\\uffff\\1\\2\\1\\4\\4\\uffff\\1\\3\"),\n        DFA.unpack(u\"\\1\\5\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\"),\n        DFA.unpack(u\"\\1\\3\\3\\uffff\\1\\2\\1\\4\\4\\uffff\\1\\3\")\n    ]\n\n    # class definition for DFA #6\n\n    class DFA6(DFA):\n        pass\n\n\n \n\n    FOLLOW_EOF_in_prog211 = frozenset([1])\n    FOLLOW_stmt_in_prog220 = frozenset([1, 34, 80, 84, 92, 105, 108, 109, 111, 115, 116, 117, 118, 119, 122, 123, 125, 128, 129, 130, 131])\n    FOLLOW_92_in_stmt232 = frozenset([1])\n    FOLLOW_exec_stmt_in_stmt239 = frozenset([1])\n    FOLLOW_import_stmt_in_stmt244 = frozenset([1])\n    FOLLOW_print_stmt_in_stmt249 = frozenset([1])\n    FOLLOW_printf_stmt_in_stmt253 = frozenset([1])\n    FOLLOW_break_stmt_in_stmt258 = frozenset([1])\n    FOLLOW_continue_stmt_in_stmt263 = frozenset([1])\n    FOLLOW_return_stmt_in_stmt268 = frozenset([1])\n    FOLLOW_if_stmt_in_stmt273 = frozenset([1])\n    FOLLOW_while_stmt_in_stmt278 = frozenset([1])\n    FOLLOW_do_while_stmt_in_stmt283 = frozenset([1])\n    FOLLOW_switch_stmt_in_stmt288 = frozenset([1])\n    FOLLOW_for_stmt_in_stmt293 = frozenset([1])\n    FOLLOW_foreach_stmt_in_stmt298 = frozenset([1])\n    FOLLOW_throw_stmt_in_stmt303 = frozenset([1])\n    FOLLOW_try_stmt_in_stmt308 = frozenset([1])\n    FOLLOW_func_decl_in_stmt313 = frozenset([1])\n    FOLLOW_class_decl_in_stmt318 = frozenset([1])\n    FOLLOW_132_in_block331 = frozenset([34, 80, 84, 92, 105, 108, 109, 111, 115, 116, 117, 118, 119, 122, 123, 125, 128, 129, 130, 131, 136])\n    FOLLOW_stmt_in_block333 = frozenset([34, 80, 84, 92, 105, 108, 109, 111, 115, 116, 117, 118, 119, 122, 123, 125, 128, 129, 130, 131, 136])\n    FOLLOW_136_in_block336 = frozenset([1])\n    FOLLOW_119_in_import_stmt358 = frozenset([34])\n    FOLLOW_module_path_in_import_stmt360 = frozenset([82, 92])\n    FOLLOW_82_in_import_stmt363 = frozenset([34])\n    FOLLOW_module_path_in_import_stmt365 = frozenset([82, 92])\n    FOLLOW_92_in_import_stmt369 = frozenset([1])\n    FOLLOW_module_in_module_path390 = frozenset([1])\n    FOLLOW_module_in_module_path395 = frozenset([87])\n    FOLLOW_87_in_module_path397 = frozenset([1])\n    FOLLOW_123_in_printf_stmt408 = frozenset([75])\n    FOLLOW_75_in_printf_stmt410 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_printf_stmt412 = frozenset([76, 82])\n    FOLLOW_82_in_printf_stmt415 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_list_in_printf_stmt417 = frozenset([76])\n    FOLLOW_76_in_printf_stmt421 = frozenset([92])\n    FOLLOW_92_in_printf_stmt423 = frozenset([1])\n    FOLLOW_122_in_print_stmt452 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_list_in_print_stmt455 = frozenset([92])\n    FOLLOW_92_in_print_stmt457 = frozenset([1])\n    FOLLOW_105_in_break_stmt478 = frozenset([92])\n    FOLLOW_92_in_break_stmt480 = frozenset([1])\n    FOLLOW_109_in_continue_stmt496 = frozenset([92])\n    FOLLOW_92_in_continue_stmt498 = frozenset([1])\n    FOLLOW_125_in_return_stmt514 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 92, 100, 121, 126, 132])\n    FOLLOW_expr_in_return_stmt516 = frozenset([92])\n    FOLLOW_92_in_return_stmt519 = frozenset([1])\n    FOLLOW_if_clause_in_if_stmt541 = frozenset([1, 112])\n    FOLLOW_else_if_clause_in_if_stmt543 = frozenset([1, 112])\n    FOLLOW_else_clause_in_if_stmt546 = frozenset([1])\n    FOLLOW_118_in_if_clause557 = frozenset([75])\n    FOLLOW_75_in_if_clause559 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_if_clause561 = frozenset([76])\n    FOLLOW_76_in_if_clause563 = frozenset([132])\n    FOLLOW_block_in_if_clause565 = frozenset([1])\n    FOLLOW_112_in_else_if_clause587 = frozenset([118])\n    FOLLOW_if_clause_in_else_if_clause589 = frozenset([1])\n    FOLLOW_112_in_else_clause609 = frozenset([132])\n    FOLLOW_block_in_else_clause611 = frozenset([1])\n    FOLLOW_131_in_while_stmt632 = frozenset([75])\n    FOLLOW_75_in_while_stmt634 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_while_stmt636 = frozenset([76])\n    FOLLOW_76_in_while_stmt638 = frozenset([132])\n    FOLLOW_block_in_while_stmt640 = frozenset([1])\n    FOLLOW_111_in_do_while_stmt663 = frozenset([132])\n    FOLLOW_block_in_do_while_stmt665 = frozenset([131])\n    FOLLOW_131_in_do_while_stmt667 = frozenset([75])\n    FOLLOW_75_in_do_while_stmt669 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_do_while_stmt671 = frozenset([76])\n    FOLLOW_76_in_do_while_stmt673 = frozenset([92])\n    FOLLOW_92_in_do_while_stmt675 = frozenset([1])\n    FOLLOW_128_in_switch_stmt698 = frozenset([75])\n    FOLLOW_75_in_switch_stmt700 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_switch_stmt702 = frozenset([76])\n    FOLLOW_76_in_switch_stmt704 = frozenset([132])\n    FOLLOW_case_block_in_switch_stmt706 = frozenset([1])\n    FOLLOW_132_in_case_block728 = frozenset([106])\n    FOLLOW_case_clause_in_case_block731 = frozenset([106, 110, 136])\n    FOLLOW_default_clause_in_case_block736 = frozenset([136])\n    FOLLOW_136_in_case_block740 = frozenset([1])\n    FOLLOW_case_test_in_case_clause750 = frozenset([34, 80, 84, 92, 105, 106, 108, 109, 111, 115, 116, 117, 118, 119, 122, 123, 125, 128, 129, 130, 131])\n    FOLLOW_stmt_in_case_clause753 = frozenset([34, 80, 84, 92, 105, 108, 109, 111, 115, 116, 117, 118, 119, 122, 123, 125, 128, 129, 130, 131])\n    FOLLOW_break_stmt_in_case_clause756 = frozenset([1])\n    FOLLOW_106_in_case_test782 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_case_test784 = frozenset([91])\n    FOLLOW_91_in_case_test786 = frozenset([1])\n    FOLLOW_110_in_default_clause806 = frozenset([91])\n    FOLLOW_91_in_default_clause808 = frozenset([1, 34, 80, 84, 92, 105, 108, 109, 111, 115, 116, 117, 118, 119, 122, 123, 125, 128, 129, 130, 131])\n    FOLLOW_stmt_in_default_clause810 = frozenset([1, 34, 80, 84, 92, 105, 108, 109, 111, 115, 116, 117, 118, 119, 122, 123, 125, 128, 129, 130, 131])\n    FOLLOW_115_in_for_stmt833 = frozenset([75])\n    FOLLOW_75_in_for_stmt835 = frozenset([34, 80, 84, 92])\n    FOLLOW_exec_list_in_for_stmt839 = frozenset([92])\n    FOLLOW_92_in_for_stmt842 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_for_stmt844 = frozenset([92])\n    FOLLOW_92_in_for_stmt846 = frozenset([34, 76, 80, 84])\n    FOLLOW_exec_list_in_for_stmt850 = frozenset([76])\n    FOLLOW_76_in_for_stmt853 = frozenset([132])\n    FOLLOW_block_in_for_stmt855 = frozenset([1])\n    FOLLOW_116_in_foreach_stmt886 = frozenset([75])\n    FOLLOW_75_in_foreach_stmt888 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_foreach_stmt890 = frozenset([104])\n    FOLLOW_104_in_foreach_stmt892 = frozenset([34])\n    FOLLOW_each_in_foreach_stmt894 = frozenset([76])\n    FOLLOW_76_in_foreach_stmt896 = frozenset([132])\n    FOLLOW_block_in_foreach_stmt898 = frozenset([1])\n    FOLLOW_each_val_in_each922 = frozenset([1])\n    FOLLOW_ID_in_each937 = frozenset([97])\n    FOLLOW_97_in_each939 = frozenset([34])\n    FOLLOW_each_val_in_each941 = frozenset([1])\n    FOLLOW_ID_in_each_val963 = frozenset([1, 82])\n    FOLLOW_82_in_each_val966 = frozenset([34])\n    FOLLOW_ID_in_each_val968 = frozenset([1, 82])\n    FOLLOW_129_in_throw_stmt993 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_throw_stmt995 = frozenset([92])\n    FOLLOW_92_in_throw_stmt997 = frozenset([1])\n    FOLLOW_130_in_try_stmt1017 = frozenset([132])\n    FOLLOW_block_in_try_stmt1019 = frozenset([107])\n    FOLLOW_catch_clause_in_try_stmt1021 = frozenset([1, 107, 114])\n    FOLLOW_finally_clause_in_try_stmt1024 = frozenset([1])\n    FOLLOW_107_in_catch_clause1051 = frozenset([75])\n    FOLLOW_75_in_catch_clause1053 = frozenset([34])\n    FOLLOW_module_in_catch_clause1055 = frozenset([34, 76])\n    FOLLOW_ID_in_catch_clause1057 = frozenset([76])\n    FOLLOW_76_in_catch_clause1060 = frozenset([132])\n    FOLLOW_block_in_catch_clause1062 = frozenset([1])\n    FOLLOW_114_in_finally_clause1087 = frozenset([132])\n    FOLLOW_block_in_finally_clause1089 = frozenset([1])\n    FOLLOW_117_in_func_decl1111 = frozenset([34])\n    FOLLOW_ID_in_func_decl1113 = frozenset([75])\n    FOLLOW_params_in_func_decl1115 = frozenset([132])\n    FOLLOW_block_in_func_decl1117 = frozenset([1])\n    FOLLOW_75_in_params1141 = frozenset([34, 76, 82])\n    FOLLOW_param_decl_in_params1143 = frozenset([76, 82])\n    FOLLOW_82_in_params1147 = frozenset([34])\n    FOLLOW_param_decl_in_params1149 = frozenset([76, 82])\n    FOLLOW_76_in_params1153 = frozenset([1])\n    FOLLOW_ID_in_param_decl1174 = frozenset([1, 95])\n    FOLLOW_95_in_param_decl1177 = frozenset([8, 30, 34, 39, 47, 61, 75, 100, 121, 126, 132])\n    FOLLOW_atom_in_param_decl1179 = frozenset([1])\n    FOLLOW_108_in_class_decl1192 = frozenset([34])\n    FOLLOW_ID_in_class_decl1194 = frozenset([113, 132])\n    FOLLOW_113_in_class_decl1197 = frozenset([34])\n    FOLLOW_ID_in_class_decl1199 = frozenset([132])\n    FOLLOW_132_in_class_decl1205 = frozenset([117, 124, 136])\n    FOLLOW_class_element_in_class_decl1207 = frozenset([117, 124, 136])\n    FOLLOW_136_in_class_decl1210 = frozenset([1])\n    FOLLOW_var_def_in_class_element1236 = frozenset([1])\n    FOLLOW_constructor_in_class_element1240 = frozenset([1])\n    FOLLOW_func_decl_in_class_element1244 = frozenset([1])\n    FOLLOW_124_in_var_def1254 = frozenset([34])\n    FOLLOW_ID_in_var_def1256 = frozenset([92, 95])\n    FOLLOW_95_in_var_def1259 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_var_def1261 = frozenset([92])\n    FOLLOW_92_in_var_def1265 = frozenset([1])\n    FOLLOW_124_in_var_def1283 = frozenset([127])\n    FOLLOW_127_in_var_def1285 = frozenset([34])\n    FOLLOW_ID_in_var_def1287 = frozenset([92, 95])\n    FOLLOW_95_in_var_def1290 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_var_def1292 = frozenset([92])\n    FOLLOW_92_in_var_def1296 = frozenset([1])\n    FOLLOW_117_in_constructor1321 = frozenset([120])\n    FOLLOW_120_in_constructor1323 = frozenset([75])\n    FOLLOW_params_in_constructor1325 = frozenset([132])\n    FOLLOW_block_in_constructor1327 = frozenset([1])\n    FOLLOW_primary_in_member_expr1354 = frozenset([1, 86])\n    FOLLOW_86_in_member_expr1357 = frozenset([34])\n    FOLLOW_primary_in_member_expr1359 = frozenset([1, 86])\n    FOLLOW_ID_in_primary1382 = frozenset([1, 75, 100])\n    FOLLOW_index_expr_in_primary1384 = frozenset([1, 75, 100])\n    FOLLOW_call_expr_in_primary1387 = frozenset([1])\n    FOLLOW_75_in_call_expr1398 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 76, 83, 100, 121, 126, 132])\n    FOLLOW_expr_list_in_call_expr1400 = frozenset([76])\n    FOLLOW_76_in_call_expr1403 = frozenset([1])\n    FOLLOW_100_in_index_expr1439 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_index_expr1441 = frozenset([101])\n    FOLLOW_101_in_index_expr1443 = frozenset([1])\n    FOLLOW_100_in_index_expr1458 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_index_expr1460 = frozenset([88])\n    FOLLOW_88_in_index_expr1462 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 101, 121, 126, 132])\n    FOLLOW_expr_in_index_expr1464 = frozenset([101])\n    FOLLOW_101_in_index_expr1467 = frozenset([1])\n    FOLLOW_exec_expr_in_exec_list1492 = frozenset([1, 82])\n    FOLLOW_82_in_exec_list1495 = frozenset([34, 80, 84])\n    FOLLOW_exec_expr_in_exec_list1497 = frozenset([1, 82])\n    FOLLOW_member_expr_in_member_list1520 = frozenset([1, 82])\n    FOLLOW_82_in_member_list1523 = frozenset([34])\n    FOLLOW_member_expr_in_member_list1525 = frozenset([1, 82])\n    FOLLOW_member_expr_in_exec_expr1537 = frozenset([1, 71, 74, 78, 80, 81, 84, 85, 90, 95, 103, 134])\n    FOLLOW_assign_op_in_exec_expr1542 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_exec_expr1544 = frozenset([1])\n    FOLLOW_80_in_exec_expr1565 = frozenset([1])\n    FOLLOW_84_in_exec_expr1582 = frozenset([1])\n    FOLLOW_80_in_exec_expr1613 = frozenset([34])\n    FOLLOW_member_expr_in_exec_expr1615 = frozenset([1])\n    FOLLOW_84_in_exec_expr1630 = frozenset([34])\n    FOLLOW_member_expr_in_exec_expr1632 = frozenset([1])\n    FOLLOW_exec_list_in_exec_stmt1678 = frozenset([92])\n    FOLLOW_92_in_exec_stmt1680 = frozenset([1])\n    FOLLOW_expr_in_expr_list1703 = frozenset([1, 82])\n    FOLLOW_82_in_expr_list1706 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_expr_list1708 = frozenset([1, 82])\n    FOLLOW_82_in_expr_list1712 = frozenset([1])\n    FOLLOW_logic_or_expr_in_expr1734 = frozenset([1])\n    FOLLOW_logic_and_expr_in_logic_or_expr1744 = frozenset([1, 135])\n    FOLLOW_135_in_logic_or_expr1747 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_logic_and_expr_in_logic_or_expr1750 = frozenset([1, 135])\n    FOLLOW_bitwise_or_expr_in_logic_and_expr1762 = frozenset([1, 72])\n    FOLLOW_72_in_logic_and_expr1765 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_bitwise_or_expr_in_logic_and_expr1768 = frozenset([1, 72])\n    FOLLOW_bitwise_xor_expr_in_bitwise_or_expr1780 = frozenset([1, 133])\n    FOLLOW_133_in_bitwise_or_expr1783 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_bitwise_xor_expr_in_bitwise_or_expr1786 = frozenset([1, 133])\n    FOLLOW_bitwise_and_expr_in_bitwise_xor_expr1798 = frozenset([1, 102])\n    FOLLOW_102_in_bitwise_xor_expr1801 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_bitwise_and_expr_in_bitwise_xor_expr1804 = frozenset([1, 102])\n    FOLLOW_relation_expr_in_bitwise_and_expr1816 = frozenset([1, 73])\n    FOLLOW_73_in_bitwise_and_expr1819 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_relation_expr_in_bitwise_and_expr1822 = frozenset([1, 73])\n    FOLLOW_add_expr_in_relation_expr1834 = frozenset([1, 69, 93, 94, 96, 98, 99])\n    FOLLOW_set_in_relation_expr1837 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_add_expr_in_relation_expr1852 = frozenset([1])\n    FOLLOW_mul_expr_in_add_expr1864 = frozenset([1, 79, 83])\n    FOLLOW_set_in_add_expr1867 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_mul_expr_in_add_expr1874 = frozenset([1, 79, 83])\n    FOLLOW_not_expr_in_mul_expr1886 = frozenset([1, 70, 77, 89])\n    FOLLOW_set_in_mul_expr1889 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_not_expr_in_mul_expr1898 = frozenset([1, 70, 77, 89])\n    FOLLOW_68_in_not_expr1912 = frozenset([8, 30, 34, 39, 47, 61, 75, 83, 100, 121, 126, 132])\n    FOLLOW_negative_expr_in_not_expr1915 = frozenset([1])\n    FOLLOW_83_in_negative_expr1950 = frozenset([8, 30, 34, 39, 47, 61, 75, 100, 121, 126, 132])\n    FOLLOW_atom_in_negative_expr1954 = frozenset([1])\n    FOLLOW_literal_in_atom1987 = frozenset([1])\n    FOLLOW_member_expr_in_atom1992 = frozenset([1])\n    FOLLOW_array_decl_in_atom1997 = frozenset([1])\n    FOLLOW_object_decl_in_atom2002 = frozenset([1])\n    FOLLOW_new_clause_in_atom2007 = frozenset([1])\n    FOLLOW_sprintf_in_atom2012 = frozenset([1])\n    FOLLOW_75_in_atom2017 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_atom2019 = frozenset([76])\n    FOLLOW_76_in_atom2021 = frozenset([1])\n    FOLLOW_121_in_new_clause2062 = frozenset([34])\n    FOLLOW_module_in_new_clause2064 = frozenset([75])\n    FOLLOW_call_expr_in_new_clause2066 = frozenset([1])\n    FOLLOW_ID_in_module2088 = frozenset([1, 86])\n    FOLLOW_86_in_module2091 = frozenset([34])\n    FOLLOW_ID_in_module2093 = frozenset([1, 86])\n    FOLLOW_100_in_array_decl2118 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 101, 121, 126, 132])\n    FOLLOW_expr_list_in_array_decl2120 = frozenset([101])\n    FOLLOW_101_in_array_decl2123 = frozenset([1])\n    FOLLOW_132_in_object_decl2145 = frozenset([34, 39, 61, 82, 136])\n    FOLLOW_property_in_object_decl2147 = frozenset([82, 136])\n    FOLLOW_82_in_object_decl2151 = frozenset([34, 39, 61])\n    FOLLOW_property_in_object_decl2153 = frozenset([82, 136])\n    FOLLOW_82_in_object_decl2157 = frozenset([136])\n    FOLLOW_136_in_object_decl2160 = frozenset([1])\n    FOLLOW_set_in_property2181 = frozenset([91])\n    FOLLOW_91_in_property2193 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_property2195 = frozenset([1])\n    FOLLOW_126_in_sprintf2207 = frozenset([75])\n    FOLLOW_75_in_sprintf2209 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_sprintf2211 = frozenset([76, 82])\n    FOLLOW_82_in_sprintf2214 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_list_in_sprintf2216 = frozenset([76])\n    FOLLOW_76_in_sprintf2220 = frozenset([1])\n    FOLLOW_100_in_synpred1_Expr1439 = frozenset([8, 30, 34, 39, 47, 61, 68, 75, 83, 100, 121, 126, 132])\n    FOLLOW_expr_in_synpred1_Expr1441 = frozenset([101])\n    FOLLOW_101_in_synpred1_Expr1443 = frozenset([1])\n\n\n\ndef main(argv, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr):\n    from antlr3.main import ParserMain\n    main = ParserMain(\"ExprLexer\", ExprParser)\n\n    main.stdin = stdin\n    main.stdout = stdout\n    main.stderr = stderr\n    main.execute(argv)\n\n\n\nif __name__ == '__main__':\n    main(sys.argv)\n"
  },
  {
    "path": "deps/cpy/Makefile",
    "content": "\nall: antlr test\n\nantlr:\n\tjava -jar ../antlr-3.4-complete.jar Expr.g Eval.g\n\nlexer:\n\tjava -jar ../antlr-3.4-complete.jar Expr.g\n\tpython test_lexer.py test.cpy\n\ntest:\n\tpython cpy.py test.cpy\n\nrun:\n\tpython a.py\n\nclean:\n\trm -rf _cpy_\n\trm -f *.pyc\n\trm -f antlr3/*.pyc\n"
  },
  {
    "path": "deps/cpy/Readme.txt",
    "content": "**********************************************\n* Author: ideawu\n* Link: http://www.ideawu.net/\n* Cpy - Cpy provides you a way to write Python\n*       codes in C syntax!\n**********************************************\n\n* Run the samples\n\t$ ./cpy samples/hello.cpy\n\n* Compile Antlr grammar files\n\t$ make antlr\n"
  },
  {
    "path": "deps/cpy/antlr3/__init__.py",
    "content": "\"\"\" @package antlr3\n@brief ANTLR3 runtime package\n\nThis module contains all support classes, which are needed to use recognizers\ngenerated by ANTLR3.\n\n@mainpage\n\n\\note Please be warned that the line numbers in the API documentation do not\nmatch the real locations in the source code of the package. This is an\nunintended artifact of doxygen, which I could only convince to use the\ncorrect module names by concatenating all files from the package into a single\nmodule file...\n\nHere is a little overview over the most commonly used classes provided by\nthis runtime:\n\n@section recognizers Recognizers\n\nThese recognizers are baseclasses for the code which is generated by ANTLR3.\n\n- BaseRecognizer: Base class with common recognizer functionality.\n- Lexer: Base class for lexers.\n- Parser: Base class for parsers.\n- tree.TreeParser: Base class for %tree parser.\n\n@section streams Streams\n\nEach recognizer pulls its input from one of the stream classes below. Streams\nhandle stuff like buffering, look-ahead and seeking.\n\nA character stream is usually the first element in the pipeline of a typical\nANTLR3 application. It is used as the input for a Lexer.\n\n- ANTLRStringStream: Reads from a string objects. The input should be a unicode\n  object, or ANTLR3 will have trouble decoding non-ascii data.\n- ANTLRFileStream: Opens a file and read the contents, with optional character\n  decoding.\n- ANTLRInputStream: Reads the date from a file-like object, with optional\n  character decoding.\n\nA Parser needs a TokenStream as input (which in turn is usually fed by a\nLexer):\n\n- CommonTokenStream: A basic and most commonly used TokenStream\n  implementation.\n- TokenRewriteStream: A modification of CommonTokenStream that allows the\n  stream to be altered (by the Parser). See the 'tweak' example for a usecase.\n\nAnd tree.TreeParser finally fetches its input from a tree.TreeNodeStream:\n\n- tree.CommonTreeNodeStream: A basic and most commonly used tree.TreeNodeStream\n  implementation.\n  \n\n@section tokenstrees Tokens and Trees\n\nA Lexer emits Token objects which are usually buffered by a TokenStream. A\nParser can build a Tree, if the output=AST option has been set in the grammar.\n\nThe runtime provides these Token implementations:\n\n- CommonToken: A basic and most commonly used Token implementation.\n- ClassicToken: A Token object as used in ANTLR 2.x, used to %tree\n  construction.\n\nTree objects are wrapper for Token objects.\n\n- tree.CommonTree: A basic and most commonly used Tree implementation.\n\nA tree.TreeAdaptor is used by the parser to create tree.Tree objects for the\ninput Token objects.\n\n- tree.CommonTreeAdaptor: A basic and most commonly used tree.TreeAdaptor\nimplementation.\n\n\n@section Exceptions\n\nRecognitionException are generated, when a recognizer encounters incorrect\nor unexpected input.\n\n- RecognitionException\n  - MismatchedRangeException\n  - MismatchedSetException\n    - MismatchedNotSetException\n    .\n  - MismatchedTokenException\n  - MismatchedTreeNodeException\n  - NoViableAltException\n  - EarlyExitException\n  - FailedPredicateException\n  .\n.\n\nA tree.RewriteCardinalityException is raised, when the parsers hits a\ncardinality mismatch during AST construction. Although this is basically a\nbug in your grammar, it can only be detected at runtime.\n\n- tree.RewriteCardinalityException\n  - tree.RewriteEarlyExitException\n  - tree.RewriteEmptyStreamException\n  .\n.\n\n\"\"\"\n\n# tree.RewriteRuleElementStream\n# tree.RewriteRuleSubtreeStream\n# tree.RewriteRuleTokenStream\n# CharStream\n# DFA\n# TokenSource\n\n# [The \"BSD licence\"]\n# Copyright (c) 2005-2008 Terence Parr\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. The name of the author may not be used to endorse or promote products\n#    derived from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n# NOT 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 OF\n# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n__version__ = '3.0.1.0'\n\ndef version_str_to_tuple(version_str):\n    import re\n    import sys\n\n    if version_str == 'HEAD':\n        return (sys.maxint, sys.maxint, sys.maxint, sys.maxint)\n\n    m = re.match(r'(\\d+)\\.(\\d+)(\\.(\\d+))?(\\.(\\d+))?', version_str)\n    if m is None:\n        raise ValueError(\"Bad version string %r\" % version_str)\n\n    major = int(m.group(1))\n    minor = int(m.group(2))\n    patch = int(m.group(4) or 0)\n    beta = int(m.group(6) or sys.maxint)\n\n    return (major, minor, patch, beta)\n\n\nruntime_version_str = __version__\nruntime_version = version_str_to_tuple(runtime_version_str)\n\n\nfrom constants import *\nfrom dfa import *\nfrom exceptions import *\nfrom recognizers import *\nfrom streams import *\nfrom tokens import *\n"
  },
  {
    "path": "deps/cpy/antlr3/compat.py",
    "content": "\"\"\"Compatibility stuff\"\"\"\n\n# begin[licence]\n#\n# [The \"BSD licence\"]\n# Copyright (c) 2005-2008 Terence Parr\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. The name of the author may not be used to endorse or promote products\n#    derived from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n# NOT 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 OF\n# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#\n# end[licence]\n\ntry:\n    set = set\n    frozenset = frozenset\nexcept NameError:\n    from sets import Set as set, ImmutableSet as frozenset\n\n\ntry:\n    reversed = reversed\nexcept NameError:\n    def reversed(l):\n        l = l[:]\n        l.reverse()\n        return l\n\n\n"
  },
  {
    "path": "deps/cpy/antlr3/constants.py",
    "content": "\"\"\"ANTLR3 runtime package\"\"\"\n\n# begin[licence]\n#\n# [The \"BSD licence\"]\n# Copyright (c) 2005-2008 Terence Parr\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. The name of the author may not be used to endorse or promote products\n#    derived from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n# NOT 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 OF\n# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#\n# end[licence]\n\nEOF = -1\n\n## All tokens go to the parser (unless skip() is called in that rule)\n# on a particular \"channel\".  The parser tunes to a particular channel\n# so that whitespace etc... can go to the parser on a \"hidden\" channel.\nDEFAULT_CHANNEL = 0\n\n## Anything on different channel than DEFAULT_CHANNEL is not parsed\n# by parser.\nHIDDEN_CHANNEL = 99\n\n# Predefined token types\nEOR_TOKEN_TYPE = 1\n\n##\n# imaginary tree navigation type; traverse \"get child\" link\nDOWN = 2\n##\n#imaginary tree navigation type; finish with a child list\nUP = 3\n\nMIN_TOKEN_TYPE = UP+1\n\t\nINVALID_TOKEN_TYPE = 0\n\n"
  },
  {
    "path": "deps/cpy/antlr3/dfa.py",
    "content": "\"\"\"ANTLR3 runtime package\"\"\"\n\n# begin[licence]\n#\n# [The \"BSD licence\"]\n# Copyright (c) 2005-2008 Terence Parr\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. The name of the author may not be used to endorse or promote products\n#    derived from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n# NOT 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 OF\n# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#\n# end[licensc]\n\nfrom antlr3.constants import EOF\nfrom antlr3.exceptions import NoViableAltException, BacktrackingFailed\n\n\nclass DFA(object):\n    \"\"\"@brief A DFA implemented as a set of transition tables.\n\n    Any state that has a semantic predicate edge is special; those states\n    are generated with if-then-else structures in a specialStateTransition()\n    which is generated by cyclicDFA template.\n    \n    \"\"\"\n    \n    def __init__(\n        self,\n        recognizer, decisionNumber,\n        eot, eof, min, max, accept, special, transition\n        ):\n        ## Which recognizer encloses this DFA?  Needed to check backtracking\n        self.recognizer = recognizer\n\n        self.decisionNumber = decisionNumber\n        self.eot = eot\n        self.eof = eof\n        self.min = min\n        self.max = max\n        self.accept = accept\n        self.special = special\n        self.transition = transition\n\n\n    def predict(self, input):\n        \"\"\"\n        From the input stream, predict what alternative will succeed\n\tusing this DFA (representing the covering regular approximation\n\tto the underlying CFL).  Return an alternative number 1..n.  Throw\n\t an exception upon error.\n\t\"\"\"\n        mark = input.mark()\n        s = 0 # we always start at s0\n        try:\n            for _ in xrange(50000):\n                #print \"***Current state = %d\" % s\n                \n                specialState = self.special[s]\n                if specialState >= 0:\n                    #print \"is special\"\n                    s = self.specialStateTransition(specialState, input)\n                    if s == -1:\n                        self.noViableAlt(s, input)\n                        return 0\n                    input.consume()\n                    continue\n\n                if self.accept[s] >= 1:\n                    #print \"accept state for alt %d\" % self.accept[s]\n                    return self.accept[s]\n\n                # look for a normal char transition\n                c = input.LA(1)\n\n                #print \"LA = %d (%r)\" % (c, unichr(c) if c >= 0 else 'EOF')\n                #print \"range = %d..%d\" % (self.min[s], self.max[s])\n\n                if c >= self.min[s] and c <= self.max[s]:\n                    # move to next state\n                    snext = self.transition[s][c-self.min[s]]\n                    #print \"in range, next state = %d\" % snext\n                    \n                    if snext < 0:\n                        #print \"not a normal transition\"\n                        # was in range but not a normal transition\n                        # must check EOT, which is like the else clause.\n                        # eot[s]>=0 indicates that an EOT edge goes to another\n                        # state.\n                        if self.eot[s] >= 0: # EOT Transition to accept state?\n                            #print \"EOT trans to accept state %d\" % self.eot[s]\n                            \n                            s = self.eot[s]\n                            input.consume()\n                            # TODO: I had this as return accept[eot[s]]\n                            # which assumed here that the EOT edge always\n                            # went to an accept...faster to do this, but\n                            # what about predicated edges coming from EOT\n                            # target?\n                            continue\n\n                        #print \"no viable alt\"\n                        self.noViableAlt(s, input)\n                        return 0\n\n                    s = snext\n                    input.consume()\n                    continue\n\n                if self.eot[s] >= 0:\n                    #print \"EOT to %d\" % self.eot[s]\n                    \n                    s = self.eot[s]\n                    input.consume()\n                    continue\n\n                # EOF Transition to accept state?\n                if c == EOF and self.eof[s] >= 0:\n                    #print \"EOF Transition to accept state %d\" \\\n                    #  % self.accept[self.eof[s]]\n                    return self.accept[self.eof[s]]\n\n                # not in range and not EOF/EOT, must be invalid symbol\n                self.noViableAlt(s, input)\n                return 0\n\n            else:\n                raise RuntimeError(\"DFA bang!\")\n            \n        finally:\n            input.rewind(mark)\n\n\n    def noViableAlt(self, s, input):\n        if self.recognizer._state.backtracking > 0:\n            raise BacktrackingFailed\n\n        nvae = NoViableAltException(\n            self.getDescription(),\n            self.decisionNumber,\n            s,\n            input\n            )\n\n        self.error(nvae)\n        raise nvae\n\n\n    def error(self, nvae):\n        \"\"\"A hook for debugging interface\"\"\"\n        pass\n\n\n    def specialStateTransition(self, s, input):\n        return -1\n\n\n    def getDescription(self):\n        return \"n/a\"\n\n\n##     def specialTransition(self, state, symbol):\n##         return 0\n\n\n    def unpack(cls, string):\n        \"\"\"@brief Unpack the runlength encoded table data.\n\n        Terence implemented packed table initializers, because Java has a\n        size restriction on .class files and the lookup tables can grow\n        pretty large. The generated JavaLexer.java of the Java.g example\n        would be about 15MB with uncompressed array initializers.\n\n        Python does not have any size restrictions, but the compilation of\n        such large source files seems to be pretty memory hungry. The memory\n        consumption of the python process grew to >1.5GB when importing a\n        15MB lexer, eating all my swap space and I was to impacient to see,\n        if it could finish at all. With packed initializers that are unpacked\n        at import time of the lexer module, everything works like a charm.\n        \n        \"\"\"\n        \n        ret = []\n        for i in range(len(string) / 2):\n            (n, v) = ord(string[i*2]), ord(string[i*2+1])\n\n            # Is there a bitwise operation to do this?\n            if v == 0xFFFF:\n                v = -1\n\n            ret += [v] * n\n\n        return ret\n    \n    unpack = classmethod(unpack)\n"
  },
  {
    "path": "deps/cpy/antlr3/dottreegen.py",
    "content": "\"\"\" @package antlr3.dottreegenerator\n@brief ANTLR3 runtime package, tree module\n\nThis module contains all support classes for AST construction and tree parsers.\n\n\"\"\"\n\n# begin[licence]\n#\n# [The \"BSD licence\"]\n# Copyright (c) 2005-2008 Terence Parr\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. The name of the author may not be used to endorse or promote products\n#    derived from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n# NOT 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 OF\n# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#\n# end[licence]\n\n# lot's of docstrings are missing, don't complain for now...\n# pylint: disable-msg=C0111\n\nfrom antlr3.tree import CommonTreeAdaptor\nimport stringtemplate3\n\nclass DOTTreeGenerator(object):\n    \"\"\"\n    A utility class to generate DOT diagrams (graphviz) from\n    arbitrary trees.  You can pass in your own templates and\n    can pass in any kind of tree or use Tree interface method.\n    \"\"\"\n\n    _treeST = stringtemplate3.StringTemplate(\n        template=(\n        \"digraph {\\n\" +\n        \"  ordering=out;\\n\" +\n        \"  ranksep=.4;\\n\" +\n        \"  node [shape=plaintext, fixedsize=true, fontsize=11, fontname=\\\"Courier\\\",\\n\" +\n        \"        width=.25, height=.25];\\n\" +\n        \"  edge [arrowsize=.5]\\n\" +\n        \"  $nodes$\\n\" +\n        \"  $edges$\\n\" +\n        \"}\\n\")\n        )\n\n    _nodeST = stringtemplate3.StringTemplate(\n        template=\"$name$ [label=\\\"$text$\\\"];\\n\"\n        )\n\n    _edgeST = stringtemplate3.StringTemplate(\n        template=\"$parent$ -> $child$ // \\\"$parentText$\\\" -> \\\"$childText$\\\"\\n\"\n        )\n\n    def __init__(self):\n        ## Track node to number mapping so we can get proper node name back\n        self.nodeToNumberMap = {}\n\n        ## Track node number so we can get unique node names\n        self.nodeNumber = 0\n\n\n    def toDOT(self, tree, adaptor=None, treeST=_treeST, edgeST=_edgeST):\n        if adaptor is None:\n            adaptor = CommonTreeAdaptor()\n\n        treeST = treeST.getInstanceOf()\n\n        self.nodeNumber = 0\n        self.toDOTDefineNodes(tree, adaptor, treeST)\n\n        self.nodeNumber = 0\n        self.toDOTDefineEdges(tree, adaptor, treeST, edgeST)\n        return treeST\n\n\n    def toDOTDefineNodes(self, tree, adaptor, treeST, knownNodes=None):\n        if knownNodes is None:\n            knownNodes = set()\n\n        if tree is None:\n            return\n\n        n = adaptor.getChildCount(tree)\n        if n == 0:\n            # must have already dumped as child from previous\n            # invocation; do nothing\n            return\n\n        # define parent node\n        number = self.getNodeNumber(tree)\n        if number not in knownNodes:\n            parentNodeST = self.getNodeST(adaptor, tree)\n            treeST.setAttribute(\"nodes\", parentNodeST)\n            knownNodes.add(number)\n\n        # for each child, do a \"<unique-name> [label=text]\" node def\n        for i in range(n):\n            child = adaptor.getChild(tree, i)\n            \n            number = self.getNodeNumber(child)\n            if number not in knownNodes:\n                nodeST = self.getNodeST(adaptor, child)\n                treeST.setAttribute(\"nodes\", nodeST)\n                knownNodes.add(number)\n\n            self.toDOTDefineNodes(child, adaptor, treeST, knownNodes)\n\n\n    def toDOTDefineEdges(self, tree, adaptor, treeST, edgeST):\n        if tree is None:\n            return\n\n        n = adaptor.getChildCount(tree)\n        if n == 0:\n            # must have already dumped as child from previous\n            # invocation; do nothing\n            return\n\n        parentName = \"n%d\" % self.getNodeNumber(tree)\n\n        # for each child, do a parent -> child edge using unique node names\n        parentText = adaptor.getText(tree)\n        for i in range(n):\n            child = adaptor.getChild(tree, i)\n            childText = adaptor.getText(child)\n            childName = \"n%d\" % self.getNodeNumber(child)\n            edgeST = edgeST.getInstanceOf()\n            edgeST.setAttribute(\"parent\", parentName)\n            edgeST.setAttribute(\"child\", childName)\n            edgeST.setAttribute(\"parentText\", parentText)\n            edgeST.setAttribute(\"childText\", childText)\n            treeST.setAttribute(\"edges\", edgeST)\n            self.toDOTDefineEdges(child, adaptor, treeST, edgeST)\n\n\n    def getNodeST(self, adaptor, t):\n        text = adaptor.getText(t)\n        nodeST = self._nodeST.getInstanceOf()\n        uniqueName = \"n%d\" % self.getNodeNumber(t)\n        nodeST.setAttribute(\"name\", uniqueName)\n        if text is not None:\n            text = text.replace('\"', r'\\\\\"')\n        nodeST.setAttribute(\"text\", text)\n        return nodeST\n\n\n    def getNodeNumber(self, t):\n        try:\n            return self.nodeToNumberMap[t]\n        except KeyError:\n            self.nodeToNumberMap[t] = self.nodeNumber\n            self.nodeNumber += 1\n            return self.nodeNumber - 1\n\n\ndef toDOT(tree, adaptor=None, treeST=DOTTreeGenerator._treeST, edgeST=DOTTreeGenerator._edgeST):\n    \"\"\"\n    Generate DOT (graphviz) for a whole tree not just a node.\n    For example, 3+4*5 should generate:\n\n    digraph {\n        node [shape=plaintext, fixedsize=true, fontsize=11, fontname=\"Courier\",\n            width=.4, height=.2];\n        edge [arrowsize=.7]\n        \"+\"->3\n        \"+\"->\"*\"\n        \"*\"->4\n        \"*\"->5\n    }\n\n    Return the ST not a string in case people want to alter.\n\n    Takes a Tree interface object.\n\n    Example of invokation:\n\n        import antlr3\n        import antlr3.extras\n\n        input = antlr3.ANTLRInputStream(sys.stdin)\n        lex = TLexer(input)\n        tokens = antlr3.CommonTokenStream(lex)\n        parser = TParser(tokens)\n        tree = parser.e().tree\n        print tree.toStringTree()\n        st = antlr3.extras.toDOT(t)\n        print st\n        \n    \"\"\"\n\n    gen = DOTTreeGenerator()\n    return gen.toDOT(tree, adaptor, treeST, edgeST)\n"
  },
  {
    "path": "deps/cpy/antlr3/exceptions.py",
    "content": "\"\"\"ANTLR3 exception hierarchy\"\"\"\n\n# begin[licence]\n#\n# [The \"BSD licence\"]\n# Copyright (c) 2005-2008 Terence Parr\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. The name of the author may not be used to endorse or promote products\n#    derived from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n# NOT 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 OF\n# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#\n# end[licence]\n\nfrom antlr3.constants import INVALID_TOKEN_TYPE\n\n\nclass BacktrackingFailed(Exception):\n    \"\"\"@brief Raised to signal failed backtrack attempt\"\"\"\n\n    pass\n\n\nclass RecognitionException(Exception):\n    \"\"\"@brief The root of the ANTLR exception hierarchy.\n\n    To avoid English-only error messages and to generally make things\n    as flexible as possible, these exceptions are not created with strings,\n    but rather the information necessary to generate an error.  Then\n    the various reporting methods in Parser and Lexer can be overridden\n    to generate a localized error message.  For example, MismatchedToken\n    exceptions are built with the expected token type.\n    So, don't expect getMessage() to return anything.\n\n    Note that as of Java 1.4, you can access the stack trace, which means\n    that you can compute the complete trace of rules from the start symbol.\n    This gives you considerable context information with which to generate\n    useful error messages.\n\n    ANTLR generates code that throws exceptions upon recognition error and\n    also generates code to catch these exceptions in each rule.  If you\n    want to quit upon first error, you can turn off the automatic error\n    handling mechanism using rulecatch action, but you still need to\n    override methods mismatch and recoverFromMismatchSet.\n    \n    In general, the recognition exceptions can track where in a grammar a\n    problem occurred and/or what was the expected input.  While the parser\n    knows its state (such as current input symbol and line info) that\n    state can change before the exception is reported so current token index\n    is computed and stored at exception time.  From this info, you can\n    perhaps print an entire line of input not just a single token, for example.\n    Better to just say the recognizer had a problem and then let the parser\n    figure out a fancy report.\n    \n    \"\"\"\n\n    def __init__(self, input=None):\n        Exception.__init__(self)\n\n\t# What input stream did the error occur in?\n        self.input = None\n\n        # What is index of token/char were we looking at when the error\n        # occurred?\n        self.index = None\n\n\t# The current Token when an error occurred.  Since not all streams\n\t# can retrieve the ith Token, we have to track the Token object.\n\t# For parsers.  Even when it's a tree parser, token might be set.\n        self.token = None\n\n\t# If this is a tree parser exception, node is set to the node with\n\t# the problem.\n        self.node = None\n\n\t# The current char when an error occurred. For lexers.\n        self.c = None\n\n\t# Track the line at which the error occurred in case this is\n\t# generated from a lexer.  We need to track this since the\n        # unexpected char doesn't carry the line info.\n        self.line = None\n\n        self.charPositionInLine = None\n\n        # If you are parsing a tree node stream, you will encounter som\n        # imaginary nodes w/o line/col info.  We now search backwards looking\n        # for most recent token with line/col info, but notify getErrorHeader()\n        # that info is approximate.\n        self.approximateLineInfo = False\n\n        \n        if input is not None:\n            self.input = input\n            self.index = input.index()\n\n            # late import to avoid cyclic dependencies\n            from antlr3.streams import TokenStream, CharStream\n            from antlr3.tree import TreeNodeStream\n\n            if isinstance(self.input, TokenStream):\n                self.token = self.input.LT(1)\n                self.line = self.token.line\n                self.charPositionInLine = self.token.charPositionInLine\n\n            if isinstance(self.input, TreeNodeStream):\n                self.extractInformationFromTreeNodeStream(self.input)\n\n            else:\n                if isinstance(self.input, CharStream):\n                    self.c = self.input.LT(1)\n                    self.line = self.input.line\n                    self.charPositionInLine = self.input.charPositionInLine\n\n                else:\n                    self.c = self.input.LA(1)\n\n    def extractInformationFromTreeNodeStream(self, nodes):\n        from antlr3.tree import Tree, CommonTree\n        from antlr3.tokens import CommonToken\n        \n        self.node = nodes.LT(1)\n        adaptor = nodes.adaptor\n        payload = adaptor.getToken(self.node)\n        if payload is not None:\n            self.token = payload\n            if payload.line <= 0:\n                # imaginary node; no line/pos info; scan backwards\n                i = -1\n                priorNode = nodes.LT(i)\n                while priorNode is not None:\n                    priorPayload = adaptor.getToken(priorNode)\n                    if priorPayload is not None and priorPayload.line > 0:\n                        # we found the most recent real line / pos info\n                        self.line = priorPayload.line\n                        self.charPositionInLine = priorPayload.charPositionInLine\n                        self.approximateLineInfo = True\n                        break\n                    \n                    i -= 1\n                    priorNode = nodes.LT(i)\n                    \n            else: # node created from real token\n                self.line = payload.line\n                self.charPositionInLine = payload.charPositionInLine\n                \n        elif isinstance(self.node, Tree):\n            self.line = self.node.line\n            self.charPositionInLine = self.node.charPositionInLine\n            if isinstance(self.node, CommonTree):\n                self.token = self.node.token\n\n        else:\n            type = adaptor.getType(self.node)\n            text = adaptor.getText(self.node)\n            self.token = CommonToken(type=type, text=text)\n\n     \n    def getUnexpectedType(self):\n        \"\"\"Return the token type or char of the unexpected input element\"\"\"\n\n        from antlr3.streams import TokenStream\n        from antlr3.tree import TreeNodeStream\n\n        if isinstance(self.input, TokenStream):\n            return self.token.type\n\n        elif isinstance(self.input, TreeNodeStream):\n            adaptor = self.input.treeAdaptor\n            return adaptor.getType(self.node)\n\n        else:\n            return self.c\n\n    unexpectedType = property(getUnexpectedType)\n    \n\nclass MismatchedTokenException(RecognitionException):\n    \"\"\"@brief A mismatched char or Token or tree node.\"\"\"\n    \n    def __init__(self, expecting, input):\n        RecognitionException.__init__(self, input)\n        self.expecting = expecting\n        \n\n    def __str__(self):\n        #return \"MismatchedTokenException(\"+self.expecting+\")\"\n        return \"MismatchedTokenException(%r!=%r)\" % (\n            self.getUnexpectedType(), self.expecting\n            )\n    __repr__ = __str__\n\n\nclass UnwantedTokenException(MismatchedTokenException):\n    \"\"\"An extra token while parsing a TokenStream\"\"\"\n\n    def getUnexpectedToken(self):\n        return self.token\n\n\n    def __str__(self):\n        exp = \", expected %s\" % self.expecting\n        if self.expecting == INVALID_TOKEN_TYPE:\n            exp = \"\"\n\n        if self.token is None:\n            return \"UnwantedTokenException(found=%s%s)\" % (None, exp)\n\n        return \"UnwantedTokenException(found=%s%s)\" % (self.token.text, exp)\n    __repr__ = __str__\n\n\nclass MissingTokenException(MismatchedTokenException):\n    \"\"\"\n    We were expecting a token but it's not found.  The current token\n    is actually what we wanted next.\n    \"\"\"\n\n    def __init__(self, expecting, input, inserted):\n        MismatchedTokenException.__init__(self, expecting, input)\n\n        self.inserted = inserted\n\n\n    def getMissingType(self):\n        return self.expecting\n\n\n    def __str__(self):\n        if self.inserted is not None and self.token is not None:\n            return \"MissingTokenException(inserted %r at %r)\" % (\n                self.inserted, self.token.text)\n\n        if self.token is not None:\n            return \"MissingTokenException(at %r)\" % self.token.text\n\n        return \"MissingTokenException\"\n    __repr__ = __str__\n\n\nclass MismatchedRangeException(RecognitionException):\n    \"\"\"@brief The next token does not match a range of expected types.\"\"\"\n\n    def __init__(self, a, b, input):\n        RecognitionException.__init__(self, input)\n\n        self.a = a\n        self.b = b\n        \n\n    def __str__(self):\n        return \"MismatchedRangeException(%r not in [%r..%r])\" % (\n            self.getUnexpectedType(), self.a, self.b\n            )\n    __repr__ = __str__\n    \n\nclass MismatchedSetException(RecognitionException):\n    \"\"\"@brief The next token does not match a set of expected types.\"\"\"\n\n    def __init__(self, expecting, input):\n        RecognitionException.__init__(self, input)\n\n        self.expecting = expecting\n        \n\n    def __str__(self):\n        return \"MismatchedSetException(%r not in %r)\" % (\n            self.getUnexpectedType(), self.expecting\n            )\n    __repr__ = __str__\n\n\nclass MismatchedNotSetException(MismatchedSetException):\n    \"\"\"@brief Used for remote debugger deserialization\"\"\"\n    \n    def __str__(self):\n        return \"MismatchedNotSetException(%r!=%r)\" % (\n            self.getUnexpectedType(), self.expecting\n            )\n    __repr__ = __str__\n\n\nclass NoViableAltException(RecognitionException):\n    \"\"\"@brief Unable to decide which alternative to choose.\"\"\"\n\n    def __init__(\n        self, grammarDecisionDescription, decisionNumber, stateNumber, input\n        ):\n        RecognitionException.__init__(self, input)\n\n        self.grammarDecisionDescription = grammarDecisionDescription\n        self.decisionNumber = decisionNumber\n        self.stateNumber = stateNumber\n\n\n    def __str__(self):\n        return \"NoViableAltException(%r!=[%r])\" % (\n            self.unexpectedType, self.grammarDecisionDescription\n            )\n    __repr__ = __str__\n    \n\nclass EarlyExitException(RecognitionException):\n    \"\"\"@brief The recognizer did not match anything for a (..)+ loop.\"\"\"\n\n    def __init__(self, decisionNumber, input):\n        RecognitionException.__init__(self, input)\n\n        self.decisionNumber = decisionNumber\n\n\nclass FailedPredicateException(RecognitionException):\n    \"\"\"@brief A semantic predicate failed during validation.\n\n    Validation of predicates\n    occurs when normally parsing the alternative just like matching a token.\n    Disambiguating predicate evaluation occurs when we hoist a predicate into\n    a prediction decision.\n    \"\"\"\n\n    def __init__(self, input, ruleName, predicateText):\n        RecognitionException.__init__(self, input)\n        \n        self.ruleName = ruleName\n        self.predicateText = predicateText\n\n\n    def __str__(self):\n        return \"FailedPredicateException(\"+self.ruleName+\",{\"+self.predicateText+\"}?)\"\n    __repr__ = __str__\n    \n\nclass MismatchedTreeNodeException(RecognitionException):\n    \"\"\"@brief The next tree mode does not match the expected type.\"\"\"\n\n    def __init__(self, expecting, input):\n        RecognitionException.__init__(self, input)\n        \n        self.expecting = expecting\n\n    def __str__(self):\n        return \"MismatchedTreeNodeException(%r!=%r)\" % (\n            self.getUnexpectedType(), self.expecting\n            )\n    __repr__ = __str__\n"
  },
  {
    "path": "deps/cpy/antlr3/extras.py",
    "content": "\"\"\" @package antlr3.dottreegenerator\n@brief ANTLR3 runtime package, tree module\n\nThis module contains all support classes for AST construction and tree parsers.\n\n\"\"\"\n\n# begin[licence]\n#\n# [The \"BSD licence\"]\n# Copyright (c) 2005-2008 Terence Parr\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. The name of the author may not be used to endorse or promote products\n#    derived from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n# NOT 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 OF\n# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#\n# end[licence]\n\n# lot's of docstrings are missing, don't complain for now...\n# pylint: disable-msg=C0111\n\nfrom treewizard import TreeWizard\n\ntry:\n    from antlr3.dottreegen import toDOT\nexcept ImportError, exc:\n    def toDOT(*args, **kwargs):\n        raise exc\n"
  },
  {
    "path": "deps/cpy/antlr3/main.py",
    "content": "\"\"\"ANTLR3 runtime package\"\"\"\n\n# begin[licence]\n#\n# [The \"BSD licence\"]\n# Copyright (c) 2005-2008 Terence Parr\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. The name of the author may not be used to endorse or promote products\n#    derived from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n# NOT 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 OF\n# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#\n# end[licence]\n\n\nimport sys\nimport optparse\n\nimport antlr3\n\n\nclass _Main(object):\n    def __init__(self):\n        self.stdin = sys.stdin\n        self.stdout = sys.stdout\n        self.stderr = sys.stderr\n\n        \n    def parseOptions(self, argv):\n        optParser = optparse.OptionParser()\n        optParser.add_option(\n            \"--encoding\",\n            action=\"store\",\n            type=\"string\",\n            dest=\"encoding\"\n            )\n        optParser.add_option(\n            \"--input\",\n            action=\"store\",\n            type=\"string\",\n            dest=\"input\"\n            )\n        optParser.add_option(\n            \"--interactive\", \"-i\",\n            action=\"store_true\",\n            dest=\"interactive\"\n            )\n        optParser.add_option(\n            \"--no-output\",\n            action=\"store_true\",\n            dest=\"no_output\"\n            )\n        optParser.add_option(\n            \"--profile\",\n            action=\"store_true\",\n            dest=\"profile\"\n            )\n        optParser.add_option(\n            \"--hotshot\",\n            action=\"store_true\",\n            dest=\"hotshot\"\n            )\n\n        self.setupOptions(optParser)\n        \n        return optParser.parse_args(argv[1:])\n\n\n    def setupOptions(self, optParser):\n        pass\n\n\n    def execute(self, argv):\n        options, args = self.parseOptions(argv)\n\n        self.setUp(options)\n        \n        if options.interactive:\n            while True:\n                try:\n                    input = raw_input(\">>> \")\n                except (EOFError, KeyboardInterrupt):\n                    self.stdout.write(\"\\nBye.\\n\")\n                    break\n            \n                inStream = antlr3.ANTLRStringStream(input)\n                self.parseStream(options, inStream)\n            \n        else:\n            if options.input is not None:\n                inStream = antlr3.ANTLRStringStream(options.input)\n\n            elif len(args) == 1 and args[0] != '-':\n                inStream = antlr3.ANTLRFileStream(\n                    args[0], encoding=options.encoding\n                    )\n\n            else:\n                inStream = antlr3.ANTLRInputStream(\n                    self.stdin, encoding=options.encoding\n                    )\n\n            if options.profile:\n                try:\n                    import cProfile as profile\n                except ImportError:\n                    import profile\n\n                profile.runctx(\n                    'self.parseStream(options, inStream)',\n                    globals(),\n                    locals(),\n                    'profile.dat'\n                    )\n\n                import pstats\n                stats = pstats.Stats('profile.dat')\n                stats.strip_dirs()\n                stats.sort_stats('time')\n                stats.print_stats(100)\n\n            elif options.hotshot:\n                import hotshot\n\n                profiler = hotshot.Profile('hotshot.dat')\n                profiler.runctx(\n                    'self.parseStream(options, inStream)',\n                    globals(),\n                    locals()\n                    )\n\n            else:\n                self.parseStream(options, inStream)\n\n\n    def setUp(self, options):\n        pass\n\n    \n    def parseStream(self, options, inStream):\n        raise NotImplementedError\n\n\n    def write(self, options, text):\n        if not options.no_output:\n            self.stdout.write(text)\n\n\n    def writeln(self, options, text):\n        self.write(options, text + '\\n')\n\n\nclass LexerMain(_Main):\n    def __init__(self, lexerClass):\n        _Main.__init__(self)\n\n        self.lexerClass = lexerClass\n        \n    \n    def parseStream(self, options, inStream):\n        lexer = self.lexerClass(inStream)\n        for token in lexer:\n            self.writeln(options, str(token))\n\n\nclass ParserMain(_Main):\n    def __init__(self, lexerClassName, parserClass):\n        _Main.__init__(self)\n\n        self.lexerClassName = lexerClassName\n        self.lexerClass = None\n        self.parserClass = parserClass\n        \n    \n    def setupOptions(self, optParser):\n        optParser.add_option(\n            \"--lexer\",\n            action=\"store\",\n            type=\"string\",\n            dest=\"lexerClass\",\n            default=self.lexerClassName\n            )\n        optParser.add_option(\n            \"--rule\",\n            action=\"store\",\n            type=\"string\",\n            dest=\"parserRule\"\n            )\n\n\n    def setUp(self, options):\n        lexerMod = __import__(options.lexerClass)\n        self.lexerClass = getattr(lexerMod, options.lexerClass)\n\n        \n    def parseStream(self, options, inStream):\n        lexer = self.lexerClass(inStream)\n        tokenStream = antlr3.CommonTokenStream(lexer)\n        parser = self.parserClass(tokenStream)\n        result = getattr(parser, options.parserRule)()\n        if result is not None:\n            if hasattr(result, 'tree'):\n                if result.tree is not None:\n                    self.writeln(options, result.tree.toStringTree())\n            else:\n                self.writeln(options, repr(result))\n\n\nclass WalkerMain(_Main):\n    def __init__(self, walkerClass):\n        _Main.__init__(self)\n\n        self.lexerClass = None\n        self.parserClass = None\n        self.walkerClass = walkerClass\n        \n    \n    def setupOptions(self, optParser):\n        optParser.add_option(\n            \"--lexer\",\n            action=\"store\",\n            type=\"string\",\n            dest=\"lexerClass\",\n            default=None\n            )\n        optParser.add_option(\n            \"--parser\",\n            action=\"store\",\n            type=\"string\",\n            dest=\"parserClass\",\n            default=None\n            )\n        optParser.add_option(\n            \"--parser-rule\",\n            action=\"store\",\n            type=\"string\",\n            dest=\"parserRule\",\n            default=None\n            )\n        optParser.add_option(\n            \"--rule\",\n            action=\"store\",\n            type=\"string\",\n            dest=\"walkerRule\"\n            )\n\n\n    def setUp(self, options):\n        lexerMod = __import__(options.lexerClass)\n        self.lexerClass = getattr(lexerMod, options.lexerClass)\n        parserMod = __import__(options.parserClass)\n        self.parserClass = getattr(parserMod, options.parserClass)\n\n        \n    def parseStream(self, options, inStream):\n        lexer = self.lexerClass(inStream)\n        tokenStream = antlr3.CommonTokenStream(lexer)\n        parser = self.parserClass(tokenStream)\n        result = getattr(parser, options.parserRule)()\n        if result is not None:\n            assert hasattr(result, 'tree'), \"Parser did not return an AST\"\n            nodeStream = antlr3.tree.CommonTreeNodeStream(result.tree)\n            nodeStream.setTokenStream(tokenStream)\n            walker = self.walkerClass(nodeStream)\n            result = getattr(walker, options.walkerRule)()\n            if result is not None:\n                if hasattr(result, 'tree'):\n                    self.writeln(options, result.tree.toStringTree())\n                else:\n                    self.writeln(options, repr(result))\n\n"
  },
  {
    "path": "deps/cpy/antlr3/recognizers.py",
    "content": "\"\"\"ANTLR3 runtime package\"\"\"\n\n# begin[licence]\n#\n# [The \"BSD licence\"]\n# Copyright (c) 2005-2008 Terence Parr\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. The name of the author may not be used to endorse or promote products\n#    derived from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n# NOT 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 OF\n# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#\n# end[licence]\n\nimport sys\nimport inspect\n\nfrom antlr3 import runtime_version, runtime_version_str\nfrom antlr3.constants import DEFAULT_CHANNEL, HIDDEN_CHANNEL, EOF, \\\n     EOR_TOKEN_TYPE, INVALID_TOKEN_TYPE\nfrom antlr3.exceptions import RecognitionException, MismatchedTokenException, \\\n     MismatchedRangeException, MismatchedTreeNodeException, \\\n     NoViableAltException, EarlyExitException, MismatchedSetException, \\\n     MismatchedNotSetException, FailedPredicateException, \\\n     BacktrackingFailed, UnwantedTokenException, MissingTokenException\nfrom antlr3.tokens import CommonToken, EOF_TOKEN, SKIP_TOKEN\nfrom antlr3.compat import set, frozenset, reversed\n\n\nclass RecognizerSharedState(object):\n    \"\"\"\n    The set of fields needed by an abstract recognizer to recognize input\n    and recover from errors etc...  As a separate state object, it can be\n    shared among multiple grammars; e.g., when one grammar imports another.\n\n    These fields are publically visible but the actual state pointer per\n    parser is protected.\n    \"\"\"\n\n    def __init__(self):\n        # Track the set of token types that can follow any rule invocation.\n        # Stack grows upwards.\n        self.following = []\n\n        # This is true when we see an error and before having successfully\n        # matched a token.  Prevents generation of more than one error message\n        # per error.\n        self.errorRecovery = False\n\n        # The index into the input stream where the last error occurred.\n        # This is used to prevent infinite loops where an error is found\n        # but no token is consumed during recovery...another error is found,\n        # ad naseum.  This is a failsafe mechanism to guarantee that at least\n        # one token/tree node is consumed for two errors.\n        self.lastErrorIndex = -1\n\n        # If 0, no backtracking is going on.  Safe to exec actions etc...\n        # If >0 then it's the level of backtracking.\n        self.backtracking = 0\n\n        # An array[size num rules] of Map<Integer,Integer> that tracks\n        # the stop token index for each rule.  ruleMemo[ruleIndex] is\n        # the memoization table for ruleIndex.  For key ruleStartIndex, you\n        # get back the stop token for associated rule or MEMO_RULE_FAILED.\n        #\n        # This is only used if rule memoization is on (which it is by default).\n        self.ruleMemo = None\n\n        ## Did the recognizer encounter a syntax error?  Track how many.\n        self.syntaxErrors = 0\n\n\n        # LEXER FIELDS (must be in same state object to avoid casting\n        # constantly in generated code and Lexer object) :(\n\n\n\t## The goal of all lexer rules/methods is to create a token object.\n        # This is an instance variable as multiple rules may collaborate to\n        # create a single token.  nextToken will return this object after\n        # matching lexer rule(s).  If you subclass to allow multiple token\n        # emissions, then set this to the last token to be matched or\n        # something nonnull so that the auto token emit mechanism will not\n        # emit another token.\n        self.token = None\n\n        ## What character index in the stream did the current token start at?\n        # Needed, for example, to get the text for current token.  Set at\n        # the start of nextToken.\n        self.tokenStartCharIndex = -1\n\n        ## The line on which the first character of the token resides\n        self.tokenStartLine = None\n\n        ## The character position of first character within the line\n        self.tokenStartCharPositionInLine = None\n\n        ## The channel number for the current token\n        self.channel = None\n\n        ## The token type for the current token\n        self.type = None\n\n        ## You can set the text for the current token to override what is in\n        # the input char buffer.  Use setText() or can set this instance var.\n        self.text = None\n        \n\nclass BaseRecognizer(object):\n    \"\"\"\n    @brief Common recognizer functionality.\n    \n    A generic recognizer that can handle recognizers generated from\n    lexer, parser, and tree grammars.  This is all the parsing\n    support code essentially; most of it is error recovery stuff and\n    backtracking.\n    \"\"\"\n\n    MEMO_RULE_FAILED = -2\n    MEMO_RULE_UNKNOWN = -1\n\n    # copies from Token object for convenience in actions\n    DEFAULT_TOKEN_CHANNEL = DEFAULT_CHANNEL\n\n    # for convenience in actions\n    HIDDEN = HIDDEN_CHANNEL\n\n    # overridden by generated subclasses\n    tokenNames = None\n\n    # The antlr_version attribute has been introduced in 3.1. If it is not\n    # overwritten in the generated recognizer, we assume a default of 3.0.1.\n    antlr_version = (3, 0, 1, 0)\n    antlr_version_str = \"3.0.1\"\n\n    def __init__(self, state=None):\n        # Input stream of the recognizer. Must be initialized by a subclass.\n        self.input = None\n\n        ## State of a lexer, parser, or tree parser are collected into a state\n        # object so the state can be shared.  This sharing is needed to\n        # have one grammar import others and share same error variables\n        # and other state variables.  It's a kind of explicit multiple\n        # inheritance via delegation of methods and shared state.\n        if state is None:\n            state = RecognizerSharedState()\n        self._state = state\n\n        if self.antlr_version > runtime_version:\n            raise RuntimeError(\n                \"ANTLR version mismatch: \"\n                \"The recognizer has been generated by V%s, but this runtime \"\n                \"is V%s. Please use the V%s runtime or higher.\"\n                % (self.antlr_version_str,\n                   runtime_version_str,\n                   self.antlr_version_str))\n        elif (self.antlr_version < (3, 1, 0, 0) and\n              self.antlr_version != runtime_version):\n            print self.antlr_version\n            print runtime_version\n            # FIXME: make the runtime compatible with 3.0.1 codegen\n            # and remove this block.\n            raise RuntimeError(\n                \"ANTLR version mismatch: \"\n                \"The recognizer has been generated by V%s, but this runtime \"\n                \"is V%s. Please use the V%s runtime.\"\n                % (self.antlr_version_str,\n                   runtime_version_str,\n                   self.antlr_version_str))\n\n    # this one only exists to shut up pylint :(\n    def setInput(self, input):\n        self.input = input\n\n        \n    def reset(self):\n        \"\"\"\n        reset the parser's state; subclasses must rewinds the input stream\n        \"\"\"\n        \n        # wack everything related to error recovery\n        if self._state is None:\n            # no shared state work to do\n            return\n        \n        self._state.following = []\n        self._state.errorRecovery = False\n        self._state.lastErrorIndex = -1\n        self._state.syntaxErrors = 0\n        # wack everything related to backtracking and memoization\n        self._state.backtracking = 0\n        if self._state.ruleMemo is not None:\n            self._state.ruleMemo = {}\n\n\n    def match(self, input, ttype, follow):\n        \"\"\"\n        Match current input symbol against ttype.  Attempt\n        single token insertion or deletion error recovery.  If\n        that fails, throw MismatchedTokenException.\n\n        To turn off single token insertion or deletion error\n        recovery, override mismatchRecover() and have it call\n        plain mismatch(), which does not recover.  Then any error\n        in a rule will cause an exception and immediate exit from\n        rule.  Rule would recover by resynchronizing to the set of\n        symbols that can follow rule ref.\n        \"\"\"\n        \n        matchedSymbol = self.getCurrentInputSymbol(input)\n        if self.input.LA(1) == ttype:\n            self.input.consume()\n            self._state.errorRecovery = False\n            return matchedSymbol\n\n        if self._state.backtracking > 0:\n            # FIXME: need to return matchedSymbol here as well. damn!!\n            raise BacktrackingFailed\n\n        matchedSymbol = self.recoverFromMismatchedToken(input, ttype, follow)\n        return matchedSymbol\n\n\n    def matchAny(self, input):\n        \"\"\"Match the wildcard: in a symbol\"\"\"\n\n        self._state.errorRecovery = False\n        self.input.consume()\n\n\n    def mismatchIsUnwantedToken(self, input, ttype):\n        return input.LA(2) == ttype\n\n\n    def mismatchIsMissingToken(self, input, follow):\n        if follow is None:\n            # we have no information about the follow; we can only consume\n            # a single token and hope for the best\n            return False\n        \n        # compute what can follow this grammar element reference\n        if EOR_TOKEN_TYPE in follow:\n            if len(self._state.following) > 0:\n                # remove EOR if we're not the start symbol\n                follow = follow - set([EOR_TOKEN_TYPE])\n\n            viableTokensFollowingThisRule = self.computeContextSensitiveRuleFOLLOW()\n            follow = follow | viableTokensFollowingThisRule\n\n        # if current token is consistent with what could come after set\n        # then we know we're missing a token; error recovery is free to\n        # \"insert\" the missing token\n        if input.LA(1) in follow or EOR_TOKEN_TYPE in follow:\n            return True\n\n        return False\n\n\n    def mismatch(self, input, ttype, follow):\n        \"\"\"\n        Factor out what to do upon token mismatch so tree parsers can behave\n        differently.  Override and call mismatchRecover(input, ttype, follow)\n        to get single token insertion and deletion. Use this to turn of\n        single token insertion and deletion. Override mismatchRecover\n        to call this instead.\n        \"\"\"\n\n        if self.mismatchIsUnwantedToken(input, ttype):\n            raise UnwantedTokenException(ttype, input)\n\n        elif self.mismatchIsMissingToken(input, follow):\n            raise MissingTokenException(ttype, input, None)\n\n        raise MismatchedTokenException(ttype, input)\n\n\n##     def mismatchRecover(self, input, ttype, follow):\n##         if self.mismatchIsUnwantedToken(input, ttype):\n##             mte = UnwantedTokenException(ttype, input)\n\n##         elif self.mismatchIsMissingToken(input, follow):\n##             mte = MissingTokenException(ttype, input)\n\n##         else:\n##             mte = MismatchedTokenException(ttype, input)\n\n##         self.recoverFromMismatchedToken(input, mte, ttype, follow)\n\n\n    def reportError(self, e):\n        \"\"\"Report a recognition problem.\n            \n        This method sets errorRecovery to indicate the parser is recovering\n        not parsing.  Once in recovery mode, no errors are generated.\n        To get out of recovery mode, the parser must successfully match\n        a token (after a resync).  So it will go:\n\n        1. error occurs\n        2. enter recovery mode, report error\n        3. consume until token found in resynch set\n        4. try to resume parsing\n        5. next match() will reset errorRecovery mode\n\n        If you override, make sure to update syntaxErrors if you care about\n        that.\n        \n        \"\"\"\n        \n        # if we've already reported an error and have not matched a token\n        # yet successfully, don't report any errors.\n        if self._state.errorRecovery:\n            return\n\n        self._state.syntaxErrors += 1 # don't count spurious\n        self._state.errorRecovery = True\n\n        self.displayRecognitionError(self.tokenNames, e)\n\n\n    def displayRecognitionError(self, tokenNames, e):\n        hdr = self.getErrorHeader(e)\n        msg = self.getErrorMessage(e, tokenNames)\n        self.emitErrorMessage(hdr+\" \"+msg)\n\n\n    def getErrorMessage(self, e, tokenNames):\n        \"\"\"\n        What error message should be generated for the various\n        exception types?\n        \n        Not very object-oriented code, but I like having all error message\n        generation within one method rather than spread among all of the\n        exception classes. This also makes it much easier for the exception\n        handling because the exception classes do not have to have pointers back\n        to this object to access utility routines and so on. Also, changing\n        the message for an exception type would be difficult because you\n        would have to subclassing exception, but then somehow get ANTLR\n        to make those kinds of exception objects instead of the default.\n        This looks weird, but trust me--it makes the most sense in terms\n        of flexibility.\n\n        For grammar debugging, you will want to override this to add\n        more information such as the stack frame with\n        getRuleInvocationStack(e, this.getClass().getName()) and,\n        for no viable alts, the decision description and state etc...\n\n        Override this to change the message generated for one or more\n        exception types.\n        \"\"\"\n\n        if isinstance(e, UnwantedTokenException):\n            tokenName = \"<unknown>\"\n            if e.expecting == EOF:\n                tokenName = \"EOF\"\n\n            else:\n                tokenName = self.tokenNames[e.expecting]\n\n            msg = \"extraneous input %s expecting %s\" % (\n                self.getTokenErrorDisplay(e.getUnexpectedToken()),\n                tokenName\n                )\n\n        elif isinstance(e, MissingTokenException):\n            tokenName = \"<unknown>\"\n            if e.expecting == EOF:\n                tokenName = \"EOF\"\n\n            else:\n                tokenName = self.tokenNames[e.expecting]\n\n            msg = \"missing %s at %s\" % (\n                tokenName, self.getTokenErrorDisplay(e.token)\n                )\n\n        elif isinstance(e, MismatchedTokenException):\n            tokenName = \"<unknown>\"\n            if e.expecting == EOF:\n                tokenName = \"EOF\"\n            else:\n                tokenName = self.tokenNames[e.expecting]\n\n            msg = \"mismatched input \" \\\n                  + self.getTokenErrorDisplay(e.token) \\\n                  + \" expecting \" \\\n                  + tokenName\n\n        elif isinstance(e, MismatchedTreeNodeException):\n            tokenName = \"<unknown>\"\n            if e.expecting == EOF:\n                tokenName = \"EOF\"\n            else:\n                tokenName = self.tokenNames[e.expecting]\n\n            msg = \"mismatched tree node: %s expecting %s\" \\\n                  % (e.node, tokenName)\n\n        elif isinstance(e, NoViableAltException):\n            msg = \"no viable alternative at input \" \\\n                  + self.getTokenErrorDisplay(e.token)\n\n        elif isinstance(e, EarlyExitException):\n            msg = \"required (...)+ loop did not match anything at input \" \\\n                  + self.getTokenErrorDisplay(e.token)\n\n        elif isinstance(e, MismatchedSetException):\n            msg = \"mismatched input \" \\\n                  + self.getTokenErrorDisplay(e.token) \\\n                  + \" expecting set \" \\\n                  + repr(e.expecting)\n\n        elif isinstance(e, MismatchedNotSetException):\n            msg = \"mismatched input \" \\\n                  + self.getTokenErrorDisplay(e.token) \\\n                  + \" expecting set \" \\\n                  + repr(e.expecting)\n\n        elif isinstance(e, FailedPredicateException):\n            msg = \"rule \" \\\n                  + e.ruleName \\\n                  + \" failed predicate: {\" \\\n                  + e.predicateText \\\n                  + \"}?\"\n\n        else:\n            msg = str(e)\n\n        return msg\n    \n\n    def getNumberOfSyntaxErrors(self):\n        \"\"\"\n        Get number of recognition errors (lexer, parser, tree parser).  Each\n        recognizer tracks its own number.  So parser and lexer each have\n        separate count.  Does not count the spurious errors found between\n        an error and next valid token match\n\n        See also reportError()\n\t\"\"\"\n        return self._state.syntaxErrors\n\n\n    def getErrorHeader(self, e):\n        \"\"\"\n        What is the error header, normally line/character position information?\n        \"\"\"\n        \n        return \"line %d:%d\" % (e.line, e.charPositionInLine)\n\n\n    def getTokenErrorDisplay(self, t):\n        \"\"\"\n        How should a token be displayed in an error message? The default\n        is to display just the text, but during development you might\n        want to have a lot of information spit out.  Override in that case\n        to use t.toString() (which, for CommonToken, dumps everything about\n        the token). This is better than forcing you to override a method in\n        your token objects because you don't have to go modify your lexer\n        so that it creates a new Java type.\n        \"\"\"\n        \n        s = t.text\n        if s is None:\n            if t.type == EOF:\n                s = \"<EOF>\"\n            else:\n                s = \"<\"+t.type+\">\"\n\n        return repr(s)\n    \n\n    def emitErrorMessage(self, msg):\n        \"\"\"Override this method to change where error messages go\"\"\"\n        sys.stderr.write(msg + '\\n')\n\n\n    def recover(self, input, re):\n        \"\"\"\n        Recover from an error found on the input stream.  This is\n        for NoViableAlt and mismatched symbol exceptions.  If you enable\n        single token insertion and deletion, this will usually not\n        handle mismatched symbol exceptions but there could be a mismatched\n        token that the match() routine could not recover from.\n        \"\"\"\n        \n        # PROBLEM? what if input stream is not the same as last time\n        # perhaps make lastErrorIndex a member of input\n        if self._state.lastErrorIndex == input.index():\n            # uh oh, another error at same token index; must be a case\n            # where LT(1) is in the recovery token set so nothing is\n            # consumed; consume a single token so at least to prevent\n            # an infinite loop; this is a failsafe.\n            input.consume()\n\n        self._state.lastErrorIndex = input.index()\n        followSet = self.computeErrorRecoverySet()\n        \n        self.beginResync()\n        self.consumeUntil(input, followSet)\n        self.endResync()\n\n\n    def beginResync(self):\n        \"\"\"\n        A hook to listen in on the token consumption during error recovery.\n        The DebugParser subclasses this to fire events to the listenter.\n        \"\"\"\n\n        pass\n\n\n    def endResync(self):\n        \"\"\"\n        A hook to listen in on the token consumption during error recovery.\n        The DebugParser subclasses this to fire events to the listenter.\n        \"\"\"\n\n        pass\n\n\n    def computeErrorRecoverySet(self):\n        \"\"\"\n        Compute the error recovery set for the current rule.  During\n        rule invocation, the parser pushes the set of tokens that can\n        follow that rule reference on the stack; this amounts to\n        computing FIRST of what follows the rule reference in the\n        enclosing rule. This local follow set only includes tokens\n        from within the rule; i.e., the FIRST computation done by\n        ANTLR stops at the end of a rule.\n\n        EXAMPLE\n\n        When you find a \"no viable alt exception\", the input is not\n        consistent with any of the alternatives for rule r.  The best\n        thing to do is to consume tokens until you see something that\n        can legally follow a call to r *or* any rule that called r.\n        You don't want the exact set of viable next tokens because the\n        input might just be missing a token--you might consume the\n        rest of the input looking for one of the missing tokens.\n\n        Consider grammar:\n\n        a : '[' b ']'\n          | '(' b ')'\n          ;\n        b : c '^' INT ;\n        c : ID\n          | INT\n          ;\n\n        At each rule invocation, the set of tokens that could follow\n        that rule is pushed on a stack.  Here are the various \"local\"\n        follow sets:\n\n        FOLLOW(b1_in_a) = FIRST(']') = ']'\n        FOLLOW(b2_in_a) = FIRST(')') = ')'\n        FOLLOW(c_in_b) = FIRST('^') = '^'\n\n        Upon erroneous input \"[]\", the call chain is\n\n        a -> b -> c\n\n        and, hence, the follow context stack is:\n\n        depth  local follow set     after call to rule\n          0         \\<EOF>                    a (from main())\n          1          ']'                     b\n          3          '^'                     c\n\n        Notice that ')' is not included, because b would have to have\n        been called from a different context in rule a for ')' to be\n        included.\n\n        For error recovery, we cannot consider FOLLOW(c)\n        (context-sensitive or otherwise).  We need the combined set of\n        all context-sensitive FOLLOW sets--the set of all tokens that\n        could follow any reference in the call chain.  We need to\n        resync to one of those tokens.  Note that FOLLOW(c)='^' and if\n        we resync'd to that token, we'd consume until EOF.  We need to\n        sync to context-sensitive FOLLOWs for a, b, and c: {']','^'}.\n        In this case, for input \"[]\", LA(1) is in this set so we would\n        not consume anything and after printing an error rule c would\n        return normally.  It would not find the required '^' though.\n        At this point, it gets a mismatched token error and throws an\n        exception (since LA(1) is not in the viable following token\n        set).  The rule exception handler tries to recover, but finds\n        the same recovery set and doesn't consume anything.  Rule b\n        exits normally returning to rule a.  Now it finds the ']' (and\n        with the successful match exits errorRecovery mode).\n\n        So, you cna see that the parser walks up call chain looking\n        for the token that was a member of the recovery set.\n\n        Errors are not generated in errorRecovery mode.\n\n        ANTLR's error recovery mechanism is based upon original ideas:\n\n        \"Algorithms + Data Structures = Programs\" by Niklaus Wirth\n\n        and\n\n        \"A note on error recovery in recursive descent parsers\":\n        http://portal.acm.org/citation.cfm?id=947902.947905\n\n        Later, Josef Grosch had some good ideas:\n\n        \"Efficient and Comfortable Error Recovery in Recursive Descent\n        Parsers\":\n        ftp://www.cocolab.com/products/cocktail/doca4.ps/ell.ps.zip\n\n        Like Grosch I implemented local FOLLOW sets that are combined\n        at run-time upon error to avoid overhead during parsing.\n        \"\"\"\n        \n        return self.combineFollows(False)\n\n        \n    def computeContextSensitiveRuleFOLLOW(self):\n        \"\"\"\n        Compute the context-sensitive FOLLOW set for current rule.\n        This is set of token types that can follow a specific rule\n        reference given a specific call chain.  You get the set of\n        viable tokens that can possibly come next (lookahead depth 1)\n        given the current call chain.  Contrast this with the\n        definition of plain FOLLOW for rule r:\n\n         FOLLOW(r)={x | S=>*alpha r beta in G and x in FIRST(beta)}\n\n        where x in T* and alpha, beta in V*; T is set of terminals and\n        V is the set of terminals and nonterminals.  In other words,\n        FOLLOW(r) is the set of all tokens that can possibly follow\n        references to r in *any* sentential form (context).  At\n        runtime, however, we know precisely which context applies as\n        we have the call chain.  We may compute the exact (rather\n        than covering superset) set of following tokens.\n\n        For example, consider grammar:\n\n        stat : ID '=' expr ';'      // FOLLOW(stat)=={EOF}\n             | \"return\" expr '.'\n             ;\n        expr : atom ('+' atom)* ;   // FOLLOW(expr)=={';','.',')'}\n        atom : INT                  // FOLLOW(atom)=={'+',')',';','.'}\n             | '(' expr ')'\n             ;\n\n        The FOLLOW sets are all inclusive whereas context-sensitive\n        FOLLOW sets are precisely what could follow a rule reference.\n        For input input \"i=(3);\", here is the derivation:\n\n        stat => ID '=' expr ';'\n             => ID '=' atom ('+' atom)* ';'\n             => ID '=' '(' expr ')' ('+' atom)* ';'\n             => ID '=' '(' atom ')' ('+' atom)* ';'\n             => ID '=' '(' INT ')' ('+' atom)* ';'\n             => ID '=' '(' INT ')' ';'\n\n        At the \"3\" token, you'd have a call chain of\n\n          stat -> expr -> atom -> expr -> atom\n\n        What can follow that specific nested ref to atom?  Exactly ')'\n        as you can see by looking at the derivation of this specific\n        input.  Contrast this with the FOLLOW(atom)={'+',')',';','.'}.\n\n        You want the exact viable token set when recovering from a\n        token mismatch.  Upon token mismatch, if LA(1) is member of\n        the viable next token set, then you know there is most likely\n        a missing token in the input stream.  \"Insert\" one by just not\n        throwing an exception.\n        \"\"\"\n\n        return self.combineFollows(True)\n\n\n    def combineFollows(self, exact):\n        followSet = set()\n        for idx, localFollowSet in reversed(list(enumerate(self._state.following))):\n            followSet |= localFollowSet\n            if exact:\n                # can we see end of rule?\n                if EOR_TOKEN_TYPE in localFollowSet:\n                    # Only leave EOR in set if at top (start rule); this lets\n                    # us know if have to include follow(start rule); i.e., EOF\n                    if idx > 0:\n                        followSet.remove(EOR_TOKEN_TYPE)\n                        \n                else:\n                    # can't see end of rule, quit\n                    break\n\n        return followSet\n\n\n    def recoverFromMismatchedToken(self, input, ttype, follow):\n        \"\"\"Attempt to recover from a single missing or extra token.\n\n        EXTRA TOKEN\n\n        LA(1) is not what we are looking for.  If LA(2) has the right token,\n        however, then assume LA(1) is some extra spurious token.  Delete it\n        and LA(2) as if we were doing a normal match(), which advances the\n        input.\n\n        MISSING TOKEN\n\n        If current token is consistent with what could come after\n        ttype then it is ok to 'insert' the missing token, else throw\n        exception For example, Input 'i=(3;' is clearly missing the\n        ')'.  When the parser returns from the nested call to expr, it\n        will have call chain:\n\n          stat -> expr -> atom\n\n        and it will be trying to match the ')' at this point in the\n        derivation:\n\n             => ID '=' '(' INT ')' ('+' atom)* ';'\n                                ^\n        match() will see that ';' doesn't match ')' and report a\n        mismatched token error.  To recover, it sees that LA(1)==';'\n        is in the set of tokens that can follow the ')' token\n        reference in rule atom.  It can assume that you forgot the ')'.\n        \"\"\"\n\n        e = None\n\n        # if next token is what we are looking for then \"delete\" this token\n        if self. mismatchIsUnwantedToken(input, ttype):\n            e = UnwantedTokenException(ttype, input)\n\n            self.beginResync()\n            input.consume() # simply delete extra token\n            self.endResync()\n\n            # report after consuming so AW sees the token in the exception\n            self.reportError(e)\n\n            # we want to return the token we're actually matching\n            matchedSymbol = self.getCurrentInputSymbol(input)\n\n            # move past ttype token as if all were ok\n            input.consume()\n            return matchedSymbol\n\n        # can't recover with single token deletion, try insertion\n        if self.mismatchIsMissingToken(input, follow):\n            inserted = self.getMissingSymbol(input, e, ttype, follow)\n            e = MissingTokenException(ttype, input, inserted)\n\n            # report after inserting so AW sees the token in the exception\n            self.reportError(e)\n            return inserted\n\n        # even that didn't work; must throw the exception\n        e = MismatchedTokenException(ttype, input)\n        raise e\n\n\n    def recoverFromMismatchedSet(self, input, e, follow):\n        \"\"\"Not currently used\"\"\"\n\n        if self.mismatchIsMissingToken(input, follow):\n            self.reportError(e)\n            # we don't know how to conjure up a token for sets yet\n            return self.getMissingSymbol(input, e, INVALID_TOKEN_TYPE, follow)\n\n        # TODO do single token deletion like above for Token mismatch\n        raise e\n\n\n    def getCurrentInputSymbol(self, input):\n        \"\"\"\n        Match needs to return the current input symbol, which gets put\n        into the label for the associated token ref; e.g., x=ID.  Token\n        and tree parsers need to return different objects. Rather than test\n        for input stream type or change the IntStream interface, I use\n        a simple method to ask the recognizer to tell me what the current\n        input symbol is.\n\n        This is ignored for lexers.\n        \"\"\"\n        \n        return None\n\n\n    def getMissingSymbol(self, input, e, expectedTokenType, follow):\n        \"\"\"Conjure up a missing token during error recovery.\n\n        The recognizer attempts to recover from single missing\n        symbols. But, actions might refer to that missing symbol.\n        For example, x=ID {f($x);}. The action clearly assumes\n        that there has been an identifier matched previously and that\n        $x points at that token. If that token is missing, but\n        the next token in the stream is what we want we assume that\n        this token is missing and we keep going. Because we\n        have to return some token to replace the missing token,\n        we have to conjure one up. This method gives the user control\n        over the tokens returned for missing tokens. Mostly,\n        you will want to create something special for identifier\n        tokens. For literals such as '{' and ',', the default\n        action in the parser or tree parser works. It simply creates\n        a CommonToken of the appropriate type. The text will be the token.\n        If you change what tokens must be created by the lexer,\n        override this method to create the appropriate tokens.\n        \"\"\"\n\n        return None\n\n\n##     def recoverFromMissingElement(self, input, e, follow):\n##         \"\"\"\n##         This code is factored out from mismatched token and mismatched set\n##         recovery.  It handles \"single token insertion\" error recovery for\n##         both.  No tokens are consumed to recover from insertions.  Return\n##         true if recovery was possible else return false.\n##         \"\"\"\n        \n##         if self.mismatchIsMissingToken(input, follow):\n##             self.reportError(e)\n##             return True\n\n##         # nothing to do; throw exception\n##         return False\n\n\n    def consumeUntil(self, input, tokenTypes):\n        \"\"\"\n        Consume tokens until one matches the given token or token set\n\n        tokenTypes can be a single token type or a set of token types\n        \n        \"\"\"\n        \n        if not isinstance(tokenTypes, (set, frozenset)):\n            tokenTypes = frozenset([tokenTypes])\n\n        ttype = input.LA(1)\n        while ttype != EOF and ttype not in tokenTypes:\n            input.consume()\n            ttype = input.LA(1)\n\n\n    def getRuleInvocationStack(self):\n        \"\"\"\n        Return List<String> of the rules in your parser instance\n        leading up to a call to this method.  You could override if\n        you want more details such as the file/line info of where\n        in the parser java code a rule is invoked.\n\n        This is very useful for error messages and for context-sensitive\n        error recovery.\n\n        You must be careful, if you subclass a generated recognizers.\n        The default implementation will only search the module of self\n        for rules, but the subclass will not contain any rules.\n        You probably want to override this method to look like\n\n        def getRuleInvocationStack(self):\n            return self._getRuleInvocationStack(<class>.__module__)\n\n        where <class> is the class of the generated recognizer, e.g.\n        the superclass of self.\n        \"\"\"\n\n        return self._getRuleInvocationStack(self.__module__)\n\n\n    def _getRuleInvocationStack(cls, module):\n        \"\"\"\n        A more general version of getRuleInvocationStack where you can\n        pass in, for example, a RecognitionException to get it's rule\n        stack trace.  This routine is shared with all recognizers, hence,\n        static.\n\n        TODO: move to a utility class or something; weird having lexer call\n        this\n        \"\"\"\n\n        # mmmhhh,... perhaps look at the first argument\n        # (f_locals[co_varnames[0]]?) and test if it's a (sub)class of\n        # requested recognizer...\n        \n        rules = []\n        for frame in reversed(inspect.stack()):\n            code = frame[0].f_code\n            codeMod = inspect.getmodule(code)\n            if codeMod is None:\n                continue\n\n            # skip frames not in requested module\n            if codeMod.__name__ != module:\n                continue\n\n            # skip some unwanted names\n            if code.co_name in ('nextToken', '<module>'):\n                continue\n\n            rules.append(code.co_name)\n\n        return rules\n        \n    _getRuleInvocationStack = classmethod(_getRuleInvocationStack)\n    \n\n    def getBacktrackingLevel(self):\n        return self._state.backtracking\n\n\n    def getGrammarFileName(self):\n        \"\"\"For debugging and other purposes, might want the grammar name.\n        \n        Have ANTLR generate an implementation for this method.\n        \"\"\"\n\n        return self.grammarFileName\n\n\n    def getSourceName(self):\n        raise NotImplementedError\n\n    \n    def toStrings(self, tokens):\n        \"\"\"A convenience method for use most often with template rewrites.\n\n        Convert a List<Token> to List<String>\n        \"\"\"\n\n        if tokens is None:\n            return None\n\n        return [token.text for token in tokens]\n\n\n    def getRuleMemoization(self, ruleIndex, ruleStartIndex):\n        \"\"\"\n        Given a rule number and a start token index number, return\n        MEMO_RULE_UNKNOWN if the rule has not parsed input starting from\n        start index.  If this rule has parsed input starting from the\n        start index before, then return where the rule stopped parsing.\n        It returns the index of the last token matched by the rule.\n        \"\"\"\n        \n        if ruleIndex not in self._state.ruleMemo:\n            self._state.ruleMemo[ruleIndex] = {}\n\n        return self._state.ruleMemo[ruleIndex].get(\n            ruleStartIndex, self.MEMO_RULE_UNKNOWN\n            )\n\n\n    def alreadyParsedRule(self, input, ruleIndex):\n        \"\"\"\n        Has this rule already parsed input at the current index in the\n        input stream?  Return the stop token index or MEMO_RULE_UNKNOWN.\n        If we attempted but failed to parse properly before, return\n        MEMO_RULE_FAILED.\n\n        This method has a side-effect: if we have seen this input for\n        this rule and successfully parsed before, then seek ahead to\n        1 past the stop token matched for this rule last time.\n        \"\"\"\n\n        stopIndex = self.getRuleMemoization(ruleIndex, input.index())\n        if stopIndex == self.MEMO_RULE_UNKNOWN:\n            return False\n\n        if stopIndex == self.MEMO_RULE_FAILED:\n            raise BacktrackingFailed\n\n        else:\n            input.seek(stopIndex + 1)\n\n        return True\n\n\n    def memoize(self, input, ruleIndex, ruleStartIndex, success):\n        \"\"\"\n        Record whether or not this rule parsed the input at this position\n        successfully.\n        \"\"\"\n\n        if success:\n            stopTokenIndex = input.index() - 1\n        else:\n            stopTokenIndex = self.MEMO_RULE_FAILED\n        \n        if ruleIndex in self._state.ruleMemo:\n            self._state.ruleMemo[ruleIndex][ruleStartIndex] = stopTokenIndex\n\n\n    def traceIn(self, ruleName, ruleIndex, inputSymbol):\n        sys.stdout.write(\"enter %s %s\" % (ruleName, inputSymbol))\n        \n##         if self._state.failed:\n##             sys.stdout.write(\" failed=%s\" % self._state.failed)\n\n        if self._state.backtracking > 0:\n            sys.stdout.write(\" backtracking=%s\" % self._state.backtracking)\n\n        sys.stdout.write('\\n')\n\n\n    def traceOut(self, ruleName, ruleIndex, inputSymbol):\n        sys.stdout.write(\"exit %s %s\" % (ruleName, inputSymbol))\n        \n##         if self._state.failed:\n##             sys.stdout.write(\" failed=%s\" % self._state.failed)\n\n        if self._state.backtracking > 0:\n            sys.stdout.write(\" backtracking=%s\" % self._state.backtracking)\n\n        sys.stdout.write('\\n')\n\n\n\nclass TokenSource(object):\n    \"\"\"\n    @brief Abstract baseclass for token producers.\n    \n    A source of tokens must provide a sequence of tokens via nextToken()\n    and also must reveal it's source of characters; CommonToken's text is\n    computed from a CharStream; it only store indices into the char stream.\n\n    Errors from the lexer are never passed to the parser.  Either you want\n    to keep going or you do not upon token recognition error.  If you do not\n    want to continue lexing then you do not want to continue parsing.  Just\n    throw an exception not under RecognitionException and Java will naturally\n    toss you all the way out of the recognizers.  If you want to continue\n    lexing then you should not throw an exception to the parser--it has already\n    requested a token.  Keep lexing until you get a valid one.  Just report\n    errors and keep going, looking for a valid token.\n    \"\"\"\n    \n    def nextToken(self):\n        \"\"\"Return a Token object from your input stream (usually a CharStream).\n        \n        Do not fail/return upon lexing error; keep chewing on the characters\n        until you get a good one; errors are not passed through to the parser.\n        \"\"\"\n\n        raise NotImplementedError\n    \n\n    def __iter__(self):\n        \"\"\"The TokenSource is an interator.\n\n        The iteration will not include the final EOF token, see also the note\n        for the next() method.\n\n        \"\"\"\n        \n        return self\n\n    \n    def next(self):\n        \"\"\"Return next token or raise StopIteration.\n\n        Note that this will raise StopIteration when hitting the EOF token,\n        so EOF will not be part of the iteration.\n        \n        \"\"\"\n\n        token = self.nextToken()\n        if token is None or token.type == EOF:\n            raise StopIteration\n        return token\n\n    \nclass Lexer(BaseRecognizer, TokenSource):\n    \"\"\"\n    @brief Baseclass for generated lexer classes.\n    \n    A lexer is recognizer that draws input symbols from a character stream.\n    lexer grammars result in a subclass of this object. A Lexer object\n    uses simplified match() and error recovery mechanisms in the interest\n    of speed.\n    \"\"\"\n\n    def __init__(self, input, state=None):\n        BaseRecognizer.__init__(self, state)\n        TokenSource.__init__(self)\n        \n        # Where is the lexer drawing characters from?\n        self.input = input\n\n\n    def reset(self):\n        BaseRecognizer.reset(self) # reset all recognizer state variables\n\n        if self.input is not None:\n            # rewind the input\n            self.input.seek(0)\n\n        if self._state is None:\n            # no shared state work to do\n            return\n        \n        # wack Lexer state variables\n        self._state.token = None\n        self._state.type = INVALID_TOKEN_TYPE\n        self._state.channel = DEFAULT_CHANNEL\n        self._state.tokenStartCharIndex = -1\n        self._state.tokenStartLine = -1\n        self._state.tokenStartCharPositionInLine = -1\n        self._state.text = None\n\n\n    def nextToken(self):\n        \"\"\"\n        Return a token from this source; i.e., match a token on the char\n        stream.\n        \"\"\"\n        \n        while 1:\n            self._state.token = None\n            self._state.channel = DEFAULT_CHANNEL\n            self._state.tokenStartCharIndex = self.input.index()\n            self._state.tokenStartCharPositionInLine = self.input.charPositionInLine\n            self._state.tokenStartLine = self.input.line\n            self._state.text = None\n            if self.input.LA(1) == EOF:\n                return EOF_TOKEN\n\n            try:\n                self.mTokens()\n                \n                if self._state.token is None:\n                    self.emit()\n                    \n                elif self._state.token == SKIP_TOKEN:\n                    continue\n\n                return self._state.token\n\n            except NoViableAltException, re:\n                self.reportError(re)\n                self.recover(re) # throw out current char and try again\n\n            except RecognitionException, re:\n                self.reportError(re)\n                # match() routine has already called recover()\n\n\n    def skip(self):\n        \"\"\"\n        Instruct the lexer to skip creating a token for current lexer rule\n        and look for another token.  nextToken() knows to keep looking when\n        a lexer rule finishes with token set to SKIP_TOKEN.  Recall that\n        if token==null at end of any token rule, it creates one for you\n        and emits it.\n        \"\"\"\n        \n        self._state.token = SKIP_TOKEN\n\n\n    def mTokens(self):\n        \"\"\"This is the lexer entry point that sets instance var 'token'\"\"\"\n\n        # abstract method\n        raise NotImplementedError\n    \n\n    def setCharStream(self, input):\n        \"\"\"Set the char stream and reset the lexer\"\"\"\n        self.input = None\n        self.reset()\n        self.input = input\n\n\n    def getSourceName(self):\n        return self.input.getSourceName()\n\n\n    def emit(self, token=None):\n        \"\"\"\n        The standard method called to automatically emit a token at the\n        outermost lexical rule.  The token object should point into the\n        char buffer start..stop.  If there is a text override in 'text',\n        use that to set the token's text.  Override this method to emit\n        custom Token objects.\n\n        If you are building trees, then you should also override\n        Parser or TreeParser.getMissingSymbol().\n        \"\"\"\n\n        if token is None:\n            token = CommonToken(\n                input=self.input,\n                type=self._state.type,\n                channel=self._state.channel,\n                start=self._state.tokenStartCharIndex,\n                stop=self.getCharIndex()-1\n                )\n            token.line = self._state.tokenStartLine\n            token.text = self._state.text\n            token.charPositionInLine = self._state.tokenStartCharPositionInLine\n\n        self._state.token = token\n        \n        return token\n\n\n    def match(self, s):\n        if isinstance(s, basestring):\n            for c in s:\n                if self.input.LA(1) != ord(c):\n                    if self._state.backtracking > 0:\n                        raise BacktrackingFailed\n\n                    mte = MismatchedTokenException(c, self.input)\n                    self.recover(mte)\n                    raise mte\n\n                self.input.consume()\n\n        else:\n            if self.input.LA(1) != s:\n                if self._state.backtracking > 0:\n                    raise BacktrackingFailed\n\n                mte = MismatchedTokenException(unichr(s), self.input)\n                self.recover(mte) # don't really recover; just consume in lexer\n                raise mte\n        \n            self.input.consume()\n            \n\n    def matchAny(self):\n        self.input.consume()\n\n\n    def matchRange(self, a, b):\n        if self.input.LA(1) < a or self.input.LA(1) > b:\n            if self._state.backtracking > 0:\n                raise BacktrackingFailed\n\n            mre = MismatchedRangeException(unichr(a), unichr(b), self.input)\n            self.recover(mre)\n            raise mre\n\n        self.input.consume()\n\n\n    def getLine(self):\n        return self.input.line\n\n\n    def getCharPositionInLine(self):\n        return self.input.charPositionInLine\n\n\n    def getCharIndex(self):\n        \"\"\"What is the index of the current character of lookahead?\"\"\"\n        \n        return self.input.index()\n\n\n    def getText(self):\n        \"\"\"\n        Return the text matched so far for the current token or any\n        text override.\n        \"\"\"\n        if self._state.text is not None:\n            return self._state.text\n        \n        return self.input.substring(\n            self._state.tokenStartCharIndex,\n            self.getCharIndex()-1\n            )\n\n\n    def setText(self, text):\n        \"\"\"\n        Set the complete text of this token; it wipes any previous\n        changes to the text.\n        \"\"\"\n        self._state.text = text\n\n\n    text = property(getText, setText)\n\n\n    def reportError(self, e):\n        ## TODO: not thought about recovery in lexer yet.\n\n        ## # if we've already reported an error and have not matched a token\n        ## # yet successfully, don't report any errors.\n        ## if self.errorRecovery:\n        ##     #System.err.print(\"[SPURIOUS] \");\n        ##     return;\n        ## \n        ## self.errorRecovery = True\n\n        self.displayRecognitionError(self.tokenNames, e)\n\n\n    def getErrorMessage(self, e, tokenNames):\n        msg = None\n        \n        if isinstance(e, MismatchedTokenException):\n            msg = \"mismatched character \" \\\n                  + self.getCharErrorDisplay(e.c) \\\n                  + \" expecting \" \\\n                  + self.getCharErrorDisplay(e.expecting)\n\n        elif isinstance(e, NoViableAltException):\n            msg = \"no viable alternative at character \" \\\n                  + self.getCharErrorDisplay(e.c)\n\n        elif isinstance(e, EarlyExitException):\n            msg = \"required (...)+ loop did not match anything at character \" \\\n                  + self.getCharErrorDisplay(e.c)\n            \n        elif isinstance(e, MismatchedNotSetException):\n            msg = \"mismatched character \" \\\n                  + self.getCharErrorDisplay(e.c) \\\n                  + \" expecting set \" \\\n                  + repr(e.expecting)\n\n        elif isinstance(e, MismatchedSetException):\n            msg = \"mismatched character \" \\\n                  + self.getCharErrorDisplay(e.c) \\\n                  + \" expecting set \" \\\n                  + repr(e.expecting)\n\n        elif isinstance(e, MismatchedRangeException):\n            msg = \"mismatched character \" \\\n                  + self.getCharErrorDisplay(e.c) \\\n                  + \" expecting set \" \\\n                  + self.getCharErrorDisplay(e.a) \\\n                  + \"..\" \\\n                  + self.getCharErrorDisplay(e.b)\n\n        else:\n            msg = BaseRecognizer.getErrorMessage(self, e, tokenNames)\n\n        return msg\n\n\n    def getCharErrorDisplay(self, c):\n        if c == EOF:\n            c = '<EOF>'\n        return repr(c)\n\n\n    def recover(self, re):\n        \"\"\"\n        Lexers can normally match any char in it's vocabulary after matching\n        a token, so do the easy thing and just kill a character and hope\n        it all works out.  You can instead use the rule invocation stack\n        to do sophisticated error recovery if you are in a fragment rule.\n        \"\"\"\n\n        self.input.consume()\n\n\n    def traceIn(self, ruleName, ruleIndex):\n        inputSymbol = \"%s line=%d:%s\" % (self.input.LT(1),\n                                         self.getLine(),\n                                         self.getCharPositionInLine()\n                                         )\n        \n        BaseRecognizer.traceIn(self, ruleName, ruleIndex, inputSymbol)\n\n\n    def traceOut(self, ruleName, ruleIndex):\n        inputSymbol = \"%s line=%d:%s\" % (self.input.LT(1),\n                                         self.getLine(),\n                                         self.getCharPositionInLine()\n                                         )\n\n        BaseRecognizer.traceOut(self, ruleName, ruleIndex, inputSymbol)\n\n\n\nclass Parser(BaseRecognizer):\n    \"\"\"\n    @brief Baseclass for generated parser classes.\n    \"\"\"\n    \n    def __init__(self, lexer, state=None):\n        BaseRecognizer.__init__(self, state)\n\n        self.setTokenStream(lexer)\n\n\n    def reset(self):\n        BaseRecognizer.reset(self) # reset all recognizer state variables\n        if self.input is not None:\n            self.input.seek(0) # rewind the input\n\n\n    def getCurrentInputSymbol(self, input):\n        return input.LT(1)\n\n\n    def getMissingSymbol(self, input, e, expectedTokenType, follow):\n        if expectedTokenType == EOF:\n            tokenText = \"<missing EOF>\"\n        else:\n            tokenText = \"<missing \" + self.tokenNames[expectedTokenType] + \">\"\n        t = CommonToken(type=expectedTokenType, text=tokenText)\n        current = input.LT(1)\n        if current.type == EOF:\n            current = input.LT(-1)\n\n        if current is not None:\n            t.line = current.line\n            t.charPositionInLine = current.charPositionInLine\n        t.channel = DEFAULT_CHANNEL\n        return t\n\n\n    def setTokenStream(self, input):\n        \"\"\"Set the token stream and reset the parser\"\"\"\n        \n        self.input = None\n        self.reset()\n        self.input = input\n\n\n    def getTokenStream(self):\n        return self.input\n\n\n    def getSourceName(self):\n        return self.input.getSourceName()\n\n\n    def traceIn(self, ruleName, ruleIndex):\n        BaseRecognizer.traceIn(self, ruleName, ruleIndex, self.input.LT(1))\n\n\n    def traceOut(self, ruleName, ruleIndex):\n        BaseRecognizer.traceOut(self, ruleName, ruleIndex, self.input.LT(1))\n\n\nclass RuleReturnScope(object):\n    \"\"\"\n    Rules can return start/stop info as well as possible trees and templates.\n    \"\"\"\n\n    def getStart(self):\n        \"\"\"Return the start token or tree.\"\"\"\n        return None\n    \n\n    def getStop(self):\n        \"\"\"Return the stop token or tree.\"\"\"\n        return None\n\n    \n    def getTree(self):\n        \"\"\"Has a value potentially if output=AST.\"\"\"\n        return None\n\n\n    def getTemplate(self):\n        \"\"\"Has a value potentially if output=template.\"\"\"\n        return None\n\n\nclass ParserRuleReturnScope(RuleReturnScope):\n    \"\"\"\n    Rules that return more than a single value must return an object\n    containing all the values.  Besides the properties defined in\n    RuleLabelScope.predefinedRulePropertiesScope there may be user-defined\n    return values.  This class simply defines the minimum properties that\n    are always defined and methods to access the others that might be\n    available depending on output option such as template and tree.\n\n    Note text is not an actual property of the return value, it is computed\n    from start and stop using the input stream's toString() method.  I\n    could add a ctor to this so that we can pass in and store the input\n    stream, but I'm not sure we want to do that.  It would seem to be undefined\n    to get the .text property anyway if the rule matches tokens from multiple\n    input streams.\n\n    I do not use getters for fields of objects that are used simply to\n    group values such as this aggregate.  The getters/setters are there to\n    satisfy the superclass interface.\n    \"\"\"\n\n    def __init__(self):\n        self.start = None\n        self.stop = None\n\n    \n    def getStart(self):\n        return self.start\n\n\n    def getStop(self):\n        return self.stop\n\n"
  },
  {
    "path": "deps/cpy/antlr3/streams.py",
    "content": "\"\"\"ANTLR3 runtime package\"\"\"\n\n# begin[licence]\n#\n# [The \"BSD licence\"]\n# Copyright (c) 2005-2008 Terence Parr\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. The name of the author may not be used to endorse or promote products\n#    derived from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n# NOT 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 OF\n# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#\n# end[licence]\n\nimport codecs\nfrom StringIO import StringIO\n\nfrom antlr3.constants import DEFAULT_CHANNEL, EOF\nfrom antlr3.tokens import Token, EOF_TOKEN\n\n\n############################################################################\n#\n# basic interfaces\n#   IntStream\n#    +- CharStream\n#    \\- TokenStream\n#\n# subclasses must implemented all methods\n#\n############################################################################\n\nclass IntStream(object):\n    \"\"\"\n    @brief Base interface for streams of integer values.\n\n    A simple stream of integers used when all I care about is the char\n    or token type sequence (such as interpretation).\n    \"\"\"\n\n    def consume(self):\n        raise NotImplementedError\n    \n\n    def LA(self, i):\n        \"\"\"Get int at current input pointer + i ahead where i=1 is next int.\n\n        Negative indexes are allowed.  LA(-1) is previous token (token\n\tjust matched).  LA(-i) where i is before first token should\n\tyield -1, invalid char / EOF.\n\t\"\"\"\n        \n        raise NotImplementedError\n        \n\n    def mark(self):\n        \"\"\"\n        Tell the stream to start buffering if it hasn't already.  Return\n        current input position, index(), or some other marker so that\n        when passed to rewind() you get back to the same spot.\n        rewind(mark()) should not affect the input cursor.  The Lexer\n        track line/col info as well as input index so its markers are\n        not pure input indexes.  Same for tree node streams.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def index(self):\n        \"\"\"\n        Return the current input symbol index 0..n where n indicates the\n        last symbol has been read.  The index is the symbol about to be\n        read not the most recently read symbol.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def rewind(self, marker=None):\n        \"\"\"\n        Reset the stream so that next call to index would return marker.\n        The marker will usually be index() but it doesn't have to be.  It's\n        just a marker to indicate what state the stream was in.  This is\n        essentially calling release() and seek().  If there are markers\n        created after this marker argument, this routine must unroll them\n        like a stack.  Assume the state the stream was in when this marker\n        was created.\n\n        If marker is None:\n        Rewind to the input position of the last marker.\n        Used currently only after a cyclic DFA and just\n        before starting a sem/syn predicate to get the\n        input position back to the start of the decision.\n        Do not \"pop\" the marker off the state.  mark(i)\n        and rewind(i) should balance still. It is\n        like invoking rewind(last marker) but it should not \"pop\"\n        the marker off.  It's like seek(last marker's input position).       \n\t\"\"\"\n\n        raise NotImplementedError\n\n\n    def release(self, marker=None):\n        \"\"\"\n        You may want to commit to a backtrack but don't want to force the\n        stream to keep bookkeeping objects around for a marker that is\n        no longer necessary.  This will have the same behavior as\n        rewind() except it releases resources without the backward seek.\n        This must throw away resources for all markers back to the marker\n        argument.  So if you're nested 5 levels of mark(), and then release(2)\n        you have to release resources for depths 2..5.\n\t\"\"\"\n\n        raise NotImplementedError\n\n\n    def seek(self, index):\n        \"\"\"\n        Set the input cursor to the position indicated by index.  This is\n        normally used to seek ahead in the input stream.  No buffering is\n        required to do this unless you know your stream will use seek to\n        move backwards such as when backtracking.\n\n        This is different from rewind in its multi-directional\n        requirement and in that its argument is strictly an input cursor\n        (index).\n\n        For char streams, seeking forward must update the stream state such\n        as line number.  For seeking backwards, you will be presumably\n        backtracking using the mark/rewind mechanism that restores state and\n        so this method does not need to update state when seeking backwards.\n\n        Currently, this method is only used for efficient backtracking using\n        memoization, but in the future it may be used for incremental parsing.\n\n        The index is 0..n-1.  A seek to position i means that LA(1) will\n        return the ith symbol.  So, seeking to 0 means LA(1) will return the\n        first element in the stream. \n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def size(self):\n        \"\"\"\n        Only makes sense for streams that buffer everything up probably, but\n        might be useful to display the entire stream or for testing.  This\n        value includes a single EOF.\n\t\"\"\"\n\n        raise NotImplementedError\n\n\n    def getSourceName(self):\n        \"\"\"\n        Where are you getting symbols from?  Normally, implementations will\n        pass the buck all the way to the lexer who can ask its input stream\n        for the file name or whatever.\n        \"\"\"\n\n        raise NotImplementedError\n\n\nclass CharStream(IntStream):\n    \"\"\"\n    @brief A source of characters for an ANTLR lexer.\n\n    This is an abstract class that must be implemented by a subclass.\n    \n    \"\"\"\n\n    # pylint does not realize that this is an interface, too\n    #pylint: disable-msg=W0223\n    \n    EOF = -1\n\n\n    def substring(self, start, stop):\n        \"\"\"\n        For infinite streams, you don't need this; primarily I'm providing\n        a useful interface for action code.  Just make sure actions don't\n        use this on streams that don't support it.\n        \"\"\"\n\n        raise NotImplementedError\n        \n    \n    def LT(self, i):\n        \"\"\"\n        Get the ith character of lookahead.  This is the same usually as\n        LA(i).  This will be used for labels in the generated\n        lexer code.  I'd prefer to return a char here type-wise, but it's\n        probably better to be 32-bit clean and be consistent with LA.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def getLine(self):\n        \"\"\"ANTLR tracks the line information automatically\"\"\"\n\n        raise NotImplementedError\n\n\n    def setLine(self, line):\n        \"\"\"\n        Because this stream can rewind, we need to be able to reset the line\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def getCharPositionInLine(self):\n        \"\"\"\n        The index of the character relative to the beginning of the line 0..n-1\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def setCharPositionInLine(self, pos):\n        raise NotImplementedError\n\n\nclass TokenStream(IntStream):\n    \"\"\"\n\n    @brief A stream of tokens accessing tokens from a TokenSource\n\n    This is an abstract class that must be implemented by a subclass.\n    \n    \"\"\"\n    \n    # pylint does not realize that this is an interface, too\n    #pylint: disable-msg=W0223\n    \n    def LT(self, k):\n        \"\"\"\n        Get Token at current input pointer + i ahead where i=1 is next Token.\n        i<0 indicates tokens in the past.  So -1 is previous token and -2 is\n        two tokens ago. LT(0) is undefined.  For i>=n, return Token.EOFToken.\n        Return null for LT(0) and any index that results in an absolute address\n        that is negative.\n\t\"\"\"\n\n        raise NotImplementedError\n\n\n    def get(self, i):\n        \"\"\"\n        Get a token at an absolute index i; 0..n-1.  This is really only\n        needed for profiling and debugging and token stream rewriting.\n        If you don't want to buffer up tokens, then this method makes no\n        sense for you.  Naturally you can't use the rewrite stream feature.\n        I believe DebugTokenStream can easily be altered to not use\n        this method, removing the dependency.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def getTokenSource(self):\n        \"\"\"\n        Where is this stream pulling tokens from?  This is not the name, but\n        the object that provides Token objects.\n\t\"\"\"\n\n        raise NotImplementedError\n\n\n    def toString(self, start=None, stop=None):\n        \"\"\"\n        Return the text of all tokens from start to stop, inclusive.\n        If the stream does not buffer all the tokens then it can just\n        return \"\" or null;  Users should not access $ruleLabel.text in\n        an action of course in that case.\n\n        Because the user is not required to use a token with an index stored\n        in it, we must provide a means for two token objects themselves to\n        indicate the start/end location.  Most often this will just delegate\n        to the other toString(int,int).  This is also parallel with\n        the TreeNodeStream.toString(Object,Object).\n\t\"\"\"\n\n        raise NotImplementedError\n\n        \n############################################################################\n#\n# character streams for use in lexers\n#   CharStream\n#   \\- ANTLRStringStream\n#\n############################################################################\n\n\nclass ANTLRStringStream(CharStream):\n    \"\"\"\n    @brief CharStream that pull data from a unicode string.\n    \n    A pretty quick CharStream that pulls all data from an array\n    directly.  Every method call counts in the lexer.\n\n    \"\"\"\n\n    \n    def __init__(self, data):\n        \"\"\"\n        @param data This should be a unicode string holding the data you want\n           to parse. If you pass in a byte string, the Lexer will choke on\n           non-ascii data.\n           \n        \"\"\"\n        \n        CharStream.__init__(self)\n        \n  \t# The data being scanned\n        self.strdata = unicode(data)\n        self.data = [ord(c) for c in self.strdata]\n        \n\t# How many characters are actually in the buffer\n        self.n = len(data)\n\n \t# 0..n-1 index into string of next char\n        self.p = 0\n\n\t# line number 1..n within the input\n        self.line = 1\n\n \t# The index of the character relative to the beginning of the\n        # line 0..n-1\n        self.charPositionInLine = 0\n\n\t# A list of CharStreamState objects that tracks the stream state\n        # values line, charPositionInLine, and p that can change as you\n        # move through the input stream.  Indexed from 0..markDepth-1.\n        self._markers = [ ]\n        self.lastMarker = None\n        self.markDepth = 0\n\n        # What is name or source of this char stream?\n        self.name = None\n\n\n    def reset(self):\n        \"\"\"\n        Reset the stream so that it's in the same state it was\n        when the object was created *except* the data array is not\n        touched.\n        \"\"\"\n        \n        self.p = 0\n        self.line = 1\n        self.charPositionInLine = 0\n        self._markers = [ ]\n\n\n    def consume(self):\n        try:\n            if self.data[self.p] == 10: # \\n\n                self.line += 1\n                self.charPositionInLine = 0\n            else:\n                self.charPositionInLine += 1\n\n            self.p += 1\n            \n        except IndexError:\n            # happend when we reached EOF and self.data[self.p] fails\n            # just do nothing\n            pass\n\n\n\n    def LA(self, i):\n        if i == 0:\n            return 0 # undefined\n\n        if i < 0:\n            i += 1 # e.g., translate LA(-1) to use offset i=0; then data[p+0-1]\n\n        try:\n            return self.data[self.p+i-1]\n        except IndexError:\n            return EOF\n\n\n\n    def LT(self, i):\n        if i == 0:\n            return 0 # undefined\n\n        if i < 0:\n            i += 1 # e.g., translate LA(-1) to use offset i=0; then data[p+0-1]\n\n        try:\n            return self.strdata[self.p+i-1]\n        except IndexError:\n            return EOF\n\n\n    def index(self):\n        \"\"\"\n        Return the current input symbol index 0..n where n indicates the\n        last symbol has been read.  The index is the index of char to\n        be returned from LA(1).\n        \"\"\"\n        \n        return self.p\n\n\n    def size(self):\n        return self.n\n\n\n    def mark(self):\n        state = (self.p, self.line, self.charPositionInLine)\n        try:\n            self._markers[self.markDepth] = state\n        except IndexError:\n            self._markers.append(state)\n        self.markDepth += 1\n        \n        self.lastMarker = self.markDepth\n        \n        return self.lastMarker\n\n\n    def rewind(self, marker=None):\n        if marker is None:\n            marker = self.lastMarker\n\n        p, line, charPositionInLine = self._markers[marker-1]\n\n        self.seek(p)\n        self.line = line\n        self.charPositionInLine = charPositionInLine\n        self.release(marker)\n\n\n    def release(self, marker=None):\n        if marker is None:\n            marker = self.lastMarker\n\n        self.markDepth = marker-1\n\n\n    def seek(self, index):\n        \"\"\"\n        consume() ahead until p==index; can't just set p=index as we must\n        update line and charPositionInLine.\n        \"\"\"\n        \n        if index <= self.p:\n            self.p = index # just jump; don't update stream state (line, ...)\n            return\n\n        # seek forward, consume until p hits index\n        while self.p < index:\n            self.consume()\n\n\n    def substring(self, start, stop):\n        return self.strdata[start:stop+1]\n\n\n    def getLine(self):\n        \"\"\"Using setter/getter methods is deprecated. Use o.line instead.\"\"\"\n        return self.line\n\n\n    def getCharPositionInLine(self):\n        \"\"\"\n        Using setter/getter methods is deprecated. Use o.charPositionInLine\n        instead.\n        \"\"\"\n        return self.charPositionInLine\n\n\n    def setLine(self, line):\n        \"\"\"Using setter/getter methods is deprecated. Use o.line instead.\"\"\"\n        self.line = line\n\n\n    def setCharPositionInLine(self, pos):\n        \"\"\"\n        Using setter/getter methods is deprecated. Use o.charPositionInLine\n        instead.\n        \"\"\"\n        self.charPositionInLine = pos\n\n\n    def getSourceName(self):\n        return self.name\n\n\nclass ANTLRFileStream(ANTLRStringStream):\n    \"\"\"\n    @brief CharStream that opens a file to read the data.\n    \n    This is a char buffer stream that is loaded from a file\n    all at once when you construct the object.\n    \"\"\"\n\n    def __init__(self, fileName, encoding=None):\n        \"\"\"\n        @param fileName The path to the file to be opened. The file will be\n           opened with mode 'rb'.\n\n        @param encoding If you set the optional encoding argument, then the\n           data will be decoded on the fly.\n           \n        \"\"\"\n        \n        self.fileName = fileName\n\n        fp = codecs.open(fileName, 'rb', encoding)\n        try:\n            data = fp.read()\n        finally:\n            fp.close()\n            \n        ANTLRStringStream.__init__(self, data)\n\n\n    def getSourceName(self):\n        \"\"\"Deprecated, access o.fileName directly.\"\"\"\n        \n        return self.fileName\n\n\nclass ANTLRInputStream(ANTLRStringStream):\n    \"\"\"\n    @brief CharStream that reads data from a file-like object.\n\n    This is a char buffer stream that is loaded from a file like object\n    all at once when you construct the object.\n    \n    All input is consumed from the file, but it is not closed.\n    \"\"\"\n\n    def __init__(self, file, encoding=None):\n        \"\"\"\n        @param file A file-like object holding your input. Only the read()\n           method must be implemented.\n\n        @param encoding If you set the optional encoding argument, then the\n           data will be decoded on the fly.\n           \n        \"\"\"\n        \n        if encoding is not None:\n            # wrap input in a decoding reader\n            reader = codecs.lookup(encoding)[2]\n            file = reader(file)\n\n        data = file.read()\n            \n        ANTLRStringStream.__init__(self, data)\n\n\n# I guess the ANTLR prefix exists only to avoid a name clash with some Java\n# mumbojumbo. A plain \"StringStream\" looks better to me, which should be\n# the preferred name in Python.\nStringStream = ANTLRStringStream\nFileStream = ANTLRFileStream\nInputStream = ANTLRInputStream\n\n\n############################################################################\n#\n# Token streams\n#   TokenStream\n#   +- CommonTokenStream\n#   \\- TokenRewriteStream\n#\n############################################################################\n\n\nclass CommonTokenStream(TokenStream):\n    \"\"\"\n    @brief The most common stream of tokens\n    \n    The most common stream of tokens is one where every token is buffered up\n    and tokens are prefiltered for a certain channel (the parser will only\n    see these tokens and cannot change the filter channel number during the\n    parse).\n    \"\"\"\n\n    def __init__(self, tokenSource=None, channel=DEFAULT_CHANNEL):\n        \"\"\"\n        @param tokenSource A TokenSource instance (usually a Lexer) to pull\n            the tokens from.\n\n        @param channel Skip tokens on any channel but this one; this is how we\n            skip whitespace...\n            \n        \"\"\"\n        \n        TokenStream.__init__(self)\n        \n        self.tokenSource = tokenSource\n\n\t# Record every single token pulled from the source so we can reproduce\n        # chunks of it later.\n        self.tokens = []\n\n\t# Map<tokentype, channel> to override some Tokens' channel numbers\n        self.channelOverrideMap = {}\n\n\t# Set<tokentype>; discard any tokens with this type\n        self.discardSet = set()\n\n\t# Skip tokens on any channel but this one; this is how we skip whitespace...\n        self.channel = channel\n\n\t# By default, track all incoming tokens\n        self.discardOffChannelTokens = False\n\n\t# The index into the tokens list of the current token (next token\n        # to consume).  p==-1 indicates that the tokens list is empty\n        self.p = -1\n\n        # Remember last marked position\n        self.lastMarker = None\n        \n\n    def setTokenSource(self, tokenSource):\n        \"\"\"Reset this token stream by setting its token source.\"\"\"\n        \n        self.tokenSource = tokenSource\n        self.tokens = []\n        self.p = -1\n        self.channel = DEFAULT_CHANNEL\n\n\n    def reset(self):\n        self.p = 0\n        self.lastMarker = None\n\n\n    def fillBuffer(self):\n        \"\"\"\n        Load all tokens from the token source and put in tokens.\n\tThis is done upon first LT request because you might want to\n        set some token type / channel overrides before filling buffer.\n        \"\"\"\n        \n\n        index = 0\n        t = self.tokenSource.nextToken()\n        while t is not None and t.type != EOF:\n            discard = False\n            \n            if self.discardSet is not None and t.type in self.discardSet:\n                discard = True\n\n            elif self.discardOffChannelTokens and t.channel != self.channel:\n                discard = True\n\n            # is there a channel override for token type?\n            try:\n                overrideChannel = self.channelOverrideMap[t.type]\n                \n            except KeyError:\n                # no override for this type\n                pass\n            \n            else:\n                if overrideChannel == self.channel:\n                    t.channel = overrideChannel\n                else:\n                    discard = True\n            \n            if not discard:\n                t.index = index\n                self.tokens.append(t)\n                index += 1\n\n            t = self.tokenSource.nextToken()\n       \n        # leave p pointing at first token on channel\n        self.p = 0\n        self.p = self.skipOffTokenChannels(self.p)\n\n\n    def consume(self):\n        \"\"\"\n        Move the input pointer to the next incoming token.  The stream\n        must become active with LT(1) available.  consume() simply\n        moves the input pointer so that LT(1) points at the next\n        input symbol. Consume at least one token.\n\n        Walk past any token not on the channel the parser is listening to.\n        \"\"\"\n        \n        if self.p < len(self.tokens):\n            self.p += 1\n\n            self.p = self.skipOffTokenChannels(self.p) # leave p on valid token\n\n\n    def skipOffTokenChannels(self, i):\n        \"\"\"\n        Given a starting index, return the index of the first on-channel\n        token.\n        \"\"\"\n\n        try:\n            while self.tokens[i].channel != self.channel:\n                i += 1\n        except IndexError:\n            # hit the end of token stream\n            pass\n        \n        return i\n\n\n    def skipOffTokenChannelsReverse(self, i):\n        while i >= 0 and self.tokens[i].channel != self.channel:\n            i -= 1\n\n        return i\n\n\n    def setTokenTypeChannel(self, ttype, channel):\n        \"\"\"\n        A simple filter mechanism whereby you can tell this token stream\n        to force all tokens of type ttype to be on channel.  For example,\n        when interpreting, we cannot exec actions so we need to tell\n        the stream to force all WS and NEWLINE to be a different, ignored\n        channel.\n\t\"\"\"\n        \n        self.channelOverrideMap[ttype] = channel\n\n\n    def discardTokenType(self, ttype):\n        self.discardSet.add(ttype)\n\n\n    def getTokens(self, start=None, stop=None, types=None):\n        \"\"\"\n        Given a start and stop index, return a list of all tokens in\n        the token type set.  Return None if no tokens were found.  This\n        method looks at both on and off channel tokens.\n        \"\"\"\n\n        if self.p == -1:\n            self.fillBuffer()\n\n        if stop is None or stop >= len(self.tokens):\n            stop = len(self.tokens) - 1\n            \n        if start is None or stop < 0:\n            start = 0\n\n        if start > stop:\n            return None\n\n        if isinstance(types, (int, long)):\n            # called with a single type, wrap into set\n            types = set([types])\n            \n        filteredTokens = [\n            token for token in self.tokens[start:stop]\n            if types is None or token.type in types\n            ]\n\n        if len(filteredTokens) == 0:\n            return None\n\n        return filteredTokens\n\n\n    def LT(self, k):\n        \"\"\"\n        Get the ith token from the current position 1..n where k=1 is the\n        first symbol of lookahead.\n        \"\"\"\n\n        if self.p == -1:\n            self.fillBuffer()\n\n        if k == 0:\n            return None\n\n        if k < 0:\n            return self.LB(-k)\n                \n        i = self.p\n        n = 1\n        # find k good tokens\n        while n < k:\n            # skip off-channel tokens\n            i = self.skipOffTokenChannels(i+1) # leave p on valid token\n            n += 1\n\n        try:\n            return self.tokens[i]\n        except IndexError:\n            return EOF_TOKEN\n\n\n    def LB(self, k):\n        \"\"\"Look backwards k tokens on-channel tokens\"\"\"\n\n        if self.p == -1:\n            self.fillBuffer()\n\n        if k == 0:\n            return None\n\n        if self.p - k < 0:\n            return None\n\n        i = self.p\n        n = 1\n        # find k good tokens looking backwards\n        while n <= k:\n            # skip off-channel tokens\n            i = self.skipOffTokenChannelsReverse(i-1) # leave p on valid token\n            n += 1\n\n        if i < 0:\n            return None\n            \n        return self.tokens[i]\n\n\n    def get(self, i):\n        \"\"\"\n        Return absolute token i; ignore which channel the tokens are on;\n        that is, count all tokens not just on-channel tokens.\n        \"\"\"\n\n        return self.tokens[i]\n\n\n    def LA(self, i):\n        return self.LT(i).type\n\n\n    def mark(self):\n        self.lastMarker = self.index()\n        return self.lastMarker\n    \n\n    def release(self, marker=None):\n        # no resources to release\n        pass\n    \n\n    def size(self):\n        return len(self.tokens)\n\n\n    def index(self):\n        return self.p\n\n\n    def rewind(self, marker=None):\n        if marker is None:\n            marker = self.lastMarker\n            \n        self.seek(marker)\n\n\n    def seek(self, index):\n        self.p = index\n\n\n    def getTokenSource(self):\n        return self.tokenSource\n\n\n    def getSourceName(self):\n        return self.tokenSource.getSourceName()\n\n\n    def toString(self, start=None, stop=None):\n        if self.p == -1:\n            self.fillBuffer()\n\n        if start is None:\n            start = 0\n        elif not isinstance(start, int):\n            start = start.index\n\n        if stop is None:\n            stop = len(self.tokens) - 1\n        elif not isinstance(stop, int):\n            stop = stop.index\n        \n        if stop >= len(self.tokens):\n            stop = len(self.tokens) - 1\n\n        return ''.join([t.text for t in self.tokens[start:stop+1]])\n\n\nclass RewriteOperation(object):\n    \"\"\"@brief Internal helper class.\"\"\"\n    \n    def __init__(self, stream, index, text):\n        self.stream = stream\n        self.index = index\n        self.text = text\n\n    def execute(self, buf):\n        \"\"\"Execute the rewrite operation by possibly adding to the buffer.\n        Return the index of the next token to operate on.\n        \"\"\"\n\n        return self.index\n\n    def toString(self):\n        opName = self.__class__.__name__\n        return '<%s@%d:\"%s\">' % (opName, self.index, self.text)\n\n    __str__ = toString\n    __repr__ = toString\n\n\nclass InsertBeforeOp(RewriteOperation):\n    \"\"\"@brief Internal helper class.\"\"\"\n\n    def execute(self, buf):\n        buf.write(self.text)\n        buf.write(self.stream.tokens[self.index].text)\n        return self.index + 1\n\n\nclass ReplaceOp(RewriteOperation):\n    \"\"\"\n    @brief Internal helper class.\n    \n    I'm going to try replacing range from x..y with (y-x)+1 ReplaceOp\n    instructions.\n    \"\"\"\n\n    def __init__(self, stream, first, last, text):\n        RewriteOperation.__init__(self, stream, first, text)\n        self.lastIndex = last\n\n\n    def execute(self, buf):\n        if self.text is not None:\n            buf.write(self.text)\n\n        return self.lastIndex + 1\n\n\n    def toString(self):\n        return '<ReplaceOp@%d..%d:\"%s\">' % (\n            self.index, self.lastIndex, self.text)\n\n    __str__ = toString\n    __repr__ = toString\n\n\nclass DeleteOp(ReplaceOp):\n    \"\"\"\n    @brief Internal helper class.\n    \"\"\"\n\n    def __init__(self, stream, first, last):\n        ReplaceOp.__init__(self, stream, first, last, None)\n\n\n    def toString(self):\n        return '<DeleteOp@%d..%d>' % (self.index, self.lastIndex)\n\n    __str__ = toString\n    __repr__ = toString\n\n\nclass TokenRewriteStream(CommonTokenStream):\n    \"\"\"@brief CommonTokenStream that can be modified.\n\n    Useful for dumping out the input stream after doing some\n    augmentation or other manipulations.\n\n    You can insert stuff, replace, and delete chunks.  Note that the\n    operations are done lazily--only if you convert the buffer to a\n    String.  This is very efficient because you are not moving data around\n    all the time.  As the buffer of tokens is converted to strings, the\n    toString() method(s) check to see if there is an operation at the\n    current index.  If so, the operation is done and then normal String\n    rendering continues on the buffer.  This is like having multiple Turing\n    machine instruction streams (programs) operating on a single input tape. :)\n\n    Since the operations are done lazily at toString-time, operations do not\n    screw up the token index values.  That is, an insert operation at token\n    index i does not change the index values for tokens i+1..n-1.\n\n    Because operations never actually alter the buffer, you may always get\n    the original token stream back without undoing anything.  Since\n    the instructions are queued up, you can easily simulate transactions and\n    roll back any changes if there is an error just by removing instructions.\n    For example,\n\n     CharStream input = new ANTLRFileStream(\"input\");\n     TLexer lex = new TLexer(input);\n     TokenRewriteStream tokens = new TokenRewriteStream(lex);\n     T parser = new T(tokens);\n     parser.startRule();\n\n     Then in the rules, you can execute\n        Token t,u;\n        ...\n        input.insertAfter(t, \"text to put after t\");}\n        input.insertAfter(u, \"text after u\");}\n        System.out.println(tokens.toString());\n\n    Actually, you have to cast the 'input' to a TokenRewriteStream. :(\n\n    You can also have multiple \"instruction streams\" and get multiple\n    rewrites from a single pass over the input.  Just name the instruction\n    streams and use that name again when printing the buffer.  This could be\n    useful for generating a C file and also its header file--all from the\n    same buffer:\n\n        tokens.insertAfter(\"pass1\", t, \"text to put after t\");}\n        tokens.insertAfter(\"pass2\", u, \"text after u\");}\n        System.out.println(tokens.toString(\"pass1\"));\n        System.out.println(tokens.toString(\"pass2\"));\n\n    If you don't use named rewrite streams, a \"default\" stream is used as\n    the first example shows.\n    \"\"\"\n    \n    DEFAULT_PROGRAM_NAME = \"default\"\n    MIN_TOKEN_INDEX = 0\n\n    def __init__(self, tokenSource=None, channel=DEFAULT_CHANNEL):\n        CommonTokenStream.__init__(self, tokenSource, channel)\n\n        # You may have multiple, named streams of rewrite operations.\n        # I'm calling these things \"programs.\"\n        #  Maps String (name) -> rewrite (List)\n        self.programs = {}\n        self.programs[self.DEFAULT_PROGRAM_NAME] = []\n        \n \t# Map String (program name) -> Integer index\n        self.lastRewriteTokenIndexes = {}\n        \n\n    def rollback(self, *args):\n        \"\"\"\n        Rollback the instruction stream for a program so that\n        the indicated instruction (via instructionIndex) is no\n        longer in the stream.  UNTESTED!\n        \"\"\"\n\n        if len(args) == 2:\n            programName = args[0]\n            instructionIndex = args[1]\n        elif len(args) == 1:\n            programName = self.DEFAULT_PROGRAM_NAME\n            instructionIndex = args[0]\n        else:\n            raise TypeError(\"Invalid arguments\")\n        \n        p = self.programs.get(programName, None)\n        if p is not None:\n            self.programs[programName] = (\n                p[self.MIN_TOKEN_INDEX:instructionIndex])\n\n\n    def deleteProgram(self, programName=DEFAULT_PROGRAM_NAME):\n        \"\"\"Reset the program so that no instructions exist\"\"\"\n            \n        self.rollback(programName, self.MIN_TOKEN_INDEX)\n\n\n    def insertAfter(self, *args):\n        if len(args) == 2:\n            programName = self.DEFAULT_PROGRAM_NAME\n            index = args[0]\n            text = args[1]\n            \n        elif len(args) == 3:\n            programName = args[0]\n            index = args[1]\n            text = args[2]\n\n        else:\n            raise TypeError(\"Invalid arguments\")\n\n        if isinstance(index, Token):\n            # index is a Token, grap the stream index from it\n            index = index.index\n\n        # to insert after, just insert before next index (even if past end)\n        self.insertBefore(programName, index+1, text)\n\n\n    def insertBefore(self, *args):\n        if len(args) == 2:\n            programName = self.DEFAULT_PROGRAM_NAME\n            index = args[0]\n            text = args[1]\n            \n        elif len(args) == 3:\n            programName = args[0]\n            index = args[1]\n            text = args[2]\n\n        else:\n            raise TypeError(\"Invalid arguments\")\n\n        if isinstance(index, Token):\n            # index is a Token, grap the stream index from it\n            index = index.index\n\n        op = InsertBeforeOp(self, index, text)\n        rewrites = self.getProgram(programName)\n        rewrites.append(op)\n\n\n    def replace(self, *args):\n        if len(args) == 2:\n            programName = self.DEFAULT_PROGRAM_NAME\n            first = args[0]\n            last = args[0]\n            text = args[1]\n            \n        elif len(args) == 3:\n            programName = self.DEFAULT_PROGRAM_NAME\n            first = args[0]\n            last = args[1]\n            text = args[2]\n            \n        elif len(args) == 4:\n            programName = args[0]\n            first = args[1]\n            last = args[2]\n            text = args[3]\n\n        else:\n            raise TypeError(\"Invalid arguments\")\n\n        if isinstance(first, Token):\n            # first is a Token, grap the stream index from it\n            first = first.index\n\n        if isinstance(last, Token):\n            # last is a Token, grap the stream index from it\n            last = last.index\n\n        if first > last or first < 0 or last < 0 or last >= len(self.tokens):\n            raise ValueError(\n                \"replace: range invalid: \"+first+\"..\"+last+\n                \"(size=\"+len(self.tokens)+\")\")\n\n        op = ReplaceOp(self, first, last, text)\n        rewrites = self.getProgram(programName)\n        rewrites.append(op)\n        \n\n    def delete(self, *args):\n        self.replace(*(list(args) + [None]))\n\n\n    def getLastRewriteTokenIndex(self, programName=DEFAULT_PROGRAM_NAME):\n        return self.lastRewriteTokenIndexes.get(programName, -1)\n\n\n    def setLastRewriteTokenIndex(self, programName, i):\n        self.lastRewriteTokenIndexes[programName] = i\n\n\n    def getProgram(self, name):\n        p = self.programs.get(name, None)\n        if p is  None:\n            p = self.initializeProgram(name)\n\n        return p\n\n\n    def initializeProgram(self, name):\n        p = []\n        self.programs[name] = p\n        return p\n\n\n    def toOriginalString(self, start=None, end=None):\n        if start is None:\n            start = self.MIN_TOKEN_INDEX\n        if end is None:\n            end = self.size() - 1\n        \n        buf = StringIO()\n        i = start\n        while i >= self.MIN_TOKEN_INDEX and i <= end and i < len(self.tokens):\n            buf.write(self.get(i).text)\n            i += 1\n\n        return buf.getvalue()\n\n\n    def toString(self, *args):\n        if len(args) == 0:\n            programName = self.DEFAULT_PROGRAM_NAME\n            start = self.MIN_TOKEN_INDEX\n            end = self.size() - 1\n            \n        elif len(args) == 1:\n            programName = args[0]\n            start = self.MIN_TOKEN_INDEX\n            end = self.size() - 1\n\n        elif len(args) == 2:\n            programName = self.DEFAULT_PROGRAM_NAME\n            start = args[0]\n            end = args[1]\n            \n        if start is None:\n            start = self.MIN_TOKEN_INDEX\n        elif not isinstance(start, int):\n            start = start.index\n\n        if end is None:\n            end = len(self.tokens) - 1\n        elif not isinstance(end, int):\n            end = end.index\n\n        # ensure start/end are in range\n        if end >= len(self.tokens):\n            end = len(self.tokens) - 1\n\n        if start < 0:\n            start = 0\n\n        rewrites = self.programs.get(programName)\n        if rewrites is None or len(rewrites) == 0:\n            # no instructions to execute\n            return self.toOriginalString(start, end)\n        \n        buf = StringIO()\n\n        # First, optimize instruction stream\n        indexToOp = self.reduceToSingleOperationPerIndex(rewrites)\n\n        # Walk buffer, executing instructions and emitting tokens\n        i = start\n        while i <= end and i < len(self.tokens):\n            op = indexToOp.get(i)\n            # remove so any left have index size-1\n            try:\n                del indexToOp[i]\n            except KeyError:\n                pass\n\n            t = self.tokens[i]\n            if op is None:\n                # no operation at that index, just dump token\n                buf.write(t.text)\n                i += 1 # move to next token\n\n            else:\n                i = op.execute(buf) # execute operation and skip\n\n        # include stuff after end if it's last index in buffer\n        # So, if they did an insertAfter(lastValidIndex, \"foo\"), include\n        # foo if end==lastValidIndex.\n        if end == len(self.tokens) - 1:\n            # Scan any remaining operations after last token\n            # should be included (they will be inserts).\n            for i in sorted(indexToOp.keys()):\n                op = indexToOp[i]\n                if op.index >= len(self.tokens)-1:\n                    buf.write(op.text)\n\n        return buf.getvalue()\n\n    __str__ = toString\n\n\n    def reduceToSingleOperationPerIndex(self, rewrites):\n        \"\"\"\n        We need to combine operations and report invalid operations (like\n        overlapping replaces that are not completed nested).  Inserts to\n        same index need to be combined etc...   Here are the cases:\n\n        I.i.u I.j.v                           leave alone, nonoverlapping\n        I.i.u I.i.v                           combine: Iivu\n\n        R.i-j.u R.x-y.v | i-j in x-y          delete first R\n        R.i-j.u R.i-j.v                       delete first R\n        R.i-j.u R.x-y.v | x-y in i-j          ERROR\n        R.i-j.u R.x-y.v | boundaries overlap  ERROR\n\n        I.i.u R.x-y.v   | i in x-y            delete I\n        I.i.u R.x-y.v   | i not in x-y        leave alone, nonoverlapping\n        R.x-y.v I.i.u   | i in x-y            ERROR\n        R.x-y.v I.x.u                         R.x-y.uv (combine, delete I)\n        R.x-y.v I.i.u   | i not in x-y        leave alone, nonoverlapping\n\n        I.i.u = insert u before op @ index i\n        R.x-y.u = replace x-y indexed tokens with u\n\n        First we need to examine replaces.  For any replace op:\n\n          1. wipe out any insertions before op within that range.\n          2. Drop any replace op before that is contained completely within\n             that range.\n          3. Throw exception upon boundary overlap with any previous replace.\n\n        Then we can deal with inserts:\n\n          1. for any inserts to same index, combine even if not adjacent.\n          2. for any prior replace with same left boundary, combine this\n             insert with replace and delete this replace.\n          3. throw exception if index in same range as previous replace\n\n        Don't actually delete; make op null in list. Easier to walk list.\n        Later we can throw as we add to index -> op map.\n\n        Note that I.2 R.2-2 will wipe out I.2 even though, technically, the\n        inserted stuff would be before the replace range.  But, if you\n        add tokens in front of a method body '{' and then delete the method\n        body, I think the stuff before the '{' you added should disappear too.\n\n        Return a map from token index to operation.\n        \"\"\"\n        \n        # WALK REPLACES\n        for i, rop in enumerate(rewrites):\n            if rop is None:\n                continue\n\n            if not isinstance(rop, ReplaceOp):\n                continue\n\n            # Wipe prior inserts within range\n            for j, iop in self.getKindOfOps(rewrites, InsertBeforeOp, i):\n                if iop.index >= rop.index and iop.index <= rop.lastIndex:\n                    rewrites[j] = None  # delete insert as it's a no-op.\n\n            # Drop any prior replaces contained within\n            for j, prevRop in self.getKindOfOps(rewrites, ReplaceOp, i):\n                if (prevRop.index >= rop.index\n                    and prevRop.lastIndex <= rop.lastIndex):\n                    rewrites[j] = None  # delete replace as it's a no-op.\n                    continue\n\n                # throw exception unless disjoint or identical\n                disjoint = (prevRop.lastIndex < rop.index\n                            or prevRop.index > rop.lastIndex)\n                same = (prevRop.index == rop.index\n                        and prevRop.lastIndex == rop.lastIndex)\n                if not disjoint and not same:\n                    raise ValueError(\n                        \"replace op boundaries of %s overlap with previous %s\"\n                        % (rop, prevRop))\n\n        # WALK INSERTS\n        for i, iop in enumerate(rewrites):\n            if iop is None:\n                continue\n\n            if not isinstance(iop, InsertBeforeOp):\n                continue\n\n            # combine current insert with prior if any at same index\n            for j, prevIop in self.getKindOfOps(rewrites, InsertBeforeOp, i):\n                if prevIop.index == iop.index: # combine objects\n                    # convert to strings...we're in process of toString'ing\n                    # whole token buffer so no lazy eval issue with any\n                    # templates\n                    iop.text = self.catOpText(iop.text, prevIop.text)\n                    rewrites[j] = None  # delete redundant prior insert\n\n            # look for replaces where iop.index is in range; error\n            for j, rop in self.getKindOfOps(rewrites, ReplaceOp, i):\n                if iop.index == rop.index:\n                    rop.text = self.catOpText(iop.text, rop.text)\n                    rewrites[i] = None  # delete current insert\n                    continue\n\n                if iop.index >= rop.index and iop.index <= rop.lastIndex:\n                    raise ValueError(\n                        \"insert op %s within boundaries of previous %s\"\n                        % (iop, rop))\n        \n        m = {}\n        for i, op in enumerate(rewrites):\n            if op is None:\n                continue # ignore deleted ops\n\n            assert op.index not in m, \"should only be one op per index\"\n            m[op.index] = op\n\n        return m\n\n\n    def catOpText(self, a, b):\n        x = \"\"\n        y = \"\"\n        if a is not None:\n            x = a\n        if b is not None:\n            y = b\n        return x + y\n\n\n    def getKindOfOps(self, rewrites, kind, before=None):\n        if before is None:\n            before = len(rewrites)\n        elif before > len(rewrites):\n            before = len(rewrites)\n\n        for i, op in enumerate(rewrites[:before]):\n            if op is None:\n                # ignore deleted\n                continue\n            if op.__class__ == kind:\n                yield i, op\n\n\n    def toDebugString(self, start=None, end=None):\n        if start is None:\n            start = self.MIN_TOKEN_INDEX\n        if end is None:\n            end = self.size() - 1\n\n        buf = StringIO()\n        i = start\n        while i >= self.MIN_TOKEN_INDEX and i <= end and i < len(self.tokens):\n            buf.write(self.get(i))\n            i += 1\n\n        return buf.getvalue()\n"
  },
  {
    "path": "deps/cpy/antlr3/tokens.py",
    "content": "\"\"\"ANTLR3 runtime package\"\"\"\n\n# begin[licence]\n#\n# [The \"BSD licence\"]\n# Copyright (c) 2005-2008 Terence Parr\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. The name of the author may not be used to endorse or promote products\n#    derived from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n# NOT 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 OF\n# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#\n# end[licence]\n\nfrom antlr3.constants import EOF, DEFAULT_CHANNEL, INVALID_TOKEN_TYPE\n\n############################################################################\n#\n# basic token interface\n#\n############################################################################\n\nclass Token(object):\n    \"\"\"@brief Abstract token baseclass.\"\"\"\n\n    def getText(self):\n        \"\"\"@brief Get the text of the token.\n\n        Using setter/getter methods is deprecated. Use o.text instead.\n        \"\"\"\n        raise NotImplementedError\n    \n    def setText(self, text):\n        \"\"\"@brief Set the text of the token.\n\n        Using setter/getter methods is deprecated. Use o.text instead.\n        \"\"\"\n        raise NotImplementedError\n\n\n    def getType(self):\n        \"\"\"@brief Get the type of the token.\n\n        Using setter/getter methods is deprecated. Use o.type instead.\"\"\"\n\n        raise NotImplementedError\n    \n    def setType(self, ttype):\n        \"\"\"@brief Get the type of the token.\n\n        Using setter/getter methods is deprecated. Use o.type instead.\"\"\"\n\n        raise NotImplementedError\n    \n    \n    def getLine(self):\n        \"\"\"@brief Get the line number on which this token was matched\n\n        Lines are numbered 1..n\n        \n        Using setter/getter methods is deprecated. Use o.line instead.\"\"\"\n\n        raise NotImplementedError\n    \n    def setLine(self, line):\n        \"\"\"@brief Set the line number on which this token was matched\n\n        Using setter/getter methods is deprecated. Use o.line instead.\"\"\"\n\n        raise NotImplementedError\n    \n    \n    def getCharPositionInLine(self):\n        \"\"\"@brief Get the column of the tokens first character,\n        \n        Columns are numbered 0..n-1\n        \n        Using setter/getter methods is deprecated. Use o.charPositionInLine instead.\"\"\"\n\n        raise NotImplementedError\n    \n    def setCharPositionInLine(self, pos):\n        \"\"\"@brief Set the column of the tokens first character,\n\n        Using setter/getter methods is deprecated. Use o.charPositionInLine instead.\"\"\"\n\n        raise NotImplementedError\n    \n\n    def getChannel(self):\n        \"\"\"@brief Get the channel of the token\n\n        Using setter/getter methods is deprecated. Use o.channel instead.\"\"\"\n\n        raise NotImplementedError\n    \n    def setChannel(self, channel):\n        \"\"\"@brief Set the channel of the token\n\n        Using setter/getter methods is deprecated. Use o.channel instead.\"\"\"\n\n        raise NotImplementedError\n    \n\n    def getTokenIndex(self):\n        \"\"\"@brief Get the index in the input stream.\n\n        An index from 0..n-1 of the token object in the input stream.\n        This must be valid in order to use the ANTLRWorks debugger.\n        \n        Using setter/getter methods is deprecated. Use o.index instead.\"\"\"\n\n        raise NotImplementedError\n    \n    def setTokenIndex(self, index):\n        \"\"\"@brief Set the index in the input stream.\n\n        Using setter/getter methods is deprecated. Use o.index instead.\"\"\"\n\n        raise NotImplementedError\n\n\n    def getInputStream(self):\n        \"\"\"@brief From what character stream was this token created.\n\n        You don't have to implement but it's nice to know where a Token\n        comes from if you have include files etc... on the input.\"\"\"\n\n        raise NotImplementedError\n\n    def setInputStream(self, input):\n        \"\"\"@brief From what character stream was this token created.\n\n        You don't have to implement but it's nice to know where a Token\n        comes from if you have include files etc... on the input.\"\"\"\n\n        raise NotImplementedError\n\n\n############################################################################\n#\n# token implementations\n#\n# Token\n# +- CommonToken\n# \\- ClassicToken\n#\n############################################################################\n\nclass CommonToken(Token):\n    \"\"\"@brief Basic token implementation.\n\n    This implementation does not copy the text from the input stream upon\n    creation, but keeps start/stop pointers into the stream to avoid\n    unnecessary copy operations.\n\n    \"\"\"\n    \n    def __init__(self, type=None, channel=DEFAULT_CHANNEL, text=None,\n                 input=None, start=None, stop=None, oldToken=None):\n        Token.__init__(self)\n        \n        if oldToken is not None:\n            self.type = oldToken.type\n            self.line = oldToken.line\n            self.charPositionInLine = oldToken.charPositionInLine\n            self.channel = oldToken.channel\n            self.index = oldToken.index\n            self._text = oldToken._text\n            if isinstance(oldToken, CommonToken):\n                self.input = oldToken.input\n                self.start = oldToken.start\n                self.stop = oldToken.stop\n            \n        else:\n            self.type = type\n            self.input = input\n            self.charPositionInLine = -1 # set to invalid position\n            self.line = 0\n            self.channel = channel\n            \n\t    #What token number is this from 0..n-1 tokens; < 0 implies invalid index\n            self.index = -1\n            \n            # We need to be able to change the text once in a while.  If\n            # this is non-null, then getText should return this.  Note that\n            # start/stop are not affected by changing this.\n            self._text = text\n\n            # The char position into the input buffer where this token starts\n            self.start = start\n\n            # The char position into the input buffer where this token stops\n            # This is the index of the last char, *not* the index after it!\n            self.stop = stop\n\n\n    def getText(self):\n        if self._text is not None:\n            return self._text\n\n        if self.input is None:\n            return None\n        \n        return self.input.substring(self.start, self.stop)\n\n\n    def setText(self, text):\n        \"\"\"\n        Override the text for this token.  getText() will return this text\n        rather than pulling from the buffer.  Note that this does not mean\n        that start/stop indexes are not valid.  It means that that input\n        was converted to a new string in the token object.\n\t\"\"\"\n        self._text = text\n\n    text = property(getText, setText)\n\n\n    def getType(self):\n        return self.type \n\n    def setType(self, ttype):\n        self.type = ttype\n\n    \n    def getLine(self):\n        return self.line\n    \n    def setLine(self, line):\n        self.line = line\n\n\n    def getCharPositionInLine(self):\n        return self.charPositionInLine\n    \n    def setCharPositionInLine(self, pos):\n        self.charPositionInLine = pos\n\n\n    def getChannel(self):\n        return self.channel\n    \n    def setChannel(self, channel):\n        self.channel = channel\n    \n\n    def getTokenIndex(self):\n        return self.index\n    \n    def setTokenIndex(self, index):\n        self.index = index\n\n\n    def getInputStream(self):\n        return self.input\n\n    def setInputStream(self, input):\n        self.input = input\n\n\n    def __str__(self):\n        if self.type == EOF:\n            return \"<EOF>\"\n\n        channelStr = \"\"\n        if self.channel > 0:\n            channelStr = \",channel=\" + str(self.channel)\n\n        txt = self.text\n        if txt is not None:\n            txt = txt.replace(\"\\n\",\"\\\\\\\\n\")\n            txt = txt.replace(\"\\r\",\"\\\\\\\\r\")\n            txt = txt.replace(\"\\t\",\"\\\\\\\\t\")\n        else:\n            txt = \"<no text>\"\n\n        return \"[@%d,%d:%d=%r,<%d>%s,%d:%d]\" % (\n            self.index,\n            self.start, self.stop,\n            txt,\n            self.type, channelStr,\n            self.line, self.charPositionInLine\n            )\n    \n\nclass ClassicToken(Token):\n    \"\"\"@brief Alternative token implementation.\n    \n    A Token object like we'd use in ANTLR 2.x; has an actual string created\n    and associated with this object.  These objects are needed for imaginary\n    tree nodes that have payload objects.  We need to create a Token object\n    that has a string; the tree node will point at this token.  CommonToken\n    has indexes into a char stream and hence cannot be used to introduce\n    new strings.\n    \"\"\"\n\n    def __init__(self, type=None, text=None, channel=DEFAULT_CHANNEL,\n                 oldToken=None\n                 ):\n        Token.__init__(self)\n        \n        if oldToken is not None:\n            self.text = oldToken.text\n            self.type = oldToken.type\n            self.line = oldToken.line\n            self.charPositionInLine = oldToken.charPositionInLine\n            self.channel = oldToken.channel\n            \n        self.text = text\n        self.type = type\n        self.line = None\n        self.charPositionInLine = None\n        self.channel = channel\n        self.index = None\n\n\n    def getText(self):\n        return self.text\n\n    def setText(self, text):\n        self.text = text\n\n\n    def getType(self):\n        return self.type \n\n    def setType(self, ttype):\n        self.type = ttype\n\n    \n    def getLine(self):\n        return self.line\n    \n    def setLine(self, line):\n        self.line = line\n\n\n    def getCharPositionInLine(self):\n        return self.charPositionInLine\n    \n    def setCharPositionInLine(self, pos):\n        self.charPositionInLine = pos\n\n\n    def getChannel(self):\n        return self.channel\n    \n    def setChannel(self, channel):\n        self.channel = channel\n    \n\n    def getTokenIndex(self):\n        return self.index\n    \n    def setTokenIndex(self, index):\n        self.index = index\n\n\n    def getInputStream(self):\n        return None\n\n    def setInputStream(self, input):\n        pass\n\n\n    def toString(self):\n        channelStr = \"\"\n        if self.channel > 0:\n            channelStr = \",channel=\" + str(self.channel)\n            \n        txt = self.text\n        if txt is None:\n            txt = \"<no text>\"\n\n        return \"[@%r,%r,<%r>%s,%r:%r]\" % (self.index,\n                                          txt,\n                                          self.type,\n                                          channelStr,\n                                          self.line,\n                                          self.charPositionInLine\n                                          )\n    \n\n    __str__ = toString\n    __repr__ = toString\n\n\n\nEOF_TOKEN = CommonToken(type=EOF)\n\t\nINVALID_TOKEN = CommonToken(type=INVALID_TOKEN_TYPE)\n\n# In an action, a lexer rule can set token to this SKIP_TOKEN and ANTLR\n# will avoid creating a token for this symbol and try to fetch another.\nSKIP_TOKEN = CommonToken(type=INVALID_TOKEN_TYPE)\n\n\n"
  },
  {
    "path": "deps/cpy/antlr3/tree.py",
    "content": "\"\"\" @package antlr3.tree\n@brief ANTLR3 runtime package, tree module\n\nThis module contains all support classes for AST construction and tree parsers.\n\n\"\"\"\n\n# begin[licence]\n#\n# [The \"BSD licence\"]\n# Copyright (c) 2005-2008 Terence Parr\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. The name of the author may not be used to endorse or promote products\n#    derived from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n# NOT 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 OF\n# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#\n# end[licence]\n\n# lot's of docstrings are missing, don't complain for now...\n# pylint: disable-msg=C0111\n\nfrom antlr3.constants import UP, DOWN, EOF, INVALID_TOKEN_TYPE\nfrom antlr3.recognizers import BaseRecognizer, RuleReturnScope\nfrom antlr3.streams import IntStream\nfrom antlr3.tokens import CommonToken, Token, INVALID_TOKEN\nfrom antlr3.exceptions import MismatchedTreeNodeException, \\\n     MissingTokenException, UnwantedTokenException, MismatchedTokenException, \\\n     NoViableAltException\n\n\n############################################################################\n#\n# tree related exceptions\n#\n############################################################################\n\n\nclass RewriteCardinalityException(RuntimeError):\n    \"\"\"\n    @brief Base class for all exceptions thrown during AST rewrite construction.\n\n    This signifies a case where the cardinality of two or more elements\n    in a subrule are different: (ID INT)+ where |ID|!=|INT|\n    \"\"\"\n\n    def __init__(self, elementDescription):\n        RuntimeError.__init__(self, elementDescription)\n\n        self.elementDescription = elementDescription\n\n\n    def getMessage(self):\n        return self.elementDescription\n\n\nclass RewriteEarlyExitException(RewriteCardinalityException):\n    \"\"\"@brief No elements within a (...)+ in a rewrite rule\"\"\"\n\n    def __init__(self, elementDescription=None):\n        RewriteCardinalityException.__init__(self, elementDescription)\n\n\nclass RewriteEmptyStreamException(RewriteCardinalityException):\n    \"\"\"\n    @brief Ref to ID or expr but no tokens in ID stream or subtrees in expr stream\n    \"\"\"\n\n    pass\n\n\n############################################################################\n#\n# basic Tree and TreeAdaptor interfaces\n#\n############################################################################\n\nclass Tree(object):\n    \"\"\"\n    @brief Abstract baseclass for tree nodes.\n    \n    What does a tree look like?  ANTLR has a number of support classes\n    such as CommonTreeNodeStream that work on these kinds of trees.  You\n    don't have to make your trees implement this interface, but if you do,\n    you'll be able to use more support code.\n\n    NOTE: When constructing trees, ANTLR can build any kind of tree; it can\n    even use Token objects as trees if you add a child list to your tokens.\n    \n    This is a tree node without any payload; just navigation and factory stuff.\n    \"\"\"\n\n\n    def getChild(self, i):\n        raise NotImplementedError\n    \n\n    def getChildCount(self):\n        raise NotImplementedError\n    \n\n    def getParent(self):\n        \"\"\"Tree tracks parent and child index now > 3.0\"\"\"\n\n        raise NotImplementedError\n    \n    def setParent(self, t):\n        \"\"\"Tree tracks parent and child index now > 3.0\"\"\"\n\n        raise NotImplementedError\n    \n\n    def getChildIndex(self):\n        \"\"\"This node is what child index? 0..n-1\"\"\"\n\n        raise NotImplementedError\n        \n    def setChildIndex(self, index):\n        \"\"\"This node is what child index? 0..n-1\"\"\"\n\n        raise NotImplementedError\n        \n\n    def freshenParentAndChildIndexes(self):\n        \"\"\"Set the parent and child index values for all children\"\"\"\n        \n        raise NotImplementedError\n\n        \n    def addChild(self, t):\n        \"\"\"\n        Add t as a child to this node.  If t is null, do nothing.  If t\n        is nil, add all children of t to this' children.\n        \"\"\"\n\n        raise NotImplementedError\n    \n\n    def setChild(self, i, t):\n        \"\"\"Set ith child (0..n-1) to t; t must be non-null and non-nil node\"\"\"\n\n        raise NotImplementedError\n\n            \n    def deleteChild(self, i):\n        raise NotImplementedError\n        \n \n    def replaceChildren(self, startChildIndex, stopChildIndex, t):\n        \"\"\"\n        Delete children from start to stop and replace with t even if t is\n        a list (nil-root tree).  num of children can increase or decrease.\n        For huge child lists, inserting children can force walking rest of\n        children to set their childindex; could be slow.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def isNil(self):\n        \"\"\"\n        Indicates the node is a nil node but may still have children, meaning\n        the tree is a flat list.\n        \"\"\"\n\n        raise NotImplementedError\n    \n\n    def getTokenStartIndex(self):\n        \"\"\"\n        What is the smallest token index (indexing from 0) for this node\n           and its children?\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def setTokenStartIndex(self, index):\n        raise NotImplementedError\n\n\n    def getTokenStopIndex(self):\n        \"\"\"\n        What is the largest token index (indexing from 0) for this node\n        and its children?\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def setTokenStopIndex(self, index):\n        raise NotImplementedError\n\n\n    def dupNode(self):\n        raise NotImplementedError\n    \n    \n    def getType(self):\n        \"\"\"Return a token type; needed for tree parsing.\"\"\"\n\n        raise NotImplementedError\n    \n\n    def getText(self):\n        raise NotImplementedError\n    \n\n    def getLine(self):\n        \"\"\"\n        In case we don't have a token payload, what is the line for errors?\n        \"\"\"\n\n        raise NotImplementedError\n    \n\n    def getCharPositionInLine(self):\n        raise NotImplementedError\n\n\n    def toStringTree(self):\n        raise NotImplementedError\n\n\n    def toString(self):\n        raise NotImplementedError\n\n\n\nclass TreeAdaptor(object):\n    \"\"\"\n    @brief Abstract baseclass for tree adaptors.\n    \n    How to create and navigate trees.  Rather than have a separate factory\n    and adaptor, I've merged them.  Makes sense to encapsulate.\n\n    This takes the place of the tree construction code generated in the\n    generated code in 2.x and the ASTFactory.\n\n    I do not need to know the type of a tree at all so they are all\n    generic Objects.  This may increase the amount of typecasting needed. :(\n    \"\"\"\n    \n    # C o n s t r u c t i o n\n\n    def createWithPayload(self, payload):\n        \"\"\"\n        Create a tree node from Token object; for CommonTree type trees,\n        then the token just becomes the payload.  This is the most\n        common create call.\n\n        Override if you want another kind of node to be built.\n        \"\"\"\n\n        raise NotImplementedError\n    \n\n    def dupNode(self, treeNode):\n        \"\"\"Duplicate a single tree node.\n\n        Override if you want another kind of node to be built.\"\"\"\n\n        raise NotImplementedError\n\n\n    def dupTree(self, tree):\n        \"\"\"Duplicate tree recursively, using dupNode() for each node\"\"\"\n\n        raise NotImplementedError\n\n\n    def nil(self):\n        \"\"\"\n        Return a nil node (an empty but non-null node) that can hold\n        a list of element as the children.  If you want a flat tree (a list)\n        use \"t=adaptor.nil(); t.addChild(x); t.addChild(y);\"\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def errorNode(self, input, start, stop, exc):\n        \"\"\"\n        Return a tree node representing an error.  This node records the\n        tokens consumed during error recovery.  The start token indicates the\n        input symbol at which the error was detected.  The stop token indicates\n        the last symbol consumed during recovery.\n\n        You must specify the input stream so that the erroneous text can\n        be packaged up in the error node.  The exception could be useful\n        to some applications; default implementation stores ptr to it in\n        the CommonErrorNode.\n\n        This only makes sense during token parsing, not tree parsing.\n        Tree parsing should happen only when parsing and tree construction\n        succeed.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def isNil(self, tree):\n        \"\"\"Is tree considered a nil node used to make lists of child nodes?\"\"\"\n\n        raise NotImplementedError\n\n\n    def addChild(self, t, child):\n        \"\"\"\n        Add a child to the tree t.  If child is a flat tree (a list), make all\n        in list children of t.  Warning: if t has no children, but child does\n        and child isNil then you can decide it is ok to move children to t via\n        t.children = child.children; i.e., without copying the array.  Just\n        make sure that this is consistent with have the user will build\n        ASTs. Do nothing if t or child is null.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def becomeRoot(self, newRoot, oldRoot):\n        \"\"\"\n        If oldRoot is a nil root, just copy or move the children to newRoot.\n        If not a nil root, make oldRoot a child of newRoot.\n        \n           old=^(nil a b c), new=r yields ^(r a b c)\n           old=^(a b c), new=r yields ^(r ^(a b c))\n\n        If newRoot is a nil-rooted single child tree, use the single\n        child as the new root node.\n\n           old=^(nil a b c), new=^(nil r) yields ^(r a b c)\n           old=^(a b c), new=^(nil r) yields ^(r ^(a b c))\n\n        If oldRoot was null, it's ok, just return newRoot (even if isNil).\n\n           old=null, new=r yields r\n           old=null, new=^(nil r) yields ^(nil r)\n\n        Return newRoot.  Throw an exception if newRoot is not a\n        simple node or nil root with a single child node--it must be a root\n        node.  If newRoot is ^(nil x) return x as newRoot.\n\n        Be advised that it's ok for newRoot to point at oldRoot's\n        children; i.e., you don't have to copy the list.  We are\n        constructing these nodes so we should have this control for\n        efficiency.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def rulePostProcessing(self, root):\n        \"\"\"\n        Given the root of the subtree created for this rule, post process\n        it to do any simplifications or whatever you want.  A required\n        behavior is to convert ^(nil singleSubtree) to singleSubtree\n        as the setting of start/stop indexes relies on a single non-nil root\n        for non-flat trees.\n\n        Flat trees such as for lists like \"idlist : ID+ ;\" are left alone\n        unless there is only one ID.  For a list, the start/stop indexes\n        are set in the nil node.\n\n        This method is executed after all rule tree construction and right\n        before setTokenBoundaries().\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def getUniqueID(self, node):\n        \"\"\"For identifying trees.\n\n        How to identify nodes so we can say \"add node to a prior node\"?\n        Even becomeRoot is an issue.  Use System.identityHashCode(node)\n        usually.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    # R e w r i t e  R u l e s\n\n    def createFromToken(self, tokenType, fromToken, text=None):\n        \"\"\"\n        Create a new node derived from a token, with a new token type and\n        (optionally) new text.\n\n        This is invoked from an imaginary node ref on right side of a\n        rewrite rule as IMAG[$tokenLabel] or IMAG[$tokenLabel \"IMAG\"].\n\n        This should invoke createToken(Token).\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def createFromType(self, tokenType, text):\n        \"\"\"Create a new node derived from a token, with a new token type.\n\n        This is invoked from an imaginary node ref on right side of a\n        rewrite rule as IMAG[\"IMAG\"].\n\n        This should invoke createToken(int,String).\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    # C o n t e n t\n\n    def getType(self, t):\n        \"\"\"For tree parsing, I need to know the token type of a node\"\"\"\n\n        raise NotImplementedError\n\n\n    def setType(self, t, type):\n        \"\"\"Node constructors can set the type of a node\"\"\"\n\n        raise NotImplementedError\n\n\n    def getText(self, t):\n        raise NotImplementedError\n\n    def setText(self, t, text):\n        \"\"\"Node constructors can set the text of a node\"\"\"\n\n        raise NotImplementedError\n\n\n    def getToken(self, t):\n        \"\"\"Return the token object from which this node was created.\n\n        Currently used only for printing an error message.\n        The error display routine in BaseRecognizer needs to\n        display where the input the error occurred. If your\n        tree of limitation does not store information that can\n        lead you to the token, you can create a token filled with\n        the appropriate information and pass that back.  See\n        BaseRecognizer.getErrorMessage().\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def setTokenBoundaries(self, t, startToken, stopToken):\n        \"\"\"\n        Where are the bounds in the input token stream for this node and\n        all children?  Each rule that creates AST nodes will call this\n        method right before returning.  Flat trees (i.e., lists) will\n        still usually have a nil root node just to hold the children list.\n        That node would contain the start/stop indexes then.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def getTokenStartIndex(self, t):\n        \"\"\"\n        Get the token start index for this subtree; return -1 if no such index\n        \"\"\"\n\n        raise NotImplementedError\n\n        \n    def getTokenStopIndex(self, t):\n        \"\"\"\n        Get the token stop index for this subtree; return -1 if no such index\n        \"\"\"\n\n        raise NotImplementedError\n        \n\n    # N a v i g a t i o n  /  T r e e  P a r s i n g\n\n    def getChild(self, t, i):\n        \"\"\"Get a child 0..n-1 node\"\"\"\n\n        raise NotImplementedError\n\n\n    def setChild(self, t, i, child):\n        \"\"\"Set ith child (0..n-1) to t; t must be non-null and non-nil node\"\"\"\n\n        raise NotImplementedError\n\n\n    def deleteChild(self, t, i):\n        \"\"\"Remove ith child and shift children down from right.\"\"\"\n        \n        raise NotImplementedError\n\n\n    def getChildCount(self, t):\n        \"\"\"How many children?  If 0, then this is a leaf node\"\"\"\n\n        raise NotImplementedError\n\n\n    def getParent(self, t):\n        \"\"\"\n        Who is the parent node of this node; if null, implies node is root.\n        If your node type doesn't handle this, it's ok but the tree rewrites\n        in tree parsers need this functionality.\n        \"\"\"\n        \n        raise NotImplementedError\n\n\n    def setParent(self, t, parent):\n        \"\"\"\n        Who is the parent node of this node; if null, implies node is root.\n        If your node type doesn't handle this, it's ok but the tree rewrites\n        in tree parsers need this functionality.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def getChildIndex(self, t):\n        \"\"\"\n        What index is this node in the child list? Range: 0..n-1\n        If your node type doesn't handle this, it's ok but the tree rewrites\n        in tree parsers need this functionality.\n        \"\"\"\n\n        raise NotImplementedError\n\n        \n    def setChildIndex(self, t, index):\n        \"\"\"\n        What index is this node in the child list? Range: 0..n-1\n        If your node type doesn't handle this, it's ok but the tree rewrites\n        in tree parsers need this functionality.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def replaceChildren(self, parent, startChildIndex, stopChildIndex, t):\n        \"\"\"\n        Replace from start to stop child index of parent with t, which might\n        be a list.  Number of children may be different\n        after this call.\n\n        If parent is null, don't do anything; must be at root of overall tree.\n        Can't replace whatever points to the parent externally.  Do nothing.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    # Misc\n\n    def create(self, *args):\n        \"\"\"\n        Deprecated, use createWithPayload, createFromToken or createFromType.\n\n        This method only exists to mimic the Java interface of TreeAdaptor.\n        \n        \"\"\"\n\n        if len(args) == 1 and isinstance(args[0], Token):\n            # Object create(Token payload);\n##             warnings.warn(\n##                 \"Using create() is deprecated, use createWithPayload()\",\n##                 DeprecationWarning,\n##                 stacklevel=2\n##                 )\n            return self.createWithPayload(args[0])\n\n        if (len(args) == 2\n            and isinstance(args[0], (int, long))\n            and isinstance(args[1], Token)\n            ):\n            # Object create(int tokenType, Token fromToken);\n##             warnings.warn(\n##                 \"Using create() is deprecated, use createFromToken()\",\n##                 DeprecationWarning,\n##                 stacklevel=2\n##                 )\n            return self.createFromToken(args[0], args[1])\n\n        if (len(args) == 3\n            and isinstance(args[0], (int, long))\n            and isinstance(args[1], Token)\n            and isinstance(args[2], basestring)\n            ):\n            # Object create(int tokenType, Token fromToken, String text);\n##             warnings.warn(\n##                 \"Using create() is deprecated, use createFromToken()\",\n##                 DeprecationWarning,\n##                 stacklevel=2\n##                 )\n            return self.createFromToken(args[0], args[1], args[2])\n\n        if (len(args) == 2\n            and isinstance(args[0], (int, long))\n            and isinstance(args[1], basestring)\n            ):\n            # Object create(int tokenType, String text);\n##             warnings.warn(\n##                 \"Using create() is deprecated, use createFromType()\",\n##                 DeprecationWarning,\n##                 stacklevel=2\n##                 )\n            return self.createFromType(args[0], args[1])\n\n        raise TypeError(\n            \"No create method with this signature found: %s\"\n            % (', '.join(type(v).__name__ for v in args))\n            )\n    \n\n############################################################################\n#\n# base implementation of Tree and TreeAdaptor\n#\n# Tree\n# \\- BaseTree\n#\n# TreeAdaptor\n# \\- BaseTreeAdaptor\n#\n############################################################################\n\n\nclass BaseTree(Tree):\n    \"\"\"\n    @brief A generic tree implementation with no payload.\n\n    You must subclass to\n    actually have any user data.  ANTLR v3 uses a list of children approach\n    instead of the child-sibling approach in v2.  A flat tree (a list) is\n    an empty node whose children represent the list.  An empty, but\n    non-null node is called \"nil\".\n    \"\"\"\n\n    # BaseTree is abstract, no need to complain about not implemented abstract\n    # methods\n    # pylint: disable-msg=W0223\n    \n    def __init__(self, node=None):\n        \"\"\"\n        Create a new node from an existing node does nothing for BaseTree\n        as there are no fields other than the children list, which cannot\n        be copied as the children are not considered part of this node. \n        \"\"\"\n        \n        Tree.__init__(self)\n        self.children = []\n        self.parent = None\n        self.childIndex = 0\n        \n\n    def getChild(self, i):\n        try:\n            return self.children[i]\n        except IndexError:\n            return None\n\n\n    def getChildren(self):\n        \"\"\"@brief Get the children internal List\n\n        Note that if you directly mess with\n        the list, do so at your own risk.\n        \"\"\"\n        \n        # FIXME: mark as deprecated\n        return self.children\n\n\n    def getFirstChildWithType(self, treeType):\n        for child in self.children:\n            if child.getType() == treeType:\n                return child\n\n        return None\n\n\n    def getChildCount(self):\n        return len(self.children)\n\n\n    def addChild(self, childTree):\n        \"\"\"Add t as child of this node.\n\n        Warning: if t has no children, but child does\n        and child isNil then this routine moves children to t via\n        t.children = child.children; i.e., without copying the array.\n        \"\"\"\n\n        # this implementation is much simpler and probably less efficient\n        # than the mumbo-jumbo that Ter did for the Java runtime.\n        \n        if childTree is None:\n            return\n\n        if childTree.isNil():\n            # t is an empty node possibly with children\n\n            if self.children is childTree.children:\n                raise ValueError(\"attempt to add child list to itself\")\n\n            # fix parent pointer and childIndex for new children\n            for idx, child in enumerate(childTree.children):\n                child.parent = self\n                child.childIndex = len(self.children) + idx\n                \n            self.children += childTree.children\n\n        else:\n            # child is not nil (don't care about children)\n            self.children.append(childTree)\n            childTree.parent = self\n            childTree.childIndex = len(self.children) - 1\n\n\n    def addChildren(self, children):\n        \"\"\"Add all elements of kids list as children of this node\"\"\"\n\n        self.children += children\n\n\n    def setChild(self, i, t):\n        if t is None:\n            return\n\n        if t.isNil():\n            raise ValueError(\"Can't set single child to a list\")\n        \n        self.children[i] = t\n        t.parent = self\n        t.childIndex = i\n        \n\n    def deleteChild(self, i):\n        killed = self.children[i]\n        \n        del self.children[i]\n        \n        # walk rest and decrement their child indexes\n        for idx, child in enumerate(self.children[i:]):\n            child.childIndex = i + idx\n            \n        return killed\n\n    \n    def replaceChildren(self, startChildIndex, stopChildIndex, newTree):\n        \"\"\"\n        Delete children from start to stop and replace with t even if t is\n        a list (nil-root tree).  num of children can increase or decrease.\n        For huge child lists, inserting children can force walking rest of\n        children to set their childindex; could be slow.\n        \"\"\"\n\n        if (startChildIndex >= len(self.children)\n            or stopChildIndex >= len(self.children)\n            ):\n            raise IndexError(\"indexes invalid\")\n\n        replacingHowMany = stopChildIndex - startChildIndex + 1\n\n        # normalize to a list of children to add: newChildren\n        if newTree.isNil():\n            newChildren = newTree.children\n\n        else:\n            newChildren = [newTree]\n\n        replacingWithHowMany = len(newChildren)\n        delta = replacingHowMany - replacingWithHowMany\n        \n        \n        if delta == 0:\n            # if same number of nodes, do direct replace\n            for idx, child in enumerate(newChildren):\n                self.children[idx + startChildIndex] = child\n                child.parent = self\n                child.childIndex = idx + startChildIndex\n\n        else:\n            # length of children changes...\n\n            # ...delete replaced segment...\n            del self.children[startChildIndex:stopChildIndex+1]\n\n            # ...insert new segment...\n            self.children[startChildIndex:startChildIndex] = newChildren\n\n            # ...and fix indeces\n            self.freshenParentAndChildIndexes(startChildIndex)\n            \n\n    def isNil(self):\n        return False\n\n\n    def freshenParentAndChildIndexes(self, offset=0):\n        for idx, child in enumerate(self.children[offset:]):\n            child.childIndex = idx + offset\n            child.parent = self\n\n\n    def sanityCheckParentAndChildIndexes(self, parent=None, i=-1):\n        if parent != self.parent:\n            raise ValueError(\n                \"parents don't match; expected %r found %r\"\n                % (parent, self.parent)\n                )\n        \n        if i != self.childIndex:\n            raise ValueError(\n                \"child indexes don't match; expected %d found %d\"\n                % (i, self.childIndex)\n                )\n\n        for idx, child in enumerate(self.children):\n            child.sanityCheckParentAndChildIndexes(self, idx)\n\n\n    def getChildIndex(self):\n        \"\"\"BaseTree doesn't track child indexes.\"\"\"\n        \n        return 0\n\n\n    def setChildIndex(self, index):\n        \"\"\"BaseTree doesn't track child indexes.\"\"\"\n\n        pass\n    \n\n    def getParent(self):\n        \"\"\"BaseTree doesn't track parent pointers.\"\"\"\n\n        return None\n\n    def setParent(self, t):\n        \"\"\"BaseTree doesn't track parent pointers.\"\"\"\n\n        pass\n\n\n    def toStringTree(self):\n        \"\"\"Print out a whole tree not just a node\"\"\"\n\n        if len(self.children) == 0:\n            return self.toString()\n\n        buf = []\n        if not self.isNil():\n            buf.append('(')\n            buf.append(self.toString())\n            buf.append(' ')\n\n        for i, child in enumerate(self.children):\n            if i > 0:\n                buf.append(' ')\n            buf.append(child.toStringTree())\n\n        if not self.isNil():\n            buf.append(')')\n\n        return ''.join(buf)\n\n\n    def getLine(self):\n        return 0\n\n\n    def getCharPositionInLine(self):\n        return 0\n\n\n    def toString(self):\n        \"\"\"Override to say how a node (not a tree) should look as text\"\"\"\n\n        raise NotImplementedError\n\n\n\nclass BaseTreeAdaptor(TreeAdaptor):\n    \"\"\"\n    @brief A TreeAdaptor that works with any Tree implementation.\n    \"\"\"\n    \n    # BaseTreeAdaptor is abstract, no need to complain about not implemented\n    # abstract methods\n    # pylint: disable-msg=W0223\n    \n    def nil(self):\n        return self.createWithPayload(None)\n\n\n    def errorNode(self, input, start, stop, exc):\n        \"\"\"\n        create tree node that holds the start and stop tokens associated\n        with an error.\n\n        If you specify your own kind of tree nodes, you will likely have to\n        override this method. CommonTree returns Token.INVALID_TOKEN_TYPE\n        if no token payload but you might have to set token type for diff\n        node type.\n        \"\"\"\n        \n        return CommonErrorNode(input, start, stop, exc)\n    \n\n    def isNil(self, tree):\n        return tree.isNil()\n\n\n    def dupTree(self, t, parent=None):\n        \"\"\"\n        This is generic in the sense that it will work with any kind of\n        tree (not just Tree interface).  It invokes the adaptor routines\n        not the tree node routines to do the construction.\n        \"\"\"\n\n        if t is None:\n            return None\n\n        newTree = self.dupNode(t)\n        \n        # ensure new subtree root has parent/child index set\n\n        # same index in new tree\n        self.setChildIndex(newTree, self.getChildIndex(t))\n        \n        self.setParent(newTree, parent)\n\n        for i in range(self.getChildCount(t)):\n            child = self.getChild(t, i)\n            newSubTree = self.dupTree(child, t)\n            self.addChild(newTree, newSubTree)\n\n        return newTree\n\n\n    def addChild(self, tree, child):\n        \"\"\"\n        Add a child to the tree t.  If child is a flat tree (a list), make all\n        in list children of t.  Warning: if t has no children, but child does\n        and child isNil then you can decide it is ok to move children to t via\n        t.children = child.children; i.e., without copying the array.  Just\n        make sure that this is consistent with have the user will build\n        ASTs.\n        \"\"\"\n\n        #if isinstance(child, Token):\n        #    child = self.createWithPayload(child)\n        \n        if tree is not None and child is not None:\n            tree.addChild(child)\n\n\n    def becomeRoot(self, newRoot, oldRoot):\n        \"\"\"\n        If oldRoot is a nil root, just copy or move the children to newRoot.\n        If not a nil root, make oldRoot a child of newRoot.\n\n          old=^(nil a b c), new=r yields ^(r a b c)\n          old=^(a b c), new=r yields ^(r ^(a b c))\n\n        If newRoot is a nil-rooted single child tree, use the single\n        child as the new root node.\n\n          old=^(nil a b c), new=^(nil r) yields ^(r a b c)\n          old=^(a b c), new=^(nil r) yields ^(r ^(a b c))\n\n        If oldRoot was null, it's ok, just return newRoot (even if isNil).\n\n          old=null, new=r yields r\n          old=null, new=^(nil r) yields ^(nil r)\n\n        Return newRoot.  Throw an exception if newRoot is not a\n        simple node or nil root with a single child node--it must be a root\n        node.  If newRoot is ^(nil x) return x as newRoot.\n\n        Be advised that it's ok for newRoot to point at oldRoot's\n        children; i.e., you don't have to copy the list.  We are\n        constructing these nodes so we should have this control for\n        efficiency.\n        \"\"\"\n\n        if isinstance(newRoot, Token):\n            newRoot = self.create(newRoot)\n\n        if oldRoot is None:\n            return newRoot\n        \n        if not isinstance(newRoot, CommonTree):\n            newRoot = self.createWithPayload(newRoot)\n\n        # handle ^(nil real-node)\n        if newRoot.isNil():\n            nc = newRoot.getChildCount()\n            if nc == 1:\n                newRoot = newRoot.getChild(0)\n                \n            elif nc > 1:\n                # TODO: make tree run time exceptions hierarchy\n                raise RuntimeError(\"more than one node as root\")\n\n        # add oldRoot to newRoot; addChild takes care of case where oldRoot\n        # is a flat list (i.e., nil-rooted tree).  All children of oldRoot\n        # are added to newRoot.\n        newRoot.addChild(oldRoot)\n        return newRoot\n\n\n    def rulePostProcessing(self, root):\n        \"\"\"Transform ^(nil x) to x and nil to null\"\"\"\n        \n        if root is not None and root.isNil():\n            if root.getChildCount() == 0:\n                root = None\n\n            elif root.getChildCount() == 1:\n                root = root.getChild(0)\n                # whoever invokes rule will set parent and child index\n                root.setParent(None)\n                root.setChildIndex(-1)\n\n        return root\n\n\n    def createFromToken(self, tokenType, fromToken, text=None):\n        assert isinstance(tokenType, (int, long)), type(tokenType).__name__\n        assert isinstance(fromToken, Token), type(fromToken).__name__\n        assert text is None or isinstance(text, basestring), type(text).__name__\n\n        fromToken = self.createToken(fromToken)\n        fromToken.type = tokenType\n        if text is not None:\n            fromToken.text = text\n        t = self.createWithPayload(fromToken)\n        return t\n\n\n    def createFromType(self, tokenType, text):\n        assert isinstance(tokenType, (int, long)), type(tokenType).__name__\n        assert isinstance(text, basestring), type(text).__name__\n                          \n        fromToken = self.createToken(tokenType=tokenType, text=text)\n        t = self.createWithPayload(fromToken)\n        return t\n\n\n    def getType(self, t):\n        return t.getType()\n\n\n    def setType(self, t, type):\n        raise RuntimeError(\"don't know enough about Tree node\")\n\n\n    def getText(self, t):\n        return t.getText()\n\n\n    def setText(self, t, text):\n        raise RuntimeError(\"don't know enough about Tree node\")\n\n\n    def getChild(self, t, i):\n        return t.getChild(i)\n\n\n    def setChild(self, t, i, child):\n        t.setChild(i, child)\n\n\n    def deleteChild(self, t, i):\n        return t.deleteChild(i)\n\n\n    def getChildCount(self, t):\n        return t.getChildCount()\n\n\n    def getUniqueID(self, node):\n        return hash(node)\n\n\n    def createToken(self, fromToken=None, tokenType=None, text=None):\n        \"\"\"\n        Tell me how to create a token for use with imaginary token nodes.\n        For example, there is probably no input symbol associated with imaginary\n        token DECL, but you need to create it as a payload or whatever for\n        the DECL node as in ^(DECL type ID).\n\n        If you care what the token payload objects' type is, you should\n        override this method and any other createToken variant.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n############################################################################\n#\n# common tree implementation\n#\n# Tree\n# \\- BaseTree\n#    \\- CommonTree\n#       \\- CommonErrorNode\n#\n# TreeAdaptor\n# \\- BaseTreeAdaptor\n#    \\- CommonTreeAdaptor\n#\n############################################################################\n\n\nclass CommonTree(BaseTree):\n    \"\"\"@brief A tree node that is wrapper for a Token object.\n\n    After 3.0 release\n    while building tree rewrite stuff, it became clear that computing\n    parent and child index is very difficult and cumbersome.  Better to\n    spend the space in every tree node.  If you don't want these extra\n    fields, it's easy to cut them out in your own BaseTree subclass.\n    \n    \"\"\"\n\n    def __init__(self, payload):\n        BaseTree.__init__(self)\n        \n        # What token indexes bracket all tokens associated with this node\n        # and below?\n        self.startIndex = -1\n        self.stopIndex = -1\n\n        # Who is the parent node of this node; if null, implies node is root\n        self.parent = None\n        \n        # What index is this node in the child list? Range: 0..n-1\n        self.childIndex = -1\n\n        # A single token is the payload\n        if payload is None:\n            self.token = None\n            \n        elif isinstance(payload, CommonTree):\n            self.token = payload.token\n            self.startIndex = payload.startIndex\n            self.stopIndex = payload.stopIndex\n            \n        elif payload is None or isinstance(payload, Token):\n            self.token = payload\n            \n        else:\n            raise TypeError(type(payload).__name__)\n\n\n\n    def getToken(self):\n        return self.token\n\n\n    def dupNode(self):\n        return CommonTree(self)\n\n\n    def isNil(self):\n        return self.token is None\n\n\n    def getType(self):\n        if self.token is None:\n            return INVALID_TOKEN_TYPE\n\n        return self.token.getType()\n\n    type = property(getType)\n    \n\n    def getText(self):\n        if self.token is None:\n            return None\n        \n        return self.token.text\n\n    text = property(getText)\n    \n\n    def getLine(self):\n        if self.token is None or self.token.getLine() == 0:\n            if self.getChildCount():\n                return self.getChild(0).getLine()\n            else:\n                return 0\n\n        return self.token.getLine()\n\n    line = property(getLine)\n    \n\n    def getCharPositionInLine(self):\n        if self.token is None or self.token.getCharPositionInLine() == -1:\n            if self.getChildCount():\n                return self.getChild(0).getCharPositionInLine()\n            else:\n                return 0\n\n        else:\n            return self.token.getCharPositionInLine()\n\n    charPositionInLine = property(getCharPositionInLine)\n    \n\n    def getTokenStartIndex(self):\n        if self.startIndex == -1 and self.token is not None:\n            return self.token.getTokenIndex()\n        \n        return self.startIndex\n    \n    def setTokenStartIndex(self, index):\n        self.startIndex = index\n\n    tokenStartIndex = property(getTokenStartIndex, setTokenStartIndex)\n\n\n    def getTokenStopIndex(self):\n        if self.stopIndex == -1 and self.token is not None:\n            return self.token.getTokenIndex()\n        \n        return self.stopIndex\n\n    def setTokenStopIndex(self, index):\n        self.stopIndex = index\n\n    tokenStopIndex = property(getTokenStopIndex, setTokenStopIndex)\n\n\n    def getChildIndex(self):\n        #FIXME: mark as deprecated\n        return self.childIndex\n\n\n    def setChildIndex(self, idx):\n        #FIXME: mark as deprecated\n        self.childIndex = idx\n\n\n    def getParent(self):\n        #FIXME: mark as deprecated\n        return self.parent\n\n\n    def setParent(self, t):\n        #FIXME: mark as deprecated\n        self.parent = t\n\n        \n    def toString(self):\n        if self.isNil():\n            return \"nil\"\n\n        if self.getType() == INVALID_TOKEN_TYPE:\n            return \"<errornode>\"\n\n        return self.token.text\n\n    __str__ = toString   \n\n\n\n    def toStringTree(self):\n        if not self.children:\n            return self.toString()\n\n        ret = ''\n        if not self.isNil():\n            ret += '(%s ' % (self.toString())\n        \n        ret += ' '.join([child.toStringTree() for child in self.children])\n\n        if not self.isNil():\n            ret += ')'\n\n        return ret\n\n\nINVALID_NODE = CommonTree(INVALID_TOKEN)\n\n\nclass CommonErrorNode(CommonTree):\n    \"\"\"A node representing erroneous token range in token stream\"\"\"\n\n    def __init__(self, input, start, stop, exc):\n        CommonTree.__init__(self, None)\n\n        if (stop is None or\n            (stop.getTokenIndex() < start.getTokenIndex() and\n             stop.getType() != EOF\n             )\n            ):\n            # sometimes resync does not consume a token (when LT(1) is\n            # in follow set.  So, stop will be 1 to left to start. adjust.\n            # Also handle case where start is the first token and no token\n            # is consumed during recovery; LT(-1) will return null.\n            stop = start\n\n        self.input = input\n        self.start = start\n        self.stop = stop\n        self.trappedException = exc\n\n\n    def isNil(self):\n        return False\n\n\n    def getType(self):\n        return INVALID_TOKEN_TYPE\n\n\n    def getText(self):\n        if isinstance(self.start, Token):\n            i = self.start.getTokenIndex()\n            j = self.stop.getTokenIndex()\n            if self.stop.getType() == EOF:\n                j = self.input.size()\n\n            badText = self.input.toString(i, j)\n\n        elif isinstance(self.start, Tree):\n            badText = self.input.toString(self.start, self.stop)\n\n        else:\n            # people should subclass if they alter the tree type so this\n            # next one is for sure correct.\n            badText = \"<unknown>\"\n\n        return badText\n\n\n    def toString(self):\n        if isinstance(self.trappedException, MissingTokenException):\n            return (\"<missing type: \"\n                    + str(self.trappedException.getMissingType())\n                    + \">\")\n\n        elif isinstance(self.trappedException, UnwantedTokenException):\n            return (\"<extraneous: \"\n                    + str(self.trappedException.getUnexpectedToken())\n                    + \", resync=\" + self.getText() + \">\")\n\n        elif isinstance(self.trappedException, MismatchedTokenException):\n            return (\"<mismatched token: \"\n                    + str(self.trappedException.token)\n                    + \", resync=\" + self.getText() + \">\")\n\n        elif isinstance(self.trappedException, NoViableAltException):\n            return (\"<unexpected: \"\n                    + str(self.trappedException.token)\n                    + \", resync=\" + self.getText() + \">\")\n\n        return \"<error: \"+self.getText()+\">\"\n\n\nclass CommonTreeAdaptor(BaseTreeAdaptor):\n    \"\"\"\n    @brief A TreeAdaptor that works with any Tree implementation.\n    \n    It provides\n    really just factory methods; all the work is done by BaseTreeAdaptor.\n    If you would like to have different tokens created than ClassicToken\n    objects, you need to override this and then set the parser tree adaptor to\n    use your subclass.\n\n    To get your parser to build nodes of a different type, override\n    create(Token).\n    \"\"\"\n    \n    def dupNode(self, treeNode):\n        \"\"\"\n        Duplicate a node.  This is part of the factory;\n        override if you want another kind of node to be built.\n\n        I could use reflection to prevent having to override this\n        but reflection is slow.\n        \"\"\"\n\n        if treeNode is None:\n            return None\n        \n        return treeNode.dupNode()\n\n\n    def createWithPayload(self, payload):\n        return CommonTree(payload)\n\n\n    def createToken(self, fromToken=None, tokenType=None, text=None):\n        \"\"\"\n        Tell me how to create a token for use with imaginary token nodes.\n        For example, there is probably no input symbol associated with imaginary\n        token DECL, but you need to create it as a payload or whatever for\n        the DECL node as in ^(DECL type ID).\n\n        If you care what the token payload objects' type is, you should\n        override this method and any other createToken variant.\n        \"\"\"\n        \n        if fromToken is not None:\n            return CommonToken(oldToken=fromToken)\n\n        return CommonToken(type=tokenType, text=text)\n\n\n    def setTokenBoundaries(self, t, startToken, stopToken):\n        \"\"\"\n        Track start/stop token for subtree root created for a rule.\n        Only works with Tree nodes.  For rules that match nothing,\n        seems like this will yield start=i and stop=i-1 in a nil node.\n        Might be useful info so I'll not force to be i..i.\n        \"\"\"\n        \n        if t is None:\n            return\n\n        start = 0\n        stop = 0\n        \n        if startToken is not None:\n            start = startToken.index\n                \n        if stopToken is not None:\n            stop = stopToken.index\n\n        t.setTokenStartIndex(start)\n        t.setTokenStopIndex(stop)\n\n\n    def getTokenStartIndex(self, t):\n        if t is None:\n            return -1\n        return t.getTokenStartIndex()\n\n\n    def getTokenStopIndex(self, t):\n        if t is None:\n            return -1\n        return t.getTokenStopIndex()\n\n\n    def getText(self, t):\n        if t is None:\n            return None\n        return t.getText()\n\n\n    def getType(self, t):\n        if t is None:\n            return INVALID_TOKEN_TYPE\n        \n        return t.getType()\n\n\n    def getToken(self, t):\n        \"\"\"\n        What is the Token associated with this node?  If\n        you are not using CommonTree, then you must\n        override this in your own adaptor.\n        \"\"\"\n\n        if isinstance(t, CommonTree):\n            return t.getToken()\n\n        return None # no idea what to do\n\n\n    def getChild(self, t, i):\n        if t is None:\n            return None\n        return t.getChild(i)\n\n\n    def getChildCount(self, t):\n        if t is None:\n            return 0\n        return t.getChildCount()\n\n\n    def getParent(self, t):\n        return t.getParent()\n\n\n    def setParent(self, t, parent):\n        t.setParent(parent)\n\n\n    def getChildIndex(self, t):\n        return t.getChildIndex()\n\n\n    def setChildIndex(self, t, index):\n        t.setChildIndex(index)\n\n\n    def replaceChildren(self, parent, startChildIndex, stopChildIndex, t):\n        if parent is not None:\n            parent.replaceChildren(startChildIndex, stopChildIndex, t)\n\n\n############################################################################\n#\n# streams\n#\n# TreeNodeStream\n# \\- BaseTree\n#    \\- CommonTree\n#\n# TreeAdaptor\n# \\- BaseTreeAdaptor\n#    \\- CommonTreeAdaptor\n#\n############################################################################\n\n\n\nclass TreeNodeStream(IntStream):\n    \"\"\"@brief A stream of tree nodes\n\n    It accessing nodes from a tree of some kind.\n    \"\"\"\n    \n    # TreeNodeStream is abstract, no need to complain about not implemented\n    # abstract methods\n    # pylint: disable-msg=W0223\n    \n    def get(self, i):\n        \"\"\"Get a tree node at an absolute index i; 0..n-1.\n        If you don't want to buffer up nodes, then this method makes no\n        sense for you.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def LT(self, k):\n        \"\"\"\n        Get tree node at current input pointer + i ahead where i=1 is next node.\n        i<0 indicates nodes in the past.  So LT(-1) is previous node, but\n        implementations are not required to provide results for k < -1.\n        LT(0) is undefined.  For i>=n, return null.\n        Return null for LT(0) and any index that results in an absolute address\n        that is negative.\n\n        This is analogus to the LT() method of the TokenStream, but this\n        returns a tree node instead of a token.  Makes code gen identical\n        for both parser and tree grammars. :)\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def getTreeSource(self):\n        \"\"\"\n        Where is this stream pulling nodes from?  This is not the name, but\n        the object that provides node objects.\n        \"\"\"\n\n        raise NotImplementedError\n    \n\n    def getTokenStream(self):\n        \"\"\"\n        If the tree associated with this stream was created from a TokenStream,\n        you can specify it here.  Used to do rule $text attribute in tree\n        parser.  Optional unless you use tree parser rule text attribute\n        or output=template and rewrite=true options.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    def getTreeAdaptor(self):\n        \"\"\"\n        What adaptor can tell me how to interpret/navigate nodes and\n        trees.  E.g., get text of a node.\n        \"\"\"\n\n        raise NotImplementedError\n        \n\n    def setUniqueNavigationNodes(self, uniqueNavigationNodes):\n        \"\"\"\n        As we flatten the tree, we use UP, DOWN nodes to represent\n        the tree structure.  When debugging we need unique nodes\n        so we have to instantiate new ones.  When doing normal tree\n        parsing, it's slow and a waste of memory to create unique\n        navigation nodes.  Default should be false;\n        \"\"\"\n\n        raise NotImplementedError\n        \n\n    def toString(self, start, stop):\n        \"\"\"\n        Return the text of all nodes from start to stop, inclusive.\n        If the stream does not buffer all the nodes then it can still\n        walk recursively from start until stop.  You can always return\n        null or \"\" too, but users should not access $ruleLabel.text in\n        an action of course in that case.\n        \"\"\"\n\n        raise NotImplementedError\n\n\n    # REWRITING TREES (used by tree parser)\n    def replaceChildren(self, parent, startChildIndex, stopChildIndex, t):\n        \"\"\"\n \tReplace from start to stop child index of parent with t, which might\n        be a list.  Number of children may be different\n        after this call.  The stream is notified because it is walking the\n        tree and might need to know you are monkeying with the underlying\n        tree.  Also, it might be able to modify the node stream to avoid\n        restreaming for future phases.\n\n        If parent is null, don't do anything; must be at root of overall tree.\n        Can't replace whatever points to the parent externally.  Do nothing.\n        \"\"\"\n\n        raise NotImplementedError\n\n\nclass CommonTreeNodeStream(TreeNodeStream):\n    \"\"\"@brief A buffered stream of tree nodes.\n\n    Nodes can be from a tree of ANY kind.\n\n    This node stream sucks all nodes out of the tree specified in\n    the constructor during construction and makes pointers into\n    the tree using an array of Object pointers. The stream necessarily\n    includes pointers to DOWN and UP and EOF nodes.\n\n    This stream knows how to mark/release for backtracking.\n\n    This stream is most suitable for tree interpreters that need to\n    jump around a lot or for tree parsers requiring speed (at cost of memory).\n    There is some duplicated functionality here with UnBufferedTreeNodeStream\n    but just in bookkeeping, not tree walking etc...\n\n    @see UnBufferedTreeNodeStream\n    \"\"\"\n    \n    def __init__(self, *args):\n        TreeNodeStream.__init__(self)\n\n        if len(args) == 1:\n            adaptor = CommonTreeAdaptor()\n            tree = args[0]\n\n        elif len(args) == 2:\n            adaptor = args[0]\n            tree = args[1]\n\n        else:\n            raise TypeError(\"Invalid arguments\")\n        \n        # all these navigation nodes are shared and hence they\n        # cannot contain any line/column info\n        self.down = adaptor.createFromType(DOWN, \"DOWN\")\n        self.up = adaptor.createFromType(UP, \"UP\")\n        self.eof = adaptor.createFromType(EOF, \"EOF\")\n\n        # The complete mapping from stream index to tree node.\n        # This buffer includes pointers to DOWN, UP, and EOF nodes.\n        # It is built upon ctor invocation.  The elements are type\n        #  Object as we don't what the trees look like.\n\n        # Load upon first need of the buffer so we can set token types\n        # of interest for reverseIndexing.  Slows us down a wee bit to\n        # do all of the if p==-1 testing everywhere though.\n        self.nodes = []\n\n        # Pull nodes from which tree?\n        self.root = tree\n\n        # IF this tree (root) was created from a token stream, track it.\n        self.tokens = None\n\n        # What tree adaptor was used to build these trees\n        self.adaptor = adaptor\n\n        # Reuse same DOWN, UP navigation nodes unless this is true\n        self.uniqueNavigationNodes = False\n\n        # The index into the nodes list of the current node (next node\n        # to consume).  If -1, nodes array not filled yet.\n        self.p = -1\n\n        # Track the last mark() call result value for use in rewind().\n        self.lastMarker = None\n\n        # Stack of indexes used for push/pop calls\n        self.calls = []\n\n\n    def fillBuffer(self):\n        \"\"\"Walk tree with depth-first-search and fill nodes buffer.\n        Don't do DOWN, UP nodes if its a list (t is isNil).\n        \"\"\"\n\n        self._fillBuffer(self.root)\n        self.p = 0 # buffer of nodes intialized now\n\n\n    def _fillBuffer(self, t):\n        nil = self.adaptor.isNil(t)\n        \n        if not nil:\n            self.nodes.append(t) # add this node\n\n        # add DOWN node if t has children\n        n = self.adaptor.getChildCount(t)\n        if not nil and n > 0:\n            self.addNavigationNode(DOWN)\n\n        # and now add all its children\n        for c in range(n):\n            self._fillBuffer(self.adaptor.getChild(t, c))\n\n        # add UP node if t has children\n        if not nil and n > 0:\n            self.addNavigationNode(UP)\n\n\n    def getNodeIndex(self, node):\n        \"\"\"What is the stream index for node? 0..n-1\n        Return -1 if node not found.\n        \"\"\"\n        \n        if self.p == -1:\n            self.fillBuffer()\n\n        for i, t in enumerate(self.nodes):\n            if t == node:\n                return i\n\n        return -1\n\n\n    def addNavigationNode(self, ttype):\n        \"\"\"\n        As we flatten the tree, we use UP, DOWN nodes to represent\n        the tree structure.  When debugging we need unique nodes\n        so instantiate new ones when uniqueNavigationNodes is true.\n        \"\"\"\n        \n        navNode = None\n        \n        if ttype == DOWN:\n            if self.hasUniqueNavigationNodes():\n                navNode = self.adaptor.createFromType(DOWN, \"DOWN\")\n\n            else:\n                navNode = self.down\n\n        else:\n            if self.hasUniqueNavigationNodes():\n                navNode = self.adaptor.createFromType(UP, \"UP\")\n                \n            else:\n                navNode = self.up\n\n        self.nodes.append(navNode)\n\n\n    def get(self, i):\n        if self.p == -1:\n            self.fillBuffer()\n\n        return self.nodes[i]\n\n\n    def LT(self, k):\n        if self.p == -1:\n            self.fillBuffer()\n\n        if k == 0:\n            return None\n\n        if k < 0:\n            return self.LB(-k)\n\n        #System.out.print(\"LT(p=\"+p+\",\"+k+\")=\");\n        if self.p + k - 1 >= len(self.nodes):\n            return self.eof\n\n        return self.nodes[self.p + k - 1]\n    \n\n    def getCurrentSymbol(self):\n        return self.LT(1)\n\n\n    def LB(self, k):\n        \"\"\"Look backwards k nodes\"\"\"\n        \n        if k == 0:\n            return None\n\n        if self.p - k < 0:\n            return None\n\n        return self.nodes[self.p - k]\n\n\n    def getTreeSource(self):\n        return self.root\n\n\n    def getSourceName(self):\n        return self.getTokenStream().getSourceName()\n\n\n    def getTokenStream(self):\n        return self.tokens\n\n\n    def setTokenStream(self, tokens):\n        self.tokens = tokens\n\n\n    def getTreeAdaptor(self):\n        return self.adaptor\n\n\n    def hasUniqueNavigationNodes(self):\n        return self.uniqueNavigationNodes\n\n\n    def setUniqueNavigationNodes(self, uniqueNavigationNodes):\n        self.uniqueNavigationNodes = uniqueNavigationNodes\n\n\n    def consume(self):\n        if self.p == -1:\n            self.fillBuffer()\n            \n        self.p += 1\n\n        \n    def LA(self, i):\n        return self.adaptor.getType(self.LT(i))\n\n\n    def mark(self):\n        if self.p == -1:\n            self.fillBuffer()\n\n        \n        self.lastMarker = self.index()\n        return self.lastMarker\n\n\n    def release(self, marker=None):\n        # no resources to release\n\n        pass\n\n\n    def index(self):\n        return self.p\n\n\n    def rewind(self, marker=None):\n        if marker is None:\n            marker = self.lastMarker\n            \n        self.seek(marker)\n\n\n    def seek(self, index):\n        if self.p == -1:\n            self.fillBuffer()\n\n        self.p = index\n\n\n    def push(self, index):\n        \"\"\"\n        Make stream jump to a new location, saving old location.\n        Switch back with pop().\n        \"\"\"\n\n        self.calls.append(self.p) # save current index\n        self.seek(index)\n\n\n    def pop(self):\n        \"\"\"\n        Seek back to previous index saved during last push() call.\n        Return top of stack (return index).\n        \"\"\"\n\n        ret = self.calls.pop(-1)\n        self.seek(ret)\n        return ret\n\n\n    def reset(self):\n        self.p = 0\n        self.lastMarker = 0\n        self.calls = []\n\n        \n    def size(self):\n        if self.p == -1:\n            self.fillBuffer()\n\n        return len(self.nodes)\n\n\n    # TREE REWRITE INTERFACE\n\n    def replaceChildren(self, parent, startChildIndex, stopChildIndex, t):\n        if parent is not None:\n            self.adaptor.replaceChildren(\n                parent, startChildIndex, stopChildIndex, t\n                )\n\n\n    def __str__(self):\n        \"\"\"Used for testing, just return the token type stream\"\"\"\n\n        if self.p == -1:\n            self.fillBuffer()\n\n        return ' '.join([str(self.adaptor.getType(node))\n                         for node in self.nodes\n                         ])\n\n\n    def toString(self, start, stop):\n        if start is None or stop is None:\n            return None\n\n        if self.p == -1:\n            self.fillBuffer()\n\n        #System.out.println(\"stop: \"+stop);\n        #if ( start instanceof CommonTree )\n        #    System.out.print(\"toString: \"+((CommonTree)start).getToken()+\", \");\n        #else\n        #    System.out.println(start);\n        #if ( stop instanceof CommonTree )\n        #    System.out.println(((CommonTree)stop).getToken());\n        #else\n        #    System.out.println(stop);\n            \n        # if we have the token stream, use that to dump text in order\n        if self.tokens is not None:\n            beginTokenIndex = self.adaptor.getTokenStartIndex(start)\n            endTokenIndex = self.adaptor.getTokenStopIndex(stop)\n            \n            # if it's a tree, use start/stop index from start node\n            # else use token range from start/stop nodes\n            if self.adaptor.getType(stop) == UP:\n                endTokenIndex = self.adaptor.getTokenStopIndex(start)\n\n            elif self.adaptor.getType(stop) == EOF:\n                endTokenIndex = self.size() -2 # don't use EOF\n\n            return self.tokens.toString(beginTokenIndex, endTokenIndex)\n\n        # walk nodes looking for start\n        i, t = 0, None\n        for i, t in enumerate(self.nodes):\n            if t == start:\n                break\n\n        # now walk until we see stop, filling string buffer with text\n        buf = []\n        t = self.nodes[i]\n        while t != stop:\n            text = self.adaptor.getText(t)\n            if text is None:\n                text = \" \" + self.adaptor.getType(t)\n\n            buf.append(text)\n            i += 1\n            t = self.nodes[i]\n\n        # include stop node too\n        text = self.adaptor.getText(stop)\n        if text is None:\n            text = \" \" +self.adaptor.getType(stop)\n\n        buf.append(text)\n        \n        return ''.join(buf)\n    \n\n    ## iterator interface\n    def __iter__(self):\n        if self.p == -1:\n            self.fillBuffer()\n\n        for node in self.nodes:\n            yield node\n\n\n#############################################################################\n#\n# tree parser\n#\n#############################################################################\n\nclass TreeParser(BaseRecognizer):\n    \"\"\"@brief Baseclass for generated tree parsers.\n    \n    A parser for a stream of tree nodes.  \"tree grammars\" result in a subclass\n    of this.  All the error reporting and recovery is shared with Parser via\n    the BaseRecognizer superclass.\n    \"\"\"\n\n    def __init__(self, input, state=None):\n        BaseRecognizer.__init__(self, state)\n\n        self.input = None\n        self.setTreeNodeStream(input)\n\n\n    def reset(self):\n        BaseRecognizer.reset(self) # reset all recognizer state variables\n        if self.input is not None:\n            self.input.seek(0) # rewind the input\n\n\n    def setTreeNodeStream(self, input):\n        \"\"\"Set the input stream\"\"\"\n\n        self.input = input\n\n\n    def getTreeNodeStream(self):\n        return self.input\n\n\n    def getSourceName(self):\n        return self.input.getSourceName()\n\n\n    def getCurrentInputSymbol(self, input):\n        return input.LT(1)\n\n\n    def getMissingSymbol(self, input, e, expectedTokenType, follow):\n        tokenText = \"<missing \" + self.tokenNames[expectedTokenType] + \">\"\n        return CommonTree(CommonToken(type=expectedTokenType, text=tokenText))\n\n\n    def matchAny(self, ignore): # ignore stream, copy of this.input\n        \"\"\"\n        Match '.' in tree parser has special meaning.  Skip node or\n        entire tree if node has children.  If children, scan until\n        corresponding UP node.\n        \"\"\"\n        \n        self._state.errorRecovery = False\n\n        look = self.input.LT(1)\n        if self.input.getTreeAdaptor().getChildCount(look) == 0:\n            self.input.consume() # not subtree, consume 1 node and return\n            return\n\n        # current node is a subtree, skip to corresponding UP.\n        # must count nesting level to get right UP\n        level = 0\n        tokenType = self.input.getTreeAdaptor().getType(look)\n        while tokenType != EOF and not (tokenType == UP and level==0):\n            self.input.consume()\n            look = self.input.LT(1)\n            tokenType = self.input.getTreeAdaptor().getType(look)\n            if tokenType == DOWN:\n                level += 1\n\n            elif tokenType == UP:\n                level -= 1\n\n        self.input.consume() # consume UP\n\n\n    def mismatch(self, input, ttype, follow):\n        \"\"\"\n        We have DOWN/UP nodes in the stream that have no line info; override.\n        plus we want to alter the exception type. Don't try to recover\n        from tree parser errors inline...\n        \"\"\"\n\n        raise MismatchedTreeNodeException(ttype, input)\n\n\n    def getErrorHeader(self, e):\n        \"\"\"\n        Prefix error message with the grammar name because message is\n        always intended for the programmer because the parser built\n        the input tree not the user.\n        \"\"\"\n\n        return (self.getGrammarFileName() +\n                \": node from %sline %s:%s\"\n                % (['', \"after \"][e.approximateLineInfo],\n                   e.line,\n                   e.charPositionInLine\n                   )\n                )\n\n    def getErrorMessage(self, e, tokenNames):\n        \"\"\"\n        Tree parsers parse nodes they usually have a token object as\n        payload. Set the exception token and do the default behavior.\n        \"\"\"\n\n        if isinstance(self, TreeParser):\n            adaptor = e.input.getTreeAdaptor()\n            e.token = adaptor.getToken(e.node)\n            if e.token is not None: # could be an UP/DOWN node\n                e.token = CommonToken(\n                    type=adaptor.getType(e.node),\n                    text=adaptor.getText(e.node)\n                    )\n\n        return BaseRecognizer.getErrorMessage(self, e, tokenNames)\n\n\n    def traceIn(self, ruleName, ruleIndex):\n        BaseRecognizer.traceIn(self, ruleName, ruleIndex, self.input.LT(1))\n\n\n    def traceOut(self, ruleName, ruleIndex):\n        BaseRecognizer.traceOut(self, ruleName, ruleIndex, self.input.LT(1))\n\n\n#############################################################################\n#\n# streams for rule rewriting\n#\n#############################################################################\n\nclass RewriteRuleElementStream(object):\n    \"\"\"@brief Internal helper class.\n    \n    A generic list of elements tracked in an alternative to be used in\n    a -> rewrite rule.  We need to subclass to fill in the next() method,\n    which returns either an AST node wrapped around a token payload or\n    an existing subtree.\n\n    Once you start next()ing, do not try to add more elements.  It will\n    break the cursor tracking I believe.\n\n    @see org.antlr.runtime.tree.RewriteRuleSubtreeStream\n    @see org.antlr.runtime.tree.RewriteRuleTokenStream\n    \n    TODO: add mechanism to detect/puke on modification after reading from\n    stream\n    \"\"\"\n\n    def __init__(self, adaptor, elementDescription, elements=None):\n        # Cursor 0..n-1.  If singleElement!=null, cursor is 0 until you next(),\n        # which bumps it to 1 meaning no more elements.\n        self.cursor = 0\n\n        # Track single elements w/o creating a list.  Upon 2nd add, alloc list\n        self.singleElement = None\n\n        # The list of tokens or subtrees we are tracking\n        self.elements = None\n\n        # Once a node / subtree has been used in a stream, it must be dup'd\n        # from then on.  Streams are reset after subrules so that the streams\n        # can be reused in future subrules.  So, reset must set a dirty bit.\n        # If dirty, then next() always returns a dup.\n        self.dirty = False\n        \n        # The element or stream description; usually has name of the token or\n        # rule reference that this list tracks.  Can include rulename too, but\n        # the exception would track that info.\n        self.elementDescription = elementDescription\n\n        self.adaptor = adaptor\n\n        if isinstance(elements, (list, tuple)):\n            # Create a stream, but feed off an existing list\n            self.singleElement = None\n            self.elements = elements\n\n        else:\n            # Create a stream with one element\n            self.add(elements)\n\n\n    def reset(self):\n        \"\"\"\n        Reset the condition of this stream so that it appears we have\n        not consumed any of its elements.  Elements themselves are untouched.\n        Once we reset the stream, any future use will need duplicates.  Set\n        the dirty bit.\n        \"\"\"\n        \n        self.cursor = 0\n        self.dirty = True\n\n        \n    def add(self, el):\n        if el is None:\n            return\n\n        if self.elements is not None: # if in list, just add\n            self.elements.append(el)\n            return\n\n        if self.singleElement is None: # no elements yet, track w/o list\n            self.singleElement = el\n            return\n\n        # adding 2nd element, move to list\n        self.elements = []\n        self.elements.append(self.singleElement)\n        self.singleElement = None\n        self.elements.append(el)\n\n\n    def nextTree(self):\n        \"\"\"\n        Return the next element in the stream.  If out of elements, throw\n        an exception unless size()==1.  If size is 1, then return elements[0].\n        \n        Return a duplicate node/subtree if stream is out of elements and\n        size==1. If we've already used the element, dup (dirty bit set).\n        \"\"\"\n        \n        if (self.dirty\n            or (self.cursor >= len(self) and len(self) == 1)\n            ):\n            # if out of elements and size is 1, dup\n            el = self._next()\n            return self.dup(el)\n\n        # test size above then fetch\n        el = self._next()\n        return el\n\n\n    def _next(self):\n        \"\"\"\n        do the work of getting the next element, making sure that it's\n        a tree node or subtree.  Deal with the optimization of single-\n        element list versus list of size > 1.  Throw an exception\n        if the stream is empty or we're out of elements and size>1.\n        protected so you can override in a subclass if necessary.\n        \"\"\"\n\n        if len(self) == 0:\n            raise RewriteEmptyStreamException(self.elementDescription)\n            \n        if self.cursor >= len(self): # out of elements?\n            if len(self) == 1: # if size is 1, it's ok; return and we'll dup \n                return self.toTree(self.singleElement)\n\n            # out of elements and size was not 1, so we can't dup\n            raise RewriteCardinalityException(self.elementDescription)\n\n        # we have elements\n        if self.singleElement is not None:\n            self.cursor += 1 # move cursor even for single element list\n            return self.toTree(self.singleElement)\n\n        # must have more than one in list, pull from elements\n        o = self.toTree(self.elements[self.cursor])\n        self.cursor += 1\n        return o\n\n\n    def dup(self, el):\n        \"\"\"\n        When constructing trees, sometimes we need to dup a token or AST\n        subtree.  Dup'ing a token means just creating another AST node\n        around it.  For trees, you must call the adaptor.dupTree() unless\n        the element is for a tree root; then it must be a node dup.\n        \"\"\"\n\n        raise NotImplementedError\n    \n\n    def toTree(self, el):\n        \"\"\"\n        Ensure stream emits trees; tokens must be converted to AST nodes.\n        AST nodes can be passed through unmolested.\n        \"\"\"\n\n        return el\n\n\n    def hasNext(self):\n        return ( (self.singleElement is not None and self.cursor < 1)\n                 or (self.elements is not None\n                     and self.cursor < len(self.elements)\n                     )\n                 )\n\n                 \n    def size(self):\n        if self.singleElement is not None:\n            return 1\n\n        if self.elements is not None:\n            return len(self.elements)\n\n        return 0\n\n    __len__ = size\n    \n\n    def getDescription(self):\n        \"\"\"Deprecated. Directly access elementDescription attribute\"\"\"\n        \n        return self.elementDescription\n\n\nclass RewriteRuleTokenStream(RewriteRuleElementStream):\n    \"\"\"@brief Internal helper class.\"\"\"\n\n    def toTree(self, el):\n        # Don't convert to a tree unless they explicitly call nextTree.\n        # This way we can do hetero tree nodes in rewrite.\n        return el\n\n\n    def nextNode(self):\n        t = self._next()\n        return self.adaptor.createWithPayload(t)\n\n    \n    def nextToken(self):\n        return self._next()\n\n    \n    def dup(self, el):\n        raise TypeError(\"dup can't be called for a token stream.\")\n\n\nclass RewriteRuleSubtreeStream(RewriteRuleElementStream):\n    \"\"\"@brief Internal helper class.\"\"\"\n\n    def nextNode(self):\n        \"\"\"\n        Treat next element as a single node even if it's a subtree.\n        This is used instead of next() when the result has to be a\n        tree root node.  Also prevents us from duplicating recently-added\n        children; e.g., ^(type ID)+ adds ID to type and then 2nd iteration\n        must dup the type node, but ID has been added.\n\n        Referencing a rule result twice is ok; dup entire tree as\n        we can't be adding trees as root; e.g., expr expr.\n\n        Hideous code duplication here with super.next().  Can't think of\n        a proper way to refactor.  This needs to always call dup node\n        and super.next() doesn't know which to call: dup node or dup tree.\n        \"\"\"\n        \n        if (self.dirty\n            or (self.cursor >= len(self) and len(self) == 1)\n            ):\n            # if out of elements and size is 1, dup (at most a single node\n            # since this is for making root nodes).\n            el = self._next()\n            return self.adaptor.dupNode(el)\n\n        # test size above then fetch\n        el = self._next()\n        return el\n\n\n    def dup(self, el):\n        return self.adaptor.dupTree(el)\n\n\n\nclass RewriteRuleNodeStream(RewriteRuleElementStream):\n    \"\"\"\n    Queues up nodes matched on left side of -> in a tree parser. This is\n    the analog of RewriteRuleTokenStream for normal parsers. \n    \"\"\"\n    \n    def nextNode(self):\n        return self._next()\n\n\n    def toTree(self, el):\n        return self.adaptor.dupNode(el)\n\n\n    def dup(self, el):\n        # we dup every node, so don't have to worry about calling dup; short-\n        #circuited next() so it doesn't call.\n        raise TypeError(\"dup can't be called for a node stream.\")\n\n\nclass TreeRuleReturnScope(RuleReturnScope):\n    \"\"\"\n    This is identical to the ParserRuleReturnScope except that\n    the start property is a tree nodes not Token object\n    when you are parsing trees.  To be generic the tree node types\n    have to be Object.\n    \"\"\"\n\n    def __init__(self):\n        self.start = None\n        self.tree = None\n        \n    \n    def getStart(self):\n        return self.start\n\n    \n    def getTree(self):\n        return self.tree\n\n"
  },
  {
    "path": "deps/cpy/antlr3/treewizard.py",
    "content": "\"\"\" @package antlr3.tree\n@brief ANTLR3 runtime package, treewizard module\n\nA utility module to create ASTs at runtime.\nSee <http://www.antlr.org/wiki/display/~admin/2007/07/02/Exploring+Concept+of+TreeWizard> for an overview. Note that the API of the Python implementation is slightly different.\n\n\"\"\"\n\n# begin[licence]\n#\n# [The \"BSD licence\"]\n# Copyright (c) 2005-2008 Terence Parr\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. The name of the author may not be used to endorse or promote products\n#    derived from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n# NOT 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 OF\n# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#\n# end[licence]\n\nfrom antlr3.constants import INVALID_TOKEN_TYPE\nfrom antlr3.tokens import CommonToken\nfrom antlr3.tree import CommonTree, CommonTreeAdaptor\n\n\ndef computeTokenTypes(tokenNames):\n    \"\"\"\n    Compute a dict that is an inverted index of\n    tokenNames (which maps int token types to names).\n    \"\"\"\n\n    if tokenNames is None:\n        return {}\n\n    return dict((name, type) for type, name in enumerate(tokenNames))\n\n\n## token types for pattern parser\nEOF = -1\nBEGIN = 1\nEND = 2\nID = 3\nARG = 4\nPERCENT = 5\nCOLON = 6\nDOT = 7\n\nclass TreePatternLexer(object):\n    def __init__(self, pattern):\n        ## The tree pattern to lex like \"(A B C)\"\n        self.pattern = pattern\n\n\t## Index into input string\n        self.p = -1\n\n\t## Current char\n        self.c = None\n\n\t## How long is the pattern in char?\n        self.n = len(pattern)\n\n\t## Set when token type is ID or ARG\n        self.sval = None\n\n        self.error = False\n\n        self.consume()\n\n\n    __idStartChar = frozenset(\n        'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_'\n        )\n    __idChar = __idStartChar | frozenset('0123456789')\n    \n    def nextToken(self):\n        self.sval = \"\"\n        while self.c != EOF:\n            if self.c in (' ', '\\n', '\\r', '\\t'):\n                self.consume()\n                continue\n\n            if self.c in self.__idStartChar:\n                self.sval += self.c\n                self.consume()\n                while self.c in self.__idChar:\n                    self.sval += self.c\n                    self.consume()\n\n                return ID\n\n            if self.c == '(':\n                self.consume()\n                return BEGIN\n\n            if self.c == ')':\n                self.consume()\n                return END\n\n            if self.c == '%':\n                self.consume()\n                return PERCENT\n\n            if self.c == ':':\n                self.consume()\n                return COLON\n\n            if self.c == '.':\n                self.consume()\n                return DOT\n\n            if self.c == '[': # grab [x] as a string, returning x\n                self.consume()\n                while self.c != ']':\n                    if self.c == '\\\\':\n                        self.consume()\n                        if self.c != ']':\n                            self.sval += '\\\\'\n\n                        self.sval += self.c\n\n                    else:\n                        self.sval += self.c\n\n                    self.consume()\n\n                self.consume()\n                return ARG\n\n            self.consume()\n            self.error = True\n            return EOF\n\n        return EOF\n\n\n    def consume(self):\n        self.p += 1\n        if self.p >= self.n:\n            self.c = EOF\n\n        else:\n            self.c = self.pattern[self.p]\n\n\nclass TreePatternParser(object):\n    def __init__(self, tokenizer, wizard, adaptor):\n        self.tokenizer = tokenizer\n        self.wizard = wizard\n        self.adaptor = adaptor\n        self.ttype = tokenizer.nextToken() # kickstart\n\n\n    def pattern(self):\n        if self.ttype == BEGIN:\n            return self.parseTree()\n\n        elif self.ttype == ID:\n            node = self.parseNode()\n            if self.ttype == EOF:\n                return node\n\n            return None # extra junk on end\n\n        return None\n\n\n    def parseTree(self):\n        if self.ttype != BEGIN:\n            return None\n\n        self.ttype = self.tokenizer.nextToken()\n        root = self.parseNode()\n        if root is None:\n            return None\n\n        while self.ttype in (BEGIN, ID, PERCENT, DOT):\n            if self.ttype == BEGIN:\n                subtree = self.parseTree()\n                self.adaptor.addChild(root, subtree)\n\n            else:\n                child = self.parseNode()\n                if child is None:\n                    return None\n\n                self.adaptor.addChild(root, child)\n\n        if self.ttype != END:\n            return None\n\n        self.ttype = self.tokenizer.nextToken()\n        return root\n\n\n    def parseNode(self):\n        # \"%label:\" prefix\n        label = None\n        \n        if self.ttype == PERCENT:\n            self.ttype = self.tokenizer.nextToken()\n            if self.ttype != ID:\n                return None\n\n            label = self.tokenizer.sval\n            self.ttype = self.tokenizer.nextToken()\n            if self.ttype != COLON:\n                return None\n            \n            self.ttype = self.tokenizer.nextToken() # move to ID following colon\n\n        # Wildcard?\n        if self.ttype == DOT:\n            self.ttype = self.tokenizer.nextToken()\n            wildcardPayload = CommonToken(0, \".\")\n            node = WildcardTreePattern(wildcardPayload)\n            if label is not None:\n                node.label = label\n            return node\n\n        # \"ID\" or \"ID[arg]\"\n        if self.ttype != ID:\n            return None\n\n        tokenName = self.tokenizer.sval\n        self.ttype = self.tokenizer.nextToken()\n        \n        if tokenName == \"nil\":\n            return self.adaptor.nil()\n\n        text = tokenName\n        # check for arg\n        arg = None\n        if self.ttype == ARG:\n            arg = self.tokenizer.sval\n            text = arg\n            self.ttype = self.tokenizer.nextToken()\n\n        # create node\n        treeNodeType = self.wizard.getTokenType(tokenName)\n        if treeNodeType == INVALID_TOKEN_TYPE:\n            return None\n\n        node = self.adaptor.createFromType(treeNodeType, text)\n        if label is not None and isinstance(node, TreePattern):\n            node.label = label\n\n        if arg is not None and isinstance(node, TreePattern):\n            node.hasTextArg = True\n\n        return node\n\n\nclass TreePattern(CommonTree):\n    \"\"\"\n    When using %label:TOKENNAME in a tree for parse(), we must\n    track the label.\n    \"\"\"\n\n    def __init__(self, payload):\n        CommonTree.__init__(self, payload)\n\n        self.label = None\n        self.hasTextArg = None\n        \n\n    def toString(self):\n        if self.label is not None:\n            return '%' + self.label + ':' + CommonTree.toString(self)\n        \n        else:\n            return CommonTree.toString(self)\n\n\nclass WildcardTreePattern(TreePattern):\n    pass\n\n\nclass TreePatternTreeAdaptor(CommonTreeAdaptor):\n    \"\"\"This adaptor creates TreePattern objects for use during scan()\"\"\"\n\n    def createWithPayload(self, payload):\n        return TreePattern(payload)\n\n\nclass TreeWizard(object):\n    \"\"\"\n    Build and navigate trees with this object.  Must know about the names\n    of tokens so you have to pass in a map or array of token names (from which\n    this class can build the map).  I.e., Token DECL means nothing unless the\n    class can translate it to a token type.\n\n    In order to create nodes and navigate, this class needs a TreeAdaptor.\n\n    This class can build a token type -> node index for repeated use or for\n    iterating over the various nodes with a particular type.\n\n    This class works in conjunction with the TreeAdaptor rather than moving\n    all this functionality into the adaptor.  An adaptor helps build and\n    navigate trees using methods.  This class helps you do it with string\n    patterns like \"(A B C)\".  You can create a tree from that pattern or\n    match subtrees against it.\n    \"\"\"\n\n    def __init__(self, adaptor=None, tokenNames=None, typeMap=None):\n        self.adaptor = adaptor\n        if typeMap is None:\n            self.tokenNameToTypeMap = computeTokenTypes(tokenNames)\n\n        else:\n            if tokenNames is not None:\n                raise ValueError(\"Can't have both tokenNames and typeMap\")\n\n            self.tokenNameToTypeMap = typeMap\n\n\n    def getTokenType(self, tokenName):\n        \"\"\"Using the map of token names to token types, return the type.\"\"\"\n\n        try:\n            return self.tokenNameToTypeMap[tokenName]\n        except KeyError:\n            return INVALID_TOKEN_TYPE\n\n\n    def create(self, pattern):\n        \"\"\"\n        Create a tree or node from the indicated tree pattern that closely\n        follows ANTLR tree grammar tree element syntax:\n        \n        (root child1 ... child2).\n        \n        You can also just pass in a node: ID\n         \n        Any node can have a text argument: ID[foo]\n        (notice there are no quotes around foo--it's clear it's a string).\n        \n        nil is a special name meaning \"give me a nil node\".  Useful for\n        making lists: (nil A B C) is a list of A B C.\n        \"\"\"\n        \n        tokenizer = TreePatternLexer(pattern)\n        parser = TreePatternParser(tokenizer, self, self.adaptor)\n        return parser.pattern()\n\n\n    def index(self, tree):\n        \"\"\"Walk the entire tree and make a node name to nodes mapping.\n        \n        For now, use recursion but later nonrecursive version may be\n        more efficient.  Returns a dict int -> list where the list is\n        of your AST node type.  The int is the token type of the node.\n        \"\"\"\n\n        m = {}\n        self._index(tree, m)\n        return m\n\n\n    def _index(self, t, m):\n        \"\"\"Do the work for index\"\"\"\n\n        if t is None:\n            return\n\n        ttype = self.adaptor.getType(t)\n        elements = m.get(ttype)\n        if elements is None:\n            m[ttype] = elements = []\n\n        elements.append(t)\n        for i in range(self.adaptor.getChildCount(t)):\n            child = self.adaptor.getChild(t, i)\n            self._index(child, m)\n\n\n    def find(self, tree, what):\n        \"\"\"Return a list of matching token.\n\n        what may either be an integer specifzing the token type to find or\n        a string with a pattern that must be matched.\n        \n        \"\"\"\n        \n        if isinstance(what, (int, long)):\n            return self._findTokenType(tree, what)\n\n        elif isinstance(what, basestring):\n            return self._findPattern(tree, what)\n\n        else:\n            raise TypeError(\"'what' must be string or integer\")\n\n\n    def _findTokenType(self, t, ttype):\n        \"\"\"Return a List of tree nodes with token type ttype\"\"\"\n\n        nodes = []\n\n        def visitor(tree, parent, childIndex, labels):\n            nodes.append(tree)\n\n        self.visit(t, ttype, visitor)\n\n        return nodes\n\n\n    def _findPattern(self, t, pattern):\n        \"\"\"Return a List of subtrees matching pattern.\"\"\"\n        \n        subtrees = []\n        \n        # Create a TreePattern from the pattern\n        tokenizer = TreePatternLexer(pattern)\n        parser = TreePatternParser(tokenizer, self, TreePatternTreeAdaptor())\n        tpattern = parser.pattern()\n        \n        # don't allow invalid patterns\n        if (tpattern is None or tpattern.isNil()\n            or isinstance(tpattern, WildcardTreePattern)):\n            return None\n\n        rootTokenType = tpattern.getType()\n\n        def visitor(tree, parent, childIndex, label):\n            if self._parse(tree, tpattern, None):\n                subtrees.append(tree)\n                \n        self.visit(t, rootTokenType, visitor)\n\n        return subtrees\n\n\n    def visit(self, tree, what, visitor):\n        \"\"\"Visit every node in tree matching what, invoking the visitor.\n\n        If what is a string, it is parsed as a pattern and only matching\n        subtrees will be visited.\n        The implementation uses the root node of the pattern in combination\n        with visit(t, ttype, visitor) so nil-rooted patterns are not allowed.\n        Patterns with wildcard roots are also not allowed.\n\n        If what is an integer, it is used as a token type and visit will match\n        all nodes of that type (this is faster than the pattern match).\n        The labels arg of the visitor action method is never set (it's None)\n        since using a token type rather than a pattern doesn't let us set a\n        label.\n        \"\"\"\n\n        if isinstance(what, (int, long)):\n            self._visitType(tree, None, 0, what, visitor)\n\n        elif isinstance(what, basestring):\n            self._visitPattern(tree, what, visitor)\n\n        else:\n            raise TypeError(\"'what' must be string or integer\")\n        \n              \n    def _visitType(self, t, parent, childIndex, ttype, visitor):\n        \"\"\"Do the recursive work for visit\"\"\"\n        \n        if t is None:\n            return\n\n        if self.adaptor.getType(t) == ttype:\n            visitor(t, parent, childIndex, None)\n\n        for i in range(self.adaptor.getChildCount(t)):\n            child = self.adaptor.getChild(t, i)\n            self._visitType(child, t, i, ttype, visitor)\n\n\n    def _visitPattern(self, tree, pattern, visitor):\n        \"\"\"\n        For all subtrees that match the pattern, execute the visit action.\n        \"\"\"\n\n        # Create a TreePattern from the pattern\n        tokenizer = TreePatternLexer(pattern)\n        parser = TreePatternParser(tokenizer, self, TreePatternTreeAdaptor())\n        tpattern = parser.pattern()\n        \n        # don't allow invalid patterns\n        if (tpattern is None or tpattern.isNil()\n            or isinstance(tpattern, WildcardTreePattern)):\n            return\n\n        rootTokenType = tpattern.getType()\n\n        def rootvisitor(tree, parent, childIndex, labels):\n            labels = {}\n            if self._parse(tree, tpattern, labels):\n                visitor(tree, parent, childIndex, labels)\n                \n        self.visit(tree, rootTokenType, rootvisitor)\n        \n\n    def parse(self, t, pattern, labels=None):\n        \"\"\"\n        Given a pattern like (ASSIGN %lhs:ID %rhs:.) with optional labels\n        on the various nodes and '.' (dot) as the node/subtree wildcard,\n        return true if the pattern matches and fill the labels Map with\n        the labels pointing at the appropriate nodes.  Return false if\n        the pattern is malformed or the tree does not match.\n\n        If a node specifies a text arg in pattern, then that must match\n        for that node in t.\n        \"\"\"\n\n        tokenizer = TreePatternLexer(pattern)\n        parser = TreePatternParser(tokenizer, self, TreePatternTreeAdaptor())\n        tpattern = parser.pattern()\n\n        return self._parse(t, tpattern, labels)\n\n\n    def _parse(self, t1, t2, labels):\n        \"\"\"\n        Do the work for parse. Check to see if the t2 pattern fits the\n        structure and token types in t1.  Check text if the pattern has\n        text arguments on nodes.  Fill labels map with pointers to nodes\n        in tree matched against nodes in pattern with labels.\n\t\"\"\"\n        \n        # make sure both are non-null\n        if t1 is None or t2 is None:\n            return False\n\n        # check roots (wildcard matches anything)\n        if not isinstance(t2, WildcardTreePattern):\n            if self.adaptor.getType(t1) != t2.getType():\n                return False\n\n            if t2.hasTextArg and self.adaptor.getText(t1) != t2.getText():\n                return False\n\n        if t2.label is not None and labels is not None:\n            # map label in pattern to node in t1\n            labels[t2.label] = t1\n\n        # check children\n        n1 = self.adaptor.getChildCount(t1)\n        n2 = t2.getChildCount()\n        if n1 != n2:\n            return False\n\n        for i in range(n1):\n            child1 = self.adaptor.getChild(t1, i)\n            child2 = t2.getChild(i)\n            if not self._parse(child1, child2, labels):\n                return False\n\n        return True\n\n\n    def equals(self, t1, t2, adaptor=None):\n        \"\"\"\n        Compare t1 and t2; return true if token types/text, structure match\n        exactly.\n        The trees are examined in their entirety so that (A B) does not match\n        (A B C) nor (A (B C)). \n        \"\"\"\n\n        if adaptor is None:\n            adaptor = self.adaptor\n\n        return self._equals(t1, t2, adaptor)\n\n\n    def _equals(self, t1, t2, adaptor):\n        # make sure both are non-null\n        if t1 is None or t2 is None:\n            return False\n\n        # check roots\n        if adaptor.getType(t1) != adaptor.getType(t2):\n            return False\n\n        if adaptor.getText(t1) != adaptor.getText(t2):\n            return False\n        \n        # check children\n        n1 = adaptor.getChildCount(t1)\n        n2 = adaptor.getChildCount(t2)\n        if n1 != n2:\n            return False\n\n        for i in range(n1):\n            child1 = adaptor.getChild(t1, i)\n            child2 = adaptor.getChild(t2, i)\n            if not self._equals(child1, child2, adaptor):\n                return False\n\n        return True\n"
  },
  {
    "path": "deps/cpy/cpy",
    "content": "#!/bin/sh\n\nDIR=`dirname $0`\n\nwhich python2.7 > /dev/null 2>&1\n[ $? -eq 0 ] && { python2.7 $DIR/cpy.py $@; exit $?;}\nwhich python2 > /dev/null 2>&1\n[ $? -eq 0 ] && { python2 $DIR/cpy.py $@; exit $?;}\n\npython $DIR/cpy.py $@\nexit $?\n"
  },
  {
    "path": "deps/cpy/cpy.bat",
    "content": "\n@echo off\npython %~dp0cpy.py %1 %2 %3 %4 %5 %6 %7 %8 %9\n"
  },
  {
    "path": "deps/cpy/cpy.py",
    "content": "# encoding=utf-8\r\n#################################\r\n# Author: ideawu\r\n# Link: http://www.ideawu.net/\r\n#################################\r\n\r\nimport sys, os\r\nimport signal\r\ndef __sigint__(n, f):\r\n\tsys.exit(0)\r\nsignal.signal(signal.SIGINT, __sigint__);\r\n\r\ndef usage():\r\n\tprint ('Cpy - A C-like scripting language.')\r\n\tprint ('Copyright (c) 2012 ideawu.com')\r\n\tprint ('')\r\n\tprint ('Usage:')\r\n\tprint ('    cpy source_file')\r\n\r\n# 不然管道时报错\r\nreload(sys)\r\nsys.setdefaultencoding('utf-8')\r\n\r\nfrom engine import CpyEngine\r\ncpy = CpyEngine()\r\n\r\nif len(sys.argv) < 2:\r\n\tusage()\r\n\tsys.exit(0)\r\n\r\nis_compile = False;\r\nif sys.argv[1] == '-c':\r\n\tis_compile = True\r\n\tif len(sys.argv) >= 3:\r\n\t\tsrcfile = sys.argv[2]\r\n\telse:\r\n\t\tusage()\r\n\t\tsys.exit(0)\r\nelse:\r\n\tsrcfile = sys.argv[1]\r\n\r\nif not srcfile.endswith('.cpy'):\r\n\tsrcfile += '.cpy'\r\nif not os.path.exists(srcfile):\r\n\tprint (\"File not found!: \" + srcfile)\r\n\tsys.exit(0)\r\n\r\nbase_dir, tail = os.path.split(srcfile)\r\nif len(base_dir) == 0:\r\n\tbase_dir = '.'\r\n\r\ndstfile = cpy.compile(srcfile, base_dir, base_dir + '/_cpy_')\r\n\r\n#print ('-----')\r\n#print (''.join(open(dstfile, 'r').readlines()))\r\n#print ('-----')\r\n\r\ndstfile = os.path.abspath(dstfile)\r\nsys.path.append(os.path.dirname(os.path.abspath(srcfile)));\r\nsys.path.append(os.path.dirname(os.path.abspath(dstfile)));\r\n\r\nos.chdir(os.path.dirname(os.path.abspath(srcfile)));\r\n#print os.getcwd();\r\n\r\nif not is_compile:\r\n\tsys.argv = sys.argv[1 :]\r\n\tsys.path.insert(0, os.path.dirname(dstfile))\r\n\ttry:\r\n\t\texecfile(dstfile)\r\n\texcept Exception:\r\n\t\timport traceback\r\n\t\tsys.stderr.write(traceback.format_exc())\r\n\t\tpass\r\n"
  },
  {
    "path": "deps/cpy/engine.py",
    "content": "# encoding=utf-8\n#################################\n# Author: ideawu\n# Link: http://www.ideawu.net/\n#################################\n\nimport sys, os, shutil, datetime\nimport antlr3\nimport antlr3.tree\nfrom ExprLexer import ExprLexer\nfrom ExprParser import ExprParser\n\nclass CpyEngine:\n\tfound_files = set()\n\n\tdef find_imports(self, srcfile, base_dir):\n\t\t#print '  file', srcfile\n\t\tsrcfile = os.path.realpath(srcfile)\n\t\tif srcfile in self.found_files:\n\t\t\treturn set()\n\t\tself.found_files.add(srcfile)\n\t\t\n\t\tfp = open(srcfile, 'rt')\n\t\tlines = fp.readlines()\n\t\tfp.close()\n\n\t\timports = []\n\t\tfor line in lines:\n\t\t\tif line.find('import') == -1:\n\t\t\t\tcontinue\n\t\t\tline = line.strip().strip(';');\n\t\t\tps = line.split();\n\t\t\tif ps[0] != 'import':\n\t\t\t\tcontinue\n\t\t\tfor p in ps[ 1 :]:\n\t\t\t\tp = p.strip(',')\n\t\t\t\timports.append(p);\n\n\t\tfor p in imports:\n\t\t\t#print 'import ' + p\n\t\t\tself.find_files(p, base_dir);\n\t\treturn self.found_files\n\n\tdef find_files(self, member, base_dir):\n\t\tps = member.split('.')\n\t\tlast = ps.pop(-1)\n\t\tpath = base_dir + '/' + '/'.join(ps)\n\t\tif last == '*':\n\t\t\tif os.path.isdir(path):\n\t\t\t\tfs = os.listdir(path)\n\t\t\t\tfor f in fs:\n\t\t\t\t\tif f.endswith('.cpy'):\n\t\t\t\t\t\tfile = os.path.realpath(path + '/' + f)\n\t\t\t\t\t\tself.find_imports(file, path)\n\t\telse:\n\t\t\tfile = path + '/' + last + '.cpy'\n\t\t\tif os.path.isfile(file):\n\t\t\t\tself.find_imports(file, path)\n\t\t\n\tdef compile(self, srcfile, base_dir, output_dir):\n\t\tsrcfile = os.path.realpath(srcfile)\n\t\tbase_dir = os.path.realpath(base_dir)\n\t\toutput_dir = os.path.realpath(output_dir)\n\n\t\t# files = self.find_imports(srcfile, base_dir)\n\t\t# files.remove(srcfile)\n\t\t# if len(files) > 0:\n\t\t# \tfiles = list(files)\n\t\t# \tfiles.sort()\n\t\t# \t#print '  ' + '\\n  '.join(files)\n\t\t#\n\t\t# shead, stail = os.path.split(srcfile)\n\t\t# slen = len(shead)\n\t\t# for f in files:\n\t\t# \thead, tail = os.path.split(f)\n\t\t# \trel_dir = head[slen :]\n\t\t# \tself._compile(f, base_dir, output_dir + rel_dir)\n\n\t\tdstfile = self._compile(srcfile, base_dir, output_dir)\n\t\treturn dstfile\n\t\t\t\t\n\tdef _compile(self, srcfile, base_dir, output_dir):\n\t\thead, tail = os.path.split(srcfile)\n\n\t\tdstfile = os.path.normpath(output_dir + '/' + tail.split('.')[0] + '.py')\n\t\tif os.path.exists(dstfile):\n\t\t\tsrc_mtime = os.path.getmtime(srcfile)\n\t\t\tdst_mtime = os.path.getmtime(dstfile)\n\t\t\t#print src_mtime, dst_mtime\n\t\t\tif src_mtime < dst_mtime:\n\t\t\t\treturn dstfile\n\t\t#print 'compile: %-30s=> %s' % (srcfile, dstfile)\n\t\t#print 'compile: %-30s=> %s' % (srcfile[len(base_dir)+1:], dstfile[len(base_dir)+1:])\n\n\t\tif not os.path.exists(output_dir):\n\t\t\tos.makedirs(output_dir)\n\t\tif not os.path.exists(output_dir + '/__init__.py'):\n\t\t\tfp = open(output_dir + '/__init__.py', 'w')\n\t\t\tfp.close()\n\n\t\t#fp = codecs.open(sys.argv[1], 'r', 'utf-8')\n\t\tfp = open(srcfile, 'r')\n\t\tchar_stream = antlr3.ANTLRInputStream(fp)\n\t\tlexer = ExprLexer(char_stream)\n\t\ttokens = antlr3.CommonTokenStream(lexer)\n\n\t\tparser = ExprParser(tokens)\n\t\tr = parser.prog()\n\n\t\t# this is the root of the AST\n\t\troot = r.tree\n\t\t#print (root.toStringTree())\n\t\t#print '-------'\n\n\t\tnodes = antlr3.tree.CommonTreeNodeStream(root)\n\t\tnodes.setTokenStream(tokens)\n\t\tfrom Eval import Eval\n\t\teval = Eval(nodes)\n\n\t\t#######################################\n\n\t\tcpy = CpyBuilder(dstfile, base_dir, output_dir)\n\t\teval.prog(cpy)\n\t\treturn dstfile\n\n\nclass CpyBuilder:\n\tcompiled_files = set()\n\n\tdef __init__(self, dstfile, base_dir, output_dir):\n\t\tself.vars = -1\n\t\tself.if_depth = 0\n\t\tself.block_depth = 0\n\t\tself.switch_expr_stack = []\n\t\tself.switch_continue_stack = []\n\t\tself.class_stack = []\n\t\tself.class_names = [];\n\t\tself.constructed = False;\n\n\t\tself.base_dir = base_dir\n\t\tself.output_dir = output_dir\n\n\t\tself.fp = open(dstfile, 'w')\n\n\t\tself.write('# encoding=utf-8\\n')\n\t\tself.write('# Generated by cpy\\n');\n\t\tself.write('# ' + datetime.datetime.now().isoformat(' ') + '\\n');\n\t\tself.write('import os, sys\\n')\n\t\tself.write('from sys import stdin, stdout\\n\\n')\n\n\tdef tmp_var(self, name = ''):\n\t\tself.vars += 1\n\t\treturn '_cpy_%s_%d' %(name, self.vars)\n\n\tdef close(self):\n\t\tself.fp.close()\n\n\tdef write(self, text):\n\t\ttext = text.encode('utf-8')\n\t\tself.fp.write(text)\n\t\t# debug\n\t\t#sys.stdout.write(text)\n\n\tdef indent(self):\n\t\treturn '\\t' * self.block_depth\n\n\tdef _compile_dir(self, rel_path):\n\t\tmods = []\n\t\tfiles = os.listdir(self.base_dir + '/' + rel_path)\n\t\tfor f in files:\n\t\t\tif f.endswith('.cpy'):\n\t\t\t\tmods.append(f[0: -4])\n\t\t\tif f.endswith('.py'):\n\t\t\t\tmods.append(f[0: -3])\n\t\t\tself._compile(rel_path, f)\n\t\treturn mods\n\n\tdef _compile(self, rel_path, f):\n\t\tbase_dir = os.path.normpath(self.base_dir + '/' + rel_path)\n\t\tsrcfile = os.path.normpath(base_dir + '/' + f)\n\t\toutput_dir = os.path.normpath(self.output_dir + '/' + rel_path)\n\t\t#print base_dir, output_dir, f, rel_path;\n\n\t\tif f.endswith('.py'):\n\t\t\thead, tail = os.path.split(f)\n\t\t\t#print 'copy:    %-30s=> %s' % (srcfile, output_dir + '/' + tail)\n\t\t\tshutil.copy(srcfile, output_dir + '/' + tail)\n\t\telif f.endswith('.cpy'):\n\t\t\tself.write('#### start cpy import ###\\n');\n\t\t\tself.write(self.indent())\n\t\t\tself.write('from engine import CpyEngine\\n')\n\t\t\tself.write(self.indent())\n\t\t\tself.write('cpy = CpyEngine()\\n')\n\t\t\tself.write(self.indent())\n\t\t\tself.write('dstfile = cpy.compile(\\'' + srcfile + '\\', \\'' + rel_path + '\\', \\'' + output_dir + '\\')\\n')\n\t\t\tself.write('#### end cpy import ###\\n');\n\n\t\t\tif srcfile in self.compiled_files:\n\t\t\t\treturn\n\t\t\tself.compiled_files.add(srcfile)\n\t\t\t#e = CpyEngine()\n\t\t\t#d = e.compile(srcfile, base_dir, output_dir)\n\n\tdef op_import(self, member, all):\n\t\tps = member.split('.')\n\t\tpackage = []\n\t\twhile True:\n\t\t\tif len(ps) == 0:\n\t\t\t\tbreak\n\t\t\tp = ps.pop(0)\n\t\t\tpackage.append(p)\n\t\t\trel_path = '/'.join(package);\n\t\t\tpath = self.base_dir + '/' + rel_path\n\t\t\tif os.path.isdir(path):\n\t\t\t\tif len(ps) == 0:\n\t\t\t\t\tmods = self._compile_dir(rel_path)\n\t\t\t\t\tif all == '*':\n\t\t\t\t\t\tfor m in mods:\n\t\t\t\t\t\t\tself.write(self.indent())\n\t\t\t\t\t\t\tself.write('from %s import %s\\n' %(member, m))\n\t\t\t\t\telse:\n\t\t\t\t\t\tself.write(self.indent())\n\t\t\t\t\t\tself.write('import %s\\n' % member)\n\t\t\t\t\tbreak\n\t\t\telif os.path.isfile(path + '.cpy') or os.path.isfile(path + '.py'):\n\t\t\t\tfilename = os.path.basename(path)\n\t\t\t\trel_path = '/'.join(package[ : -1]);\n\t\t\t\tif os.path.isfile(path + '.cpy'):\n\t\t\t\t\tself._compile(rel_path, filename + '.cpy')\n\t\t\t\telse:\n\t\t\t\t\tself._compile(rel_path, filename + '.py')\n\t\t\t\tif len(ps) == 0:\n\t\t\t\t\tif all == '*':\n\t\t\t\t\t\tself.write(self.indent())\n\t\t\t\t\t\tself.write('from %s import *\\n' % member)\n\t\t\t\t\telse:\n\t\t\t\t\t\tself.write(self.indent())\n\t\t\t\t\t\tself.write('import %s\\n' % member)\n\t\t\t\t\tbreak\n\t\t\t\telif len(ps) == 1:\n\t\t\t\t\tmod = '.'.join(package)\n\t\t\t\t\tcls = ps[-1]\n\t\t\t\t\tself.write(self.indent())\n\t\t\t\t\tself.write('from %s import %s\\n' %(mod, cls))\n\t\t\t\telse:\n\t\t\t\t\t# error\n\t\t\t\t\tprint (\"Cpy error: invalid module '%s'\" % member)\n\t\t\t\t\tsys.exit(0)\n\t\t\t\tbreak\n\t\t\telse:\n\t\t\t\tself.write(self.indent())\n\t\t\t\tif all == '*':\n\t\t\t\t\tself.write('from %s import *\\n' % member)\n\t\t\t\telse:\n\t\t\t\t\tps = member.split('.')\n\t\t\t\t\tif len(ps) == 1:\n\t\t\t\t\t\tself.write('import %s\\n' % member)\n\t\t\t\t\telse:\n\t\t\t\t\t\tself.write('from %s import %s\\n' %('.'.join(ps[0 : -1]), ps[-1]))\n\t\t\t\tbreak\n\n\tdef block_enter(self):\n\t\tself.block_depth += 1\n\t\tself.write(self.indent() + 'pass\\n')\n\n\tdef block_leave(self):\n\t\tself.block_depth -= 1\n\n\tdef if_enter(self):\n\t\tself.write('\\n')\n\t\tself.write(self.indent())\n\t\tself.if_depth += 1\n\n\tdef if_leave(self):\n\t\tself.if_depth -= 1\n\n\tdef op_if(self, expr):\n\t\tself.write('if %s:\\n' % expr)\n\n\tdef op_else(self):\n\t\tself.write(self.indent() + 'else:\\n')\n\n\tdef op_else_if(self):\n\t\tself.write(self.indent() + 'el')\n\n\tdef stmt(self, text):\n\t\tself.write(self.indent() + text + '\\n')\n\n\tdef op_assign(self, id, val, op):\n\t\ttext = '%s %s %s' % (id, op, val)\n\t\treturn text\n\n\tdef op_inc(self, id):\n\t\treturn id + ' += 1';\n\n\tdef op_dec(self, id):\n\t\treturn id + ' -= 1';\n\n\tdef op_call(self, text):\n\t\tself.write(self.indent() + text + '\\n')\n\n\tdef op_print(self, text):\n\t\tself.write(self.indent())\n\t\tself.write('print %s\\n' % text)\n\n\tdef op_printf(self, format, text):\n\t\tself.write(self.indent())\n\t\tif text == None:\n\t\t\tself.write('sys.stdout.write(%s)\\n' % (format))\n\t\telse:\n\t\t\tself.write('sys.stdout.write(%s %% (%s))\\n' % (format, text))\n\n\tdef op_while(self, expr):\n\t\tself.write('\\n')\n\t\tself.write(self.indent())\n\t\tself.write('while %s:\\n' % expr)\n\n\tdef op_do_while_enter(self):\n\t\tself.write('\\n')\n\t\tself.write(self.indent())\n\t\tself.write('while True:\\n')\n\n\tdef op_do_while_leave(self, expr):\n\t\tself.write('\\n')\n\t\tself.block_depth += 1\n\t\tself.write(self.indent())\n\t\tself.write('if %s:\\n' % expr)\n\t\tself.block_depth += 1\n\t\tself.write(self.indent())\n\t\tself.write('continue')\n\t\tself.block_depth -= 1\n\t\tself.write('\\n')\n\t\tself.write(self.indent())\n\t\tself.write('break')\n\t\tself.block_depth -= 1\n\n\tdef op_switch_enter(self, expr):\n\t\tself.write('\\n')\n\t\tself.switch_expr_stack.append(expr)\n\t\tvar = '_continue_%d' % len(self.switch_expr_stack)\n\t\tself.switch_continue_stack.append(var)\n\n\t\tself.write(self.indent() + '# {{{ switch: ' + expr + '\\n')\n\t\tself.write(self.indent())\n\t\tself.write(var + ' = False\\n')\n\t\tself.write(self.indent())\n\t\tself.write('while True:\\n')\n\t\tself.block_depth += 1\n\n\tdef op_switch_leave(self):\n\t\tself.write(self.indent() + 'break\\n')\n\t\tvar = self.switch_continue_stack[-1]\n\t\tself.write(self.indent())\n\t\tself.write('if %s:\\n' % var)\n\t\tself.block_depth += 1\n\t\tself.write(self.indent())\n\t\tself.write('continue\\n')\n\t\tself.block_depth -= 1\n\t\tself.block_depth -= 1\n\t\tself.write(self.indent() + '# }}} switch\\n\\n')\n\n\t\tself.switch_expr_stack.pop()\n\t\tself.switch_continue_stack.pop()\n\n\tdef op_case_enter(self):\n\t\tself.write(self.indent())\n\t\tself.write('if False')\n\t\tself.block_depth += 1\n\n\tdef op_case_test(self, expr):\n\t\tself.write(' or ((%s) == %s)' % (self.switch_expr_stack[-1], expr))\n\n\tdef op_case(self):\n\t\tself.write(':\\n')\n\t\tself.write(self.indent())\n\t\tself.write('pass\\n')\n\n\tdef op_case_leave(self):\n\t\tself.block_depth -= 1\n\n\tdef op_break(self):\n\t\tself.write(self.indent())\n\t\tself.write('break\\n')\n\n\tdef op_continue(self):\n\t\tif self.switch_expr_stack:\n\t\t\tvar = self.switch_continue_stack[-1]\n\t\t\tself.write(self.indent())\n\t\t\tself.write(var + ' = True\\n')\n\t\t\tself.write(self.indent())\n\t\t\tself.write('break\\n')\n\t\telse:\n\t\t\tself.write(self.indent())\n\t\t\tself.write('continue\\n')\n\n\tdef op_return(self, expr):\n\t\tself.write(self.indent())\n\t\tif expr == None: expr = ''\n\t\tself.write('return %s\\n' % expr)\n\n\n\tdef op_default_enter(self):\n\t\tself.write(self.indent() + '### default\\n')\n\n\tdef op_default_leave(self):\n\t\tpass\n\n\tdef op_function(self, id, params):\n\t\tself.write('\\n')\n\t\tif len(self.class_stack) > 0:\n\t\t\t# in class\n\t\t\tif params == None or params == '':\n\t\t\t\tparams = 'this'\n\t\t\telse:\n\t\t\t\tparams = 'this, ' + params\n\t\telse:\n\t\t\tif params == None:\n\t\t\t\tparams = ''\n\t\tself.write(self.indent() + 'def ' + id + '(' + params + '):\\n')\n\n\tdef op_foreach(self, expr, k, vals):\n\t\tself.write('\\n')\n\t\ttmp_var_ref = self.tmp_var('r')\n\t\ttmp_var_l = self.tmp_var('l')\n\t\ttmp_var_k = self.tmp_var('k')\n\t\ttmp_var_is_dict = self.tmp_var('b')\n\t\tself.write(self.indent())\n\t\tself.write('%s = %s = %s\\n' %(tmp_var_ref, tmp_var_l, expr))\n\n\t\tself.write(self.indent())\n\t\tself.write('if type(%s).__name__ == \\'dict\\': %s=True; %s=%s.iterkeys()\\n' %(tmp_var_ref, tmp_var_is_dict, tmp_var_l, tmp_var_ref))\n\t\tself.write(self.indent())\n\t\tself.write('else: %s=False;' %tmp_var_is_dict)\n\t\tif k != None:\n\t\t\tself.write('%s=-1' %k)\n\t\tself.write('\\n')\n\n\t\tself.write(self.indent())\n\t\tself.write('for %s in %s:\\n' %(tmp_var_k, tmp_var_l))\n\t\tif k == None:\n\t\t\tself.block_depth += 1\n\t\t\tself.write(self.indent())\n\t\t\tself.write('if %s: %s=%s[%s]\\n' %(tmp_var_is_dict, vals, tmp_var_ref, tmp_var_k))\n\t\t\tself.write(self.indent())\n\t\t\tself.write('else: %s=%s\\n' %(vals, tmp_var_k))\n\t\t\tself.block_depth -= 1\n\t\telse:\n\t\t\tself.block_depth += 1\n\t\t\tself.write(self.indent())\n\t\t\tself.write('if %s: %s=%s; %s=%s[%s]\\n' %(tmp_var_is_dict, k, tmp_var_k, vals, tmp_var_ref, tmp_var_k))\n\t\t\tself.write(self.indent())\n\t\t\tself.write('else: %s += 1; %s=%s\\n' %(k, vals, tmp_var_k))\n\t\t\tself.block_depth -= 1\n\n\tdef op_throw(self, expr):\n\t\tself.write(self.indent())\n\t\tself.write('raise %s\\n' % expr)\n\n\tdef op_try(self):\n\t\tself.write(self.indent())\n\t\tself.write('try:\\n')\n\n\tdef op_catch(self, type, var):\n\t\tself.write(self.indent())\n\t\tif var == None:\n\t\t\tself.write('except %s:\\n' % type)\n\t\telse:\n\t\t\tself.write('except %s , %s:\\n' %(type, var))\n\n\tdef op_finally(self):\n\t\tself.write(self.indent())\n\t\tself.write('finally:\\n')\n\n\tdef op_class_enter(self, name, parent):\n\t\tself.class_stack.append([])\n\t\tself.class_names.append(name)\n\t\tself.constructed = False;\n\t\tself.parent = parent;\n\n\t\tself.write(self.indent())\n\t\tif parent == None:\n\t\t\tself.write('class %s(object):\\n' % name)\n\t\telse:\n\t\t\tself.write('class %s(%s):\\n' % (name, parent))\n\t\tself.block_depth += 1\n\t\tself.write(self.indent())\n\t\tself.write('pass\\n')\n\n\tdef op_class_leave(self):\n\t\tif not self.constructed:\n\t\t\tself.op_construct('');\n\t\tself.class_stack.pop()\n\t\tself.class_names.pop()\n\t\tself.write('\\n')\n\t\tself.block_depth -= 1\n\n\tdef op_var_def(self, is_static, id, val):\n\t\tif is_static:\n\t\t\tself.write(self.indent())\n\t\t\tif val == None:\n\t\t\t\ts = '%s = None' % id\n\t\t\telse:\n\t\t\t\ts = '%s = %s' % (id, val)\n\t\t\tself.write(s)\n\t\telse:\n\t\t\tif val == None:\n\t\t\t\ts = 'this.%s = None' % id\n\t\t\telse:\n\t\t\t\ts = 'this.%s = %s' % (id, val)\n\t\t\tself.class_stack[-1].append(s)\n\n\tdef op_construct(self, params):\n\t\tself.constructed = True;\n\t\tself.write('\\n')\n\n\t\tself.op_function('__init__', params)\n\t\tself.block_depth += 1\n\t\tif self.parent and self.parent != 'object':\n\t\t\tself.write(self.indent())\n\t\t\tself.write('super(' + self.class_names[-1] + ', this).__init__(' + params + ')\\n')\n\t\tfor s in self.class_stack[-1]:\n\t\t\tself.write(self.indent())\n\t\t\tself.write(s + '\\n')\n\n\t\tself.block_depth -= 1\n"
  },
  {
    "path": "deps/cpy/samples/class.cpy",
    "content": "class A{\n\tpublic a = 0;\n\tpublic static s = 1;\n\n\tfunction init(a){\n\t\tthis.a = a;\n\t\tprint 'A init', a;\n\t}\n\n\tfunction f(a, b=1){\n\t\treturn a + b;\n\t}\n}\n\nprint A.s; // 1\na = new A(1); // A init 1\nprint a.f(1, 2);\n"
  },
  {
    "path": "deps/cpy/samples/extends.cpy",
    "content": "class A{\n\tfunction f(){\n\t\tprint 'A.f';\n\t}\n}\nclass B extends A{\n\tfunction g(){\n\t\tprint \"B.g\";\n\t}\n}\n\nb = new B();\nb.f();\nb.g();\n"
  },
  {
    "path": "deps/cpy/samples/foreach.cpy",
    "content": "\narr = [10, 11, 12];\nforeach(arr as k=>v){\n\tprint k, v;\n}\n\n# output: #\n\nd = {\n\t'a': 1,\n\t'b': 2,\n\t'c': 3,\n\t};\n\nforeach(d as k=>v){\n\tprint k, v;\n}\n"
  },
  {
    "path": "deps/cpy/samples/function.cpy",
    "content": "\nfunction f(a, b=1){\n\treturn a + b;\n}\n\nprint f(1);\nprint f(1, 2);\n\n"
  },
  {
    "path": "deps/cpy/samples/hello.cpy",
    "content": "\nprintf(\"Hello World!\\n\");\n"
  },
  {
    "path": "deps/cpy/samples/list.cpy",
    "content": "a = []; // empty array\na.append(1);\na.append(2);\nprint a[0]; // output: 1\nprint a; // output: [1, 2]\n\na = [1, 2];\nprint a;\n"
  },
  {
    "path": "deps/cpy/samples/object.cpy",
    "content": "\na = {}; // empty dictionary\na['x'] = [1, 2];\na['y'] = [3, 4];\nforeach(a as k=>v1, v2){\n\tprintf('%s: %d, %d\\n', k, v1, v2);\n}\n\n"
  },
  {
    "path": "deps/cpy/samples/simple_client.cpy",
    "content": ""
  },
  {
    "path": "deps/cpy/samples/simple_server.cpy",
    "content": ""
  },
  {
    "path": "deps/cpy/samples/stdin.cpy",
    "content": "\n\nprint \"input 'q' to quit:\";\n\nwhile(true){\n\tprintf(\"> \");\n\tline = stdin.readline();\n\tline = line.strip().lower();\n\tif(line == 'q'){\n\t\tprint \"bye.\";\n\t\tbreak;\n\t}else{\n\t\tprint 'your input:', repr(line);\n\t}\n}\n"
  },
  {
    "path": "deps/cpy/samples/test.cpy",
    "content": "a = {}; // empty dictionary\na['x'] = 1;\na['y'] = 2;\nforeach(a as k,v){\n\tprint k, v;\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/.autom4te.cfg",
    "content": "begin-language: \"Autoconf-without-aclocal-m4\"\nargs: --no-cache\nend-language: \"Autoconf-without-aclocal-m4\"\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/.gitattributes",
    "content": "* text=auto eol=lf\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/.gitignore",
    "content": "/*.gcov.*\n\n/bin/jemalloc-config\n/bin/jemalloc.sh\n/bin/jeprof\n\n/config.stamp\n/config.log\n/config.status\n/configure\n\n/doc/html.xsl\n/doc/manpages.xsl\n/doc/jemalloc.xml\n/doc/jemalloc.html\n/doc/jemalloc.3\n\n/jemalloc.pc\n\n/lib/\n\n/Makefile\n\n/include/jemalloc/internal/jemalloc_internal.h\n/include/jemalloc/internal/jemalloc_internal_defs.h\n/include/jemalloc/internal/private_namespace.h\n/include/jemalloc/internal/private_unnamespace.h\n/include/jemalloc/internal/public_namespace.h\n/include/jemalloc/internal/public_symbols.txt\n/include/jemalloc/internal/public_unnamespace.h\n/include/jemalloc/internal/size_classes.h\n/include/jemalloc/jemalloc.h\n/include/jemalloc/jemalloc_defs.h\n/include/jemalloc/jemalloc_macros.h\n/include/jemalloc/jemalloc_mangle.h\n/include/jemalloc/jemalloc_mangle_jet.h\n/include/jemalloc/jemalloc_protos.h\n/include/jemalloc/jemalloc_protos_jet.h\n/include/jemalloc/jemalloc_rename.h\n/include/jemalloc/jemalloc_typedefs.h\n\n/src/*.[od]\n/src/*.gcda\n/src/*.gcno\n\n/test/test.sh\ntest/include/test/jemalloc_test.h\ntest/include/test/jemalloc_test_defs.h\n\n/test/integration/[A-Za-z]*\n!/test/integration/[A-Za-z]*.*\n/test/integration/*.[od]\n/test/integration/*.gcda\n/test/integration/*.gcno\n/test/integration/*.out\n\n/test/src/*.[od]\n/test/src/*.gcda\n/test/src/*.gcno\n\n/test/stress/[A-Za-z]*\n!/test/stress/[A-Za-z]*.*\n/test/stress/*.[od]\n/test/stress/*.gcda\n/test/stress/*.gcno\n/test/stress/*.out\n\n/test/unit/[A-Za-z]*\n!/test/unit/[A-Za-z]*.*\n/test/unit/*.[od]\n/test/unit/*.gcda\n/test/unit/*.gcno\n/test/unit/*.out\n\n/VERSION\n\n*.pdb\n*.sdf\n*.opendb\n*.opensdf\n*.cachefile\n*.suo\n*.user\n*.sln.docstates\n*.tmp\n/msvc/Win32/\n/msvc/x64/\n/msvc/projects/*/*/Debug*/\n/msvc/projects/*/*/Release*/\n/msvc/projects/*/*/Win32/\n/msvc/projects/*/*/x64/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/COPYING",
    "content": "Unless otherwise specified, files in the jemalloc source distribution are\nsubject to the following license:\n--------------------------------------------------------------------------------\nCopyright (C) 2002-2015 Jason Evans <jasone@canonware.com>.\nAll rights reserved.\nCopyright (C) 2007-2012 Mozilla Foundation.  All rights reserved.\nCopyright (C) 2009-2015 Facebook, Inc.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n1. Redistributions of source code must retain the above copyright notice(s),\n   this list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright notice(s),\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS\nOR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO\nEVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\nOR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\nADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n--------------------------------------------------------------------------------\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/ChangeLog",
    "content": "Following are change highlights associated with official releases.  Important\nbug fixes are all mentioned, but some internal enhancements are omitted here for\nbrevity.  Much more detail can be found in the git revision history:\n\n    https://github.com/jemalloc/jemalloc\n\n* 4.1.0 (February 28, 2016)\n\n  This release is primarily about optimizations, but it also incorporates a lot\n  of portability-motivated refactoring and enhancements.  Many people worked on\n  this release, to an extent that even with the omission here of minor changes\n  (see git revision history), and of the people who reported and diagnosed\n  issues, so much of the work was contributed that starting with this release,\n  changes are annotated with author credits to help reflect the collaborative\n  effort involved.\n\n  New features:\n  - Implement decay-based unused dirty page purging, a major optimization with\n    mallctl API impact.  This is an alternative to the existing ratio-based\n    unused dirty page purging, and is intended to eventually become the sole\n    purging mechanism.  New mallctls:\n    + opt.purge\n    + opt.decay_time\n    + arena.<i>.decay\n    + arena.<i>.decay_time\n    + arenas.decay_time\n    + stats.arenas.<i>.decay_time\n    (@jasone, @cevans87)\n  - Add --with-malloc-conf, which makes it possible to embed a default\n    options string during configuration.  This was motivated by the desire to\n    specify --with-malloc-conf=purge:decay , since the default must remain\n    purge:ratio until the 5.0.0 release.  (@jasone)\n  - Add MS Visual Studio 2015 support.  (@rustyx, @yuslepukhin)\n  - Make *allocx() size class overflow behavior defined.  The maximum\n    size class is now less than PTRDIFF_MAX to protect applications against\n    numerical overflow, and all allocation functions are guaranteed to indicate\n    errors rather than potentially crashing if the request size exceeds the\n    maximum size class.  (@jasone)\n  - jeprof:\n    + Add raw heap profile support.  (@jasone)\n    + Add --retain and --exclude for backtrace symbol filtering.  (@jasone)\n\n  Optimizations:\n  - Optimize the fast path to combine various bootstrapping and configuration\n    checks and execute more streamlined code in the common case.  (@interwq)\n  - Use linear scan for small bitmaps (used for small object tracking).  In\n    addition to speeding up bitmap operations on 64-bit systems, this reduces\n    allocator metadata overhead by approximately 0.2%.  (@djwatson)\n  - Separate arena_avail trees, which substantially speeds up run tree\n    operations.  (@djwatson)\n  - Use memoization (boot-time-computed table) for run quantization.  Separate\n    arena_avail trees reduced the importance of this optimization.  (@jasone)\n  - Attempt mmap-based in-place huge reallocation.  This can dramatically speed\n    up incremental huge reallocation.  (@jasone)\n\n  Incompatible changes:\n  - Make opt.narenas unsigned rather than size_t.  (@jasone)\n\n  Bug fixes:\n  - Fix stats.cactive accounting regression.  (@rustyx, @jasone)\n  - Handle unaligned keys in hash().  This caused problems for some ARM systems.\n    (@jasone, Christopher Ferris)\n  - Refactor arenas array.  In addition to fixing a fork-related deadlock, this\n    makes arena lookups faster and simpler.  (@jasone)\n  - Move retained memory allocation out of the default chunk allocation\n    function, to a location that gets executed even if the application installs\n    a custom chunk allocation function.  This resolves a virtual memory leak.\n    (@buchgr)\n  - Fix a potential tsd cleanup leak.  (Christopher Ferris, @jasone)\n  - Fix run quantization.  In practice this bug had no impact unless\n    applications requested memory with alignment exceeding one page.\n    (@jasone, @djwatson)\n  - Fix LinuxThreads-specific bootstrapping deadlock.  (Cosmin Paraschiv)\n  - jeprof:\n    + Don't discard curl options if timeout is not defined.  (@djwatson)\n    + Detect failed profile fetches.  (@djwatson)\n  - Fix stats.arenas.<i>.{dss,lg_dirty_mult,decay_time,pactive,pdirty} for\n    --disable-stats case.  (@jasone)\n\n* 4.0.4 (October 24, 2015)\n\n  This bugfix release fixes another xallocx() regression.  No other regressions\n  have come to light in over a month, so this is likely a good starting point\n  for people who prefer to wait for \"dot one\" releases with all the major issues\n  shaken out.\n\n  Bug fixes:\n  - Fix xallocx(..., MALLOCX_ZERO to zero the last full trailing page of large\n    allocations that have been randomly assigned an offset of 0 when\n    --enable-cache-oblivious configure option is enabled.\n\n* 4.0.3 (September 24, 2015)\n\n  This bugfix release continues the trend of xallocx() and heap profiling fixes.\n\n  Bug fixes:\n  - Fix xallocx(..., MALLOCX_ZERO) to zero all trailing bytes of large\n    allocations when --enable-cache-oblivious configure option is enabled.\n  - Fix xallocx(..., MALLOCX_ZERO) to zero trailing bytes of huge allocations\n    when resizing from/to a size class that is not a multiple of the chunk size.\n  - Fix prof_tctx_dump_iter() to filter out nodes that were created after heap\n    profile dumping started.\n  - Work around a potentially bad thread-specific data initialization\n    interaction with NPTL (glibc's pthreads implementation).\n\n* 4.0.2 (September 21, 2015)\n\n  This bugfix release addresses a few bugs specific to heap profiling.\n\n  Bug fixes:\n  - Fix ixallocx_prof_sample() to never modify nor create sampled small\n    allocations.  xallocx() is in general incapable of moving small allocations,\n    so this fix removes buggy code without loss of generality.\n  - Fix irallocx_prof_sample() to always allocate large regions, even when\n    alignment is non-zero.\n  - Fix prof_alloc_rollback() to read tdata from thread-specific data rather\n    than dereferencing a potentially invalid tctx.\n\n* 4.0.1 (September 15, 2015)\n\n  This is a bugfix release that is somewhat high risk due to the amount of\n  refactoring required to address deep xallocx() problems.  As a side effect of\n  these fixes, xallocx() now tries harder to partially fulfill requests for\n  optional extra space.  Note that a couple of minor heap profiling\n  optimizations are included, but these are better thought of as performance\n  fixes that were integral to disovering most of the other bugs.\n\n  Optimizations:\n  - Avoid a chunk metadata read in arena_prof_tctx_set(), since it is in the\n    fast path when heap profiling is enabled.  Additionally, split a special\n    case out into arena_prof_tctx_reset(), which also avoids chunk metadata\n    reads.\n  - Optimize irallocx_prof() to optimistically update the sampler state.  The\n    prior implementation appears to have been a holdover from when\n    rallocx()/xallocx() functionality was combined as rallocm().\n\n  Bug fixes:\n  - Fix TLS configuration such that it is enabled by default for platforms on\n    which it works correctly.\n  - Fix arenas_cache_cleanup() and arena_get_hard() to handle\n    allocation/deallocation within the application's thread-specific data\n    cleanup functions even after arenas_cache is torn down.\n  - Fix xallocx() bugs related to size+extra exceeding HUGE_MAXCLASS.\n  - Fix chunk purge hook calls for in-place huge shrinking reallocation to\n    specify the old chunk size rather than the new chunk size.  This bug caused\n    no correctness issues for the default chunk purge function, but was\n    visible to custom functions set via the \"arena.<i>.chunk_hooks\" mallctl.\n  - Fix heap profiling bugs:\n    + Fix heap profiling to distinguish among otherwise identical sample sites\n      with interposed resets (triggered via the \"prof.reset\" mallctl).  This bug\n      could cause data structure corruption that would most likely result in a\n      segfault.\n    + Fix irealloc_prof() to prof_alloc_rollback() on OOM.\n    + Make one call to prof_active_get_unlocked() per allocation event, and use\n      the result throughout the relevant functions that handle an allocation\n      event.  Also add a missing check in prof_realloc().  These fixes protect\n      allocation events against concurrent prof_active changes.\n    + Fix ixallocx_prof() to pass usize_max and zero to ixallocx_prof_sample()\n      in the correct order.\n    + Fix prof_realloc() to call prof_free_sampled_object() after calling\n      prof_malloc_sample_object().  Prior to this fix, if tctx and old_tctx were\n      the same, the tctx could have been prematurely destroyed.\n  - Fix portability bugs:\n    + Don't bitshift by negative amounts when encoding/decoding run sizes in\n      chunk header maps.  This affected systems with page sizes greater than 8\n      KiB.\n    + Rename index_t to szind_t to avoid an existing type on Solaris.\n    + Add JEMALLOC_CXX_THROW to the memalign() function prototype, in order to\n      match glibc and avoid compilation errors when including both\n      jemalloc/jemalloc.h and malloc.h in C++ code.\n    + Don't assume that /bin/sh is appropriate when running size_classes.sh\n      during configuration.\n    + Consider __sparcv9 a synonym for __sparc64__ when defining LG_QUANTUM.\n    + Link tests to librt if it contains clock_gettime(2).\n\n* 4.0.0 (August 17, 2015)\n\n  This version contains many speed and space optimizations, both minor and\n  major.  The major themes are generalization, unification, and simplification.\n  Although many of these optimizations cause no visible behavior change, their\n  cumulative effect is substantial.\n\n  New features:\n  - Normalize size class spacing to be consistent across the complete size\n    range.  By default there are four size classes per size doubling, but this\n    is now configurable via the --with-lg-size-class-group option.  Also add the\n    --with-lg-page, --with-lg-page-sizes, --with-lg-quantum, and\n    --with-lg-tiny-min options, which can be used to tweak page and size class\n    settings.  Impacts:\n    + Worst case performance for incrementally growing/shrinking reallocation\n      is improved because there are far fewer size classes, and therefore\n      copying happens less often.\n    + Internal fragmentation is limited to 20% for all but the smallest size\n      classes (those less than four times the quantum).  (1B + 4 KiB)\n      and (1B + 4 MiB) previously suffered nearly 50% internal fragmentation.\n    + Chunk fragmentation tends to be lower because there are fewer distinct run\n      sizes to pack.\n  - Add support for explicit tcaches.  The \"tcache.create\", \"tcache.flush\", and\n    \"tcache.destroy\" mallctls control tcache lifetime and flushing, and the\n    MALLOCX_TCACHE(tc) and MALLOCX_TCACHE_NONE flags to the *allocx() API\n    control which tcache is used for each operation.\n  - Implement per thread heap profiling, as well as the ability to\n    enable/disable heap profiling on a per thread basis.  Add the \"prof.reset\",\n    \"prof.lg_sample\", \"thread.prof.name\", \"thread.prof.active\",\n    \"opt.prof_thread_active_init\", \"prof.thread_active_init\", and\n    \"thread.prof.active\" mallctls.\n  - Add support for per arena application-specified chunk allocators, configured\n    via the \"arena.<i>.chunk_hooks\" mallctl.\n  - Refactor huge allocation to be managed by arenas, so that arenas now\n    function as general purpose independent allocators.  This is important in\n    the context of user-specified chunk allocators, aside from the scalability\n    benefits.  Related new statistics:\n    + The \"stats.arenas.<i>.huge.allocated\", \"stats.arenas.<i>.huge.nmalloc\",\n      \"stats.arenas.<i>.huge.ndalloc\", and \"stats.arenas.<i>.huge.nrequests\"\n      mallctls provide high level per arena huge allocation statistics.\n    + The \"arenas.nhchunks\", \"arenas.hchunk.<i>.size\",\n      \"stats.arenas.<i>.hchunks.<j>.nmalloc\",\n      \"stats.arenas.<i>.hchunks.<j>.ndalloc\",\n      \"stats.arenas.<i>.hchunks.<j>.nrequests\", and\n      \"stats.arenas.<i>.hchunks.<j>.curhchunks\" mallctls provide per size class\n      statistics.\n  - Add the 'util' column to malloc_stats_print() output, which reports the\n    proportion of available regions that are currently in use for each small\n    size class.\n  - Add \"alloc\" and \"free\" modes for for junk filling (see the \"opt.junk\"\n    mallctl), so that it is possible to separately enable junk filling for\n    allocation versus deallocation.\n  - Add the jemalloc-config script, which provides information about how\n    jemalloc was configured, and how to integrate it into application builds.\n  - Add metadata statistics, which are accessible via the \"stats.metadata\",\n    \"stats.arenas.<i>.metadata.mapped\", and\n    \"stats.arenas.<i>.metadata.allocated\" mallctls.\n  - Add the \"stats.resident\" mallctl, which reports the upper limit of\n    physically resident memory mapped by the allocator.\n  - Add per arena control over unused dirty page purging, via the\n    \"arenas.lg_dirty_mult\", \"arena.<i>.lg_dirty_mult\", and\n    \"stats.arenas.<i>.lg_dirty_mult\" mallctls.\n  - Add the \"prof.gdump\" mallctl, which makes it possible to toggle the gdump\n    feature on/off during program execution.\n  - Add sdallocx(), which implements sized deallocation.  The primary\n    optimization over dallocx() is the removal of a metadata read, which often\n    suffers an L1 cache miss.\n  - Add missing header includes in jemalloc/jemalloc.h, so that applications\n    only have to #include <jemalloc/jemalloc.h>.\n  - Add support for additional platforms:\n    + Bitrig\n    + Cygwin\n    + DragonFlyBSD\n    + iOS\n    + OpenBSD\n    + OpenRISC/or1k\n\n  Optimizations:\n  - Maintain dirty runs in per arena LRUs rather than in per arena trees of\n    dirty-run-containing chunks.  In practice this change significantly reduces\n    dirty page purging volume.\n  - Integrate whole chunks into the unused dirty page purging machinery.  This\n    reduces the cost of repeated huge allocation/deallocation, because it\n    effectively introduces a cache of chunks.\n  - Split the arena chunk map into two separate arrays, in order to increase\n    cache locality for the frequently accessed bits.\n  - Move small run metadata out of runs, into arena chunk headers.  This reduces\n    run fragmentation, smaller runs reduce external fragmentation for small size\n    classes, and packed (less uniformly aligned) metadata layout improves CPU\n    cache set distribution.\n  - Randomly distribute large allocation base pointer alignment relative to page\n    boundaries in order to more uniformly utilize CPU cache sets.  This can be\n    disabled via the --disable-cache-oblivious configure option, and queried via\n    the \"config.cache_oblivious\" mallctl.\n  - Micro-optimize the fast paths for the public API functions.\n  - Refactor thread-specific data to reside in a single structure.  This assures\n    that only a single TLS read is necessary per call into the public API.\n  - Implement in-place huge allocation growing and shrinking.\n  - Refactor rtree (radix tree for chunk lookups) to be lock-free, and make\n    additional optimizations that reduce maximum lookup depth to one or two\n    levels.  This resolves what was a concurrency bottleneck for per arena huge\n    allocation, because a global data structure is critical for determining\n    which arenas own which huge allocations.\n\n  Incompatible changes:\n  - Replace --enable-cc-silence with --disable-cc-silence to suppress spurious\n    warnings by default.\n  - Assure that the constness of malloc_usable_size()'s return type matches that\n    of the system implementation.\n  - Change the heap profile dump format to support per thread heap profiling,\n    rename pprof to jeprof, and enhance it with the --thread=<n> option.  As a\n    result, the bundled jeprof must now be used rather than the upstream\n    (gperftools) pprof.\n  - Disable \"opt.prof_final\" by default, in order to avoid atexit(3), which can\n    internally deadlock on some platforms.\n  - Change the \"arenas.nlruns\" mallctl type from size_t to unsigned.\n  - Replace the \"stats.arenas.<i>.bins.<j>.allocated\" mallctl with\n    \"stats.arenas.<i>.bins.<j>.curregs\".\n  - Ignore MALLOC_CONF in set{uid,gid,cap} binaries.\n  - Ignore MALLOCX_ARENA(a) in dallocx(), in favor of using the\n    MALLOCX_TCACHE(tc) and MALLOCX_TCACHE_NONE flags to control tcache usage.\n\n  Removed features:\n  - Remove the *allocm() API, which is superseded by the *allocx() API.\n  - Remove the --enable-dss options, and make dss non-optional on all platforms\n    which support sbrk(2).\n  - Remove the \"arenas.purge\" mallctl, which was obsoleted by the\n    \"arena.<i>.purge\" mallctl in 3.1.0.\n  - Remove the unnecessary \"opt.valgrind\" mallctl; jemalloc automatically\n    detects whether it is running inside Valgrind.\n  - Remove the \"stats.huge.allocated\", \"stats.huge.nmalloc\", and\n    \"stats.huge.ndalloc\" mallctls.\n  - Remove the --enable-mremap option.\n  - Remove the \"stats.chunks.current\", \"stats.chunks.total\", and\n    \"stats.chunks.high\" mallctls.\n\n  Bug fixes:\n  - Fix the cactive statistic to decrease (rather than increase) when active\n    memory decreases.  This regression was first released in 3.5.0.\n  - Fix OOM handling in memalign() and valloc().  A variant of this bug existed\n    in all releases since 2.0.0, which introduced these functions.\n  - Fix an OOM-related regression in arena_tcache_fill_small(), which could\n    cause cache corruption on OOM.  This regression was present in all releases\n    from 2.2.0 through 3.6.0.\n  - Fix size class overflow handling for malloc(), posix_memalign(), memalign(),\n    calloc(), and realloc() when profiling is enabled.\n  - Fix the \"arena.<i>.dss\" mallctl to return an error if \"primary\" or\n    \"secondary\" precedence is specified, but sbrk(2) is not supported.\n  - Fix fallback lg_floor() implementations to handle extremely large inputs.\n  - Ensure the default purgeable zone is after the default zone on OS X.\n  - Fix latent bugs in atomic_*().\n  - Fix the \"arena.<i>.dss\" mallctl to handle read-only calls.\n  - Fix tls_model configuration to enable the initial-exec model when possible.\n  - Mark malloc_conf as a weak symbol so that the application can override it.\n  - Correctly detect glibc's adaptive pthread mutexes.\n  - Fix the --without-export configure option.\n\n* 3.6.0 (March 31, 2014)\n\n  This version contains a critical bug fix for a regression present in 3.5.0 and\n  3.5.1.\n\n  Bug fixes:\n  - Fix a regression in arena_chunk_alloc() that caused crashes during\n    small/large allocation if chunk allocation failed.  In the absence of this\n    bug, chunk allocation failure would result in allocation failure, e.g.  NULL\n    return from malloc().  This regression was introduced in 3.5.0.\n  - Fix backtracing for gcc intrinsics-based backtracing by specifying\n    -fno-omit-frame-pointer to gcc.  Note that the application (and all the\n    libraries it links to) must also be compiled with this option for\n    backtracing to be reliable.\n  - Use dss allocation precedence for huge allocations as well as small/large\n    allocations.\n  - Fix test assertion failure message formatting.  This bug did not manifest on\n    x86_64 systems because of implementation subtleties in va_list.\n  - Fix inconsequential test failures for hash and SFMT code.\n\n  New features:\n  - Support heap profiling on FreeBSD.  This feature depends on the proc\n    filesystem being mounted during heap profile dumping.\n\n* 3.5.1 (February 25, 2014)\n\n  This version primarily addresses minor bugs in test code.\n\n  Bug fixes:\n  - Configure Solaris/Illumos to use MADV_FREE.\n  - Fix junk filling for mremap(2)-based huge reallocation.  This is only\n    relevant if configuring with the --enable-mremap option specified.\n  - Avoid compilation failure if 'restrict' C99 keyword is not supported by the\n    compiler.\n  - Add a configure test for SSE2 rather than assuming it is usable on i686\n    systems.  This fixes test compilation errors, especially on 32-bit Linux\n    systems.\n  - Fix mallctl argument size mismatches (size_t vs. uint64_t) in the stats unit\n    test.\n  - Fix/remove flawed alignment-related overflow tests.\n  - Prevent compiler optimizations that could change backtraces in the\n    prof_accum unit test.\n\n* 3.5.0 (January 22, 2014)\n\n  This version focuses on refactoring and automated testing, though it also\n  includes some non-trivial heap profiling optimizations not mentioned below.\n\n  New features:\n  - Add the *allocx() API, which is a successor to the experimental *allocm()\n    API.  The *allocx() functions are slightly simpler to use because they have\n    fewer parameters, they directly return the results of primary interest, and\n    mallocx()/rallocx() avoid the strict aliasing pitfall that\n    allocm()/rallocm() share with posix_memalign().  Note that *allocm() is\n    slated for removal in the next non-bugfix release.\n  - Add support for LinuxThreads.\n\n  Bug fixes:\n  - Unless heap profiling is enabled, disable floating point code and don't link\n    with libm.  This, in combination with e.g. EXTRA_CFLAGS=-mno-sse on x64\n    systems, makes it possible to completely disable floating point register\n    use.  Some versions of glibc neglect to save/restore caller-saved floating\n    point registers during dynamic lazy symbol loading, and the symbol loading\n    code uses whatever malloc the application happens to have linked/loaded\n    with, the result being potential floating point register corruption.\n  - Report ENOMEM rather than EINVAL if an OOM occurs during heap profiling\n    backtrace creation in imemalign().  This bug impacted posix_memalign() and\n    aligned_alloc().\n  - Fix a file descriptor leak in a prof_dump_maps() error path.\n  - Fix prof_dump() to close the dump file descriptor for all relevant error\n    paths.\n  - Fix rallocm() to use the arena specified by the ALLOCM_ARENA(s) flag for\n    allocation, not just deallocation.\n  - Fix a data race for large allocation stats counters.\n  - Fix a potential infinite loop during thread exit.  This bug occurred on\n    Solaris, and could affect other platforms with similar pthreads TSD\n    implementations.\n  - Don't junk-fill reallocations unless usable size changes.  This fixes a\n    violation of the *allocx()/*allocm() semantics.\n  - Fix growing large reallocation to junk fill new space.\n  - Fix huge deallocation to junk fill when munmap is disabled.\n  - Change the default private namespace prefix from empty to je_, and change\n    --with-private-namespace-prefix so that it prepends an additional prefix\n    rather than replacing je_.  This reduces the likelihood of applications\n    which statically link jemalloc experiencing symbol name collisions.\n  - Add missing private namespace mangling (relevant when\n    --with-private-namespace is specified).\n  - Add and use JEMALLOC_INLINE_C so that static inline functions are marked as\n    static even for debug builds.\n  - Add a missing mutex unlock in a malloc_init_hard() error path.  In practice\n    this error path is never executed.\n  - Fix numerous bugs in malloc_strotumax() error handling/reporting.  These\n    bugs had no impact except for malformed inputs.\n  - Fix numerous bugs in malloc_snprintf().  These bugs were not exercised by\n    existing calls, so they had no impact.\n\n* 3.4.1 (October 20, 2013)\n\n  Bug fixes:\n  - Fix a race in the \"arenas.extend\" mallctl that could cause memory corruption\n    of internal data structures and subsequent crashes.\n  - Fix Valgrind integration flaws that caused Valgrind warnings about reads of\n    uninitialized memory in:\n    + arena chunk headers\n    + internal zero-initialized data structures (relevant to tcache and prof\n      code)\n  - Preserve errno during the first allocation.  A readlink(2) call during\n    initialization fails unless /etc/malloc.conf exists, so errno was typically\n    set during the first allocation prior to this fix.\n  - Fix compilation warnings reported by gcc 4.8.1.\n\n* 3.4.0 (June 2, 2013)\n\n  This version is essentially a small bugfix release, but the addition of\n  aarch64 support requires that the minor version be incremented.\n\n  Bug fixes:\n  - Fix race-triggered deadlocks in chunk_record().  These deadlocks were\n    typically triggered by multiple threads concurrently deallocating huge\n    objects.\n\n  New features:\n  - Add support for the aarch64 architecture.\n\n* 3.3.1 (March 6, 2013)\n\n  This version fixes bugs that are typically encountered only when utilizing\n  custom run-time options.\n\n  Bug fixes:\n  - Fix a locking order bug that could cause deadlock during fork if heap\n    profiling were enabled.\n  - Fix a chunk recycling bug that could cause the allocator to lose track of\n    whether a chunk was zeroed.  On FreeBSD, NetBSD, and OS X, it could cause\n    corruption if allocating via sbrk(2) (unlikely unless running with the\n    \"dss:primary\" option specified).  This was completely harmless on Linux\n    unless using mlockall(2) (and unlikely even then, unless the\n    --disable-munmap configure option or the \"dss:primary\" option was\n    specified).  This regression was introduced in 3.1.0 by the\n    mlockall(2)/madvise(2) interaction fix.\n  - Fix TLS-related memory corruption that could occur during thread exit if the\n    thread never allocated memory.  Only the quarantine and prof facilities were\n    susceptible.\n  - Fix two quarantine bugs:\n    + Internal reallocation of the quarantined object array leaked the old\n      array.\n    + Reallocation failure for internal reallocation of the quarantined object\n      array (very unlikely) resulted in memory corruption.\n  - Fix Valgrind integration to annotate all internally allocated memory in a\n    way that keeps Valgrind happy about internal data structure access.\n  - Fix building for s390 systems.\n\n* 3.3.0 (January 23, 2013)\n\n  This version includes a few minor performance improvements in addition to the\n  listed new features and bug fixes.\n\n  New features:\n  - Add clipping support to lg_chunk option processing.\n  - Add the --enable-ivsalloc option.\n  - Add the --without-export option.\n  - Add the --disable-zone-allocator option.\n\n  Bug fixes:\n  - Fix \"arenas.extend\" mallctl to output the number of arenas.\n  - Fix chunk_recycle() to unconditionally inform Valgrind that returned memory\n    is undefined.\n  - Fix build break on FreeBSD related to alloca.h.\n\n* 3.2.0 (November 9, 2012)\n\n  In addition to a couple of bug fixes, this version modifies page run\n  allocation and dirty page purging algorithms in order to better control\n  page-level virtual memory fragmentation.\n\n  Incompatible changes:\n  - Change the \"opt.lg_dirty_mult\" default from 5 to 3 (32:1 to 8:1).\n\n  Bug fixes:\n  - Fix dss/mmap allocation precedence code to use recyclable mmap memory only\n    after primary dss allocation fails.\n  - Fix deadlock in the \"arenas.purge\" mallctl.  This regression was introduced\n    in 3.1.0 by the addition of the \"arena.<i>.purge\" mallctl.\n\n* 3.1.0 (October 16, 2012)\n\n  New features:\n  - Auto-detect whether running inside Valgrind, thus removing the need to\n    manually specify MALLOC_CONF=valgrind:true.\n  - Add the \"arenas.extend\" mallctl, which allows applications to create\n    manually managed arenas.\n  - Add the ALLOCM_ARENA() flag for {,r,d}allocm().\n  - Add the \"opt.dss\", \"arena.<i>.dss\", and \"stats.arenas.<i>.dss\" mallctls,\n    which provide control over dss/mmap precedence.\n  - Add the \"arena.<i>.purge\" mallctl, which obsoletes \"arenas.purge\".\n  - Define LG_QUANTUM for hppa.\n\n  Incompatible changes:\n  - Disable tcache by default if running inside Valgrind, in order to avoid\n    making unallocated objects appear reachable to Valgrind.\n  - Drop const from malloc_usable_size() argument on Linux.\n\n  Bug fixes:\n  - Fix heap profiling crash if sampled object is freed via realloc(p, 0).\n  - Remove const from __*_hook variable declarations, so that glibc can modify\n    them during process forking.\n  - Fix mlockall(2)/madvise(2) interaction.\n  - Fix fork(2)-related deadlocks.\n  - Fix error return value for \"thread.tcache.enabled\" mallctl.\n\n* 3.0.0 (May 11, 2012)\n\n  Although this version adds some major new features, the primary focus is on\n  internal code cleanup that facilitates maintainability and portability, most\n  of which is not reflected in the ChangeLog.  This is the first release to\n  incorporate substantial contributions from numerous other developers, and the\n  result is a more broadly useful allocator (see the git revision history for\n  contribution details).  Note that the license has been unified, thanks to\n  Facebook granting a license under the same terms as the other copyright\n  holders (see COPYING).\n\n  New features:\n  - Implement Valgrind support, redzones, and quarantine.\n  - Add support for additional platforms:\n    + FreeBSD\n    + Mac OS X Lion\n    + MinGW\n    + Windows (no support yet for replacing the system malloc)\n  - Add support for additional architectures:\n    + MIPS\n    + SH4\n    + Tilera\n  - Add support for cross compiling.\n  - Add nallocm(), which rounds a request size up to the nearest size class\n    without actually allocating.\n  - Implement aligned_alloc() (blame C11).\n  - Add the \"thread.tcache.enabled\" mallctl.\n  - Add the \"opt.prof_final\" mallctl.\n  - Update pprof (from gperftools 2.0).\n  - Add the --with-mangling option.\n  - Add the --disable-experimental option.\n  - Add the --disable-munmap option, and make it the default on Linux.\n  - Add the --enable-mremap option, which disables use of mremap(2) by default.\n\n  Incompatible changes:\n  - Enable stats by default.\n  - Enable fill by default.\n  - Disable lazy locking by default.\n  - Rename the \"tcache.flush\" mallctl to \"thread.tcache.flush\".\n  - Rename the \"arenas.pagesize\" mallctl to \"arenas.page\".\n  - Change the \"opt.lg_prof_sample\" default from 0 to 19 (1 B to 512 KiB).\n  - Change the \"opt.prof_accum\" default from true to false.\n\n  Removed features:\n  - Remove the swap feature, including the \"config.swap\", \"swap.avail\",\n    \"swap.prezeroed\", \"swap.nfds\", and \"swap.fds\" mallctls.\n  - Remove highruns statistics, including the\n    \"stats.arenas.<i>.bins.<j>.highruns\" and\n    \"stats.arenas.<i>.lruns.<j>.highruns\" mallctls.\n  - As part of small size class refactoring, remove the \"opt.lg_[qc]space_max\",\n    \"arenas.cacheline\", \"arenas.subpage\", \"arenas.[tqcs]space_{min,max}\", and\n    \"arenas.[tqcs]bins\" mallctls.\n  - Remove the \"arenas.chunksize\" mallctl.\n  - Remove the \"opt.lg_prof_tcmax\" option.\n  - Remove the \"opt.lg_prof_bt_max\" option.\n  - Remove the \"opt.lg_tcache_gc_sweep\" option.\n  - Remove the --disable-tiny option, including the \"config.tiny\" mallctl.\n  - Remove the --enable-dynamic-page-shift configure option.\n  - Remove the --enable-sysv configure option.\n\n  Bug fixes:\n  - Fix a statistics-related bug in the \"thread.arena\" mallctl that could cause\n    invalid statistics and crashes.\n  - Work around TLS deallocation via free() on Linux.  This bug could cause\n    write-after-free memory corruption.\n  - Fix a potential deadlock that could occur during interval- and\n    growth-triggered heap profile dumps.\n  - Fix large calloc() zeroing bugs due to dropping chunk map unzeroed flags.\n  - Fix chunk_alloc_dss() to stop claiming memory is zeroed.  This bug could\n    cause memory corruption and crashes with --enable-dss specified.\n  - Fix fork-related bugs that could cause deadlock in children between fork\n    and exec.\n  - Fix malloc_stats_print() to honor 'b' and 'l' in the opts parameter.\n  - Fix realloc(p, 0) to act like free(p).\n  - Do not enforce minimum alignment in memalign().\n  - Check for NULL pointer in malloc_usable_size().\n  - Fix an off-by-one heap profile statistics bug that could be observed in\n    interval- and growth-triggered heap profiles.\n  - Fix the \"epoch\" mallctl to update cached stats even if the passed in epoch\n    is 0.\n  - Fix bin->runcur management to fix a layout policy bug.  This bug did not\n    affect correctness.\n  - Fix a bug in choose_arena_hard() that potentially caused more arenas to be\n    initialized than necessary.\n  - Add missing \"opt.lg_tcache_max\" mallctl implementation.\n  - Use glibc allocator hooks to make mixed allocator usage less likely.\n  - Fix build issues for --disable-tcache.\n  - Don't mangle pthread_create() when --with-private-namespace is specified.\n\n* 2.2.5 (November 14, 2011)\n\n  Bug fixes:\n  - Fix huge_ralloc() race when using mremap(2).  This is a serious bug that\n    could cause memory corruption and/or crashes.\n  - Fix huge_ralloc() to maintain chunk statistics.\n  - Fix malloc_stats_print(..., \"a\") output.\n\n* 2.2.4 (November 5, 2011)\n\n  Bug fixes:\n  - Initialize arenas_tsd before using it.  This bug existed for 2.2.[0-3], as\n    well as for --disable-tls builds in earlier releases.\n  - Do not assume a 4 KiB page size in test/rallocm.c.\n\n* 2.2.3 (August 31, 2011)\n\n  This version fixes numerous bugs related to heap profiling.\n\n  Bug fixes:\n  - Fix a prof-related race condition.  This bug could cause memory corruption,\n    but only occurred in non-default configurations (prof_accum:false).\n  - Fix off-by-one backtracing issues (make sure that prof_alloc_prep() is\n    excluded from backtraces).\n  - Fix a prof-related bug in realloc() (only triggered by OOM errors).\n  - Fix prof-related bugs in allocm() and rallocm().\n  - Fix prof_tdata_cleanup() for --disable-tls builds.\n  - Fix a relative include path, to fix objdir builds.\n\n* 2.2.2 (July 30, 2011)\n\n  Bug fixes:\n  - Fix a build error for --disable-tcache.\n  - Fix assertions in arena_purge() (for real this time).\n  - Add the --with-private-namespace option.  This is a workaround for symbol\n    conflicts that can inadvertently arise when using static libraries.\n\n* 2.2.1 (March 30, 2011)\n\n  Bug fixes:\n  - Implement atomic operations for x86/x64.  This fixes compilation failures\n    for versions of gcc that are still in wide use.\n  - Fix an assertion in arena_purge().\n\n* 2.2.0 (March 22, 2011)\n\n  This version incorporates several improvements to algorithms and data\n  structures that tend to reduce fragmentation and increase speed.\n\n  New features:\n  - Add the \"stats.cactive\" mallctl.\n  - Update pprof (from google-perftools 1.7).\n  - Improve backtracing-related configuration logic, and add the\n    --disable-prof-libgcc option.\n\n  Bug fixes:\n  - Change default symbol visibility from \"internal\", to \"hidden\", which\n    decreases the overhead of library-internal function calls.\n  - Fix symbol visibility so that it is also set on OS X.\n  - Fix a build dependency regression caused by the introduction of the .pic.o\n    suffix for PIC object files.\n  - Add missing checks for mutex initialization failures.\n  - Don't use libgcc-based backtracing except on x64, where it is known to work.\n  - Fix deadlocks on OS X that were due to memory allocation in\n    pthread_mutex_lock().\n  - Heap profiling-specific fixes:\n    + Fix memory corruption due to integer overflow in small region index\n      computation, when using a small enough sample interval that profiling\n      context pointers are stored in small run headers.\n    + Fix a bootstrap ordering bug that only occurred with TLS disabled.\n    + Fix a rallocm() rsize bug.\n    + Fix error detection bugs for aligned memory allocation.\n\n* 2.1.3 (March 14, 2011)\n\n  Bug fixes:\n  - Fix a cpp logic regression (due to the \"thread.{de,}allocatedp\" mallctl fix\n    for OS X in 2.1.2).\n  - Fix a \"thread.arena\" mallctl bug.\n  - Fix a thread cache stats merging bug.\n\n* 2.1.2 (March 2, 2011)\n\n  Bug fixes:\n  - Fix \"thread.{de,}allocatedp\" mallctl for OS X.\n  - Add missing jemalloc.a to build system.\n\n* 2.1.1 (January 31, 2011)\n\n  Bug fixes:\n  - Fix aligned huge reallocation (affected allocm()).\n  - Fix the ALLOCM_LG_ALIGN macro definition.\n  - Fix a heap dumping deadlock.\n  - Fix a \"thread.arena\" mallctl bug.\n\n* 2.1.0 (December 3, 2010)\n\n  This version incorporates some optimizations that can't quite be considered\n  bug fixes.\n\n  New features:\n  - Use Linux's mremap(2) for huge object reallocation when possible.\n  - Avoid locking in mallctl*() when possible.\n  - Add the \"thread.[de]allocatedp\" mallctl's.\n  - Convert the manual page source from roff to DocBook, and generate both roff\n    and HTML manuals.\n\n  Bug fixes:\n  - Fix a crash due to incorrect bootstrap ordering.  This only impacted\n    --enable-debug --enable-dss configurations.\n  - Fix a minor statistics bug for mallctl(\"swap.avail\", ...).\n\n* 2.0.1 (October 29, 2010)\n\n  Bug fixes:\n  - Fix a race condition in heap profiling that could cause undefined behavior\n    if \"opt.prof_accum\" were disabled.\n  - Add missing mutex unlocks for some OOM error paths in the heap profiling\n    code.\n  - Fix a compilation error for non-C99 builds.\n\n* 2.0.0 (October 24, 2010)\n\n  This version focuses on the experimental *allocm() API, and on improved\n  run-time configuration/introspection.  Nonetheless, numerous performance\n  improvements are also included.\n\n  New features:\n  - Implement the experimental {,r,s,d}allocm() API, which provides a superset\n    of the functionality available via malloc(), calloc(), posix_memalign(),\n    realloc(), malloc_usable_size(), and free().  These functions can be used to\n    allocate/reallocate aligned zeroed memory, ask for optional extra memory\n    during reallocation, prevent object movement during reallocation, etc.\n  - Replace JEMALLOC_OPTIONS/JEMALLOC_PROF_PREFIX with MALLOC_CONF, which is\n    more human-readable, and more flexible.  For example:\n      JEMALLOC_OPTIONS=AJP\n    is now:\n      MALLOC_CONF=abort:true,fill:true,stats_print:true\n  - Port to Apple OS X.  Sponsored by Mozilla.\n  - Make it possible for the application to control thread-->arena mappings via\n    the \"thread.arena\" mallctl.\n  - Add compile-time support for all TLS-related functionality via pthreads TSD.\n    This is mainly of interest for OS X, which does not support TLS, but has a\n    TSD implementation with similar performance.\n  - Override memalign() and valloc() if they are provided by the system.\n  - Add the \"arenas.purge\" mallctl, which can be used to synchronously purge all\n    dirty unused pages.\n  - Make cumulative heap profiling data optional, so that it is possible to\n    limit the amount of memory consumed by heap profiling data structures.\n  - Add per thread allocation counters that can be accessed via the\n    \"thread.allocated\" and \"thread.deallocated\" mallctls.\n\n  Incompatible changes:\n  - Remove JEMALLOC_OPTIONS and malloc_options (see MALLOC_CONF above).\n  - Increase default backtrace depth from 4 to 128 for heap profiling.\n  - Disable interval-based profile dumps by default.\n\n  Bug fixes:\n  - Remove bad assertions in fork handler functions.  These assertions could\n    cause aborts for some combinations of configure settings.\n  - Fix strerror_r() usage to deal with non-standard semantics in GNU libc.\n  - Fix leak context reporting.  This bug tended to cause the number of contexts\n    to be underreported (though the reported number of objects and bytes were\n    correct).\n  - Fix a realloc() bug for large in-place growing reallocation.  This bug could\n    cause memory corruption, but it was hard to trigger.\n  - Fix an allocation bug for small allocations that could be triggered if\n    multiple threads raced to create a new run of backing pages.\n  - Enhance the heap profiler to trigger samples based on usable size, rather\n    than request size.\n  - Fix a heap profiling bug due to sometimes losing track of requested object\n    size for sampled objects.\n\n* 1.0.3 (August 12, 2010)\n\n  Bug fixes:\n  - Fix the libunwind-based implementation of stack backtracing (used for heap\n    profiling).  This bug could cause zero-length backtraces to be reported.\n  - Add a missing mutex unlock in library initialization code.  If multiple\n    threads raced to initialize malloc, some of them could end up permanently\n    blocked.\n\n* 1.0.2 (May 11, 2010)\n\n  Bug fixes:\n  - Fix junk filling of large objects, which could cause memory corruption.\n  - Add MAP_NORESERVE support for chunk mapping, because otherwise virtual\n    memory limits could cause swap file configuration to fail.  Contributed by\n    Jordan DeLong.\n\n* 1.0.1 (April 14, 2010)\n\n  Bug fixes:\n  - Fix compilation when --enable-fill is specified.\n  - Fix threads-related profiling bugs that affected accuracy and caused memory\n    to be leaked during thread exit.\n  - Fix dirty page purging race conditions that could cause crashes.\n  - Fix crash in tcache flushing code during thread destruction.\n\n* 1.0.0 (April 11, 2010)\n\n  This release focuses on speed and run-time introspection.  Numerous\n  algorithmic improvements make this release substantially faster than its\n  predecessors.\n\n  New features:\n  - Implement autoconf-based configuration system.\n  - Add mallctl*(), for the purposes of introspection and run-time\n    configuration.\n  - Make it possible for the application to manually flush a thread's cache, via\n    the \"tcache.flush\" mallctl.\n  - Base maximum dirty page count on proportion of active memory.\n  - Compute various additional run-time statistics, including per size class\n    statistics for large objects.\n  - Expose malloc_stats_print(), which can be called repeatedly by the\n    application.\n  - Simplify the malloc_message() signature to only take one string argument,\n    and incorporate an opaque data pointer argument for use by the application\n    in combination with malloc_stats_print().\n  - Add support for allocation backed by one or more swap files, and allow the\n    application to disable over-commit if swap files are in use.\n  - Implement allocation profiling and leak checking.\n\n  Removed features:\n  - Remove the dynamic arena rebalancing code, since thread-specific caching\n    reduces its utility.\n\n  Bug fixes:\n  - Modify chunk allocation to work when address space layout randomization\n    (ASLR) is in use.\n  - Fix thread cleanup bugs related to TLS destruction.\n  - Handle 0-size allocation requests in posix_memalign().\n  - Fix a chunk leak.  The leaked chunks were never touched, so this impacted\n    virtual memory usage, but not physical memory usage.\n\n* linux_2008082[78]a (August 27/28, 2008)\n\n  These snapshot releases are the simple result of incorporating Linux-specific\n  support into the FreeBSD malloc sources.\n\n--------------------------------------------------------------------------------\nvim:filetype=text:textwidth=80\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/INSTALL",
    "content": "Building and installing a packaged release of jemalloc can be as simple as\ntyping the following while in the root directory of the source tree:\n\n    ./configure\n    make\n    make install\n\nIf building from unpackaged developer sources, the simplest command sequence\nthat might work is:\n\n    ./autogen.sh\n    make dist\n    make\n    make install\n\nNote that documentation is not built by the default target because doing so\nwould create a dependency on xsltproc in packaged releases, hence the\nrequirement to either run 'make dist' or avoid installing docs via the various\ninstall_* targets documented below.\n\n=== Advanced configuration =====================================================\n\nThe 'configure' script supports numerous options that allow control of which\nfunctionality is enabled, where jemalloc is installed, etc.  Optionally, pass\nany of the following arguments (not a definitive list) to 'configure':\n\n--help\n    Print a definitive list of options.\n\n--prefix=<install-root-dir>\n    Set the base directory in which to install.  For example:\n\n        ./configure --prefix=/usr/local\n\n    will cause files to be installed into /usr/local/include, /usr/local/lib,\n    and /usr/local/man.\n\n--with-rpath=<colon-separated-rpath>\n    Embed one or more library paths, so that libjemalloc can find the libraries\n    it is linked to.  This works only on ELF-based systems.\n\n--with-mangling=<map>\n    Mangle public symbols specified in <map> which is a comma-separated list of\n    name:mangled pairs.\n\n    For example, to use ld's --wrap option as an alternative method for\n    overriding libc's malloc implementation, specify something like:\n\n      --with-mangling=malloc:__wrap_malloc,free:__wrap_free[...]\n\n    Note that mangling happens prior to application of the prefix specified by\n    --with-jemalloc-prefix, and mangled symbols are then ignored when applying\n    the prefix.\n\n--with-jemalloc-prefix=<prefix>\n    Prefix all public APIs with <prefix>.  For example, if <prefix> is\n    \"prefix_\", API changes like the following occur:\n\n      malloc()         --> prefix_malloc()\n      malloc_conf      --> prefix_malloc_conf\n      /etc/malloc.conf --> /etc/prefix_malloc.conf\n      MALLOC_CONF      --> PREFIX_MALLOC_CONF\n\n    This makes it possible to use jemalloc at the same time as the system\n    allocator, or even to use multiple copies of jemalloc simultaneously.\n\n    By default, the prefix is \"\", except on OS X, where it is \"je_\".  On OS X,\n    jemalloc overlays the default malloc zone, but makes no attempt to actually\n    replace the \"malloc\", \"calloc\", etc. symbols.\n\n--without-export\n    Don't export public APIs.  This can be useful when building jemalloc as a\n    static library, or to avoid exporting public APIs when using the zone\n    allocator on OSX.\n\n--with-private-namespace=<prefix>\n    Prefix all library-private APIs with <prefix>je_.  For shared libraries,\n    symbol visibility mechanisms prevent these symbols from being exported, but\n    for static libraries, naming collisions are a real possibility.  By\n    default, <prefix> is empty, which results in a symbol prefix of je_ .\n\n--with-install-suffix=<suffix>\n    Append <suffix> to the base name of all installed files, such that multiple\n    versions of jemalloc can coexist in the same installation directory.  For\n    example, libjemalloc.so.0 becomes libjemalloc<suffix>.so.0.\n\n--with-malloc-conf=<malloc_conf>\n    Embed <malloc_conf> as a run-time options string that is processed prior to\n    the malloc_conf global variable, the /etc/malloc.conf symlink, and the\n    MALLOC_CONF environment variable.  For example, to change the default chunk\n    size to 256 KiB:\n\n      --with-malloc-conf=lg_chunk:18\n\n--disable-cc-silence\n    Disable code that silences non-useful compiler warnings.  This is mainly\n    useful during development when auditing the set of warnings that are being\n    silenced.\n\n--enable-debug\n    Enable assertions and validation code.  This incurs a substantial\n    performance hit, but is very useful during application development.\n    Implies --enable-ivsalloc.\n\n--enable-code-coverage\n    Enable code coverage support, for use during jemalloc test development.\n    Additional testing targets are available if this option is enabled:\n\n      coverage\n      coverage_unit\n      coverage_integration\n      coverage_stress\n\n    These targets do not clear code coverage results from previous runs, and\n    there are interactions between the various coverage targets, so it is\n    usually advisable to run 'make clean' between repeated code coverage runs.\n\n--disable-stats\n    Disable statistics gathering functionality.  See the \"opt.stats_print\"\n    option documentation for usage details.\n\n--enable-ivsalloc\n    Enable validation code, which verifies that pointers reside within\n    jemalloc-owned chunks before dereferencing them.  This incurs a minor\n    performance hit.\n\n--enable-prof\n    Enable heap profiling and leak detection functionality.  See the \"opt.prof\"\n    option documentation for usage details.  When enabled, there are several\n    approaches to backtracing, and the configure script chooses the first one\n    in the following list that appears to function correctly:\n\n    + libunwind      (requires --enable-prof-libunwind)\n    + libgcc         (unless --disable-prof-libgcc)\n    + gcc intrinsics (unless --disable-prof-gcc)\n\n--enable-prof-libunwind\n    Use the libunwind library (http://www.nongnu.org/libunwind/) for stack\n    backtracing.\n\n--disable-prof-libgcc\n    Disable the use of libgcc's backtracing functionality.\n\n--disable-prof-gcc\n    Disable the use of gcc intrinsics for backtracing.\n\n--with-static-libunwind=<libunwind.a>\n    Statically link against the specified libunwind.a rather than dynamically\n    linking with -lunwind.\n\n--disable-tcache\n    Disable thread-specific caches for small objects.  Objects are cached and\n    released in bulk, thus reducing the total number of mutex operations.  See\n    the \"opt.tcache\" option for usage details.\n\n--disable-munmap\n    Disable virtual memory deallocation via munmap(2); instead keep track of\n    the virtual memory for later use.  munmap() is disabled by default (i.e.\n    --disable-munmap is implied) on Linux, which has a quirk in its virtual\n    memory allocation algorithm that causes semi-permanent VM map holes under\n    normal jemalloc operation.\n\n--disable-fill\n    Disable support for junk/zero filling of memory, quarantine, and redzones.\n    See the \"opt.junk\", \"opt.zero\", \"opt.quarantine\", and \"opt.redzone\" option\n    documentation for usage details.\n\n--disable-valgrind\n    Disable support for Valgrind.\n\n--disable-zone-allocator\n    Disable zone allocator for Darwin.  This means jemalloc won't be hooked as\n    the default allocator on OSX/iOS.\n\n--enable-utrace\n    Enable utrace(2)-based allocation tracing.  This feature is not broadly\n    portable (FreeBSD has it, but Linux and OS X do not).\n\n--enable-xmalloc\n    Enable support for optional immediate termination due to out-of-memory\n    errors, as is commonly implemented by \"xmalloc\" wrapper function for malloc.\n    See the \"opt.xmalloc\" option documentation for usage details.\n\n--enable-lazy-lock\n    Enable code that wraps pthread_create() to detect when an application\n    switches from single-threaded to multi-threaded mode, so that it can avoid\n    mutex locking/unlocking operations while in single-threaded mode.  In\n    practice, this feature usually has little impact on performance unless\n    thread-specific caching is disabled.\n\n--disable-tls\n    Disable thread-local storage (TLS), which allows for fast access to\n    thread-local variables via the __thread keyword.  If TLS is available,\n    jemalloc uses it for several purposes.\n\n--disable-cache-oblivious\n    Disable cache-oblivious large allocation alignment for large allocation\n    requests with no alignment constraints.  If this feature is disabled, all\n    large allocations are page-aligned as an implementation artifact, which can\n    severely harm CPU cache utilization.  However, the cache-oblivious layout\n    comes at the cost of one extra page per large allocation, which in the\n    most extreme case increases physical memory usage for the 16 KiB size class\n    to 20 KiB.\n\n--with-xslroot=<path>\n    Specify where to find DocBook XSL stylesheets when building the\n    documentation.\n\n--with-lg-page=<lg-page>\n    Specify the base 2 log of the system page size.  This option is only useful\n    when cross compiling, since the configure script automatically determines\n    the host's page size by default.\n\n--with-lg-page-sizes=<lg-page-sizes>\n    Specify the comma-separated base 2 logs of the page sizes to support.  This\n    option may be useful when cross-compiling in combination with\n    --with-lg-page, but its primary use case is for integration with FreeBSD's\n    libc, wherein jemalloc is embedded.\n\n--with-lg-size-class-group=<lg-size-class-group>\n    Specify the base 2 log of how many size classes to use for each doubling in\n    size.  By default jemalloc uses <lg-size-class-group>=2, which results in\n    e.g. the following size classes:\n\n      [...], 64,\n      80, 96, 112, 128,\n      160, [...]\n\n    <lg-size-class-group>=3 results in e.g. the following size classes:\n\n      [...], 64,\n      72, 80, 88, 96, 104, 112, 120, 128,\n      144, [...]\n\n    The minimal <lg-size-class-group>=0 causes jemalloc to only provide size\n    classes that are powers of 2:\n\n      [...],\n      64,\n      128,\n      256,\n      [...]\n\n    An implementation detail currently limits the total number of small size\n    classes to 255, and a compilation error will result if the\n    <lg-size-class-group> you specify cannot be supported.  The limit is\n    roughly <lg-size-class-group>=4, depending on page size.\n\n--with-lg-quantum=<lg-quantum>\n    Specify the base 2 log of the minimum allocation alignment.  jemalloc needs\n    to know the minimum alignment that meets the following C standard\n    requirement (quoted from the April 12, 2011 draft of the C11 standard):\n\n      The pointer returned if the allocation succeeds is suitably aligned so\n      that it may be assigned to a pointer to any type of object with a\n      fundamental alignment requirement and then used to access such an object\n      or an array of such objects in the space allocated [...]\n\n    This setting is architecture-specific, and although jemalloc includes known\n    safe values for the most commonly used modern architectures, there is a\n    wrinkle related to GNU libc (glibc) that may impact your choice of\n    <lg-quantum>.  On most modern architectures, this mandates 16-byte alignment\n    (<lg-quantum>=4), but the glibc developers chose not to meet this\n    requirement for performance reasons.  An old discussion can be found at\n    https://sourceware.org/bugzilla/show_bug.cgi?id=206 .  Unlike glibc,\n    jemalloc does follow the C standard by default (caveat: jemalloc\n    technically cheats if --with-lg-tiny-min is smaller than\n    --with-lg-quantum), but the fact that Linux systems already work around\n    this allocator noncompliance means that it is generally safe in practice to\n    let jemalloc's minimum alignment follow glibc's lead.  If you specify\n    --with-lg-quantum=3 during configuration, jemalloc will provide additional\n    size classes that are not 16-byte-aligned (24, 40, and 56, assuming\n    --with-lg-size-class-group=2).\n\n--with-lg-tiny-min=<lg-tiny-min>\n    Specify the base 2 log of the minimum tiny size class to support.  Tiny\n    size classes are powers of 2 less than the quantum, and are only\n    incorporated if <lg-tiny-min> is less than <lg-quantum> (see\n    --with-lg-quantum).  Tiny size classes technically violate the C standard\n    requirement for minimum alignment, and crashes could conceivably result if\n    the compiler were to generate instructions that made alignment assumptions,\n    both because illegal instruction traps could result, and because accesses\n    could straddle page boundaries and cause segmentation faults due to\n    accessing unmapped addresses.\n\n    The default of <lg-tiny-min>=3 works well in practice even on architectures\n    that technically require 16-byte alignment, probably for the same reason\n    --with-lg-quantum=3 works.  Smaller tiny size classes can, and will, cause\n    crashes (see https://bugzilla.mozilla.org/show_bug.cgi?id=691003 for an\n    example).\n\n    This option is rarely useful, and is mainly provided as documentation of a\n    subtle implementation detail.  If you do use this option, specify a\n    value in [3, ..., <lg-quantum>].\n\nThe following environment variables (not a definitive list) impact configure's\nbehavior:\n\nCFLAGS=\"?\"\n    Pass these flags to the compiler.  You probably shouldn't define this unless\n    you know what you are doing.  (Use EXTRA_CFLAGS instead.)\n\nEXTRA_CFLAGS=\"?\"\n    Append these flags to CFLAGS.  This makes it possible to add flags such as\n    -Werror, while allowing the configure script to determine what other flags\n    are appropriate for the specified configuration.\n\n    The configure script specifically checks whether an optimization flag (-O*)\n    is specified in EXTRA_CFLAGS, and refrains from specifying an optimization\n    level if it finds that one has already been specified.\n\nCPPFLAGS=\"?\"\n    Pass these flags to the C preprocessor.  Note that CFLAGS is not passed to\n    'cpp' when 'configure' is looking for include files, so you must use\n    CPPFLAGS instead if you need to help 'configure' find header files.\n\nLD_LIBRARY_PATH=\"?\"\n    'ld' uses this colon-separated list to find libraries.\n\nLDFLAGS=\"?\"\n    Pass these flags when linking.\n\nPATH=\"?\"\n    'configure' uses this to find programs.\n\n=== Advanced compilation =======================================================\n\nTo build only parts of jemalloc, use the following targets:\n\n    build_lib_shared\n    build_lib_static\n    build_lib\n    build_doc_html\n    build_doc_man\n    build_doc\n\nTo install only parts of jemalloc, use the following targets:\n\n    install_bin\n    install_include\n    install_lib_shared\n    install_lib_static\n    install_lib\n    install_doc_html\n    install_doc_man\n    install_doc\n\nTo clean up build results to varying degrees, use the following make targets:\n\n    clean\n    distclean\n    relclean\n\n=== Advanced installation ======================================================\n\nOptionally, define make variables when invoking make, including (not\nexclusively):\n\nINCLUDEDIR=\"?\"\n    Use this as the installation prefix for header files.\n\nLIBDIR=\"?\"\n    Use this as the installation prefix for libraries.\n\nMANDIR=\"?\"\n    Use this as the installation prefix for man pages.\n\nDESTDIR=\"?\"\n    Prepend DESTDIR to INCLUDEDIR, LIBDIR, DATADIR, and MANDIR.  This is useful\n    when installing to a different path than was specified via --prefix.\n\nCC=\"?\"\n    Use this to invoke the C compiler.\n\nCFLAGS=\"?\"\n    Pass these flags to the compiler.\n\nCPPFLAGS=\"?\"\n    Pass these flags to the C preprocessor.\n\nLDFLAGS=\"?\"\n    Pass these flags when linking.\n\nPATH=\"?\"\n    Use this to search for programs used during configuration and building.\n\n=== Development ================================================================\n\nIf you intend to make non-trivial changes to jemalloc, use the 'autogen.sh'\nscript rather than 'configure'.  This re-generates 'configure', enables\nconfiguration dependency rules, and enables re-generation of automatically\ngenerated source files.\n\nThe build system supports using an object directory separate from the source\ntree.  For example, you can create an 'obj' directory, and from within that\ndirectory, issue configuration and build commands:\n\n    autoconf\n    mkdir obj\n    cd obj\n    ../configure --enable-autogen\n    make\n\n=== Documentation ==============================================================\n\nThe manual page is generated in both html and roff formats.  Any web browser\ncan be used to view the html manual.  The roff manual page can be formatted\nprior to installation via the following command:\n\n    nroff -man -t doc/jemalloc.3\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/Makefile.in",
    "content": "# Clear out all vpaths, then set just one (default vpath) for the main build\n# directory.\nvpath\nvpath % .\n\n# Clear the default suffixes, so that built-in rules are not used.\n.SUFFIXES :\n\nSHELL := /bin/sh\n\nCC := @CC@\n\n# Configuration parameters.\nDESTDIR =\nBINDIR := $(DESTDIR)@BINDIR@\nINCLUDEDIR := $(DESTDIR)@INCLUDEDIR@\nLIBDIR := $(DESTDIR)@LIBDIR@\nDATADIR := $(DESTDIR)@DATADIR@\nMANDIR := $(DESTDIR)@MANDIR@\nsrcroot := @srcroot@\nobjroot := @objroot@\nabs_srcroot := @abs_srcroot@\nabs_objroot := @abs_objroot@\n\n# Build parameters.\nCPPFLAGS := @CPPFLAGS@ -I$(srcroot)include -I$(objroot)include\nCFLAGS := @CFLAGS@\nLDFLAGS := @LDFLAGS@\nEXTRA_LDFLAGS := @EXTRA_LDFLAGS@\nLIBS := @LIBS@\nTESTLIBS := @TESTLIBS@\nRPATH_EXTRA := @RPATH_EXTRA@\nSO := @so@\nIMPORTLIB := @importlib@\nO := @o@\nA := @a@\nEXE := @exe@\nLIBPREFIX := @libprefix@\nREV := @rev@\ninstall_suffix := @install_suffix@\nABI := @abi@\nXSLTPROC := @XSLTPROC@\nAUTOCONF := @AUTOCONF@\n_RPATH = @RPATH@\nRPATH = $(if $(1),$(call _RPATH,$(1)))\ncfghdrs_in := $(addprefix $(srcroot),@cfghdrs_in@)\ncfghdrs_out := @cfghdrs_out@\ncfgoutputs_in := $(addprefix $(srcroot),@cfgoutputs_in@)\ncfgoutputs_out := @cfgoutputs_out@\nenable_autogen := @enable_autogen@\nenable_code_coverage := @enable_code_coverage@\nenable_prof := @enable_prof@\nenable_valgrind := @enable_valgrind@\nenable_zone_allocator := @enable_zone_allocator@\nMALLOC_CONF := @JEMALLOC_CPREFIX@MALLOC_CONF\nDSO_LDFLAGS = @DSO_LDFLAGS@\nSOREV = @SOREV@\nPIC_CFLAGS = @PIC_CFLAGS@\nCTARGET = @CTARGET@\nLDTARGET = @LDTARGET@\nMKLIB = @MKLIB@\nAR = @AR@\nARFLAGS = @ARFLAGS@\nCC_MM = @CC_MM@\n\nifeq (macho, $(ABI))\nTEST_LIBRARY_PATH := DYLD_FALLBACK_LIBRARY_PATH=\"$(objroot)lib\"\nelse\nifeq (pecoff, $(ABI))\nTEST_LIBRARY_PATH := PATH=\"$(PATH):$(objroot)lib\"\nelse\nTEST_LIBRARY_PATH :=\nendif\nendif\n\nLIBJEMALLOC := $(LIBPREFIX)jemalloc$(install_suffix)\n\n# Lists of files.\nBINS := $(objroot)bin/jemalloc-config $(objroot)bin/jemalloc.sh $(objroot)bin/jeprof\nC_HDRS := $(objroot)include/jemalloc/jemalloc$(install_suffix).h\nC_SRCS := $(srcroot)src/jemalloc.c \\\n\t$(srcroot)src/arena.c \\\n\t$(srcroot)src/atomic.c \\\n\t$(srcroot)src/base.c \\\n\t$(srcroot)src/bitmap.c \\\n\t$(srcroot)src/chunk.c \\\n\t$(srcroot)src/chunk_dss.c \\\n\t$(srcroot)src/chunk_mmap.c \\\n\t$(srcroot)src/ckh.c \\\n\t$(srcroot)src/ctl.c \\\n\t$(srcroot)src/extent.c \\\n\t$(srcroot)src/hash.c \\\n\t$(srcroot)src/huge.c \\\n\t$(srcroot)src/mb.c \\\n\t$(srcroot)src/mutex.c \\\n\t$(srcroot)src/nstime.c \\\n\t$(srcroot)src/pages.c \\\n\t$(srcroot)src/prng.c \\\n\t$(srcroot)src/prof.c \\\n\t$(srcroot)src/quarantine.c \\\n\t$(srcroot)src/rtree.c \\\n\t$(srcroot)src/stats.c \\\n\t$(srcroot)src/tcache.c \\\n\t$(srcroot)src/ticker.c \\\n\t$(srcroot)src/tsd.c \\\n\t$(srcroot)src/util.c\nifeq ($(enable_valgrind), 1)\nC_SRCS += $(srcroot)src/valgrind.c\nendif\nifeq ($(enable_zone_allocator), 1)\nC_SRCS += $(srcroot)src/zone.c\nendif\nifeq ($(IMPORTLIB),$(SO))\nSTATIC_LIBS := $(objroot)lib/$(LIBJEMALLOC).$(A)\nendif\nifdef PIC_CFLAGS\nSTATIC_LIBS += $(objroot)lib/$(LIBJEMALLOC)_pic.$(A)\nelse\nSTATIC_LIBS += $(objroot)lib/$(LIBJEMALLOC)_s.$(A)\nendif\nDSOS := $(objroot)lib/$(LIBJEMALLOC).$(SOREV)\nifneq ($(SOREV),$(SO))\nDSOS += $(objroot)lib/$(LIBJEMALLOC).$(SO)\nendif\nPC := $(objroot)jemalloc.pc\nMAN3 := $(objroot)doc/jemalloc$(install_suffix).3\nDOCS_XML := $(objroot)doc/jemalloc$(install_suffix).xml\nDOCS_HTML := $(DOCS_XML:$(objroot)%.xml=$(objroot)%.html)\nDOCS_MAN3 := $(DOCS_XML:$(objroot)%.xml=$(objroot)%.3)\nDOCS := $(DOCS_HTML) $(DOCS_MAN3)\nC_TESTLIB_SRCS := $(srcroot)test/src/btalloc.c $(srcroot)test/src/btalloc_0.c \\\n\t$(srcroot)test/src/btalloc_1.c $(srcroot)test/src/math.c \\\n\t$(srcroot)test/src/mtx.c $(srcroot)test/src/mq.c \\\n\t$(srcroot)test/src/SFMT.c $(srcroot)test/src/test.c \\\n\t$(srcroot)test/src/thd.c $(srcroot)test/src/timer.c\nC_UTIL_INTEGRATION_SRCS := $(srcroot)src/nstime.c $(srcroot)src/util.c\nTESTS_UNIT := $(srcroot)test/unit/atomic.c \\\n\t$(srcroot)test/unit/bitmap.c \\\n\t$(srcroot)test/unit/ckh.c \\\n\t$(srcroot)test/unit/decay.c \\\n\t$(srcroot)test/unit/hash.c \\\n\t$(srcroot)test/unit/junk.c \\\n\t$(srcroot)test/unit/junk_alloc.c \\\n\t$(srcroot)test/unit/junk_free.c \\\n\t$(srcroot)test/unit/lg_chunk.c \\\n\t$(srcroot)test/unit/mallctl.c \\\n\t$(srcroot)test/unit/math.c \\\n\t$(srcroot)test/unit/mq.c \\\n\t$(srcroot)test/unit/mtx.c \\\n\t$(srcroot)test/unit/prng.c \\\n\t$(srcroot)test/unit/prof_accum.c \\\n\t$(srcroot)test/unit/prof_active.c \\\n\t$(srcroot)test/unit/prof_gdump.c \\\n\t$(srcroot)test/unit/prof_idump.c \\\n\t$(srcroot)test/unit/prof_reset.c \\\n\t$(srcroot)test/unit/prof_thread_name.c \\\n\t$(srcroot)test/unit/ql.c \\\n\t$(srcroot)test/unit/qr.c \\\n\t$(srcroot)test/unit/quarantine.c \\\n\t$(srcroot)test/unit/rb.c \\\n\t$(srcroot)test/unit/rtree.c \\\n\t$(srcroot)test/unit/run_quantize.c \\\n\t$(srcroot)test/unit/SFMT.c \\\n\t$(srcroot)test/unit/size_classes.c \\\n\t$(srcroot)test/unit/smoothstep.c \\\n\t$(srcroot)test/unit/stats.c \\\n\t$(srcroot)test/unit/ticker.c \\\n\t$(srcroot)test/unit/nstime.c \\\n\t$(srcroot)test/unit/tsd.c \\\n\t$(srcroot)test/unit/util.c \\\n\t$(srcroot)test/unit/zero.c\nTESTS_INTEGRATION := $(srcroot)test/integration/aligned_alloc.c \\\n\t$(srcroot)test/integration/allocated.c \\\n\t$(srcroot)test/integration/sdallocx.c \\\n\t$(srcroot)test/integration/mallocx.c \\\n\t$(srcroot)test/integration/MALLOCX_ARENA.c \\\n\t$(srcroot)test/integration/overflow.c \\\n\t$(srcroot)test/integration/posix_memalign.c \\\n\t$(srcroot)test/integration/rallocx.c \\\n\t$(srcroot)test/integration/thread_arena.c \\\n\t$(srcroot)test/integration/thread_tcache_enabled.c \\\n\t$(srcroot)test/integration/xallocx.c \\\n\t$(srcroot)test/integration/chunk.c\nTESTS_STRESS := $(srcroot)test/stress/microbench.c\nTESTS := $(TESTS_UNIT) $(TESTS_INTEGRATION) $(TESTS_STRESS)\n\nC_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.$(O))\nC_PIC_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.pic.$(O))\nC_JET_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.jet.$(O))\nC_TESTLIB_UNIT_OBJS := $(C_TESTLIB_SRCS:$(srcroot)%.c=$(objroot)%.unit.$(O))\nC_TESTLIB_INTEGRATION_OBJS := $(C_TESTLIB_SRCS:$(srcroot)%.c=$(objroot)%.integration.$(O))\nC_UTIL_INTEGRATION_OBJS := $(C_UTIL_INTEGRATION_SRCS:$(srcroot)%.c=$(objroot)%.integration.$(O))\nC_TESTLIB_STRESS_OBJS := $(C_TESTLIB_SRCS:$(srcroot)%.c=$(objroot)%.stress.$(O))\nC_TESTLIB_OBJS := $(C_TESTLIB_UNIT_OBJS) $(C_TESTLIB_INTEGRATION_OBJS) $(C_UTIL_INTEGRATION_OBJS) $(C_TESTLIB_STRESS_OBJS)\n\nTESTS_UNIT_OBJS := $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%.$(O))\nTESTS_INTEGRATION_OBJS := $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%.$(O))\nTESTS_STRESS_OBJS := $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%.$(O))\nTESTS_OBJS := $(TESTS_UNIT_OBJS) $(TESTS_INTEGRATION_OBJS) $(TESTS_STRESS_OBJS)\n\n.PHONY: all dist build_doc_html build_doc_man build_doc\n.PHONY: install_bin install_include install_lib\n.PHONY: install_doc_html install_doc_man install_doc install\n.PHONY: tests check clean distclean relclean\n\n.SECONDARY : $(TESTS_OBJS)\n\n# Default target.\nall: build_lib\n\ndist: build_doc\n\n$(objroot)doc/%.html : $(objroot)doc/%.xml $(srcroot)doc/stylesheet.xsl $(objroot)doc/html.xsl\n\t$(XSLTPROC) -o $@ $(objroot)doc/html.xsl $<\n\n$(objroot)doc/%.3 : $(objroot)doc/%.xml $(srcroot)doc/stylesheet.xsl $(objroot)doc/manpages.xsl\n\t$(XSLTPROC) -o $@ $(objroot)doc/manpages.xsl $<\n\nbuild_doc_html: $(DOCS_HTML)\nbuild_doc_man: $(DOCS_MAN3)\nbuild_doc: $(DOCS)\n\n#\n# Include generated dependency files.\n#\nifdef CC_MM\n-include $(C_OBJS:%.$(O)=%.d)\n-include $(C_PIC_OBJS:%.$(O)=%.d)\n-include $(C_JET_OBJS:%.$(O)=%.d)\n-include $(C_TESTLIB_OBJS:%.$(O)=%.d)\n-include $(TESTS_OBJS:%.$(O)=%.d)\nendif\n\n$(C_OBJS): $(objroot)src/%.$(O): $(srcroot)src/%.c\n$(C_PIC_OBJS): $(objroot)src/%.pic.$(O): $(srcroot)src/%.c\n$(C_PIC_OBJS): CFLAGS += $(PIC_CFLAGS)\n$(C_JET_OBJS): $(objroot)src/%.jet.$(O): $(srcroot)src/%.c\n$(C_JET_OBJS): CFLAGS += -DJEMALLOC_JET\n$(C_TESTLIB_UNIT_OBJS): $(objroot)test/src/%.unit.$(O): $(srcroot)test/src/%.c\n$(C_TESTLIB_UNIT_OBJS): CPPFLAGS += -DJEMALLOC_UNIT_TEST\n$(C_TESTLIB_INTEGRATION_OBJS): $(objroot)test/src/%.integration.$(O): $(srcroot)test/src/%.c\n$(C_TESTLIB_INTEGRATION_OBJS): CPPFLAGS += -DJEMALLOC_INTEGRATION_TEST\n$(C_UTIL_INTEGRATION_OBJS): $(objroot)src/%.integration.$(O): $(srcroot)src/%.c\n$(C_TESTLIB_STRESS_OBJS): $(objroot)test/src/%.stress.$(O): $(srcroot)test/src/%.c\n$(C_TESTLIB_STRESS_OBJS): CPPFLAGS += -DJEMALLOC_STRESS_TEST -DJEMALLOC_STRESS_TESTLIB\n$(C_TESTLIB_OBJS): CPPFLAGS += -I$(srcroot)test/include -I$(objroot)test/include\n$(TESTS_UNIT_OBJS): CPPFLAGS += -DJEMALLOC_UNIT_TEST\n$(TESTS_INTEGRATION_OBJS): CPPFLAGS += -DJEMALLOC_INTEGRATION_TEST\n$(TESTS_STRESS_OBJS): CPPFLAGS += -DJEMALLOC_STRESS_TEST\n$(TESTS_OBJS): $(objroot)test/%.$(O): $(srcroot)test/%.c\n$(TESTS_OBJS): CPPFLAGS += -I$(srcroot)test/include -I$(objroot)test/include\nifneq ($(IMPORTLIB),$(SO))\n$(C_OBJS) $(C_JET_OBJS): CPPFLAGS += -DDLLEXPORT\nendif\n\nifndef CC_MM\n# Dependencies.\nHEADER_DIRS = $(srcroot)include/jemalloc/internal \\\n\t$(objroot)include/jemalloc $(objroot)include/jemalloc/internal\nHEADERS = $(wildcard $(foreach dir,$(HEADER_DIRS),$(dir)/*.h))\n$(C_OBJS) $(C_PIC_OBJS) $(C_JET_OBJS) $(C_TESTLIB_OBJS) $(TESTS_OBJS): $(HEADERS)\n$(TESTS_OBJS): $(objroot)test/include/test/jemalloc_test.h\nendif\n\n$(C_OBJS) $(C_PIC_OBJS) $(C_JET_OBJS) $(C_TESTLIB_OBJS) $(TESTS_OBJS): %.$(O):\n\t@mkdir -p $(@D)\n\t$(CC) $(CFLAGS) -c $(CPPFLAGS) $(CTARGET) $<\nifdef CC_MM\n\t@$(CC) -MM $(CPPFLAGS) -MT $@ -o $(@:%.$(O)=%.d) $<\nendif\n\nifneq ($(SOREV),$(SO))\n%.$(SO) : %.$(SOREV)\n\t@mkdir -p $(@D)\n\tln -sf $(<F) $@\nendif\n\n$(objroot)lib/$(LIBJEMALLOC).$(SOREV) : $(if $(PIC_CFLAGS),$(C_PIC_OBJS),$(C_OBJS))\n\t@mkdir -p $(@D)\n\t$(CC) $(DSO_LDFLAGS) $(call RPATH,$(RPATH_EXTRA)) $(LDTARGET) $+ $(LDFLAGS) $(LIBS) $(EXTRA_LDFLAGS)\n\n$(objroot)lib/$(LIBJEMALLOC)_pic.$(A) : $(C_PIC_OBJS)\n$(objroot)lib/$(LIBJEMALLOC).$(A) : $(C_OBJS)\n$(objroot)lib/$(LIBJEMALLOC)_s.$(A) : $(C_OBJS)\n\n$(STATIC_LIBS):\n\t@mkdir -p $(@D)\n\t$(AR) $(ARFLAGS)@AROUT@ $+\n\n$(objroot)test/unit/%$(EXE): $(objroot)test/unit/%.$(O) $(TESTS_UNIT_LINK_OBJS) $(C_JET_OBJS) $(C_TESTLIB_UNIT_OBJS)\n\t@mkdir -p $(@D)\n\t$(CC) $(LDTARGET) $(filter %.$(O),$^) $(call RPATH,$(objroot)lib) $(LDFLAGS) $(filter-out -lm,$(LIBS)) -lm $(TESTLIBS) $(EXTRA_LDFLAGS)\n\n$(objroot)test/integration/%$(EXE): $(objroot)test/integration/%.$(O) $(C_TESTLIB_INTEGRATION_OBJS) $(C_UTIL_INTEGRATION_OBJS) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB)\n\t@mkdir -p $(@D)\n\t$(CC) $(LDTARGET) $(filter %.$(O),$^) $(call RPATH,$(objroot)lib) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB) $(LDFLAGS) $(filter-out -lm,$(filter -lpthread,$(LIBS))) -lm $(TESTLIBS) $(EXTRA_LDFLAGS)\n\n$(objroot)test/stress/%$(EXE): $(objroot)test/stress/%.$(O) $(C_JET_OBJS) $(C_TESTLIB_STRESS_OBJS) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB)\n\t@mkdir -p $(@D)\n\t$(CC) $(LDTARGET) $(filter %.$(O),$^) $(call RPATH,$(objroot)lib) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB) $(LDFLAGS) $(filter-out -lm,$(LIBS)) -lm $(TESTLIBS) $(EXTRA_LDFLAGS)\n\nbuild_lib_shared: $(DSOS)\nbuild_lib_static: $(STATIC_LIBS)\nbuild_lib: build_lib_shared build_lib_static\n\ninstall_bin:\n\tinstall -d $(BINDIR)\n\t@for b in $(BINS); do \\\n\techo \"install -m 755 $$b $(BINDIR)\"; \\\n\tinstall -m 755 $$b $(BINDIR); \\\ndone\n\ninstall_include:\n\tinstall -d $(INCLUDEDIR)/jemalloc\n\t@for h in $(C_HDRS); do \\\n\techo \"install -m 644 $$h $(INCLUDEDIR)/jemalloc\"; \\\n\tinstall -m 644 $$h $(INCLUDEDIR)/jemalloc; \\\ndone\n\ninstall_lib_shared: $(DSOS)\n\tinstall -d $(LIBDIR)\n\tinstall -m 755 $(objroot)lib/$(LIBJEMALLOC).$(SOREV) $(LIBDIR)\nifneq ($(SOREV),$(SO))\n\tln -sf $(LIBJEMALLOC).$(SOREV) $(LIBDIR)/$(LIBJEMALLOC).$(SO)\nendif\n\ninstall_lib_static: $(STATIC_LIBS)\n\tinstall -d $(LIBDIR)\n\t@for l in $(STATIC_LIBS); do \\\n\techo \"install -m 755 $$l $(LIBDIR)\"; \\\n\tinstall -m 755 $$l $(LIBDIR); \\\ndone\n\ninstall_lib_pc: $(PC)\n\tinstall -d $(LIBDIR)/pkgconfig\n\t@for l in $(PC); do \\\n\techo \"install -m 644 $$l $(LIBDIR)/pkgconfig\"; \\\n\tinstall -m 644 $$l $(LIBDIR)/pkgconfig; \\\ndone\n\ninstall_lib: install_lib_shared install_lib_static install_lib_pc\n\ninstall_doc_html:\n\tinstall -d $(DATADIR)/doc/jemalloc$(install_suffix)\n\t@for d in $(DOCS_HTML); do \\\n\techo \"install -m 644 $$d $(DATADIR)/doc/jemalloc$(install_suffix)\"; \\\n\tinstall -m 644 $$d $(DATADIR)/doc/jemalloc$(install_suffix); \\\ndone\n\ninstall_doc_man:\n\tinstall -d $(MANDIR)/man3\n\t@for d in $(DOCS_MAN3); do \\\n\techo \"install -m 644 $$d $(MANDIR)/man3\"; \\\n\tinstall -m 644 $$d $(MANDIR)/man3; \\\ndone\n\ninstall_doc: install_doc_html install_doc_man\n\ninstall: install_bin install_include install_lib install_doc\n\ntests_unit: $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%$(EXE))\ntests_integration: $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%$(EXE))\ntests_stress: $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%$(EXE))\ntests: tests_unit tests_integration tests_stress\n\ncheck_unit_dir:\n\t@mkdir -p $(objroot)test/unit\ncheck_integration_dir:\n\t@mkdir -p $(objroot)test/integration\nstress_dir:\n\t@mkdir -p $(objroot)test/stress\ncheck_dir: check_unit_dir check_integration_dir\n\ncheck_unit: tests_unit check_unit_dir\n\t$(MALLOC_CONF)=\"purge:ratio\" $(SHELL) $(objroot)test/test.sh $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%)\n\t$(MALLOC_CONF)=\"purge:decay\" $(SHELL) $(objroot)test/test.sh $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%)\ncheck_integration_prof: tests_integration check_integration_dir\nifeq ($(enable_prof), 1)\n\t$(MALLOC_CONF)=\"prof:true\" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%)\n\t$(MALLOC_CONF)=\"prof:true,prof_active:false\" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%)\nendif\ncheck_integration_decay: tests_integration check_integration_dir\n\t$(MALLOC_CONF)=\"purge:decay,decay_time:-1\" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%)\n\t$(MALLOC_CONF)=\"purge:decay,decay_time:0\" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%)\n\t$(MALLOC_CONF)=\"purge:decay\" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%)\ncheck_integration: tests_integration check_integration_dir\n\t$(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%)\nstress: tests_stress stress_dir\n\t$(SHELL) $(objroot)test/test.sh $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%)\ncheck: check_unit check_integration check_integration_decay check_integration_prof\n\nifeq ($(enable_code_coverage), 1)\ncoverage_unit: check_unit\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)src jet $(C_JET_OBJS)\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src unit $(C_TESTLIB_UNIT_OBJS)\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)test/unit unit $(TESTS_UNIT_OBJS)\n\ncoverage_integration: check_integration\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)src pic $(C_PIC_OBJS)\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)src integration $(C_UTIL_INTEGRATION_OBJS)\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src integration $(C_TESTLIB_INTEGRATION_OBJS)\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)test/integration integration $(TESTS_INTEGRATION_OBJS)\n\ncoverage_stress: stress\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)src pic $(C_PIC_OBJS)\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)src jet $(C_JET_OBJS)\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src stress $(C_TESTLIB_STRESS_OBJS)\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)test/stress stress $(TESTS_STRESS_OBJS)\n\ncoverage: check\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)src pic $(C_PIC_OBJS)\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)src jet $(C_JET_OBJS)\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)src integration $(C_UTIL_INTEGRATION_OBJS)\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src unit $(C_TESTLIB_UNIT_OBJS)\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src integration $(C_TESTLIB_INTEGRATION_OBJS)\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src stress $(C_TESTLIB_STRESS_OBJS)\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)test/unit unit $(TESTS_UNIT_OBJS) $(TESTS_UNIT_AUX_OBJS)\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)test/integration integration $(TESTS_INTEGRATION_OBJS)\n\t$(SHELL) $(srcroot)coverage.sh $(srcroot)test/stress integration $(TESTS_STRESS_OBJS)\nendif\n\nclean:\n\trm -f $(C_OBJS)\n\trm -f $(C_PIC_OBJS)\n\trm -f $(C_JET_OBJS)\n\trm -f $(C_TESTLIB_OBJS)\n\trm -f $(C_OBJS:%.$(O)=%.d)\n\trm -f $(C_OBJS:%.$(O)=%.gcda)\n\trm -f $(C_OBJS:%.$(O)=%.gcno)\n\trm -f $(C_PIC_OBJS:%.$(O)=%.d)\n\trm -f $(C_PIC_OBJS:%.$(O)=%.gcda)\n\trm -f $(C_PIC_OBJS:%.$(O)=%.gcno)\n\trm -f $(C_JET_OBJS:%.$(O)=%.d)\n\trm -f $(C_JET_OBJS:%.$(O)=%.gcda)\n\trm -f $(C_JET_OBJS:%.$(O)=%.gcno)\n\trm -f $(C_TESTLIB_OBJS:%.$(O)=%.d)\n\trm -f $(C_TESTLIB_OBJS:%.$(O)=%.gcda)\n\trm -f $(C_TESTLIB_OBJS:%.$(O)=%.gcno)\n\trm -f $(TESTS_OBJS:%.$(O)=%$(EXE))\n\trm -f $(TESTS_OBJS)\n\trm -f $(TESTS_OBJS:%.$(O)=%.d)\n\trm -f $(TESTS_OBJS:%.$(O)=%.gcda)\n\trm -f $(TESTS_OBJS:%.$(O)=%.gcno)\n\trm -f $(TESTS_OBJS:%.$(O)=%.out)\n\trm -f $(DSOS) $(STATIC_LIBS)\n\trm -f $(objroot)*.gcov.*\n\ndistclean: clean\n\trm -f $(objroot)bin/jemalloc-config\n\trm -f $(objroot)bin/jemalloc.sh\n\trm -f $(objroot)bin/jeprof\n\trm -f $(objroot)config.log\n\trm -f $(objroot)config.status\n\trm -f $(objroot)config.stamp\n\trm -f $(cfghdrs_out)\n\trm -f $(cfgoutputs_out)\n\nrelclean: distclean\n\trm -f $(objroot)configure\n\trm -f $(objroot)VERSION\n\trm -f $(DOCS_HTML)\n\trm -f $(DOCS_MAN3)\n\n#===============================================================================\n# Re-configuration rules.\n\nifeq ($(enable_autogen), 1)\n$(srcroot)configure : $(srcroot)configure.ac\n\tcd ./$(srcroot) && $(AUTOCONF)\n\n$(objroot)config.status : $(srcroot)configure\n\t./$(objroot)config.status --recheck\n\n$(srcroot)config.stamp.in : $(srcroot)configure.ac\n\techo stamp > $(srcroot)config.stamp.in\n\n$(objroot)config.stamp : $(cfgoutputs_in) $(cfghdrs_in) $(srcroot)configure\n\t./$(objroot)config.status\n\t@touch $@\n\n# There must be some action in order for make to re-read Makefile when it is\n# out of date.\n$(cfgoutputs_out) $(cfghdrs_out) : $(objroot)config.stamp\n\t@true\nendif\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/README",
    "content": "jemalloc is a general purpose malloc(3) implementation that emphasizes\nfragmentation avoidance and scalable concurrency support.  jemalloc first came\ninto use as the FreeBSD libc allocator in 2005, and since then it has found its\nway into numerous applications that rely on its predictable behavior.  In 2010\njemalloc development efforts broadened to include developer support features\nsuch as heap profiling, Valgrind integration, and extensive monitoring/tuning\nhooks.  Modern jemalloc releases continue to be integrated back into FreeBSD,\nand therefore versatility remains critical.  Ongoing development efforts trend\ntoward making jemalloc among the best allocators for a broad range of demanding\napplications, and eliminating/mitigating weaknesses that have practical\nrepercussions for real world applications.\n\nThe COPYING file contains copyright and licensing information.\n\nThe INSTALL file contains information on how to configure, build, and install\njemalloc.\n\nThe ChangeLog file contains a brief summary of changes for each release.\n\nURL: http://www.canonware.com/jemalloc/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/autogen.sh",
    "content": "#!/bin/sh\n\nfor i in autoconf; do\n    echo \"$i\"\n    $i\n    if [ $? -ne 0 ]; then\n\techo \"Error $? in $i\"\n\texit 1\n    fi\ndone\n\necho \"./configure --enable-autogen $@\"\n./configure --enable-autogen $@\nif [ $? -ne 0 ]; then\n    echo \"Error $? in ./configure\"\n    exit 1\nfi\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/bin/jemalloc-config.in",
    "content": "#!/bin/sh\n\nusage() {\n\tcat <<EOF\nUsage:\n  @BINDIR@/jemalloc-config <option>\nOptions:\n  --help | -h  : Print usage.\n  --version    : Print jemalloc version.\n  --revision   : Print shared library revision number.\n  --config     : Print configure options used to build jemalloc.\n  --prefix     : Print installation directory prefix.\n  --bindir     : Print binary installation directory.\n  --datadir    : Print data installation directory.\n  --includedir : Print include installation directory.\n  --libdir     : Print library installation directory.\n  --mandir     : Print manual page installation directory.\n  --cc         : Print compiler used to build jemalloc.\n  --cflags     : Print compiler flags used to build jemalloc.\n  --cppflags   : Print preprocessor flags used to build jemalloc.\n  --ldflags    : Print library flags used to build jemalloc.\n  --libs       : Print libraries jemalloc was linked against.\nEOF\n}\n\nprefix=\"@prefix@\"\nexec_prefix=\"@exec_prefix@\"\n\ncase \"$1\" in\n--help | -h)\n\tusage\n\texit 0\n\t;;\n--version)\n\techo \"@jemalloc_version@\"\n\t;;\n--revision)\n\techo \"@rev@\"\n\t;;\n--config)\n\techo \"@CONFIG@\"\n\t;;\n--prefix)\n\techo \"@PREFIX@\"\n\t;;\n--bindir)\n\techo \"@BINDIR@\"\n\t;;\n--datadir)\n\techo \"@DATADIR@\"\n\t;;\n--includedir)\n\techo \"@INCLUDEDIR@\"\n\t;;\n--libdir)\n\techo \"@LIBDIR@\"\n\t;;\n--mandir)\n\techo \"@MANDIR@\"\n\t;;\n--cc)\n\techo \"@CC@\"\n\t;;\n--cflags)\n\techo \"@CFLAGS@\"\n\t;;\n--cppflags)\n\techo \"@CPPFLAGS@\"\n\t;;\n--ldflags)\n\techo \"@LDFLAGS@ @EXTRA_LDFLAGS@\"\n\t;;\n--libs)\n\techo \"@LIBS@\"\n\t;;\n*)\n\tusage\n\texit 1\nesac\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/bin/jemalloc.sh.in",
    "content": "#!/bin/sh\n\nprefix=@prefix@\nexec_prefix=@exec_prefix@\nlibdir=@libdir@\n\n@LD_PRELOAD_VAR@=${libdir}/libjemalloc.@SOREV@\nexport @LD_PRELOAD_VAR@\nexec \"$@\"\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/bin/jeprof.in",
    "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/jeprof \"program\" \"profile\"\n#   Enters \"interactive\" mode\n#\n# % tools/jeprof --text \"program\" \"profile\"\n#   Generates one line per procedure\n#\n# % tools/jeprof --gv \"program\" \"profile\"\n#   Generates annotated call-graph and displays via \"gv\"\n#\n# % tools/jeprof --gv --focus=Mutex \"program\" \"profile\"\n#   Restrict to code paths that involve an entry that matches \"Mutex\"\n#\n# % tools/jeprof --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/jeprof --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/jeprof --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 $JEPROF_VERSION = \"@jemalloc_version@\";\nmy $PPROF_VERSION = \"2.0\";\n\n# These are the object tools we use which can come from a\n# user-specified location using --tools, from the JEPROF_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);\n# NOTE: these are lists, so you can put in commandline flags if you want.\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\", \"--fail\");\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 cgi-param\n                                                       # \"?seconds=#\",\n                                                       # \"?tags_regexp=#\" and\n                                                       # \"?type=#\".\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\nmy $dev_null = \"/dev/null\";\nif (! -e $dev_null && $^O =~ /MSWin/) {    # $^O is the OS perl was built for\n  $dev_null = \"nul\";\n}\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:\njeprof [options] <program> <profiles>\n   <profiles> is a space separated list of profile names.\njeprof [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).\njeprof [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:\n     jeprof http://myserver.com:80$HEAP_PAGE\n   If /<service> is omitted, the service defaults to $PROFILE_PAGE (cpu profiling).\njeprof --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/gperftools-$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 jeprof 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 backtraces with nodes matching <regexp>\n   --thread=<n>        Show profile for thread <n>\n   --ignore=<regexp>   Ignore backtraces with 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   --retain=<regexp>   Retain only nodes that match <regexp>\n   --exclude=<regexp>  Exclude all nodes that match <regexp>\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   JEPROF_TMPDIR        Profiles directory. Defaults to \\$HOME/jeprof\n   JEPROF_TOOLS         Prefix for object tools pathnames\n\nExamples:\n\njeprof /bin/ls ls.prof\n                       Enters \"interactive\" mode\njeprof --text /bin/ls ls.prof\n                       Outputs one line per procedure\njeprof --web /bin/ls ls.prof\n                       Displays annotated call-graph in web browser\njeprof --gv /bin/ls ls.prof\n                       Displays annotated call-graph via 'gv'\njeprof --gv --focus=Mutex /bin/ls ls.prof\n                       Restricts to code paths including a .*Mutex.* entry\njeprof --gv --focus=Mutex --ignore=string /bin/ls ls.prof\n                       Code paths including Mutex but not string\njeprof --list=getdir /bin/ls ls.prof\n                       (Per-line) annotated source listing for getdir()\njeprof --disasm=getdir /bin/ls ls.prof\n                       (Per-PC) annotated disassembly for getdir()\n\njeprof http://localhost:1234/\n                       Enters \"interactive\" mode\njeprof --text localhost:1234\n                       Outputs one line per procedure for localhost:1234\njeprof --raw localhost:1234 > ./local.raw\njeprof --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\njeprof (part of jemalloc $JEPROF_VERSION)\nbased on pprof (part of gperftools $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/jeprof$$.sym\";\n  $main::tmpfile_ps = \"/tmp/jeprof$$\";\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_thread = undef;\n  $main::opt_ignore = '';\n  $main::opt_scale = 0;\n  $main::opt_heapcheck = 0;\n  $main::opt_retain = '';\n  $main::opt_exclude = '';\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             \"thread=s\"       => \\$main::opt_thread,\n             \"ignore=s\"       => \\$main::opt_ignore,\n             \"scale=i\"        => \\$main::opt_scale,\n             \"heapcheck\"      => \\$main::opt_heapcheck,\n             \"retain=s\"       => \\$main::opt_retain,\n             \"exclude=s\"      => \\$main::opt_exclude,\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 (@ARGV > 0) {\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\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_lib_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 FilterAndPrint {\n  my ($profile, $symbols, $libs, $thread) = @_;\n\n  # Get total data in profile\n  my $total = TotalProfile($profile);\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);\n    } elsif ($main::opt_list) {\n      PrintListing($total, $libs, $flat, $cumulative, $main::opt_list, 0);\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 %s\\n\",\n               (defined($thread) ? \" (t$thread)\" : \"\"),\n               Unparse($total), Units());\n      }\n      PrintText($symbols, $flat, $cumulative, -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          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\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  # 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  if (!defined($main::opt_thread)) {\n    FilterAndPrint($profile, $symbols, $libs);\n  }\n  if (defined($data->{threads})) {\n    foreach my $thread (sort { $a <=> $b } keys(%{$data->{threads}})) {\n      if (defined($main::opt_thread) &&\n          ($main::opt_thread eq '*' || $main::opt_thread == $thread)) {\n        my $thread_profile = $data->{threads}{$thread};\n        FilterAndPrint($thread_profile, $symbols, $libs, $thread);\n      }\n    }\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(ShellEscape(@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(ShellEscape(@GV, \"--scale=$main::opt_scale\", \"--noantialias\", $fname)\n           . $bg);\n  } else {\n    # Old gv version - only supports options that use single dash.\n    print STDERR ShellEscape(@GV, \"-scale\", $main::opt_scale) . \"\\n\";\n    system(ShellEscape(@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(ShellEscape(@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(ShellEscape(@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 jeprof!  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 'jeprof';\n    while ( defined ($_ = $term->readline('(jeprof) '))) {\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 \"(jeprof) \";\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($total, $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, $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*(web)?list\\s*(.+)/) {\n    my $html = (defined($1) && ($1 eq \"web\"));\n    $main::opt_list = 1;\n\n    my $routine;\n    my $ignore;\n    ($routine, $ignore) = ParseInteractiveArgs($2);\n\n    my $profile = ProcessProfile($total, $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($total, $libs, $flat, $cumulative, $routine, $html);\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($total, $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);\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($total, $orig_profile, $symbols,\n                                 $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 $total_count = shift;\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  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 jeprof 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  weblist [routine_regexp] [-ignore1] [-ignore2]\n     Displays a source listing of routines whose names match \"routine_regexp\"\n     in a web browser.  You can click on source lines to view the\n     corresponding disassembly.\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 jeprof\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/gperftools-$PPROF_VERSION/cpu_profiler.html\n /usr/doc/gperftools-$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  my $profile_marker;\n  if ($main::profile_type eq 'heap') {\n    $HEAP_PAGE =~ m,[^/]+$,;    # matches everything after the last slash\n    $profile_marker = $&;\n  } elsif ($main::profile_type eq 'growth') {\n    $GROWTH_PAGE =~ m,[^/]+$,;    # matches everything after the last slash\n    $profile_marker = $&;\n  } elsif ($main::profile_type eq 'contention') {\n    $CONTENTION_PAGE =~ m,[^/]+$,;    # matches everything after the last slash\n    $profile_marker = $&;\n  } else { # elsif ($main::profile_type eq 'cpu')\n    $PROFILE_PAGE =~ m,[^/]+$,;    # matches everything after the last slash\n    $profile_marker = $&;\n  }\n\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    # --raw/http: For everything to work correctly for non-remote profiles, we\n    # would need to extend PrintProfileData() to handle all possible profile\n    # types, re-enable the code that is currently disabled in ReadCPUProfile()\n    # and FixCallerAddresses(), and remove the remote profile dumping code in\n    # the block above.\n    die \"--raw/http: jeprof can only dump remote profiles for --raw\\n\";\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 $line_limit = shift;\n\n  my $total = TotalProfile($flat);\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# Callgrind format has a compression for repeated function and file\n# names.  You show the name the first time, and just use its number\n# subsequently.  This can cut down the file to about a third or a\n# quarter of its uncompressed size.  $key and $val are the key/value\n# pair that would normally be printed by callgrind; $map is a map from\n# value to number.\nsub CompressedCGName {\n  my($key, $val, $map) = @_;\n  my $idx = $map->{$val};\n  # For very short keys, providing an index hurts rather than helps.\n  if (length($val) <= 3) {\n    return \"$key=$val\\n\";\n  } elsif (defined($idx)) {\n    return \"$key=($idx)\\n\";\n  } else {\n    # scalar(keys $map) gives the number of items in the map.\n    $idx = scalar(keys(%{$map})) + 1;\n    $map->{$val} = $idx;\n    return \"$key=($idx) $val\\n\";\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  my %filename_to_index_map;\n  my %fnname_to_index_map;\n\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    # TODO(csilvers): for better compression, collect all the\n    # caller/callee_files and functions first, before printing\n    # anything, and only compress those referenced more than once.\n    printf CG CompressedCGName(\"fl\", $caller_file, \\%filename_to_index_map);\n    printf CG CompressedCGName(\"fn\", $caller_function, \\%fnname_to_index_map);\n    if (defined $6) {\n      printf CG CompressedCGName(\"cfl\", $callee_file, \\%filename_to_index_map);\n      printf CG CompressedCGName(\"cfn\", $callee_function, \\%fnname_to_index_map);\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\n  my $total = TotalProfile($flat);\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 = ShellEscape($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(\"$cmd: $!\\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 $list_opts\nsub PrintListing {\n  my $total = shift;\n  my $libs = shift;\n  my $flat = shift;\n  my $cumulative = shift;\n  my $list_opts = shift;\n  my $html = shift;\n\n  my $output = \\*STDOUT;\n  my $fname = \"\";\n\n  if ($html) {\n    # Arrange to write the output to a temporary file\n    $fname = TempName($main::next_tmpfile, \"html\");\n    $main::next_tmpfile++;\n    if (!open(TEMP, \">$fname\")) {\n      print STDERR \"$fname: $!\\n\";\n      return;\n    }\n    $output = \\*TEMP;\n    print $output HtmlListingHeader();\n    printf $output (\"<div class=\\\"legend\\\">%s<br>Total: %s %s</div>\\n\",\n                    $main::prog, Unparse($total), Units());\n  }\n\n  my $listed = 0;\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          $listed += PrintSource(\n            $lib->[0], $offset,\n            $routine, $flat, $cumulative,\n            $start_addr, $end_addr,\n            $html,\n            $output);\n          last;\n        }\n        $addr = AddressInc($addr);\n      }\n    }\n  }\n\n  if ($html) {\n    if ($listed > 0) {\n      print $output HtmlListingFooter();\n      close($output);\n      RunWeb($fname);\n    } else {\n      close($output);\n      unlink($fname);\n    }\n  }\n}\n\nsub HtmlListingHeader {\n  return <<'EOF';\n<DOCTYPE html>\n<html>\n<head>\n<title>Pprof listing</title>\n<style type=\"text/css\">\nbody {\n  font-family: sans-serif;\n}\nh1 {\n  font-size: 1.5em;\n  margin-bottom: 4px;\n}\n.legend {\n  font-size: 1.25em;\n}\n.line {\n  color: #aaaaaa;\n}\n.nop {\n  color: #aaaaaa;\n}\n.unimportant {\n  color: #cccccc;\n}\n.disasmloc {\n  color: #000000;\n}\n.deadsrc {\n  cursor: pointer;\n}\n.deadsrc:hover {\n  background-color: #eeeeee;\n}\n.livesrc {\n  color: #0000ff;\n  cursor: pointer;\n}\n.livesrc:hover {\n  background-color: #eeeeee;\n}\n.asm {\n  color: #008800;\n  display: none;\n}\n</style>\n<script type=\"text/javascript\">\nfunction jeprof_toggle_asm(e) {\n  var target;\n  if (!e) e = window.event;\n  if (e.target) target = e.target;\n  else if (e.srcElement) target = e.srcElement;\n\n  if (target) {\n    var asm = target.nextSibling;\n    if (asm && asm.className == \"asm\") {\n      asm.style.display = (asm.style.display == \"block\" ? \"\" : \"block\");\n      e.preventDefault();\n      return false;\n    }\n  }\n}\n</script>\n</head>\n<body>\nEOF\n}\n\nsub HtmlListingFooter {\n  return <<'EOF';\n</body>\n</html>\nEOF\n}\n\nsub HtmlEscape {\n  my $text = shift;\n  $text =~ s/&/&amp;/g;\n  $text =~ s/</&lt;/g;\n  $text =~ s/>/&gt;/g;\n  return $text;\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# If the symbol table contains inlining info, Disassemble() may tag an\n# instruction with a location inside an inlined function.  But for\n# source listings, we prefer to use the location in the function we\n# are listing.  So use MapToSymbols() to fetch full location\n# information for each instruction and then pick out the first\n# location from a location list (location list contains callers before\n# callees in case of inlining).\n#\n# After this routine has run, each entry in $instructions contains:\n#   [0] start address\n#   [1] filename for function we are listing\n#   [2] line number for function we are listing\n#   [3] disassembly\n#   [4] limit address\n#   [5] most specific filename (may be different from [1] due to inlining)\n#   [6] most specific line number (may be different from [2] due to inlining)\nsub GetTopLevelLineNumbers {\n  my ($lib, $offset, $instructions) = @_;\n  my $pcs = [];\n  for (my $i = 0; $i <= $#{$instructions}; $i++) {\n    push(@{$pcs}, $instructions->[$i]->[0]);\n  }\n  my $symbols = {};\n  MapToSymbols($lib, $offset, $pcs, $symbols);\n  for (my $i = 0; $i <= $#{$instructions}; $i++) {\n    my $e = $instructions->[$i];\n    push(@{$e}, $e->[1]);\n    push(@{$e}, $e->[2]);\n    my $addr = $e->[0];\n    my $sym = $symbols->{$addr};\n    if (defined($sym)) {\n      if ($#{$sym} >= 2 && $sym->[1] =~ m/^(.*):(\\d+)$/) {\n        $e->[1] = $1;  # File name\n        $e->[2] = $2;  # Line number\n      }\n    }\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  my $html = shift;\n  my $output = shift;\n\n  # Disassemble all instructions (just to get line numbers)\n  my @instructions = Disassemble($prog, $offset, $start_addr, $end_addr);\n  GetTopLevelLineNumbers($prog, $offset, \\@instructions);\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 0;\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 0;\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 = {};        # Map from line number to flat count\n  my $samples2 = {};        # Map from line number to cumulative count\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  my %disasm = ();          # Map from line number to disassembly\n  my $running_disasm = \"\";  # Unassigned disassembly\n  my $skip_marker = \"---\\n\";\n  if ($html) {\n    $skip_marker = \"\";\n    for (my $l = $firstline; $l <= $lastline; $l++) {\n      $disasm{$l} = \"\";\n    }\n  }\n  my $last_dis_filename = '';\n  my $last_dis_linenum = -1;\n  my $last_touched_line = -1;  # To detect gaps in disassembly for a line\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\n    if ($html) {\n      my $dis = sprintf(\"      %6s %6s \\t\\t%8s: %s \",\n                        HtmlPrintNumber($c1),\n                        HtmlPrintNumber($c2),\n                        UnparseAddress($offset, $e->[0]),\n                        CleanDisassembly($e->[3]));\n\n      # Append the most specific source line associated with this instruction\n      if (length($dis) < 80) { $dis .= (' ' x (80 - length($dis))) };\n      $dis = HtmlEscape($dis);\n      my $f = $e->[5];\n      my $l = $e->[6];\n      if ($f ne $last_dis_filename) {\n        $dis .= sprintf(\"<span class=disasmloc>%s:%d</span>\",\n                        HtmlEscape(CleanFileName($f)), $l);\n      } elsif ($l ne $last_dis_linenum) {\n        # De-emphasize the unchanged file name portion\n        $dis .= sprintf(\"<span class=unimportant>%s</span>\" .\n                        \"<span class=disasmloc>:%d</span>\",\n                        HtmlEscape(CleanFileName($f)), $l);\n      } else {\n        # De-emphasize the entire location\n        $dis .= sprintf(\"<span class=unimportant>%s:%d</span>\",\n                        HtmlEscape(CleanFileName($f)), $l);\n      }\n      $last_dis_filename = $f;\n      $last_dis_linenum = $l;\n      $running_disasm .= $dis;\n      $running_disasm .= \"\\n\";\n    }\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      if ($html) {\n        if ($line != $last_touched_line && $disasm{$line} ne '') {\n          $disasm{$line} .= \"\\n\";\n        }\n        $disasm{$line} .= $running_disasm;\n        $running_disasm = '';\n        $last_touched_line = $line;\n      }\n    }\n  }\n\n  # Assign any leftover samples to $lastline\n  AddEntry($samples1, $lastline, $running1);\n  AddEntry($samples2, $lastline, $running2);\n  if ($html) {\n    if ($lastline != $last_touched_line && $disasm{$lastline} ne '') {\n      $disasm{$lastline} .= \"\\n\";\n    }\n    $disasm{$lastline} .= $running_disasm;\n  }\n\n  if ($html) {\n    printf $output (\n      \"<h1>%s</h1>%s\\n<pre onClick=\\\"jeprof_toggle_asm()\\\">\\n\" .\n      \"Total:%6s %6s (flat / cumulative %s)\\n\",\n      HtmlEscape(ShortFunctionName($routine)),\n      HtmlEscape(CleanFileName($filename)),\n      Unparse($total1),\n      Unparse($total2),\n      Units());\n  } else {\n    printf $output (\n      \"ROUTINE ====================== %s in %s\\n\" .\n      \"%6s %6s Total %s (flat / cumulative)\\n\",\n      ShortFunctionName($routine),\n      CleanFileName($filename),\n      Unparse($total1),\n      Unparse($total2),\n      Units());\n  }\n  if (!open(FILE, \"<$filename\")) {\n    print STDERR \"$filename: $!\\n\";\n    return 0;\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) { print $output $skip_marker; }\n      my $n1 = GetEntry($samples1, $l);\n      my $n2 = GetEntry($samples2, $l);\n      if ($html) {\n        # Emit a span that has one of the following classes:\n        #    livesrc -- has samples\n        #    deadsrc -- has disassembly, but with no samples\n        #    nop     -- has no matching disasembly\n        # Also emit an optional span containing disassembly.\n        my $dis = $disasm{$l};\n        my $asm = \"\";\n        if (defined($dis) && $dis ne '') {\n          $asm = \"<span class=\\\"asm\\\">\" . $dis . \"</span>\";\n        }\n        my $source_class = (($n1 + $n2 > 0)\n                            ? \"livesrc\"\n                            : (($asm ne \"\") ? \"deadsrc\" : \"nop\"));\n        printf $output (\n          \"<span class=\\\"line\\\">%5d</span> \" .\n          \"<span class=\\\"%s\\\">%6s %6s %s</span>%s\\n\",\n          $l, $source_class,\n          HtmlPrintNumber($n1),\n          HtmlPrintNumber($n2),\n          HtmlEscape($text),\n          $asm);\n      } else {\n        printf $output(\n          \"%6s %6s %4d: %s\\n\",\n          UnparseAlt($n1),\n          UnparseAlt($n2),\n          $l,\n          $text);\n      }\n      if ($l == $lastline)  { print $output $skip_marker; }\n    };\n  }\n  close(FILE);\n  if ($html) {\n    print $output \"</pre>\\n\";\n  }\n  return 1;\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      printf(\"%6s %6s    %8s: %6s\\n\",\n             UnparseAlt($flat_count[$x]),\n             UnparseAlt($cum_count[$x]),\n             UnparseAddress($offset, $e->[0]),\n             CleanDisassembly($e->[3]));\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  my $escaped_dot = ShellEscape(@DOT);\n  my $escaped_ps2pdf = ShellEscape(@PS2PDF);\n  if ($main::opt_gv) {\n    my $escaped_outfile = ShellEscape(TempName($main::next_tmpfile, \"ps\"));\n    $output = \"| $escaped_dot -Tps2 >$escaped_outfile\";\n  } elsif ($main::opt_evince) {\n    my $escaped_outfile = ShellEscape(TempName($main::next_tmpfile, \"pdf\"));\n    $output = \"| $escaped_dot -Tps2 | $escaped_ps2pdf - $escaped_outfile\";\n  } elsif ($main::opt_ps) {\n    $output = \"| $escaped_dot -Tps2\";\n  } elsif ($main::opt_pdf) {\n    $output = \"| $escaped_dot -Tps2 | $escaped_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    my $escaped_outfile = ShellEscape(TempName($main::next_tmpfile, \"svg\"));\n    $output = \"| $escaped_dot -Tsvg >$escaped_outfile\";\n  } elsif ($main::opt_gif) {\n    $output = \"| $escaped_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, $local_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, $local_total),\n                $extra,\n                $fs,\n                $style,\n               );\n  }\n\n  # Get edges and counts per edge\n  my %edge = ();\n  my $n;\n  my $fullname_to_shortname_map = {};\n  FillFullnameToShortnameMap($symbols, $fullname_to_shortname_map);\n  foreach my $k (keys(%{$raw})) {\n    # TODO: omit low %age edges\n    $n = $raw->{$k};\n    my @translated = TranslateStack($symbols, $fullname_to_shortname_map, $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# Provides a map from fullname to shortname for cases where the\n# shortname is ambiguous.  The symlist has both the fullname and\n# shortname for all symbols, which is usually fine, but sometimes --\n# such as overloaded functions -- two different fullnames can map to\n# the same shortname.  In that case, we use the address of the\n# function to disambiguate the two.  This function fills in a map that\n# maps fullnames to modified shortnames in such cases.  If a fullname\n# is not present in the map, the 'normal' shortname provided by the\n# symlist is the appropriate one to use.\nsub FillFullnameToShortnameMap {\n  my $symbols = shift;\n  my $fullname_to_shortname_map = shift;\n  my $shortnames_seen_once = {};\n  my $shortnames_seen_more_than_once = {};\n\n  foreach my $symlist (values(%{$symbols})) {\n    # TODO(csilvers): deal with inlined symbols too.\n    my $shortname = $symlist->[0];\n    my $fullname = $symlist->[2];\n    if ($fullname !~ /<[0-9a-fA-F]+>$/) {  # fullname doesn't end in an address\n      next;       # the only collisions we care about are when addresses differ\n    }\n    if (defined($shortnames_seen_once->{$shortname}) &&\n        $shortnames_seen_once->{$shortname} ne $fullname) {\n      $shortnames_seen_more_than_once->{$shortname} = 1;\n    } else {\n      $shortnames_seen_once->{$shortname} = $fullname;\n    }\n  }\n\n  foreach my $symlist (values(%{$symbols})) {\n    my $shortname = $symlist->[0];\n    my $fullname = $symlist->[2];\n    # TODO(csilvers): take in a list of addresses we care about, and only\n    # store in the map if $symlist->[1] is in that list.  Saves space.\n    next if defined($fullname_to_shortname_map->{$fullname});\n    if (defined($shortnames_seen_more_than_once->{$shortname})) {\n      if ($fullname =~ /<0*([^>]*)>$/) {   # fullname has address at end of it\n        $fullname_to_shortname_map->{$fullname} = \"$shortname\\@$1\";\n      }\n    }\n  }\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 $fullname_to_shortname_map = 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 (defined($fullname_to_shortname_map->{$fullfunc})) {\n        $func = $fullname_to_shortname_map->{$fullfunc};\n      }\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# Alternate pretty-printed form: 0 maps to \"\"\nsub HtmlPrintNumber {\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 FilterFrames {\n  my $symbols = shift;\n  my $profile = shift;\n\n  if ($main::opt_retain eq '' && $main::opt_exclude eq '') {\n    return $profile;\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      my $sym;\n      if (exists($symbols->{$a})) {\n        $sym = $symbols->{$a}->[0];\n      } else {\n        $sym = $a;\n      }\n      if ($main::opt_retain ne '' && $sym !~ m/$main::opt_retain/) {\n        next;\n      }\n      if ($main::opt_exclude ne '' && $sym =~ m/$main::opt_exclude/) {\n        next;\n      }\n      push(@path, $a);\n    }\n    if (scalar(@path) > 0) {\n      my $reduced_path = join(\"\\n\", @path);\n      AddEntry($result, $reduced_path, $count);\n    }\n  }\n\n  return $result;\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                      'aligned_alloc',\n                      'pvalloc',\n                      'valloc',\n                      'realloc',\n                      'mallocx', # jemalloc\n                      'rallocx', # jemalloc\n                      'xallocx', # jemalloc\n                      'dallocx', # jemalloc\n                      'sdallocx', # jemalloc\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                      # The entry to our memory-allocation routines on OS X\n                      'malloc_zone_malloc',\n                      'malloc_zone_calloc',\n                      'malloc_zone_valloc',\n                      'malloc_zone_realloc',\n                      'malloc_zone_memalign',\n                      'malloc_zone_free',\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          # Throw away the portion of the backtrace seen so far, under the\n          # assumption that previous frames were for functions internal to the\n          # allocator.\n          @path = ();\n          next;\n        }\n      }\n      push(@path, $a);\n    }\n    my $reduced_path = join(\"\\n\", @path);\n    AddEntry($result, $reduced_path, $count);\n  }\n\n  $result = FilterFrames($symbols, $result);\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  my $fullname_to_shortname_map = {};\n  FillFullnameToShortnameMap($symbols, $fullname_to_shortname_map);\n  foreach my $k (keys(%{$profile})) {\n    my $count = $profile->{$k};\n    my @translated = TranslateStack($symbols, $fullname_to_shortname_map, $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  my $command = ShellEscape(@URL_FETCHER, $url);\n  open(SYMBOL, \"$command |\") or error($command);\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 = ShellEscape(@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 = ShellEscape(@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.  Returns a new list.\nsub AddFetchTimeout {\n  my $timeout = shift;\n  my @fetcher = @_;\n  if (defined($timeout)) {\n    if (join(\" \", @fetcher) =~ m/\\bcurl -s/) {\n      push(@fetcher, \"--max-time\", sprintf(\"%d\", $timeout));\n    } elsif (join(\" \", @fetcher) =~ m/\\brpcget\\b/) {\n      push(@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\nsub URLEncode {\n  my $str = shift;\n  $str =~ s/([^A-Za-z0-9\\-_.!~*'()])/ sprintf \"%%%02x\", ord $1 /eg;\n  return $str;\n}\n\nsub AppendSymbolFilterParams {\n  my $url = shift;\n  my @params = ();\n  if ($main::opt_retain ne '') {\n    push(@params, sprintf(\"retain=%s\", URLEncode($main::opt_retain)));\n  }\n  if ($main::opt_exclude ne '') {\n    push(@params, sprintf(\"exclude=%s\", URLEncode($main::opt_exclude)));\n  }\n  if (scalar @params > 0) {\n    $url = sprintf(\"%s?%s\", $url, join(\"&\", @params));\n  }\n  return $url;\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 (join(\" \", @URL_FETCHER) =~ m/\\bcurl -s/) {\n      $url = ResolveRedirectionForCurl($url);\n      $url = AppendSymbolFilterParams($url);\n      $command_line = ShellEscape(@URL_FETCHER, \"-d\", \"\\@$main::tmpfile_sym\",\n                                  $url);\n    } else {\n      $url = AppendSymbolFilterParams($url);\n      $command_line = (ShellEscape(@URL_FETCHER, \"--post\", $url)\n                       . \" < \" . ShellEscape($main::tmpfile_sym));\n    }\n    # We use c++filt in case $SYMBOL_PAGE gives us mangled symbols.\n    my $escaped_cppfilt = ShellEscape($obj_tool_map{\"c++filt\"});\n    open(SYMBOL, \"$command_line | $escaped_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 (in\n    # PrintSymbolizedProfile), 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      # Set $profile_type for consumption by PrintSymbolizedProfile.\n      $main::profile_type = 'cpu';\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      # Set $profile_type for consumption by PrintSymbolizedProfile.\n      if ($path =~ m/$HEAP_PAGE/) {\n        $main::profile_type = 'heap';\n      } elsif ($path =~ m/$GROWTH_PAGE/) {\n        $main::profile_type = 'growth';\n      } elsif ($path =~ m/$CONTENTION_PAGE/) {\n        $main::profile_type = 'contention';\n      }\n    }\n\n    my $profile_dir = $ENV{\"JEPROF_TMPDIR\"} || ($ENV{HOME} . \"/jeprof\");\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($fetch_timeout, @URL_FETCHER);\n    my $cmd = ShellEscape(@fetcher, $url) . \" > \" . ShellEscape($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        $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        #    Right now, we just die.\n        my ($lo, $hi) = ($b32_values[$i], $b32_values[$i+1]);\n        if ($self->{unpack_code} eq 'N') {    # big-endian\n          ($lo, $hi) = ($hi, $lo);\n        }\n        my $value = $lo + $hi * (2**32);\n        if (!$self->{perl_is_64bit} &&   # check value is exactly represented\n            (($value % (2**32)) != $lo || int($value / (2**32)) != $hi)) {\n          ::error(\"Need a 64-bit perl to process this 64-bit profile.\\n\");\n        }\n        push(@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 jeprof, which jeprof 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->{threads}     Map of thread IDs to profile objects\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  $HEAP_PAGE =~ m,[^/]+$,;    # matches everything after the last slash\n  my $heap_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            \"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  if ($header =~ m/^--- *($heap_marker|$growth_marker)/o) {\n    # Skip \"--- ...\" line for profile types that have their own headers.\n    $header = ReadProfileHeader(*PROFILE) || \"\";\n  }\n\n  $main::profile_type = '';\n\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/^heap/) {\n    $main::profile_type = 'heap';\n    $result = ReadThreadedHeapProfile($prog, $fname, $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  # --raw/http: Always subtract one from pc's, because PrintSymbolizedProfile()\n  # dumps unadjusted profiles.\n  {\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      $pc--;\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 HeapProfileIndex {\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  return $index;\n}\n\nsub ReadMappedLibraries {\n  my $fh = shift;\n  my $map = \"\";\n  # Read the /proc/self/maps data\n  while (<$fh>) {\n    s/\\r//g;         # turn windows-looking lines into unix-looking lines\n    $map .= $_;\n  }\n  return $map;\n}\n\nsub ReadMemoryMap {\n  my $fh = shift;\n  my $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  return $map;\n}\n\nsub AdjustSamples {\n  my ($sample_adjustment, $sampling_algorithm, $n1, $s1, $n2, $s2) = @_;\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      if ($n1 != 0) {\n        my $ratio = (($s1*1.0)/$n1)/($sample_adjustment);\n        my $scale_factor = 1/(1 - exp(-$ratio));\n        $n1 *= $scale_factor;\n        $s1 *= $scale_factor;\n      }\n      if ($n2 != 0) {\n        my $ratio = (($s2*1.0)/$n2)/($sample_adjustment);\n        my $scale_factor = 1/(1 - exp(-$ratio));\n        $n2 *= $scale_factor;\n        $s2 *= $scale_factor;\n      }\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  return ($n1, $s1, $n2, $s2);\n}\n\nsub ReadHeapProfile {\n  my $prog = shift;\n  local *PROFILE = shift;\n  my $header = shift;\n\n  my $index = HeapProfileIndex();\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      $map .= ReadMappedLibraries(*PROFILE);\n      last;\n    }\n\n    if (/^--- Memory map:/) {\n      $map .= ReadMemoryMap(*PROFILE);\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      my @counts = AdjustSamples($sample_adjustment, $sampling_algorithm,\n                                 $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 ReadThreadedHeapProfile {\n  my ($prog, $fname, $header) = @_;\n\n  my $index = HeapProfileIndex();\n  my $sampling_algorithm = 0;\n  my $sample_adjustment = 0;\n  chomp($header);\n  my $type = \"unknown\";\n  # Assuming a very specific type of header for now.\n  if ($header =~ m\"^heap_v2/(\\d+)\") {\n    $type = \"_v2\";\n    $sampling_algorithm = 2;\n    $sample_adjustment = int($1);\n  }\n  if ($type ne \"_v2\" || !defined($sample_adjustment)) {\n    die \"Threaded heap profiles require v2 sampling with a sample rate\\n\";\n  }\n\n  my $profile = {};\n  my $thread_profiles = {};\n  my $pcs = {};\n  my $map = \"\";\n  my $stack = \"\";\n\n  while (<PROFILE>) {\n    s/\\r//g;\n    if (/^MAPPED_LIBRARIES:/) {\n      $map .= ReadMappedLibraries(*PROFILE);\n      last;\n    }\n\n    if (/^--- Memory map:/) {\n      $map .= ReadMemoryMap(*PROFILE);\n      last;\n    }\n\n    # Read entry of the form:\n    # @ a1 a2 ... an\n    #   t*: <count1>: <bytes1> [<count2>: <bytes2>]\n    #   t1: <count1>: <bytes1> [<count2>: <bytes2>]\n    #     ...\n    #   tn: <count1>: <bytes1> [<count2>: <bytes2>]\n    s/^\\s*//;\n    s/\\s*$//;\n    if (m/^@\\s+(.*)$/) {\n      $stack = $1;\n    } elsif (m/^\\s*(t(\\*|\\d+)):\\s+(\\d+):\\s+(\\d+)\\s+\\[\\s*(\\d+):\\s+(\\d+)\\]$/) {\n      if ($stack eq \"\") {\n        # Still in the header, so this is just a per-thread summary.\n        next;\n      }\n      my $thread = $2;\n      my ($n1, $s1, $n2, $s2) = ($3, $4, $5, $6);\n      my @counts = AdjustSamples($sample_adjustment, $sampling_algorithm,\n                                 $n1, $s1, $n2, $s2);\n      if ($thread eq \"*\") {\n        AddEntries($profile, $pcs, FixCallerAddresses($stack), $counts[$index]);\n      } else {\n        if (!exists($thread_profiles->{$thread})) {\n          $thread_profiles->{$thread} = {};\n        }\n        AddEntries($thread_profiles->{$thread}, $pcs,\n                   FixCallerAddresses($stack), $counts[$index]);\n      }\n    }\n  }\n\n  my $r = {};\n  $r->{version} = \"heap\";\n  $r->{period} = 1;\n  $r->{profile} = $profile;\n  $r->{threads} = $thread_profiles;\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 jeprof\n        # So we just silently ignore it for now\n      } elsif ($variable eq \"discarded samples\") {\n        # Currently nothing is done with this value in jeprof\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\" or \"1abcd\", return either\n# \"0001abcd\" or \"000000000001abcd\", depending on the current (global)\n# address length.\nsub HexExtend {\n  my $addr = shift;\n\n  $addr =~ s/^(0x)?0*//;\n  my $zeros_needed = $address_length - length($addr);\n  if ($zeros_needed < 0) {\n    printf STDERR \"Warning: address $addr is longer than address length $address_length\\n\";\n    return $addr;\n  }\n  return (\"0\" x $zeros_needed) . $addr;\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|^/|) {\n      if (-f \"/usr/lib/debug$file\") {\n        return \"/usr/lib/debug$file\";\n      } elsif (-f \"/usr/lib/debug$file.debug\") {\n        return \"/usr/lib/debug$file.debug\";\n      }\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 $cmd = ShellEscape($obj_tool_map{\"objdump\"}, \"-h\", $lib);\n  open(OBJDUMP, \"$cmd |\") || error(\"$cmd: $!\\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 $command = ShellEscape($obj_tool_map{\"otool\"}, \"-l\", $lib);\n  open(OTOOL, \"$command |\") || error(\"$command: $!\\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    }\n    # FreeBSD 10.0 virtual memory map /proc/curproc/map as defined in\n    # function procfs_doprocmap (sys/fs/procfs/procfs_map.c)\n    #\n    # Example:\n    # 0x800600000 0x80061a000 26 0 0xfffff800035a0000 r-x 75 33 0x1004 COW NC vnode /libexec/ld-elf.s\n    # o.1 NCH -1\n    elsif ($l =~ /^(0x$h)\\s(0x$h)\\s\\d+\\s\\d+\\s0x$h\\sr-x\\s\\d+\\s\\d+\\s0x\\d+\\s(COW|NCO)\\s(NC|NNC)\\svnode\\s(\\S+\\.so(\\.\\d+)*)/) {\n      $start = HexExtend($1);\n      $finish = HexExtend($2);\n      $offset = $zero_offset;\n      $lib = FindLibrary($5);\n\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    if($main::opt_debug) { printf STDERR \"$start:$finish ($offset) $lib\\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 jeprof --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 jeprof --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 jeprof --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    # Use debug library if it exists\n    my $debug_libname = DebuggingLibrary($libname);\n    if ($debug_libname) {\n        $libname = $debug_libname;\n    }\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         $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         $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                           $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 = ShellEscape($addr2line, \"-f\", \"-C\", \"-e\", $image);\n  if (exists $obj_tool_map{\"addr2line_pdb\"}) {\n    $addr2line = $obj_tool_map{\"addr2line_pdb\"};\n    $cmd = ShellEscape($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(ShellEscape($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  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 < \" . ShellEscape($main::tmpfile_sym));\n    print(\"----\\n\");\n  }\n\n  open(SYMBOLS, \"$cmd <\" . ShellEscape($main::tmpfile_sym) . \" |\")\n      || 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    my $nms = $nm_symbols->{$pcstr};\n    if (defined($nms)) {\n      if ($fullfunction eq '??') {\n        # nm found a symbol for us.\n        $function = $nms->[0];\n        $fullfunction = $nms->[2];\n      } else {\n\t# MapSymbolsWithNM tags each routine with its starting address,\n\t# useful in case the image has multiple occurrences of this\n\t# routine.  (It uses a syntax that resembles template paramters,\n\t# that are automatically stripped out by ShortFunctionName().)\n\t# addr2line does not provide the same information.  So we check\n\t# if nm disambiguated our symbol, and if so take the annotated\n\t# (nm) version of the routine-name.  TODO(csilvers): this won't\n\t# catch overloaded, inlined symbols, which nm doesn't see.\n\t# Better would be to do a check similar to nm's, in this fn.\n\tif ($nms->[2] =~ m/^\\Q$function\\E/) {  # sanity check it's the right fn\n\t  $function = $nms->[0];\n\t  $fullfunction = $nms->[2];\n\t}\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, so 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# Trim overly long symbols found in disassembler output\nsub CleanDisassembly {\n  my $d = shift;\n  while ($d =~ s/\\([^()%]*\\)(\\s*const)?//g) { } # Argument types, not (%rax)\n  while ($d =~ s/(\\w+)<[^<>]*>/$1/g)  { }       # Remove template arguments\n  return $d;\n}\n\n# Clean file name for display\nsub CleanFileName {\n  my ($f) = @_;\n  $f =~ s|^/proc/self/cwd/||;\n  $f =~ s|^\\./||;\n  return $f;\n}\n\n# Make address relative to section and clean up for display\nsub UnparseAddress {\n  my ($offset, $address) = @_;\n  $address = AddressSub($address, $offset);\n  $address =~ s/^0x//;\n  $address =~ s/^0*//;\n  return $address;\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) JEPROF_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  my $file_type = undef;\n  if (-e \"/usr/bin/file\") {\n    # Follow symlinks (at least for systems where \"file\" supports that).\n    my $escaped_prog_file = ShellEscape($prog_file);\n    $file_type = `/usr/bin/file -L $escaped_prog_file 2>$dev_null ||\n                  /usr/bin/file $escaped_prog_file`;\n  } elsif ($^O == \"MSWin32\") {\n    $file_type = \"MS Windows\";\n  } else {\n    print STDERR \"WARNING: Can't determine the file type of $prog_file\";\n  }\n\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 jeprof.\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# JEPROF_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 $JEPROF_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{\"JEPROF_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 \\$JEPROF_TOOLS) '$tools'\\n\");\n    }\n  } else {\n    # ... otherwise use the version that exists in the same directory as\n    # jeprof.  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 ShellEscape {\n  my @escaped_words = ();\n  foreach my $word (@_) {\n    my $escaped_word = $word;\n    if ($word =~ m![^a-zA-Z0-9/.,_=-]!) {  # check for anything not in whitelist\n      $escaped_word =~ s/'/'\\\\''/;\n      $escaped_word = \"'$escaped_word'\";\n    }\n    push(@escaped_words, $escaped_word);\n  }\n  return join(\" \", @escaped_words);\n}\n\nsub cleanup {\n  unlink($main::tmpfile_sym);\n  unlink(keys %main::tempnames);\n\n  # We leave any collected profiles in $HOME/jeprof 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 \"  jeprof \\\\\\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 $escaped_nm_command = shift;    # shell-escaped\n  my $regexp = shift;\n\n  my $symbol_table = {};\n  open(NM, \"$escaped_nm_command |\") || error(\"$escaped_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 parameters 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  # If $image doesn't start with /, then put ./ in front of it.  This works\n  # around an obnoxious bug in our probing of nm -f behavior.\n  # \"nm -f $image\" is supposed to fail on GNU nm, but if:\n  #\n  # a. $image starts with [BbSsPp] (for example, bin/foo/bar), AND\n  # b. you have a.out in your current directory (a not uncommon occurence)\n  #\n  # then \"nm -f $image\" succeeds because -f only looks at the first letter of\n  # the argument, which looks valid because it's [BbSsPp], and then since\n  # there's no image provided, it looks for a.out and finds it.\n  #\n  # This regex makes sure that $image starts with . or /, forcing the -f\n  # parsing to fail since . and / are not valid formats.\n  $image =~ s#^[^/]#./$&#;\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  my $to_devnull = \">$dev_null 2>&1\";\n  if (system(ShellEscape($nm, \"--demangle\", \"image\") . $to_devnull) == 0) {\n    # In this mode, we do \"nm --demangle <foo>\"\n    $demangle_flag = \"--demangle\";\n    $cppfilt_flag = \"\";\n  } elsif (system(ShellEscape($cppfilt, $image) . $to_devnull) == 0) {\n    # In this mode, we do \"nm <foo> | c++filt\"\n    $cppfilt_flag = \" | \" . ShellEscape($cppfilt);\n  };\n  my $flatten_flag = \"\";\n  if (system(ShellEscape($nm, \"-f\", $image) . $to_devnull) == 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 = (ShellEscape($nm, \"-n\", $flatten_flag, $demangle_flag,\n                                 $image) . \" 2>$dev_null $cppfilt_flag\",\n                     ShellEscape($nm, \"-D\", \"-n\", $flatten_flag, $demangle_flag,\n                                 $image) . \" 2>$dev_null $cppfilt_flag\",\n                     # 6nm is for Go binaries\n                     ShellEscape(\"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    push(@nm_commands,\n         ShellEscape($obj_tool_map{\"nm_pdb\"}, \"--demangle\", $image)\n         . \" 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 jeprof 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": "deps/jemalloc-4.1.0/build-aux/config.guess",
    "content": "#! /bin/sh\n# Attempt to guess a canonical system name.\n#   Copyright 1992-2014 Free Software Foundation, Inc.\n\ntimestamp='2014-03-23'\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 3 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, see <http://www.gnu.org/licenses/>.\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\n# program.  This Exception is an additional permission under section 7\n# of the GNU General Public License, version 3 (\"GPLv3\").\n#\n# Originally written by Per Bothner.\n#\n# You can get the latest version of this script from:\n# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD\n#\n# Please send patches with a ChangeLog entry to config-patches@gnu.org.\n\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 1992-2014 Free 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\ncase \"${UNAME_SYSTEM}\" in\nLinux|GNU|GNU/*)\n\t# If the system lacks a compiler, then just pick glibc.\n\t# We could probably try harder.\n\tLIBC=gnu\n\n\teval $set_cc_for_build\n\tcat <<-EOF > $dummy.c\n\t#include <features.h>\n\t#if defined(__UCLIBC__)\n\tLIBC=uclibc\n\t#elif defined(__dietlibc__)\n\tLIBC=dietlibc\n\t#else\n\tLIBC=gnu\n\t#endif\n\tEOF\n\teval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`\n\t;;\nesac\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 tuples: *-*-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 -q __ELF__\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\tos=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    *:Bitrig:*:*)\n\tUNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`\n\techo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_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\tUNAME_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\t# Reset EXIT trap before exiting to avoid spurious non-zero exit code.\n\texitcode=$?\n\ttrap '' 0\n\texit $exitcode ;;\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\techo 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    s390x:SunOS:*:*)\n\techo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit ;;\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:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)\n\techo i386-pc-auroraux${UNAME_RELEASE}\n\texit ;;\n    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)\n\teval $set_cc_for_build\n\tSUN_ARCH=\"i386\"\n\t# If there is a compiler, see if it is configured for 64-bit objects.\n\t# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.\n\t# This test works for both compilers.\n\tif [ \"$CC_FOR_BUILD\" != 'no_compiler_found' ]; then\n\t    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \\\n\t\t(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \\\n\t\tgrep IS_64BIT_ARCH >/dev/null\n\t    then\n\t\tSUN_ARCH=\"x86_64\"\n\t    fi\n\tfi\n\techo ${SUN_ARCH}-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\techo m68k-atari-mint${UNAME_RELEASE}\n\texit ;;\n    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)\n\techo m68k-atari-mint${UNAME_RELEASE}\n\texit ;;\n    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)\n\techo m68k-atari-mint${UNAME_RELEASE}\n\texit ;;\n    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)\n\techo m68k-milan-mint${UNAME_RELEASE}\n\texit ;;\n    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)\n\techo m68k-hades-mint${UNAME_RELEASE}\n\texit ;;\n    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)\n\techo m68k-unknown-mint${UNAME_RELEASE}\n\texit ;;\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\t# DG/UX returns AViiON for all architectures\n\tUNAME_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:*:[4567])\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\t\t    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`\n\t\t    case \"${sc_cpu_version}\" in\n\t\t      523) HP_ARCH=\"hppa1.0\" ;; # CPU_PA_RISC1_0\n\t\t      528) HP_ARCH=\"hppa1.1\" ;; # CPU_PA_RISC1_1\n\t\t      532)                      # CPU_PA_RISC2_0\n\t\t\tcase \"${sc_kernel_bits}\" in\n\t\t\t  32) HP_ARCH=\"hppa2.0n\" ;;\n\t\t\t  64) HP_ARCH=\"hppa2.0w\" ;;\n\t\t\t  '') HP_ARCH=\"hppa2.0\" ;;   # HP-UX 10.20\n\t\t\tesac ;;\n\t\t    esac\n\t\tfi\n\t\tif [ \"${HP_ARCH}\" = \"\" ]; then\n\t\t    eval $set_cc_for_build\n\t\t    sed 's/^\t\t//' << EOF >$dummy.c\n\n\t\t#define _HPUX_SOURCE\n\t\t#include <stdlib.h>\n\t\t#include <unistd.h>\n\n\t\tint main ()\n\t\t{\n\t\t#if defined(_SC_KERNEL_BITS)\n\t\t    long bits = sysconf(_SC_KERNEL_BITS);\n\t\t#endif\n\t\t    long cpu  = sysconf (_SC_CPU_VERSION);\n\n\t\t    switch (cpu)\n\t\t\t{\n\t\t\tcase CPU_PA_RISC1_0: puts (\"hppa1.0\"); break;\n\t\t\tcase CPU_PA_RISC1_1: puts (\"hppa1.1\"); break;\n\t\t\tcase CPU_PA_RISC2_0:\n\t\t#if defined(_SC_KERNEL_BITS)\n\t\t\t    switch (bits)\n\t\t\t\t{\n\t\t\t\tcase 64: puts (\"hppa2.0w\"); break;\n\t\t\t\tcase 32: puts (\"hppa2.0n\"); break;\n\t\t\t\tdefault: puts (\"hppa2.0\"); break;\n\t\t\t\t} break;\n\t\t#else  /* !defined(_SC_KERNEL_BITS) */\n\t\t\t    puts (\"hppa2.0\"); break;\n\t\t#endif\n\t\t\tdefault: puts (\"hppa1.0\"); break;\n\t\t\t}\n\t\t    exit (0);\n\t\t}\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 -q __LP64__\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\texit ;;\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\texit ;;\n    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)\n\techo c34-convex-bsd\n\texit ;;\n    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)\n\techo c38-convex-bsd\n\texit ;;\n    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)\n\techo c4-convex-bsd\n\texit ;;\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\tFUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\\///'`\n\tFUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`\n\techo \"${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}\"\n\texit ;;\n    5000:UNIX_System_V:4.*:*)\n\tFUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\\///'`\n\tFUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`\n\techo \"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\tUNAME_PROCESSOR=`/usr/bin/uname -p`\n\tcase ${UNAME_PROCESSOR} in\n\t    amd64)\n\t\techo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;\n\t    *)\n\t\techo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;\n\tesac\n\texit ;;\n    i*:CYGWIN*:*)\n\techo ${UNAME_MACHINE}-pc-cygwin\n\texit ;;\n    *:MINGW64*:*)\n\techo ${UNAME_MACHINE}-pc-mingw64\n\texit ;;\n    *:MINGW*:*)\n\techo ${UNAME_MACHINE}-pc-mingw32\n\texit ;;\n    *:MSYS*:*)\n\techo ${UNAME_MACHINE}-pc-msys\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*:*)\n\tcase ${UNAME_MACHINE} in\n\t    x86)\n\t\techo i586-pc-interix${UNAME_RELEASE}\n\t\texit ;;\n\t    authenticamd | genuineintel | EM64T)\n\t\techo x86_64-unknown-interix${UNAME_RELEASE}\n\t\texit ;;\n\t    IA64)\n\t\techo ia64-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    8664:Windows_NT:*)\n\techo x86_64-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-${LIBC}`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/[-(].*//'`-${LIBC}\n\texit ;;\n    i*86:Minix:*:*)\n\techo ${UNAME_MACHINE}-pc-minix\n\texit ;;\n    aarch64:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\texit ;;\n    aarch64_be:Linux:*:*)\n\tUNAME_MACHINE=aarch64_be\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\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\tesac\n\tobjdump --private-headers /bin/sh | grep -q ld.so.1\n\tif test \"$?\" = 0 ; then LIBC=\"gnulibc1\" ; fi\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\texit ;;\n    arc:Linux:*:* | arceb:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\texit ;;\n    arm*:Linux:*:*)\n\teval $set_cc_for_build\n\tif echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \\\n\t    | grep -q __ARM_EABI__\n\tthen\n\t    echo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\telse\n\t    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \\\n\t\t| grep -q __ARM_PCS_VFP\n\t    then\n\t\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi\n\t    else\n\t\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf\n\t    fi\n\tfi\n\texit ;;\n    avr32*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\texit ;;\n    cris:Linux:*:*)\n\techo ${UNAME_MACHINE}-axis-linux-${LIBC}\n\texit ;;\n    crisv32:Linux:*:*)\n\techo ${UNAME_MACHINE}-axis-linux-${LIBC}\n\texit ;;\n    frv:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\texit ;;\n    hexagon:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\texit ;;\n    i*86:Linux:*:*)\n\techo ${UNAME_MACHINE}-pc-linux-${LIBC}\n\texit ;;\n    ia64:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\texit ;;\n    m32r*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\texit ;;\n    m68*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\texit ;;\n    mips:Linux:*:* | mips64:Linux:*:*)\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n\t#undef CPU\n\t#undef ${UNAME_MACHINE}\n\t#undef ${UNAME_MACHINE}el\n\t#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)\n\tCPU=${UNAME_MACHINE}el\n\t#else\n\t#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)\n\tCPU=${UNAME_MACHINE}\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-${LIBC}\"; exit; }\n\t;;\n    openrisc*:Linux:*:*)\n\techo or1k-unknown-linux-${LIBC}\n\texit ;;\n    or32:Linux:*:* | or1k*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\texit ;;\n    padre:Linux:*:*)\n\techo sparc-unknown-linux-${LIBC}\n\texit ;;\n    parisc64:Linux:*:* | hppa64:Linux:*:*)\n\techo hppa64-unknown-linux-${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-${LIBC} ;;\n\t  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;\n\t  *)    echo hppa-unknown-linux-${LIBC} ;;\n\tesac\n\texit ;;\n    ppc64:Linux:*:*)\n\techo powerpc64-unknown-linux-${LIBC}\n\texit ;;\n    ppc:Linux:*:*)\n\techo powerpc-unknown-linux-${LIBC}\n\texit ;;\n    ppc64le:Linux:*:*)\n\techo powerpc64le-unknown-linux-${LIBC}\n\texit ;;\n    ppcle:Linux:*:*)\n\techo powerpcle-unknown-linux-${LIBC}\n\texit ;;\n    s390:Linux:*:* | s390x:Linux:*:*)\n\techo ${UNAME_MACHINE}-ibm-linux-${LIBC}\n\texit ;;\n    sh64*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\texit ;;\n    sh*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\texit ;;\n    sparc:Linux:*:* | sparc64:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\texit ;;\n    tile*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\texit ;;\n    vax:Linux:*:*)\n\techo ${UNAME_MACHINE}-dec-linux-${LIBC}\n\texit ;;\n    x86_64:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\texit ;;\n    xtensa*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-${LIBC}\n\texit ;;\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\t# Unixware is an offshoot of SVR4, but it has its own version\n\t# number series starting with 2...\n\t# I am not positive that other SVR4 systems won't match this,\n\t# I just have to hope.  -- rms.\n\t# 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.[02]*:*)\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\t# uname -m prints for DJGPP always 'pc', but it prints nothing about\n\t# the processor, so we play safe by assuming i586.\n\t# Note: whatever this is, it MUST be the same as what config.sub\n\t# prints for the \"djgpp\" host, or else GDB configury will decide that\n\t# this is a cross-build.\n\techo i586-pc-msdosdjgpp\n\texit ;;\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\t/bin/uname -p 2>/dev/null | grep 86 >/dev/null \\\n\t  && { echo i486-ncr-sysv4; exit; } ;;\n    NCR*:*:4.2:* | MPRAS*:*:4.2:*)\n\tOS_REL='.3'\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\t/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \\\n\t    && { echo i586-ncr-sysv4.3${OS_REL}; 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.[02]*:*)\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*:*)\t# Unisys `ClearPath HMP IX 4000' SVR4/MP effort\n\t\t\t# says <Richard.M.Bartel@ccMail.Census.GOV>\n\techo i586-unisys-sysv4\n\texit ;;\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\techo mips-nec-sysv${UNAME_RELEASE}\n\telse\n\t\techo mips-unknown-sysv${UNAME_RELEASE}\n\tfi\n\texit ;;\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    BePC:Haiku:*:*)\t# Haiku running on Intel PC compatible.\n\techo i586-pc-haiku\n\texit ;;\n    x86_64:Haiku:*:*)\n\techo x86_64-unknown-haiku\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\teval $set_cc_for_build\n\tif test \"$UNAME_PROCESSOR\" = unknown ; then\n\t    UNAME_PROCESSOR=powerpc\n\tfi\n\tif test `echo \"$UNAME_RELEASE\" | sed -e 's/\\..*//'` -le 10 ; then\n\t    if [ \"$CC_FOR_BUILD\" != 'no_compiler_found' ]; then\n\t\tif (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \\\n\t\t    (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \\\n\t\t    grep IS_64BIT_ARCH >/dev/null\n\t\tthen\n\t\t    case $UNAME_PROCESSOR in\n\t\t\ti386) UNAME_PROCESSOR=x86_64 ;;\n\t\t\tpowerpc) UNAME_PROCESSOR=powerpc64 ;;\n\t\t    esac\n\t\tfi\n\t    fi\n\telif test \"$UNAME_PROCESSOR\" = i386 ; then\n\t    # Avoid executing cc on OS X 10.9, as it ships with a stub\n\t    # that puts up a graphical alert prompting to install\n\t    # developer tools.  Any system running Mac OS X 10.7 or\n\t    # later (Darwin 11 and later) is required to have a 64-bit\n\t    # processor. This is not true of the ARM version of Darwin\n\t    # that Apple uses in portable devices.\n\t    UNAME_PROCESSOR=x86_64\n\tfi\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    NEO-?:NONSTOP_KERNEL:*:*)\n\techo neo-tandem-nsk${UNAME_RELEASE}\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\techo 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 ;;\n    i*86:AROS:*:*)\n\techo ${UNAME_MACHINE}-pc-aros\n\texit ;;\n    x86_64:VMkernel:*:*)\n\techo ${UNAME_MACHINE}-unknown-esx\n\texit ;;\nesac\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://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD\nand\n  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD\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": "deps/jemalloc-4.1.0/build-aux/config.sub",
    "content": "#! /bin/sh\n# Configuration validation subroutine script.\n#   Copyright 1992-2014 Free Software Foundation, Inc.\n\ntimestamp='2014-05-01'\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 3 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, see <http://www.gnu.org/licenses/>.\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\n# program.  This Exception is an additional permission under section 7\n# of the GNU General Public License, version 3 (\"GPLv3\").\n\n\n# Please send patches with a ChangeLog entry to config-patches@gnu.org.\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# You can get the latest version of this script from:\n# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD\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 1992-2014 Free 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-android* | linux-dietlibc | linux-newlib* | \\\n  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \\\n  knetbsd*-gnu* | netbsd*-gnu* | \\\n  kopensolaris*-gnu* | \\\n  storm-chaos* | os2-emx* | rtmk-nova*)\n    os=-$maybe_os\n    basic_machine=`echo $1 | sed 's/^\\(.*\\)-\\([^-]*-[^-]*\\)$/\\1/'`\n    ;;\n  android-linux)\n    os=-linux-android\n    basic_machine=`echo $1 | sed 's/^\\(.*\\)-\\([^-]*-[^-]*\\)$/\\1/'`-unknown\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 | -microblaze*)\n\t\tos=\n\t\tbasic_machine=$1\n\t\t;;\n\t-bluegene*)\n\t\tos=-cnk\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*178)\n\t\tos=-lynxos178\n\t\t;;\n\t-lynx*5)\n\t\tos=-lynxos5\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| aarch64 | aarch64_be \\\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 | arceb \\\n\t| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \\\n\t| avr | avr32 \\\n\t| be32 | be64 \\\n\t| bfin \\\n\t| c4x | c8051 | clipper \\\n\t| d10v | d30v | dlx | dsp16xx \\\n\t| epiphany \\\n\t| fido | fr30 | frv \\\n\t| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \\\n\t| hexagon \\\n\t| i370 | i860 | i960 | ia64 \\\n\t| ip2k | iq2000 \\\n\t| k1om \\\n\t| le32 | le64 \\\n\t| lm32 \\\n\t| m32c | m32r | m32rle | m68000 | m68k | m88k \\\n\t| maxq | mb | microblaze | microblazeel | mcore | mep | metag \\\n\t| mips | mipsbe | mipseb | mipsel | mipsle \\\n\t| mips16 \\\n\t| mips64 | mips64el \\\n\t| mips64octeon | mips64octeonel \\\n\t| mips64orion | mips64orionel \\\n\t| mips64r5900 | mips64r5900el \\\n\t| mips64vr | mips64vrel \\\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| mipsisa32r6 | mipsisa32r6el \\\n\t| mipsisa64 | mipsisa64el \\\n\t| mipsisa64r2 | mipsisa64r2el \\\n\t| mipsisa64r6 | mipsisa64r6el \\\n\t| mipsisa64sb1 | mipsisa64sb1el \\\n\t| mipsisa64sr71k | mipsisa64sr71kel \\\n\t| mipsr5900 | mipsr5900el \\\n\t| mipstx39 | mipstx39el \\\n\t| mn10200 | mn10300 \\\n\t| moxie \\\n\t| mt \\\n\t| msp430 \\\n\t| nds32 | nds32le | nds32be \\\n\t| nios | nios2 | nios2eb | nios2el \\\n\t| ns16k | ns32k \\\n\t| open8 | or1k | or1knd | or32 \\\n\t| pdp10 | pdp11 | pj | pjl \\\n\t| powerpc | powerpc64 | powerpc64le | powerpcle \\\n\t| pyramid \\\n\t| rl78 | rx \\\n\t| score \\\n\t| sh | sh[1234] | sh[24]a | sh[24]aeb | 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 \\\n\t| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \\\n\t| ubicom32 \\\n\t| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \\\n\t| we32k \\\n\t| x86 | xc16x | xstormy16 | xtensa \\\n\t| z8k | z80)\n\t\tbasic_machine=$basic_machine-unknown\n\t\t;;\n\tc54x)\n\t\tbasic_machine=tic54x-unknown\n\t\t;;\n\tc55x)\n\t\tbasic_machine=tic55x-unknown\n\t\t;;\n\tc6x)\n\t\tbasic_machine=tic6x-unknown\n\t\t;;\n\tm6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)\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\tstrongarm | thumb | xscale)\n\t\tbasic_machine=arm-unknown\n\t\t;;\n\txgate)\n\t\tbasic_machine=$basic_machine-unknown\n\t\tos=-none\n\t\t;;\n\txscaleeb)\n\t\tbasic_machine=armeb-unknown\n\t\t;;\n\n\txscaleel)\n\t\tbasic_machine=armel-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| aarch64-* | aarch64_be-* \\\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-* | arceb-* \\\n\t| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \\\n\t| avr-* | avr32-* \\\n\t| be32-* | be64-* \\\n\t| bfin-* | bs2000-* \\\n\t| c[123]* | c30-* | [cjt]90-* | c4x-* \\\n\t| c8051-* | 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| hexagon-* \\\n\t| i*86-* | i860-* | i960-* | ia64-* \\\n\t| ip2k-* | iq2000-* \\\n\t| k1om-* \\\n\t| le32-* | le64-* \\\n\t| lm32-* \\\n\t| m32c-* | m32r-* | m32rle-* \\\n\t| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \\\n\t| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \\\n\t| microblaze-* | microblazeel-* \\\n\t| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \\\n\t| mips16-* \\\n\t| mips64-* | mips64el-* \\\n\t| mips64octeon-* | mips64octeonel-* \\\n\t| mips64orion-* | mips64orionel-* \\\n\t| mips64r5900-* | mips64r5900el-* \\\n\t| mips64vr-* | mips64vrel-* \\\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| mipsisa32r6-* | mipsisa32r6el-* \\\n\t| mipsisa64-* | mipsisa64el-* \\\n\t| mipsisa64r2-* | mipsisa64r2el-* \\\n\t| mipsisa64r6-* | mipsisa64r6el-* \\\n\t| mipsisa64sb1-* | mipsisa64sb1el-* \\\n\t| mipsisa64sr71k-* | mipsisa64sr71kel-* \\\n\t| mipsr5900-* | mipsr5900el-* \\\n\t| mipstx39-* | mipstx39el-* \\\n\t| mmix-* \\\n\t| mt-* \\\n\t| msp430-* \\\n\t| nds32-* | nds32le-* | nds32be-* \\\n\t| nios-* | nios2-* | nios2eb-* | nios2el-* \\\n\t| none-* | np1-* | ns16k-* | ns32k-* \\\n\t| open8-* \\\n\t| or1k*-* \\\n\t| orion-* \\\n\t| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \\\n\t| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \\\n\t| pyramid-* \\\n\t| rl78-* | romp-* | rs6000-* | rx-* \\\n\t| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | 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-* | sv1-* | sx?-* \\\n\t| tahoe-* \\\n\t| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \\\n\t| tile*-* \\\n\t| tron-* \\\n\t| ubicom32-* \\\n\t| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \\\n\t| vax-* \\\n\t| we32k-* \\\n\t| x86-* | x86_64-* | xc16x-* | xps100-* \\\n\t| xstormy16-* | xtensa*-* \\\n\t| ymp-* \\\n\t| z8k-* | z80-*)\n\t\t;;\n\t# Recognize the basic CPU types without company name, with glob match.\n\txtensa*)\n\t\tbasic_machine=$basic_machine-unknown\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\taros)\n\t\tbasic_machine=i386-pc\n\t\tos=-aros\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\tblackfin)\n\t\tbasic_machine=bfin-unknown\n\t\tos=-linux\n\t\t;;\n\tblackfin-*)\n\t\tbasic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\tos=-linux\n\t\t;;\n\tbluegene*)\n\t\tbasic_machine=powerpc-ibm\n\t\tos=-cnk\n\t\t;;\n\tc54x-*)\n\t\tbasic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tc55x-*)\n\t\tbasic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tc6x-*)\n\t\tbasic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tc90)\n\t\tbasic_machine=c90-cray\n\t\tos=-unicos\n\t\t;;\n\tcegcc)\n\t\tbasic_machine=arm-unknown\n\t\tos=-cegcc\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 | cr16-*)\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\tdicos)\n\t\tbasic_machine=i686-pc\n\t\tos=-dicos\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\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\tm68knommu)\n\t\tbasic_machine=m68k-unknown\n\t\tos=-linux\n\t\t;;\n\tm68knommu-*)\n\t\tbasic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\tos=-linux\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\tmicroblaze*)\n\t\tbasic_machine=microblaze-xilinx\n\t\t;;\n\tmingw64)\n\t\tbasic_machine=x86_64-pc\n\t\tos=-mingw64\n\t\t;;\n\tmingw32)\n\t\tbasic_machine=i686-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\tmsys)\n\t\tbasic_machine=i686-pc\n\t\tos=-msys\n\t\t;;\n\tmvs)\n\t\tbasic_machine=i370-ibm\n\t\tos=-mvs\n\t\t;;\n\tnacl)\n\t\tbasic_machine=le32-unknown\n\t\tos=-nacl\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\tneo-tandem)\n\t\tbasic_machine=neo-tandem\n\t\t;;\n\tnse-tandem)\n\t\tbasic_machine=nse-tandem\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\tparisc)\n\t\tbasic_machine=hppa-unknown\n\t\tos=-linux\n\t\t;;\n\tparisc-*)\n\t\tbasic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\tos=-linux\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 | ppcbe)\tbasic_machine=powerpc-unknown\n\t\t;;\n\tppc-* | ppcbe-*)\n\t\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 | rdos64)\n\t\tbasic_machine=x86_64-pc\n\t\tos=-rdos\n\t\t;;\n\trdos32)\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\tstrongarm-* | thumb-*)\n\t\tbasic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`\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\ttile*)\n\t\tbasic_machine=$basic_machine-unknown\n\t\tos=-linux-gnu\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\txscale-* | xscalee[bl]-*)\n\t\tbasic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`\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\tz80-*-coff)\n\t\tbasic_machine=z80-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[24]aeb | 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\t# First match some system type aliases\n\t# that might get confused with valid system types.\n\t# -solaris* is a basic system type, with this one exception.\n\t-auroraux)\n\t\tos=-auroraux\n\t\t;;\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* | -cnk* | -sunos | -sunos[34]*\\\n\t      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \\\n\t      | -sym* | -kopensolaris* | -plan9* \\\n\t      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \\\n\t      | -aos* | -aros* \\\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      | -bitrig* | -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* | -cegcc* \\\n\t      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \\\n\t      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \\\n\t      | -linux-newlib* | -linux-musl* | -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* | -es* | -tirtos*)\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# Apple iOS\n\t-ios*)\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\t-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\t-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-zvmoe)\n\t\tos=-zvmoe\n\t\t;;\n\t-dicos*)\n\t\tos=-dicos\n\t\t;;\n\t-nacl*)\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\tscore-*)\n\t\tos=-elf\n\t\t;;\n\tspu-*)\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\tc4x-* | tic4x-*)\n\t\tos=-coff\n\t\t;;\n\tc8051-*)\n\t\tos=-elf\n\t\t;;\n\thexagon-*)\n\t\tos=-elf\n\t\t;;\n\ttic54x-*)\n\t\tos=-coff\n\t\t;;\n\ttic55x-*)\n\t\tos=-coff\n\t\t;;\n\ttic6x-*)\n\t\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;;\n\tm68*-cisco)\n\t\tos=-aout\n\t\t;;\n\tmep-*)\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-cnk*|-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": "deps/jemalloc-4.1.0/build-aux/install-sh",
    "content": "#! /bin/sh\n#\n# install - install a program, script, or datafile\n# This comes from X11R5 (mit/util/scripts/install.sh).\n#\n# Copyright 1991 by the Massachusetts Institute of Technology\n#\n# Permission to use, copy, modify, distribute, and sell this software and its\n# documentation for any purpose is hereby granted without fee, provided that\n# the above copyright notice appear in all copies and that both that\n# copyright notice and this permission notice appear in supporting\n# documentation, and that the name of M.I.T. not be used in advertising or\n# publicity pertaining to distribution of the software without specific,\n# written prior permission.  M.I.T. makes no representations about the\n# suitability of this software for any purpose.  It is provided \"as is\"\n# without express or implied warranty.\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\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\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\ntransformbasename=\"\"\ntransform_arg=\"\"\ninstcmd=\"$mvprog\"\nchmodcmd=\"$chmodprog 0755\"\nchowncmd=\"\"\nchgrpcmd=\"\"\nstripcmd=\"\"\nrmcmd=\"$rmprog -f\"\nmvcmd=\"$mvprog\"\nsrc=\"\"\ndst=\"\"\ndir_arg=\"\"\n\nwhile [ x\"$1\" != x ]; do\n    case $1 in\n\t-c) instcmd=\"$cpprog\"\n\t    shift\n\t    continue;;\n\n\t-d) dir_arg=true\n\t    shift\n\t    continue;;\n\n\t-m) chmodcmd=\"$chmodprog $2\"\n\t    shift\n\t    shift\n\t    continue;;\n\n\t-o) chowncmd=\"$chownprog $2\"\n\t    shift\n\t    shift\n\t    continue;;\n\n\t-g) chgrpcmd=\"$chgrpprog $2\"\n\t    shift\n\t    shift\n\t    continue;;\n\n\t-s) stripcmd=\"$stripprog\"\n\t    shift\n\t    continue;;\n\n\t-t=*) transformarg=`echo $1 | sed 's/-t=//'`\n\t    shift\n\t    continue;;\n\n\t-b=*) transformbasename=`echo $1 | sed 's/-b=//'`\n\t    shift\n\t    continue;;\n\n\t*)  if [ x\"$src\" = x ]\n\t    then\n\t\tsrc=$1\n\t    else\n\t\t# this colon is to work around a 386BSD /bin/sh bug\n\t\t:\n\t\tdst=$1\n\t    fi\n\t    shift\n\t    continue;;\n    esac\ndone\n\nif [ x\"$src\" = x ]\nthen\n\techo \"install:\tno input file specified\"\n\texit 1\nelse\n\ttrue\nfi\n\nif [ x\"$dir_arg\" != x ]; then\n\tdst=$src\n\tsrc=\"\"\n\t\n\tif [ -d $dst ]; then\n\t\tinstcmd=:\n\telse\n\t\tinstcmd=mkdir\n\tfi\nelse\n\n# Waiting for this to be detected by the \"$instcmd $src $dsttmp\" command\n# might cause directories to be created, which would be especially bad \n# if $src (and thus $dsttmp) contains '*'.\n\n\tif [ -f $src -o -d $src ]\n\tthen\n\t\ttrue\n\telse\n\t\techo \"install:  $src does not exist\"\n\t\texit 1\n\tfi\n\t\n\tif [ x\"$dst\" = x ]\n\tthen\n\t\techo \"install:\tno destination specified\"\n\t\texit 1\n\telse\n\t\ttrue\n\tfi\n\n# If destination is a directory, append the input filename; if your system\n# does not like double slashes in filenames, you may need to add some logic\n\n\tif [ -d $dst ]\n\tthen\n\t\tdst=\"$dst\"/`basename $src`\n\telse\n\t\ttrue\n\tfi\nfi\n\n## this sed command emulates the dirname command\ndstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`\n\n# Make sure that the destination directory exists.\n#  this part is taken from Noah Friedman's mkinstalldirs script\n\n# Skip lots of stat calls in the usual case.\nif [ ! -d \"$dstdir\" ]; then\ndefaultIFS='\t\n'\nIFS=\"${IFS-${defaultIFS}}\"\n\noIFS=\"${IFS}\"\n# Some sh's can't handle IFS=/ for some reason.\nIFS='%'\nset - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`\nIFS=\"${oIFS}\"\n\npathcomp=''\n\nwhile [ $# -ne 0 ] ; do\n\tpathcomp=\"${pathcomp}${1}\"\n\tshift\n\n\tif [ ! -d \"${pathcomp}\" ] ;\n        then\n\t\t$mkdirprog \"${pathcomp}\"\n\telse\n\t\ttrue\n\tfi\n\n\tpathcomp=\"${pathcomp}/\"\ndone\nfi\n\nif [ x\"$dir_arg\" != x ]\nthen\n\t$doit $instcmd $dst &&\n\n\tif [ x\"$chowncmd\" != x ]; then $doit $chowncmd $dst; else true ; fi &&\n\tif [ x\"$chgrpcmd\" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&\n\tif [ x\"$stripcmd\" != x ]; then $doit $stripcmd $dst; else true ; fi &&\n\tif [ x\"$chmodcmd\" != x ]; then $doit $chmodcmd $dst; else true ; fi\nelse\n\n# If we're going to rename the final executable, determine the name now.\n\n\tif [ x\"$transformarg\" = x ] \n\tthen\n\t\tdstfile=`basename $dst`\n\telse\n\t\tdstfile=`basename $dst $transformbasename | \n\t\t\tsed $transformarg`$transformbasename\n\tfi\n\n# don't allow the sed command to completely eliminate the filename\n\n\tif [ x\"$dstfile\" = x ] \n\tthen\n\t\tdstfile=`basename $dst`\n\telse\n\t\ttrue\n\tfi\n\n# Make a temp file name in the proper directory.\n\n\tdsttmp=$dstdir/#inst.$$#\n\n# Move or copy the file name to the temp name\n\n\t$doit $instcmd $src $dsttmp &&\n\n\ttrap \"rm -f ${dsttmp}\" 0 &&\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 $instcmd $src $dsttmp\" command.\n\n\tif [ x\"$chowncmd\" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&\n\tif [ x\"$chgrpcmd\" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&\n\tif [ x\"$stripcmd\" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&\n\tif [ x\"$chmodcmd\" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&\n\n# Now rename the file to the real destination.\n\n\t$doit $rmcmd -f $dstdir/$dstfile &&\n\t$doit $mvcmd $dsttmp $dstdir/$dstfile \n\nfi &&\n\n\nexit 0\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/config.stamp.in",
    "content": ""
  },
  {
    "path": "deps/jemalloc-4.1.0/configure.ac",
    "content": "dnl Process this file with autoconf to produce a configure script.\nAC_INIT([Makefile.in])\n\nAC_CONFIG_AUX_DIR([build-aux])\n\ndnl ============================================================================\ndnl Custom macro definitions.\n\ndnl JE_CFLAGS_APPEND(cflag)\nAC_DEFUN([JE_CFLAGS_APPEND],\n[\nAC_MSG_CHECKING([whether compiler supports $1])\nTCFLAGS=\"${CFLAGS}\"\nif test \"x${CFLAGS}\" = \"x\" ; then\n  CFLAGS=\"$1\"\nelse\n  CFLAGS=\"${CFLAGS} $1\"\nfi\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM(\n[[\n]], [[\n    return 0;\n]])],\n              [je_cv_cflags_appended=$1]\n              AC_MSG_RESULT([yes]),\n              [je_cv_cflags_appended=]\n              AC_MSG_RESULT([no])\n              [CFLAGS=\"${TCFLAGS}\"]\n)\n])\n\ndnl JE_COMPILABLE(label, hcode, mcode, rvar)\ndnl \ndnl Use AC_LINK_IFELSE() rather than AC_COMPILE_IFELSE() so that linker errors\ndnl cause failure.\nAC_DEFUN([JE_COMPILABLE],\n[\nAC_CACHE_CHECK([whether $1 is compilable],\n               [$4],\n               [AC_LINK_IFELSE([AC_LANG_PROGRAM([$2],\n                                                [$3])],\n                               [$4=yes],\n                               [$4=no])])\n])\n\ndnl ============================================================================\n\nCONFIG=`echo ${ac_configure_args} | sed -e 's#'\"'\"'\\([^ ]*\\)'\"'\"'#\\1#g'`\nAC_SUBST([CONFIG])\n\ndnl Library revision.\nrev=2\nAC_SUBST([rev])\n\nsrcroot=$srcdir\nif test \"x${srcroot}\" = \"x.\" ; then\n  srcroot=\"\"\nelse\n  srcroot=\"${srcroot}/\"\nfi\nAC_SUBST([srcroot])\nabs_srcroot=\"`cd \\\"${srcdir}\\\"; pwd`/\"\nAC_SUBST([abs_srcroot])\n\nobjroot=\"\"\nAC_SUBST([objroot])\nabs_objroot=\"`pwd`/\"\nAC_SUBST([abs_objroot])\n\ndnl Munge install path variables.\nif test \"x$prefix\" = \"xNONE\" ; then\n  prefix=\"/usr/local\"\nfi\nif test \"x$exec_prefix\" = \"xNONE\" ; then\n  exec_prefix=$prefix\nfi\nPREFIX=$prefix\nAC_SUBST([PREFIX])\nBINDIR=`eval echo $bindir`\nBINDIR=`eval echo $BINDIR`\nAC_SUBST([BINDIR])\nINCLUDEDIR=`eval echo $includedir`\nINCLUDEDIR=`eval echo $INCLUDEDIR`\nAC_SUBST([INCLUDEDIR])\nLIBDIR=`eval echo $libdir`\nLIBDIR=`eval echo $LIBDIR`\nAC_SUBST([LIBDIR])\nDATADIR=`eval echo $datadir`\nDATADIR=`eval echo $DATADIR`\nAC_SUBST([DATADIR])\nMANDIR=`eval echo $mandir`\nMANDIR=`eval echo $MANDIR`\nAC_SUBST([MANDIR])\n\ndnl Support for building documentation.\nAC_PATH_PROG([XSLTPROC], [xsltproc], [false], [$PATH])\nif test -d \"/usr/share/xml/docbook/stylesheet/docbook-xsl\" ; then\n  DEFAULT_XSLROOT=\"/usr/share/xml/docbook/stylesheet/docbook-xsl\"\nelif test -d \"/usr/share/sgml/docbook/xsl-stylesheets\" ; then\n  DEFAULT_XSLROOT=\"/usr/share/sgml/docbook/xsl-stylesheets\"\nelse\n  dnl Documentation building will fail if this default gets used.\n  DEFAULT_XSLROOT=\"\"\nfi\nAC_ARG_WITH([xslroot],\n  [AS_HELP_STRING([--with-xslroot=<path>], [XSL stylesheet root path])], [\nif test \"x$with_xslroot\" = \"xno\" ; then\n  XSLROOT=\"${DEFAULT_XSLROOT}\"\nelse\n  XSLROOT=\"${with_xslroot}\"\nfi\n],\n  XSLROOT=\"${DEFAULT_XSLROOT}\"\n)\nAC_SUBST([XSLROOT])\n\ndnl If CFLAGS isn't defined, set CFLAGS to something reasonable.  Otherwise,\ndnl just prevent autoconf from molesting CFLAGS.\nCFLAGS=$CFLAGS\nAC_PROG_CC\nif test \"x$GCC\" != \"xyes\" ; then\n  AC_CACHE_CHECK([whether compiler is MSVC],\n                 [je_cv_msvc],\n                 [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],\n                                                     [\n#ifndef _MSC_VER\n  int fail[-1];\n#endif\n])],\n                               [je_cv_msvc=yes],\n                               [je_cv_msvc=no])])\nfi\n\nif test \"x$CFLAGS\" = \"x\" ; then\n  no_CFLAGS=\"yes\"\n  if test \"x$GCC\" = \"xyes\" ; then\n    JE_CFLAGS_APPEND([-std=gnu99])\n    if test \"x$je_cv_cflags_appended\" = \"x-std=gnu99\" ; then\n      AC_DEFINE_UNQUOTED([JEMALLOC_HAS_RESTRICT])\n    fi\n    JE_CFLAGS_APPEND([-Wall])\n    JE_CFLAGS_APPEND([-Werror=declaration-after-statement])\n    JE_CFLAGS_APPEND([-Wshorten-64-to-32])\n    JE_CFLAGS_APPEND([-pipe])\n    JE_CFLAGS_APPEND([-g3])\n  elif test \"x$je_cv_msvc\" = \"xyes\" ; then\n    CC=\"$CC -nologo\"\n    JE_CFLAGS_APPEND([-Zi])\n    JE_CFLAGS_APPEND([-MT])\n    JE_CFLAGS_APPEND([-W3])\n    JE_CFLAGS_APPEND([-FS])\n    CPPFLAGS=\"$CPPFLAGS -I${srcdir}/include/msvc_compat\"\n  fi\nfi\ndnl Append EXTRA_CFLAGS to CFLAGS, if defined.\nif test \"x$EXTRA_CFLAGS\" != \"x\" ; then\n  JE_CFLAGS_APPEND([$EXTRA_CFLAGS])\nfi\nAC_PROG_CPP\n\nAC_C_BIGENDIAN([ac_cv_big_endian=1], [ac_cv_big_endian=0])\nif test \"x${ac_cv_big_endian}\" = \"x1\" ; then\n  AC_DEFINE_UNQUOTED([JEMALLOC_BIG_ENDIAN], [ ])\nfi\n\nif test \"x${je_cv_msvc}\" = \"xyes\" -a \"x${ac_cv_header_inttypes_h}\" = \"xno\"; then\n  CPPFLAGS=\"$CPPFLAGS -I${srcdir}/include/msvc_compat/C99\"\nfi\n\nif test \"x${je_cv_msvc}\" = \"xyes\" ; then\n  LG_SIZEOF_PTR=LG_SIZEOF_PTR_WIN\n  AC_MSG_RESULT([Using a predefined value for sizeof(void *): 4 for 32-bit, 8 for 64-bit])\nelse\n  AC_CHECK_SIZEOF([void *])\n  if test \"x${ac_cv_sizeof_void_p}\" = \"x8\" ; then\n    LG_SIZEOF_PTR=3\n  elif test \"x${ac_cv_sizeof_void_p}\" = \"x4\" ; then\n    LG_SIZEOF_PTR=2\n  else\n    AC_MSG_ERROR([Unsupported pointer size: ${ac_cv_sizeof_void_p}])\n  fi\nfi\nAC_DEFINE_UNQUOTED([LG_SIZEOF_PTR], [$LG_SIZEOF_PTR])\n\nAC_CHECK_SIZEOF([int])\nif test \"x${ac_cv_sizeof_int}\" = \"x8\" ; then\n  LG_SIZEOF_INT=3\nelif test \"x${ac_cv_sizeof_int}\" = \"x4\" ; then\n  LG_SIZEOF_INT=2\nelse\n  AC_MSG_ERROR([Unsupported int size: ${ac_cv_sizeof_int}])\nfi\nAC_DEFINE_UNQUOTED([LG_SIZEOF_INT], [$LG_SIZEOF_INT])\n\nAC_CHECK_SIZEOF([long])\nif test \"x${ac_cv_sizeof_long}\" = \"x8\" ; then\n  LG_SIZEOF_LONG=3\nelif test \"x${ac_cv_sizeof_long}\" = \"x4\" ; then\n  LG_SIZEOF_LONG=2\nelse\n  AC_MSG_ERROR([Unsupported long size: ${ac_cv_sizeof_long}])\nfi\nAC_DEFINE_UNQUOTED([LG_SIZEOF_LONG], [$LG_SIZEOF_LONG])\n\nAC_CHECK_SIZEOF([long long])\nif test \"x${ac_cv_sizeof_long_long}\" = \"x8\" ; then\n  LG_SIZEOF_LONG_LONG=3\nelif test \"x${ac_cv_sizeof_long_long}\" = \"x4\" ; then\n  LG_SIZEOF_LONG_LONG=2\nelse\n  AC_MSG_ERROR([Unsupported long long size: ${ac_cv_sizeof_long_long}])\nfi\nAC_DEFINE_UNQUOTED([LG_SIZEOF_LONG_LONG], [$LG_SIZEOF_LONG_LONG])\n\nAC_CHECK_SIZEOF([intmax_t])\nif test \"x${ac_cv_sizeof_intmax_t}\" = \"x16\" ; then\n  LG_SIZEOF_INTMAX_T=4\nelif test \"x${ac_cv_sizeof_intmax_t}\" = \"x8\" ; then\n  LG_SIZEOF_INTMAX_T=3\nelif test \"x${ac_cv_sizeof_intmax_t}\" = \"x4\" ; then\n  LG_SIZEOF_INTMAX_T=2\nelse\n  AC_MSG_ERROR([Unsupported intmax_t size: ${ac_cv_sizeof_intmax_t}])\nfi\nAC_DEFINE_UNQUOTED([LG_SIZEOF_INTMAX_T], [$LG_SIZEOF_INTMAX_T])\n\nAC_CANONICAL_HOST\ndnl CPU-specific settings.\nCPU_SPINWAIT=\"\"\ncase \"${host_cpu}\" in\n  i686|x86_64)\n\tif test \"x${je_cv_msvc}\" = \"xyes\" ; then\n\t    AC_CACHE_VAL([je_cv_pause_msvc],\n\t      [JE_COMPILABLE([pause instruction MSVC], [],\n\t\t\t\t\t[[_mm_pause(); return 0;]],\n\t\t\t\t\t[je_cv_pause_msvc])])\n\t    if test \"x${je_cv_pause_msvc}\" = \"xyes\" ; then\n\t\tCPU_SPINWAIT='_mm_pause()'\n\t    fi\n\telse\n\t    AC_CACHE_VAL([je_cv_pause],\n\t      [JE_COMPILABLE([pause instruction], [],\n\t\t\t\t\t[[__asm__ volatile(\"pause\"); return 0;]],\n\t\t\t\t\t[je_cv_pause])])\n\t    if test \"x${je_cv_pause}\" = \"xyes\" ; then\n\t\tCPU_SPINWAIT='__asm__ volatile(\"pause\")'\n\t    fi\n\tfi\n\t;;\n  powerpc)\n\tAC_DEFINE_UNQUOTED([HAVE_ALTIVEC], [ ])\n\t;;\n  *)\n\t;;\nesac\nAC_DEFINE_UNQUOTED([CPU_SPINWAIT], [$CPU_SPINWAIT])\n\nLD_PRELOAD_VAR=\"LD_PRELOAD\"\nso=\"so\"\nimportlib=\"${so}\"\no=\"$ac_objext\"\na=\"a\"\nexe=\"$ac_exeext\"\nlibprefix=\"lib\"\nDSO_LDFLAGS='-shared -Wl,-soname,$(@F)'\nRPATH='-Wl,-rpath,$(1)'\nSOREV=\"${so}.${rev}\"\nPIC_CFLAGS='-fPIC -DPIC'\nCTARGET='-o $@'\nLDTARGET='-o $@'\nEXTRA_LDFLAGS=\nARFLAGS='crus'\nAROUT=' $@'\nCC_MM=1\n\nAN_MAKEVAR([AR], [AC_PROG_AR])\nAN_PROGRAM([ar], [AC_PROG_AR])\nAC_DEFUN([AC_PROG_AR], [AC_CHECK_TOOL(AR, ar, :)])\nAC_PROG_AR\n\ndnl Platform-specific settings.  abi and RPATH can probably be determined\ndnl programmatically, but doing so is error-prone, which makes it generally\ndnl not worth the trouble.\ndnl \ndnl Define cpp macros in CPPFLAGS, rather than doing AC_DEFINE(macro), since the\ndnl definitions need to be seen before any headers are included, which is a pain\ndnl to make happen otherwise.\ndefault_munmap=\"1\"\nmaps_coalesce=\"1\"\ncase \"${host}\" in\n  *-*-darwin* | *-*-ios*)\n\tCFLAGS=\"$CFLAGS\"\n\tabi=\"macho\"\n\tAC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])\n\tRPATH=\"\"\n\tLD_PRELOAD_VAR=\"DYLD_INSERT_LIBRARIES\"\n\tso=\"dylib\"\n\timportlib=\"${so}\"\n\tforce_tls=\"0\"\n\tDSO_LDFLAGS='-shared -Wl,-install_name,$(LIBDIR)/$(@F)'\n\tSOREV=\"${rev}.${so}\"\n\tsbrk_deprecated=\"1\"\n\t;;\n  *-*-freebsd*)\n\tCFLAGS=\"$CFLAGS\"\n\tabi=\"elf\"\n\tAC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])\n\tforce_lazy_lock=\"1\"\n\t;;\n  *-*-dragonfly*)\n\tCFLAGS=\"$CFLAGS\"\n\tabi=\"elf\"\n\tAC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])\n\t;;\n  *-*-openbsd*)\n\tCFLAGS=\"$CFLAGS\"\n\tabi=\"elf\"\n\tAC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])\n\tforce_tls=\"0\"\n\t;;\n  *-*-bitrig*)\n\tCFLAGS=\"$CFLAGS\"\n\tabi=\"elf\"\n\tAC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])\n\t;;\n  *-*-linux*)\n\tCFLAGS=\"$CFLAGS\"\n\tCPPFLAGS=\"$CPPFLAGS -D_GNU_SOURCE\"\n\tabi=\"elf\"\n\tAC_DEFINE([JEMALLOC_HAS_ALLOCA_H])\n\tAC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED], [ ])\n\tAC_DEFINE([JEMALLOC_THREADED_INIT], [ ])\n\tAC_DEFINE([JEMALLOC_USE_CXX_THROW], [ ])\n\tdefault_munmap=\"0\"\n\t;;\n  *-*-netbsd*)\n\tAC_MSG_CHECKING([ABI])\n        AC_COMPILE_IFELSE([AC_LANG_PROGRAM(\n[[#ifdef __ELF__\n/* ELF */\n#else\n#error aout\n#endif\n]])],\n                          [CFLAGS=\"$CFLAGS\"; abi=\"elf\"],\n                          [abi=\"aout\"])\n\tAC_MSG_RESULT([$abi])\n\tAC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])\n\t;;\n  *-*-solaris2*)\n\tCFLAGS=\"$CFLAGS\"\n\tabi=\"elf\"\n\tAC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])\n\tRPATH='-Wl,-R,$(1)'\n\tdnl Solaris needs this for sigwait().\n\tCPPFLAGS=\"$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS\"\n\tLIBS=\"$LIBS -lposix4 -lsocket -lnsl\"\n\t;;\n  *-ibm-aix*)\n\tif \"$LG_SIZEOF_PTR\" = \"8\"; then\n\t  dnl 64bit AIX\n\t  LD_PRELOAD_VAR=\"LDR_PRELOAD64\"\n\telse\n\t  dnl 32bit AIX\n\t  LD_PRELOAD_VAR=\"LDR_PRELOAD\"\n\tfi\n\tabi=\"xcoff\"\n\t;;\n  *-*-mingw* | *-*-cygwin*)\n\tabi=\"pecoff\"\n\tforce_tls=\"0\"\n\tforce_lazy_lock=\"1\"\n\tmaps_coalesce=\"0\"\n\tRPATH=\"\"\n\tso=\"dll\"\n\tif test \"x$je_cv_msvc\" = \"xyes\" ; then\n\t  importlib=\"lib\"\n\t  DSO_LDFLAGS=\"-LD\"\n\t  EXTRA_LDFLAGS=\"-link -DEBUG\"\n\t  CTARGET='-Fo$@'\n\t  LDTARGET='-Fe$@'\n\t  AR='lib'\n\t  ARFLAGS='-nologo -out:'\n\t  AROUT='$@'\n\t  CC_MM=\n        else\n\t  importlib=\"${so}\"\n\t  DSO_LDFLAGS=\"-shared\"\n\tfi\n\ta=\"lib\"\n\tlibprefix=\"\"\n\tSOREV=\"${so}\"\n\tPIC_CFLAGS=\"\"\n\t;;\n  *)\n\tAC_MSG_RESULT([Unsupported operating system: ${host}])\n\tabi=\"elf\"\n\t;;\nesac\n\nJEMALLOC_USABLE_SIZE_CONST=const\nAC_CHECK_HEADERS([malloc.h], [\n  AC_MSG_CHECKING([whether malloc_usable_size definition can use const argument])\n  AC_COMPILE_IFELSE([AC_LANG_PROGRAM(\n    [#include <malloc.h>\n     #include <stddef.h>\n    size_t malloc_usable_size(const void *ptr);\n    ],\n    [])],[\n                AC_MSG_RESULT([yes])\n         ],[\n                JEMALLOC_USABLE_SIZE_CONST=\n                AC_MSG_RESULT([no])\n         ])\n])\nAC_DEFINE_UNQUOTED([JEMALLOC_USABLE_SIZE_CONST], [$JEMALLOC_USABLE_SIZE_CONST])\nAC_SUBST([abi])\nAC_SUBST([RPATH])\nAC_SUBST([LD_PRELOAD_VAR])\nAC_SUBST([so])\nAC_SUBST([importlib])\nAC_SUBST([o])\nAC_SUBST([a])\nAC_SUBST([exe])\nAC_SUBST([libprefix])\nAC_SUBST([DSO_LDFLAGS])\nAC_SUBST([EXTRA_LDFLAGS])\nAC_SUBST([SOREV])\nAC_SUBST([PIC_CFLAGS])\nAC_SUBST([CTARGET])\nAC_SUBST([LDTARGET])\nAC_SUBST([MKLIB])\nAC_SUBST([ARFLAGS])\nAC_SUBST([AROUT])\nAC_SUBST([CC_MM])\n\nJE_COMPILABLE([__attribute__ syntax],\n              [static __attribute__((unused)) void foo(void){}],\n              [],\n              [je_cv_attribute])\nif test \"x${je_cv_attribute}\" = \"xyes\" ; then\n  AC_DEFINE([JEMALLOC_HAVE_ATTR], [ ])\n  if test \"x${GCC}\" = \"xyes\" -a \"x${abi}\" = \"xelf\"; then\n    JE_CFLAGS_APPEND([-fvisibility=hidden])\n  fi\nfi\ndnl Check for tls_model attribute support (clang 3.0 still lacks support).\nSAVED_CFLAGS=\"${CFLAGS}\"\nJE_CFLAGS_APPEND([-Werror])\nJE_COMPILABLE([tls_model attribute], [],\n              [static __thread int\n               __attribute__((tls_model(\"initial-exec\"), unused)) foo;\n               foo = 0;],\n              [je_cv_tls_model])\nCFLAGS=\"${SAVED_CFLAGS}\"\nif test \"x${je_cv_tls_model}\" = \"xyes\" ; then\n  AC_DEFINE([JEMALLOC_TLS_MODEL],\n            [__attribute__((tls_model(\"initial-exec\")))])\nelse\n  AC_DEFINE([JEMALLOC_TLS_MODEL], [ ])\nfi\ndnl Check for alloc_size attribute support.\nSAVED_CFLAGS=\"${CFLAGS}\"\nJE_CFLAGS_APPEND([-Werror])\nJE_COMPILABLE([alloc_size attribute], [#include <stdlib.h>],\n              [void *foo(size_t size) __attribute__((alloc_size(1)));],\n              [je_cv_alloc_size])\nCFLAGS=\"${SAVED_CFLAGS}\"\nif test \"x${je_cv_alloc_size}\" = \"xyes\" ; then\n  AC_DEFINE([JEMALLOC_HAVE_ATTR_ALLOC_SIZE], [ ])\nfi\ndnl Check for format(gnu_printf, ...) attribute support.\nSAVED_CFLAGS=\"${CFLAGS}\"\nJE_CFLAGS_APPEND([-Werror])\nJE_COMPILABLE([format(gnu_printf, ...) attribute], [#include <stdlib.h>],\n              [void *foo(const char *format, ...) __attribute__((format(gnu_printf, 1, 2)));],\n              [je_cv_format_gnu_printf])\nCFLAGS=\"${SAVED_CFLAGS}\"\nif test \"x${je_cv_format_gnu_printf}\" = \"xyes\" ; then\n  AC_DEFINE([JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF], [ ])\nfi\ndnl Check for format(printf, ...) attribute support.\nSAVED_CFLAGS=\"${CFLAGS}\"\nJE_CFLAGS_APPEND([-Werror])\nJE_COMPILABLE([format(printf, ...) attribute], [#include <stdlib.h>],\n              [void *foo(const char *format, ...) __attribute__((format(printf, 1, 2)));],\n              [je_cv_format_printf])\nCFLAGS=\"${SAVED_CFLAGS}\"\nif test \"x${je_cv_format_printf}\" = \"xyes\" ; then\n  AC_DEFINE([JEMALLOC_HAVE_ATTR_FORMAT_PRINTF], [ ])\nfi\n\ndnl Support optional additions to rpath.\nAC_ARG_WITH([rpath],\n  [AS_HELP_STRING([--with-rpath=<rpath>], [Colon-separated rpath (ELF systems only)])],\nif test \"x$with_rpath\" = \"xno\" ; then\n  RPATH_EXTRA=\nelse\n  RPATH_EXTRA=\"`echo $with_rpath | tr \\\":\\\" \\\" \\\"`\"\nfi,\n  RPATH_EXTRA=\n)\nAC_SUBST([RPATH_EXTRA])\n\ndnl Disable rules that do automatic regeneration of configure output by default.\nAC_ARG_ENABLE([autogen],\n  [AS_HELP_STRING([--enable-autogen], [Automatically regenerate configure output])],\nif test \"x$enable_autogen\" = \"xno\" ; then\n  enable_autogen=\"0\"\nelse\n  enable_autogen=\"1\"\nfi\n,\nenable_autogen=\"0\"\n)\nAC_SUBST([enable_autogen])\n\nAC_PROG_INSTALL\nAC_PROG_RANLIB\nAC_PATH_PROG([LD], [ld], [false], [$PATH])\nAC_PATH_PROG([AUTOCONF], [autoconf], [false], [$PATH])\n\npublic_syms=\"malloc_conf malloc_message malloc calloc posix_memalign aligned_alloc realloc free mallocx rallocx xallocx sallocx dallocx sdallocx nallocx mallctl mallctlnametomib mallctlbymib malloc_stats_print malloc_usable_size\"\n\ndnl Check for allocator-related functions that should be wrapped.\nAC_CHECK_FUNC([memalign],\n\t      [AC_DEFINE([JEMALLOC_OVERRIDE_MEMALIGN], [ ])\n\t       public_syms=\"${public_syms} memalign\"])\nAC_CHECK_FUNC([valloc],\n\t      [AC_DEFINE([JEMALLOC_OVERRIDE_VALLOC], [ ])\n\t       public_syms=\"${public_syms} valloc\"])\n\ndnl Do not compute test code coverage by default.\nGCOV_FLAGS=\nAC_ARG_ENABLE([code-coverage],\n  [AS_HELP_STRING([--enable-code-coverage],\n   [Enable code coverage])],\n[if test \"x$enable_code_coverage\" = \"xno\" ; then\n  enable_code_coverage=\"0\"\nelse\n  enable_code_coverage=\"1\"\nfi\n],\n[enable_code_coverage=\"0\"]\n)\nif test \"x$enable_code_coverage\" = \"x1\" ; then\n  deoptimize=\"no\"\n  echo \"$CFLAGS $EXTRA_CFLAGS\" | grep '\\-O' >/dev/null || deoptimize=\"yes\"\n  if test \"x${deoptimize}\" = \"xyes\" ; then\n    JE_CFLAGS_APPEND([-O0])\n  fi\n  JE_CFLAGS_APPEND([-fprofile-arcs -ftest-coverage])\n  EXTRA_LDFLAGS=\"$EXTRA_LDFLAGS -fprofile-arcs -ftest-coverage\"\n  AC_DEFINE([JEMALLOC_CODE_COVERAGE], [ ])\nfi\nAC_SUBST([enable_code_coverage])\n\ndnl Perform no name mangling by default.\nAC_ARG_WITH([mangling],\n  [AS_HELP_STRING([--with-mangling=<map>], [Mangle symbols in <map>])],\n  [mangling_map=\"$with_mangling\"], [mangling_map=\"\"])\n\ndnl Do not prefix public APIs by default.\nAC_ARG_WITH([jemalloc_prefix],\n  [AS_HELP_STRING([--with-jemalloc-prefix=<prefix>], [Prefix to prepend to all public APIs])],\n  [JEMALLOC_PREFIX=\"$with_jemalloc_prefix\"],\n  [if test \"x$abi\" != \"xmacho\" -a \"x$abi\" != \"xpecoff\"; then\n  JEMALLOC_PREFIX=\"\"\nelse\n  JEMALLOC_PREFIX=\"je_\"\nfi]\n)\nif test \"x$JEMALLOC_PREFIX\" != \"x\" ; then\n  JEMALLOC_CPREFIX=`echo ${JEMALLOC_PREFIX} | tr \"a-z\" \"A-Z\"`\n  AC_DEFINE_UNQUOTED([JEMALLOC_PREFIX], [\"$JEMALLOC_PREFIX\"])\n  AC_DEFINE_UNQUOTED([JEMALLOC_CPREFIX], [\"$JEMALLOC_CPREFIX\"])\nfi\nAC_SUBST([JEMALLOC_CPREFIX])\n\nAC_ARG_WITH([export],\n  [AS_HELP_STRING([--without-export], [disable exporting jemalloc public APIs])],\n  [if test \"x$with_export\" = \"xno\"; then\n  AC_DEFINE([JEMALLOC_EXPORT],[])\nfi]\n)\n\ndnl Mangle library-private APIs.\nAC_ARG_WITH([private_namespace],\n  [AS_HELP_STRING([--with-private-namespace=<prefix>], [Prefix to prepend to all library-private APIs])],\n  [JEMALLOC_PRIVATE_NAMESPACE=\"${with_private_namespace}je_\"],\n  [JEMALLOC_PRIVATE_NAMESPACE=\"je_\"]\n)\nAC_DEFINE_UNQUOTED([JEMALLOC_PRIVATE_NAMESPACE], [$JEMALLOC_PRIVATE_NAMESPACE])\nprivate_namespace=\"$JEMALLOC_PRIVATE_NAMESPACE\"\nAC_SUBST([private_namespace])\n\ndnl Do not add suffix to installed files by default.\nAC_ARG_WITH([install_suffix],\n  [AS_HELP_STRING([--with-install-suffix=<suffix>], [Suffix to append to all installed files])],\n  [INSTALL_SUFFIX=\"$with_install_suffix\"],\n  [INSTALL_SUFFIX=]\n)\ninstall_suffix=\"$INSTALL_SUFFIX\"\nAC_SUBST([install_suffix])\n\ndnl Specify default malloc_conf.\nAC_ARG_WITH([malloc_conf],\n  [AS_HELP_STRING([--with-malloc-conf=<malloc_conf>], [config.malloc_conf options string])],\n  [JEMALLOC_CONFIG_MALLOC_CONF=\"$with_malloc_conf\"],\n  [JEMALLOC_CONFIG_MALLOC_CONF=\"\"]\n)\nconfig_malloc_conf=\"$JEMALLOC_CONFIG_MALLOC_CONF\"\nAC_DEFINE_UNQUOTED([JEMALLOC_CONFIG_MALLOC_CONF], [\"$config_malloc_conf\"])\n\ndnl Substitute @je_@ in jemalloc_protos.h.in, primarily to make generation of\ndnl jemalloc_protos_jet.h easy.\nje_=\"je_\"\nAC_SUBST([je_])\n\ncfgoutputs_in=\"Makefile.in\"\ncfgoutputs_in=\"${cfgoutputs_in} jemalloc.pc.in\"\ncfgoutputs_in=\"${cfgoutputs_in} doc/html.xsl.in\"\ncfgoutputs_in=\"${cfgoutputs_in} doc/manpages.xsl.in\"\ncfgoutputs_in=\"${cfgoutputs_in} doc/jemalloc.xml.in\"\ncfgoutputs_in=\"${cfgoutputs_in} include/jemalloc/jemalloc_macros.h.in\"\ncfgoutputs_in=\"${cfgoutputs_in} include/jemalloc/jemalloc_protos.h.in\"\ncfgoutputs_in=\"${cfgoutputs_in} include/jemalloc/jemalloc_typedefs.h.in\"\ncfgoutputs_in=\"${cfgoutputs_in} include/jemalloc/internal/jemalloc_internal.h.in\"\ncfgoutputs_in=\"${cfgoutputs_in} test/test.sh.in\"\ncfgoutputs_in=\"${cfgoutputs_in} test/include/test/jemalloc_test.h.in\"\n\ncfgoutputs_out=\"Makefile\"\ncfgoutputs_out=\"${cfgoutputs_out} jemalloc.pc\"\ncfgoutputs_out=\"${cfgoutputs_out} doc/html.xsl\"\ncfgoutputs_out=\"${cfgoutputs_out} doc/manpages.xsl\"\ncfgoutputs_out=\"${cfgoutputs_out} doc/jemalloc.xml\"\ncfgoutputs_out=\"${cfgoutputs_out} include/jemalloc/jemalloc_macros.h\"\ncfgoutputs_out=\"${cfgoutputs_out} include/jemalloc/jemalloc_protos.h\"\ncfgoutputs_out=\"${cfgoutputs_out} include/jemalloc/jemalloc_typedefs.h\"\ncfgoutputs_out=\"${cfgoutputs_out} include/jemalloc/internal/jemalloc_internal.h\"\ncfgoutputs_out=\"${cfgoutputs_out} test/test.sh\"\ncfgoutputs_out=\"${cfgoutputs_out} test/include/test/jemalloc_test.h\"\n\ncfgoutputs_tup=\"Makefile\"\ncfgoutputs_tup=\"${cfgoutputs_tup} jemalloc.pc:jemalloc.pc.in\"\ncfgoutputs_tup=\"${cfgoutputs_tup} doc/html.xsl:doc/html.xsl.in\"\ncfgoutputs_tup=\"${cfgoutputs_tup} doc/manpages.xsl:doc/manpages.xsl.in\"\ncfgoutputs_tup=\"${cfgoutputs_tup} doc/jemalloc.xml:doc/jemalloc.xml.in\"\ncfgoutputs_tup=\"${cfgoutputs_tup} include/jemalloc/jemalloc_macros.h:include/jemalloc/jemalloc_macros.h.in\"\ncfgoutputs_tup=\"${cfgoutputs_tup} include/jemalloc/jemalloc_protos.h:include/jemalloc/jemalloc_protos.h.in\"\ncfgoutputs_tup=\"${cfgoutputs_tup} include/jemalloc/jemalloc_typedefs.h:include/jemalloc/jemalloc_typedefs.h.in\"\ncfgoutputs_tup=\"${cfgoutputs_tup} include/jemalloc/internal/jemalloc_internal.h\"\ncfgoutputs_tup=\"${cfgoutputs_tup} test/test.sh:test/test.sh.in\"\ncfgoutputs_tup=\"${cfgoutputs_tup} test/include/test/jemalloc_test.h:test/include/test/jemalloc_test.h.in\"\n\ncfghdrs_in=\"include/jemalloc/jemalloc_defs.h.in\"\ncfghdrs_in=\"${cfghdrs_in} include/jemalloc/internal/jemalloc_internal_defs.h.in\"\ncfghdrs_in=\"${cfghdrs_in} include/jemalloc/internal/private_namespace.sh\"\ncfghdrs_in=\"${cfghdrs_in} include/jemalloc/internal/private_unnamespace.sh\"\ncfghdrs_in=\"${cfghdrs_in} include/jemalloc/internal/private_symbols.txt\"\ncfghdrs_in=\"${cfghdrs_in} include/jemalloc/internal/public_namespace.sh\"\ncfghdrs_in=\"${cfghdrs_in} include/jemalloc/internal/public_unnamespace.sh\"\ncfghdrs_in=\"${cfghdrs_in} include/jemalloc/internal/size_classes.sh\"\ncfghdrs_in=\"${cfghdrs_in} include/jemalloc/jemalloc_rename.sh\"\ncfghdrs_in=\"${cfghdrs_in} include/jemalloc/jemalloc_mangle.sh\"\ncfghdrs_in=\"${cfghdrs_in} include/jemalloc/jemalloc.sh\"\ncfghdrs_in=\"${cfghdrs_in} test/include/test/jemalloc_test_defs.h.in\"\n\ncfghdrs_out=\"include/jemalloc/jemalloc_defs.h\"\ncfghdrs_out=\"${cfghdrs_out} include/jemalloc/jemalloc${install_suffix}.h\"\ncfghdrs_out=\"${cfghdrs_out} include/jemalloc/internal/private_namespace.h\"\ncfghdrs_out=\"${cfghdrs_out} include/jemalloc/internal/private_unnamespace.h\"\ncfghdrs_out=\"${cfghdrs_out} include/jemalloc/internal/public_symbols.txt\"\ncfghdrs_out=\"${cfghdrs_out} include/jemalloc/internal/public_namespace.h\"\ncfghdrs_out=\"${cfghdrs_out} include/jemalloc/internal/public_unnamespace.h\"\ncfghdrs_out=\"${cfghdrs_out} include/jemalloc/internal/size_classes.h\"\ncfghdrs_out=\"${cfghdrs_out} include/jemalloc/jemalloc_protos_jet.h\"\ncfghdrs_out=\"${cfghdrs_out} include/jemalloc/jemalloc_rename.h\"\ncfghdrs_out=\"${cfghdrs_out} include/jemalloc/jemalloc_mangle.h\"\ncfghdrs_out=\"${cfghdrs_out} include/jemalloc/jemalloc_mangle_jet.h\"\ncfghdrs_out=\"${cfghdrs_out} include/jemalloc/internal/jemalloc_internal_defs.h\"\ncfghdrs_out=\"${cfghdrs_out} test/include/test/jemalloc_test_defs.h\"\n\ncfghdrs_tup=\"include/jemalloc/jemalloc_defs.h:include/jemalloc/jemalloc_defs.h.in\"\ncfghdrs_tup=\"${cfghdrs_tup} include/jemalloc/internal/jemalloc_internal_defs.h:include/jemalloc/internal/jemalloc_internal_defs.h.in\"\ncfghdrs_tup=\"${cfghdrs_tup} test/include/test/jemalloc_test_defs.h:test/include/test/jemalloc_test_defs.h.in\"\n\ndnl Silence irrelevant compiler warnings by default.\nAC_ARG_ENABLE([cc-silence],\n  [AS_HELP_STRING([--disable-cc-silence],\n                  [Do not silence irrelevant compiler warnings])],\n[if test \"x$enable_cc_silence\" = \"xno\" ; then\n  enable_cc_silence=\"0\"\nelse\n  enable_cc_silence=\"1\"\nfi\n],\n[enable_cc_silence=\"1\"]\n)\nif test \"x$enable_cc_silence\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_CC_SILENCE], [ ])\nfi\n\ndnl Do not compile with debugging by default.\nAC_ARG_ENABLE([debug],\n  [AS_HELP_STRING([--enable-debug],\n                  [Build debugging code (implies --enable-ivsalloc)])],\n[if test \"x$enable_debug\" = \"xno\" ; then\n  enable_debug=\"0\"\nelse\n  enable_debug=\"1\"\nfi\n],\n[enable_debug=\"0\"]\n)\nif test \"x$enable_debug\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_DEBUG], [ ])\nfi\nif test \"x$enable_debug\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_DEBUG], [ ])\n  enable_ivsalloc=\"1\"\nfi\nAC_SUBST([enable_debug])\n\ndnl Do not validate pointers by default.\nAC_ARG_ENABLE([ivsalloc],\n  [AS_HELP_STRING([--enable-ivsalloc],\n                  [Validate pointers passed through the public API])],\n[if test \"x$enable_ivsalloc\" = \"xno\" ; then\n  enable_ivsalloc=\"0\"\nelse\n  enable_ivsalloc=\"1\"\nfi\n],\n[enable_ivsalloc=\"0\"]\n)\nif test \"x$enable_ivsalloc\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_IVSALLOC], [ ])\nfi\n\ndnl Only optimize if not debugging.\nif test \"x$enable_debug\" = \"x0\" -a \"x$no_CFLAGS\" = \"xyes\" ; then\n  dnl Make sure that an optimization flag was not specified in EXTRA_CFLAGS.\n  optimize=\"no\"\n  echo \"$CFLAGS $EXTRA_CFLAGS\" | grep '\\-O' >/dev/null || optimize=\"yes\"\n  if test \"x${optimize}\" = \"xyes\" ; then\n    if test \"x$GCC\" = \"xyes\" ; then\n      JE_CFLAGS_APPEND([-O3])\n      JE_CFLAGS_APPEND([-funroll-loops])\n    elif test \"x$je_cv_msvc\" = \"xyes\" ; then\n      JE_CFLAGS_APPEND([-O2])\n    else\n      JE_CFLAGS_APPEND([-O])\n    fi\n  fi\nfi\n\ndnl Enable statistics calculation by default.\nAC_ARG_ENABLE([stats],\n  [AS_HELP_STRING([--disable-stats],\n                  [Disable statistics calculation/reporting])],\n[if test \"x$enable_stats\" = \"xno\" ; then\n  enable_stats=\"0\"\nelse\n  enable_stats=\"1\"\nfi\n],\n[enable_stats=\"1\"]\n)\nif test \"x$enable_stats\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_STATS], [ ])\nfi\nAC_SUBST([enable_stats])\n\ndnl Do not enable profiling by default.\nAC_ARG_ENABLE([prof],\n  [AS_HELP_STRING([--enable-prof], [Enable allocation profiling])],\n[if test \"x$enable_prof\" = \"xno\" ; then\n  enable_prof=\"0\"\nelse\n  enable_prof=\"1\"\nfi\n],\n[enable_prof=\"0\"]\n)\nif test \"x$enable_prof\" = \"x1\" ; then\n  backtrace_method=\"\"\nelse\n  backtrace_method=\"N/A\"\nfi\n\nAC_ARG_ENABLE([prof-libunwind],\n  [AS_HELP_STRING([--enable-prof-libunwind], [Use libunwind for backtracing])],\n[if test \"x$enable_prof_libunwind\" = \"xno\" ; then\n  enable_prof_libunwind=\"0\"\nelse\n  enable_prof_libunwind=\"1\"\nfi\n],\n[enable_prof_libunwind=\"0\"]\n)\nAC_ARG_WITH([static_libunwind],\n  [AS_HELP_STRING([--with-static-libunwind=<libunwind.a>],\n  [Path to static libunwind library; use rather than dynamically linking])],\nif test \"x$with_static_libunwind\" = \"xno\" ; then\n  LUNWIND=\"-lunwind\"\nelse\n  if test ! -f \"$with_static_libunwind\" ; then\n    AC_MSG_ERROR([Static libunwind not found: $with_static_libunwind])\n  fi\n  LUNWIND=\"$with_static_libunwind\"\nfi,\n  LUNWIND=\"-lunwind\"\n)\nif test \"x$backtrace_method\" = \"x\" -a \"x$enable_prof_libunwind\" = \"x1\" ; then\n  AC_CHECK_HEADERS([libunwind.h], , [enable_prof_libunwind=\"0\"])\n  if test \"x$LUNWIND\" = \"x-lunwind\" ; then\n    AC_CHECK_LIB([unwind], [unw_backtrace], [LIBS=\"$LIBS $LUNWIND\"],\n                 [enable_prof_libunwind=\"0\"])\n  else\n    LIBS=\"$LIBS $LUNWIND\"\n  fi\n  if test \"x${enable_prof_libunwind}\" = \"x1\" ; then\n    backtrace_method=\"libunwind\"\n    AC_DEFINE([JEMALLOC_PROF_LIBUNWIND], [ ])\n  fi\nfi\n\nAC_ARG_ENABLE([prof-libgcc],\n  [AS_HELP_STRING([--disable-prof-libgcc],\n  [Do not use libgcc for backtracing])],\n[if test \"x$enable_prof_libgcc\" = \"xno\" ; then\n  enable_prof_libgcc=\"0\"\nelse\n  enable_prof_libgcc=\"1\"\nfi\n],\n[enable_prof_libgcc=\"1\"]\n)\nif test \"x$backtrace_method\" = \"x\" -a \"x$enable_prof_libgcc\" = \"x1\" \\\n     -a \"x$GCC\" = \"xyes\" ; then\n  AC_CHECK_HEADERS([unwind.h], , [enable_prof_libgcc=\"0\"])\n  AC_CHECK_LIB([gcc], [_Unwind_Backtrace], [LIBS=\"$LIBS -lgcc\"], [enable_prof_libgcc=\"0\"])\n  if test \"x${enable_prof_libgcc}\" = \"x1\" ; then\n    backtrace_method=\"libgcc\"\n    AC_DEFINE([JEMALLOC_PROF_LIBGCC], [ ])\n  fi\nelse\n  enable_prof_libgcc=\"0\"\nfi\n\nAC_ARG_ENABLE([prof-gcc],\n  [AS_HELP_STRING([--disable-prof-gcc],\n  [Do not use gcc intrinsics for backtracing])],\n[if test \"x$enable_prof_gcc\" = \"xno\" ; then\n  enable_prof_gcc=\"0\"\nelse\n  enable_prof_gcc=\"1\"\nfi\n],\n[enable_prof_gcc=\"1\"]\n)\nif test \"x$backtrace_method\" = \"x\" -a \"x$enable_prof_gcc\" = \"x1\" \\\n     -a \"x$GCC\" = \"xyes\" ; then\n  JE_CFLAGS_APPEND([-fno-omit-frame-pointer])\n  backtrace_method=\"gcc intrinsics\"\n  AC_DEFINE([JEMALLOC_PROF_GCC], [ ])\nelse\n  enable_prof_gcc=\"0\"\nfi\n\nif test \"x$backtrace_method\" = \"x\" ; then\n  backtrace_method=\"none (disabling profiling)\"\n  enable_prof=\"0\"\nfi\nAC_MSG_CHECKING([configured backtracing method])\nAC_MSG_RESULT([$backtrace_method])\nif test \"x$enable_prof\" = \"x1\" ; then\n  if test \"x$abi\" != \"xpecoff\"; then\n    dnl Heap profiling uses the log(3) function.\n    LIBS=\"$LIBS -lm\"\n  fi\n\n  AC_DEFINE([JEMALLOC_PROF], [ ])\nfi\nAC_SUBST([enable_prof])\n\ndnl Enable thread-specific caching by default.\nAC_ARG_ENABLE([tcache],\n  [AS_HELP_STRING([--disable-tcache], [Disable per thread caches])],\n[if test \"x$enable_tcache\" = \"xno\" ; then\n  enable_tcache=\"0\"\nelse\n  enable_tcache=\"1\"\nfi\n],\n[enable_tcache=\"1\"]\n)\nif test \"x$enable_tcache\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_TCACHE], [ ])\nfi\nAC_SUBST([enable_tcache])\n\ndnl Indicate whether adjacent virtual memory mappings automatically coalesce\ndnl (and fragment on demand).\nif test \"x${maps_coalesce}\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_MAPS_COALESCE], [ ])\nfi\n\ndnl Enable VM deallocation via munmap() by default.\nAC_ARG_ENABLE([munmap],\n  [AS_HELP_STRING([--disable-munmap], [Disable VM deallocation via munmap(2)])],\n[if test \"x$enable_munmap\" = \"xno\" ; then\n  enable_munmap=\"0\"\nelse\n  enable_munmap=\"1\"\nfi\n],\n[enable_munmap=\"${default_munmap}\"]\n)\nif test \"x$enable_munmap\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_MUNMAP], [ ])\nfi\nAC_SUBST([enable_munmap])\n\ndnl Enable allocation from DSS if supported by the OS.\nhave_dss=\"1\"\ndnl Check whether the BSD/SUSv1 sbrk() exists.  If not, disable DSS support.\nAC_CHECK_FUNC([sbrk], [have_sbrk=\"1\"], [have_sbrk=\"0\"])\nif test \"x$have_sbrk\" = \"x1\" ; then\n  if test \"x$sbrk_deprecated\" = \"x1\" ; then\n    AC_MSG_RESULT([Disabling dss allocation because sbrk is deprecated])\n    have_dss=\"0\"\n  fi\nelse\n  have_dss=\"0\"\nfi\n\nif test \"x$have_dss\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_DSS], [ ])\nfi\n\ndnl Support the junk/zero filling option by default.\nAC_ARG_ENABLE([fill],\n  [AS_HELP_STRING([--disable-fill],\n                  [Disable support for junk/zero filling, quarantine, and redzones])],\n[if test \"x$enable_fill\" = \"xno\" ; then\n  enable_fill=\"0\"\nelse\n  enable_fill=\"1\"\nfi\n],\n[enable_fill=\"1\"]\n)\nif test \"x$enable_fill\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_FILL], [ ])\nfi\nAC_SUBST([enable_fill])\n\ndnl Disable utrace(2)-based tracing by default.\nAC_ARG_ENABLE([utrace],\n  [AS_HELP_STRING([--enable-utrace], [Enable utrace(2)-based tracing])],\n[if test \"x$enable_utrace\" = \"xno\" ; then\n  enable_utrace=\"0\"\nelse\n  enable_utrace=\"1\"\nfi\n],\n[enable_utrace=\"0\"]\n)\nJE_COMPILABLE([utrace(2)], [\n#include <sys/types.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <sys/uio.h>\n#include <sys/ktrace.h>\n], [\n\tutrace((void *)0, 0);\n], [je_cv_utrace])\nif test \"x${je_cv_utrace}\" = \"xno\" ; then\n  enable_utrace=\"0\"\nfi\nif test \"x$enable_utrace\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_UTRACE], [ ])\nfi\nAC_SUBST([enable_utrace])\n\ndnl Support Valgrind by default.\nAC_ARG_ENABLE([valgrind],\n  [AS_HELP_STRING([--disable-valgrind], [Disable support for Valgrind])],\n[if test \"x$enable_valgrind\" = \"xno\" ; then\n  enable_valgrind=\"0\"\nelse\n  enable_valgrind=\"1\"\nfi\n],\n[enable_valgrind=\"1\"]\n)\nif test \"x$enable_valgrind\" = \"x1\" ; then\n  JE_COMPILABLE([valgrind], [\n#include <valgrind/valgrind.h>\n#include <valgrind/memcheck.h>\n\n#if !defined(VALGRIND_RESIZEINPLACE_BLOCK)\n#  error \"Incompatible Valgrind version\"\n#endif\n], [], [je_cv_valgrind])\n  if test \"x${je_cv_valgrind}\" = \"xno\" ; then\n    enable_valgrind=\"0\"\n  fi\n  if test \"x$enable_valgrind\" = \"x1\" ; then\n    AC_DEFINE([JEMALLOC_VALGRIND], [ ])\n  fi\nfi\nAC_SUBST([enable_valgrind])\n\ndnl Do not support the xmalloc option by default.\nAC_ARG_ENABLE([xmalloc],\n  [AS_HELP_STRING([--enable-xmalloc], [Support xmalloc option])],\n[if test \"x$enable_xmalloc\" = \"xno\" ; then\n  enable_xmalloc=\"0\"\nelse\n  enable_xmalloc=\"1\"\nfi\n],\n[enable_xmalloc=\"0\"]\n)\nif test \"x$enable_xmalloc\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_XMALLOC], [ ])\nfi\nAC_SUBST([enable_xmalloc])\n\ndnl Support cache-oblivious allocation alignment by default.\nAC_ARG_ENABLE([cache-oblivious],\n  [AS_HELP_STRING([--disable-cache-oblivious],\n                  [Disable support for cache-oblivious allocation alignment])],\n[if test \"x$enable_cache_oblivious\" = \"xno\" ; then\n  enable_cache_oblivious=\"0\"\nelse\n  enable_cache_oblivious=\"1\"\nfi\n],\n[enable_cache_oblivious=\"1\"]\n)\nif test \"x$enable_cache_oblivious\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_CACHE_OBLIVIOUS], [ ])\nfi\nAC_SUBST([enable_cache_oblivious])\n\ndnl ============================================================================\ndnl Check for  __builtin_ffsl(), then ffsl(3), and fail if neither are found.\ndnl One of those two functions should (theoretically) exist on all platforms\ndnl that jemalloc currently has a chance of functioning on without modification.\ndnl We additionally assume ffs[ll]() or __builtin_ffs[ll]() are defined if\ndnl ffsl() or __builtin_ffsl() are defined, respectively.\nJE_COMPILABLE([a program using __builtin_ffsl], [\n#include <stdio.h>\n#include <strings.h>\n#include <string.h>\n], [\n\t{\n\t\tint rv = __builtin_ffsl(0x08);\n\t\tprintf(\"%d\\n\", rv);\n\t}\n], [je_cv_gcc_builtin_ffsl])\nif test \"x${je_cv_gcc_builtin_ffsl}\" = \"xyes\" ; then\n  AC_DEFINE([JEMALLOC_INTERNAL_FFSLL], [__builtin_ffsll])\n  AC_DEFINE([JEMALLOC_INTERNAL_FFSL], [__builtin_ffsl])\n  AC_DEFINE([JEMALLOC_INTERNAL_FFS], [__builtin_ffs])\nelse\n  JE_COMPILABLE([a program using ffsl], [\n  #include <stdio.h>\n  #include <strings.h>\n  #include <string.h>\n  ], [\n\t{\n\t\tint rv = ffsl(0x08);\n\t\tprintf(\"%d\\n\", rv);\n\t}\n  ], [je_cv_function_ffsl])\n  if test \"x${je_cv_function_ffsl}\" = \"xyes\" ; then\n    AC_DEFINE([JEMALLOC_INTERNAL_FFSLL], [ffsll])\n    AC_DEFINE([JEMALLOC_INTERNAL_FFSL], [ffsl])\n    AC_DEFINE([JEMALLOC_INTERNAL_FFS], [ffs])\n  else\n    AC_MSG_ERROR([Cannot build without ffsl(3) or __builtin_ffsl()])\n  fi\nfi\n\nAC_ARG_WITH([lg_tiny_min],\n  [AS_HELP_STRING([--with-lg-tiny-min=<lg-tiny-min>],\n   [Base 2 log of minimum tiny size class to support])],\n  [LG_TINY_MIN=\"$with_lg_tiny_min\"],\n  [LG_TINY_MIN=\"3\"])\nAC_DEFINE_UNQUOTED([LG_TINY_MIN], [$LG_TINY_MIN])\n\nAC_ARG_WITH([lg_quantum],\n  [AS_HELP_STRING([--with-lg-quantum=<lg-quantum>],\n   [Base 2 log of minimum allocation alignment])],\n  [LG_QUANTA=\"$with_lg_quantum\"],\n  [LG_QUANTA=\"3 4\"])\nif test \"x$with_lg_quantum\" != \"x\" ; then\n  AC_DEFINE_UNQUOTED([LG_QUANTUM], [$with_lg_quantum])\nfi\n\nAC_ARG_WITH([lg_page],\n  [AS_HELP_STRING([--with-lg-page=<lg-page>], [Base 2 log of system page size])],\n  [LG_PAGE=\"$with_lg_page\"], [LG_PAGE=\"detect\"])\nif test \"x$LG_PAGE\" = \"xdetect\"; then\n  AC_CACHE_CHECK([LG_PAGE],\n               [je_cv_lg_page],\n               AC_RUN_IFELSE([AC_LANG_PROGRAM(\n[[\n#include <strings.h>\n#ifdef _WIN32\n#include <windows.h>\n#else\n#include <unistd.h>\n#endif\n#include <stdio.h>\n]],\n[[\n    int result;\n    FILE *f;\n\n#ifdef _WIN32\n    SYSTEM_INFO si;\n    GetSystemInfo(&si);\n    result = si.dwPageSize;\n#else\n    result = sysconf(_SC_PAGESIZE);\n#endif\n    if (result == -1) {\n\treturn 1;\n    }\n    result = JEMALLOC_INTERNAL_FFSL(result) - 1;\n\n    f = fopen(\"conftest.out\", \"w\");\n    if (f == NULL) {\n\treturn 1;\n    }\n    fprintf(f, \"%d\", result);\n    fclose(f);\n\n    return 0;\n]])],\n                             [je_cv_lg_page=`cat conftest.out`],\n                             [je_cv_lg_page=undefined],\n                             [je_cv_lg_page=12]))\nfi\nif test \"x${je_cv_lg_page}\" != \"x\" ; then\n  LG_PAGE=\"${je_cv_lg_page}\"\nfi\nif test \"x${LG_PAGE}\" != \"xundefined\" ; then\n   AC_DEFINE_UNQUOTED([LG_PAGE], [$LG_PAGE])\nelse\n   AC_MSG_ERROR([cannot determine value for LG_PAGE])\nfi\n\nAC_ARG_WITH([lg_page_sizes],\n  [AS_HELP_STRING([--with-lg-page-sizes=<lg-page-sizes>],\n   [Base 2 logs of system page sizes to support])],\n  [LG_PAGE_SIZES=\"$with_lg_page_sizes\"], [LG_PAGE_SIZES=\"$LG_PAGE\"])\n\nAC_ARG_WITH([lg_size_class_group],\n  [AS_HELP_STRING([--with-lg-size-class-group=<lg-size-class-group>],\n   [Base 2 log of size classes per doubling])],\n  [LG_SIZE_CLASS_GROUP=\"$with_lg_size_class_group\"],\n  [LG_SIZE_CLASS_GROUP=\"2\"])\n\ndnl ============================================================================\ndnl jemalloc configuration.\ndnl \n\ndnl Set VERSION if source directory is inside a git repository.\nif test \"x`test ! \\\"${srcroot}\\\" && cd \\\"${srcroot}\\\"; git rev-parse --is-inside-work-tree 2>/dev/null`\" = \"xtrue\" ; then\n  dnl Pattern globs aren't powerful enough to match both single- and\n  dnl double-digit version numbers, so iterate over patterns to support up to\n  dnl version 99.99.99 without any accidental matches.\n  rm -f \"${objroot}VERSION\"\n  for pattern in ['[0-9].[0-9].[0-9]' '[0-9].[0-9].[0-9][0-9]' \\\n                 '[0-9].[0-9][0-9].[0-9]' '[0-9].[0-9][0-9].[0-9][0-9]' \\\n                 '[0-9][0-9].[0-9].[0-9]' '[0-9][0-9].[0-9].[0-9][0-9]' \\\n                 '[0-9][0-9].[0-9][0-9].[0-9]' \\\n                 '[0-9][0-9].[0-9][0-9].[0-9][0-9]']; do\n    if test ! -e \"${objroot}VERSION\" ; then\n      (test ! \"${srcroot}\" && cd \"${srcroot}\"; git describe --long --abbrev=40 --match=\"${pattern}\") > \"${objroot}VERSION.tmp\" 2>/dev/null\n      if test $? -eq 0 ; then\n        mv \"${objroot}VERSION.tmp\" \"${objroot}VERSION\"\n        break\n      fi\n    fi\n  done\nfi\nrm -f \"${objroot}VERSION.tmp\"\nif test ! -e \"${objroot}VERSION\" ; then\n  if test ! -e \"${srcroot}VERSION\" ; then\n    AC_MSG_RESULT(\n      [Missing VERSION file, and unable to generate it; creating bogus VERSION])\n    echo \"0.0.0-0-g0000000000000000000000000000000000000000\" > \"${objroot}VERSION\"\n  else\n    cp ${srcroot}VERSION ${objroot}VERSION\n  fi\nfi\njemalloc_version=`cat \"${objroot}VERSION\"`\njemalloc_version_major=`echo ${jemalloc_version} | tr \".g-\" \" \" | awk '{print [$]1}'`\njemalloc_version_minor=`echo ${jemalloc_version} | tr \".g-\" \" \" | awk '{print [$]2}'`\njemalloc_version_bugfix=`echo ${jemalloc_version} | tr \".g-\" \" \" | awk '{print [$]3}'`\njemalloc_version_nrev=`echo ${jemalloc_version} | tr \".g-\" \" \" | awk '{print [$]4}'`\njemalloc_version_gid=`echo ${jemalloc_version} | tr \".g-\" \" \" | awk '{print [$]5}'`\nAC_SUBST([jemalloc_version])\nAC_SUBST([jemalloc_version_major])\nAC_SUBST([jemalloc_version_minor])\nAC_SUBST([jemalloc_version_bugfix])\nAC_SUBST([jemalloc_version_nrev])\nAC_SUBST([jemalloc_version_gid])\n\ndnl ============================================================================\ndnl Configure pthreads.\n\nif test \"x$abi\" != \"xpecoff\" ; then\n  AC_CHECK_HEADERS([pthread.h], , [AC_MSG_ERROR([pthread.h is missing])])\n  dnl Some systems may embed pthreads functionality in libc; check for libpthread\n  dnl first, but try libc too before failing.\n  AC_CHECK_LIB([pthread], [pthread_create], [LIBS=\"$LIBS -lpthread\"],\n               [AC_SEARCH_LIBS([pthread_create], , ,\n                               AC_MSG_ERROR([libpthread is missing]))])\nfi\n\nCPPFLAGS=\"$CPPFLAGS -D_REENTRANT\"\n\ndnl Check whether clock_gettime(2) is in libc or librt.  This function is only\ndnl used in test code, so save the result to TESTLIBS to avoid poluting LIBS.\nSAVED_LIBS=\"${LIBS}\"\nLIBS=\nAC_SEARCH_LIBS([clock_gettime], [rt], [TESTLIBS=\"${LIBS}\"])\nAC_SUBST([TESTLIBS])\nLIBS=\"${SAVED_LIBS}\"\n\ndnl Check if the GNU-specific secure_getenv function exists.\nAC_CHECK_FUNC([secure_getenv],\n              [have_secure_getenv=\"1\"],\n              [have_secure_getenv=\"0\"]\n             )\nif test \"x$have_secure_getenv\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_HAVE_SECURE_GETENV], [ ])\nfi\n\ndnl Check if the Solaris/BSD issetugid function exists.\nAC_CHECK_FUNC([issetugid],\n              [have_issetugid=\"1\"],\n              [have_issetugid=\"0\"]\n             )\nif test \"x$have_issetugid\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_HAVE_ISSETUGID], [ ])\nfi\n\ndnl Check whether the BSD-specific _malloc_thread_cleanup() exists.  If so, use\ndnl it rather than pthreads TSD cleanup functions to support cleanup during\ndnl thread exit, in order to avoid pthreads library recursion during\ndnl bootstrapping.\nAC_CHECK_FUNC([_malloc_thread_cleanup],\n              [have__malloc_thread_cleanup=\"1\"],\n              [have__malloc_thread_cleanup=\"0\"]\n             )\nif test \"x$have__malloc_thread_cleanup\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_MALLOC_THREAD_CLEANUP], [ ])\n  force_tls=\"1\"\nfi\n\ndnl Check whether the BSD-specific _pthread_mutex_init_calloc_cb() exists.  If\ndnl so, mutex initialization causes allocation, and we need to implement this\ndnl callback function in order to prevent recursive allocation.\nAC_CHECK_FUNC([_pthread_mutex_init_calloc_cb],\n              [have__pthread_mutex_init_calloc_cb=\"1\"],\n              [have__pthread_mutex_init_calloc_cb=\"0\"]\n             )\nif test \"x$have__pthread_mutex_init_calloc_cb\" = \"x1\" ; then\n  AC_DEFINE([JEMALLOC_MUTEX_INIT_CB])\nfi\n\ndnl Disable lazy locking by default.\nAC_ARG_ENABLE([lazy_lock],\n  [AS_HELP_STRING([--enable-lazy-lock],\n  [Enable lazy locking (only lock when multi-threaded)])],\n[if test \"x$enable_lazy_lock\" = \"xno\" ; then\n  enable_lazy_lock=\"0\"\nelse\n  enable_lazy_lock=\"1\"\nfi\n],\n[enable_lazy_lock=\"\"]\n)\nif test \"x$enable_lazy_lock\" = \"x\" -a \"x${force_lazy_lock}\" = \"x1\" ; then\n  AC_MSG_RESULT([Forcing lazy-lock to avoid allocator/threading bootstrap issues])\n  enable_lazy_lock=\"1\"\nfi\nif test \"x$enable_lazy_lock\" = \"x1\" ; then\n  if test \"x$abi\" != \"xpecoff\" ; then\n    AC_CHECK_HEADERS([dlfcn.h], , [AC_MSG_ERROR([dlfcn.h is missing])])\n    AC_CHECK_FUNC([dlsym], [],\n      [AC_CHECK_LIB([dl], [dlsym], [LIBS=\"$LIBS -ldl\"],\n                    [AC_MSG_ERROR([libdl is missing])])\n      ])\n  fi\n  AC_DEFINE([JEMALLOC_LAZY_LOCK], [ ])\nelse\n  enable_lazy_lock=\"0\"\nfi\nAC_SUBST([enable_lazy_lock])\n\nAC_ARG_ENABLE([tls],\n  [AS_HELP_STRING([--disable-tls], [Disable thread-local storage (__thread keyword)])],\nif test \"x$enable_tls\" = \"xno\" ; then\n  enable_tls=\"0\"\nelse\n  enable_tls=\"1\"\nfi\n,\nenable_tls=\"\"\n)\nif test \"x${enable_tls}\" = \"x\" ; then\n  if test \"x${force_tls}\" = \"x1\" ; then\n    AC_MSG_RESULT([Forcing TLS to avoid allocator/threading bootstrap issues])\n    enable_tls=\"1\"\n  elif test \"x${force_tls}\" = \"x0\" ; then\n    AC_MSG_RESULT([Forcing no TLS to avoid allocator/threading bootstrap issues])\n    enable_tls=\"0\"\n  else\n    enable_tls=\"1\"\n  fi\nfi\nif test \"x${enable_tls}\" = \"x1\" ; then\nAC_MSG_CHECKING([for TLS])\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM(\n[[\n    __thread int x;\n]], [[\n    x = 42;\n\n    return 0;\n]])],\n              AC_MSG_RESULT([yes]),\n              AC_MSG_RESULT([no])\n              enable_tls=\"0\")\nelse\n  enable_tls=\"0\"\nfi\nAC_SUBST([enable_tls])\nif test \"x${enable_tls}\" = \"x1\" ; then\n  if test \"x${force_tls}\" = \"x0\" ; then\n    AC_MSG_WARN([TLS enabled despite being marked unusable on this platform])\n  fi\n  AC_DEFINE_UNQUOTED([JEMALLOC_TLS], [ ])\nelif test \"x${force_tls}\" = \"x1\" ; then\n  AC_MSG_WARN([TLS disabled despite being marked critical on this platform])\nfi\n\ndnl ============================================================================\ndnl Check for C11 atomics.\n\nJE_COMPILABLE([C11 atomics], [\n#include <stdint.h>\n#if (__STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_ATOMICS__)\n#include <stdatomic.h>\n#else\n#error Atomics not available\n#endif\n], [\n    uint64_t *p = (uint64_t *)0;\n    uint64_t x = 1;\n    volatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p;\n    uint64_t r = atomic_fetch_add(a, x) + x;\n    return (r == 0);\n], [je_cv_c11atomics])\nif test \"x${je_cv_c11atomics}\" = \"xyes\" ; then\n  AC_DEFINE([JEMALLOC_C11ATOMICS])\nfi\n\ndnl ============================================================================\ndnl Check for atomic(9) operations as provided on FreeBSD.\n\nJE_COMPILABLE([atomic(9)], [\n#include <sys/types.h>\n#include <machine/atomic.h>\n#include <inttypes.h>\n], [\n\t{\n\t\tuint32_t x32 = 0;\n\t\tvolatile uint32_t *x32p = &x32;\n\t\tatomic_fetchadd_32(x32p, 1);\n\t}\n\t{\n\t\tunsigned long xlong = 0;\n\t\tvolatile unsigned long *xlongp = &xlong;\n\t\tatomic_fetchadd_long(xlongp, 1);\n\t}\n], [je_cv_atomic9])\nif test \"x${je_cv_atomic9}\" = \"xyes\" ; then\n  AC_DEFINE([JEMALLOC_ATOMIC9])\nfi\n\ndnl ============================================================================\ndnl Check for atomic(3) operations as provided on Darwin.\n\nJE_COMPILABLE([Darwin OSAtomic*()], [\n#include <libkern/OSAtomic.h>\n#include <inttypes.h>\n], [\n\t{\n\t\tint32_t x32 = 0;\n\t\tvolatile int32_t *x32p = &x32;\n\t\tOSAtomicAdd32(1, x32p);\n\t}\n\t{\n\t\tint64_t x64 = 0;\n\t\tvolatile int64_t *x64p = &x64;\n\t\tOSAtomicAdd64(1, x64p);\n\t}\n], [je_cv_osatomic])\nif test \"x${je_cv_osatomic}\" = \"xyes\" ; then\n  AC_DEFINE([JEMALLOC_OSATOMIC], [ ])\nfi\n\ndnl ============================================================================\ndnl Check for madvise(2).\n\nJE_COMPILABLE([madvise(2)], [\n#include <sys/mman.h>\n], [\n\t{\n\t\tmadvise((void *)0, 0, 0);\n\t}\n], [je_cv_madvise])\nif test \"x${je_cv_madvise}\" = \"xyes\" ; then\n  AC_DEFINE([JEMALLOC_HAVE_MADVISE], [ ])\nfi\n\ndnl ============================================================================\ndnl Check whether __sync_{add,sub}_and_fetch() are available despite\ndnl __GCC_HAVE_SYNC_COMPARE_AND_SWAP_n macros being undefined.\n\nAC_DEFUN([JE_SYNC_COMPARE_AND_SWAP_CHECK],[\n  AC_CACHE_CHECK([whether to force $1-bit __sync_{add,sub}_and_fetch()],\n               [je_cv_sync_compare_and_swap_$2],\n               [AC_LINK_IFELSE([AC_LANG_PROGRAM([\n                                                 #include <stdint.h>\n                                                ],\n                                                [\n                                                 #ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_$2\n                                                 {\n                                                    uint$1_t x$1 = 0;\n                                                    __sync_add_and_fetch(&x$1, 42);\n                                                    __sync_sub_and_fetch(&x$1, 1);\n                                                 }\n                                                 #else\n                                                 #error __GCC_HAVE_SYNC_COMPARE_AND_SWAP_$2 is defined, no need to force\n                                                 #endif\n                                                ])],\n                               [je_cv_sync_compare_and_swap_$2=yes],\n                               [je_cv_sync_compare_and_swap_$2=no])])\n\n  if test \"x${je_cv_sync_compare_and_swap_$2}\" = \"xyes\" ; then\n    AC_DEFINE([JE_FORCE_SYNC_COMPARE_AND_SWAP_$2], [ ])\n  fi\n])\n\nif test \"x${je_cv_atomic9}\" != \"xyes\" -a \"x${je_cv_osatomic}\" != \"xyes\" ; then\n  JE_SYNC_COMPARE_AND_SWAP_CHECK(32, 4)\n  JE_SYNC_COMPARE_AND_SWAP_CHECK(64, 8)\nfi\n\ndnl ============================================================================\ndnl Check for __builtin_clz() and __builtin_clzl().\n\nAC_CACHE_CHECK([for __builtin_clz],\n               [je_cv_builtin_clz],\n               [AC_LINK_IFELSE([AC_LANG_PROGRAM([],\n                                                [\n                                                {\n                                                        unsigned x = 0;\n                                                        int y = __builtin_clz(x);\n                                                }\n                                                {\n                                                        unsigned long x = 0;\n                                                        int y = __builtin_clzl(x);\n                                                }\n                                                ])],\n                               [je_cv_builtin_clz=yes],\n                               [je_cv_builtin_clz=no])])\n\nif test \"x${je_cv_builtin_clz}\" = \"xyes\" ; then\n  AC_DEFINE([JEMALLOC_HAVE_BUILTIN_CLZ], [ ])\nfi\n\ndnl ============================================================================\ndnl Check for spinlock(3) operations as provided on Darwin.\n\nJE_COMPILABLE([Darwin OSSpin*()], [\n#include <libkern/OSAtomic.h>\n#include <inttypes.h>\n], [\n\tOSSpinLock lock = 0;\n\tOSSpinLockLock(&lock);\n\tOSSpinLockUnlock(&lock);\n], [je_cv_osspin])\nif test \"x${je_cv_osspin}\" = \"xyes\" ; then\n  AC_DEFINE([JEMALLOC_OSSPIN], [ ])\nfi\n\ndnl ============================================================================\ndnl Darwin-related configuration.\n\nAC_ARG_ENABLE([zone-allocator],\n  [AS_HELP_STRING([--disable-zone-allocator],\n                  [Disable zone allocator for Darwin])],\n[if test \"x$enable_zone_allocator\" = \"xno\" ; then\n  enable_zone_allocator=\"0\"\nelse\n  enable_zone_allocator=\"1\"\nfi\n],\n[if test \"x${abi}\" = \"xmacho\"; then\n  enable_zone_allocator=\"1\"\nfi\n]\n)\nAC_SUBST([enable_zone_allocator])\n\nif test \"x${enable_zone_allocator}\" = \"x1\" ; then\n  if test \"x${abi}\" != \"xmacho\"; then\n    AC_MSG_ERROR([--enable-zone-allocator is only supported on Darwin])\n  fi\n  AC_DEFINE([JEMALLOC_ZONE], [ ])\n\n  dnl The szone version jumped from 3 to 6 between the OS X 10.5.x and 10.6\n  dnl releases.  malloc_zone_t and malloc_introspection_t have new fields in\n  dnl 10.6, which is the only source-level indication of the change.\n  AC_MSG_CHECKING([malloc zone version])\n  AC_DEFUN([JE_ZONE_PROGRAM],\n    [AC_LANG_PROGRAM(\n      [#include <malloc/malloc.h>],\n      [static int foo[[sizeof($1) $2 sizeof(void *) * $3 ? 1 : -1]]]\n    )])\n\n  AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,==,14)],[JEMALLOC_ZONE_VERSION=3],[\n  AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,==,15)],[JEMALLOC_ZONE_VERSION=5],[\n  AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,==,16)],[\n    AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_introspection_t,==,9)],[JEMALLOC_ZONE_VERSION=6],[\n    AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_introspection_t,==,13)],[JEMALLOC_ZONE_VERSION=7],[JEMALLOC_ZONE_VERSION=]\n  )])],[\n  AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,==,17)],[JEMALLOC_ZONE_VERSION=8],[\n  AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,>,17)],[JEMALLOC_ZONE_VERSION=9],[JEMALLOC_ZONE_VERSION=]\n  )])])])])\n  if test \"x${JEMALLOC_ZONE_VERSION}\" = \"x\"; then\n    AC_MSG_RESULT([unsupported])\n    AC_MSG_ERROR([Unsupported malloc zone version])\n  fi\n  if test \"${JEMALLOC_ZONE_VERSION}\" = 9; then\n    JEMALLOC_ZONE_VERSION=8\n    AC_MSG_RESULT([> 8])\n  else\n    AC_MSG_RESULT([$JEMALLOC_ZONE_VERSION])\n  fi\n  AC_DEFINE_UNQUOTED(JEMALLOC_ZONE_VERSION, [$JEMALLOC_ZONE_VERSION])\nfi\n\ndnl ============================================================================\ndnl Check for glibc malloc hooks\n\nJE_COMPILABLE([glibc malloc hook], [\n#include <stddef.h>\n\nextern void (* __free_hook)(void *ptr);\nextern void *(* __malloc_hook)(size_t size);\nextern void *(* __realloc_hook)(void *ptr, size_t size);\n], [\n  void *ptr = 0L;\n  if (__malloc_hook) ptr = __malloc_hook(1);\n  if (__realloc_hook) ptr = __realloc_hook(ptr, 2);\n  if (__free_hook && ptr) __free_hook(ptr);\n], [je_cv_glibc_malloc_hook])\nif test \"x${je_cv_glibc_malloc_hook}\" = \"xyes\" ; then\n  AC_DEFINE([JEMALLOC_GLIBC_MALLOC_HOOK], [ ])\nfi\n\nJE_COMPILABLE([glibc memalign hook], [\n#include <stddef.h>\n\nextern void *(* __memalign_hook)(size_t alignment, size_t size);\n], [\n  void *ptr = 0L;\n  if (__memalign_hook) ptr = __memalign_hook(16, 7);\n], [je_cv_glibc_memalign_hook])\nif test \"x${je_cv_glibc_memalign_hook}\" = \"xyes\" ; then\n  AC_DEFINE([JEMALLOC_GLIBC_MEMALIGN_HOOK], [ ])\nfi\n\nJE_COMPILABLE([pthreads adaptive mutexes], [\n#include <pthread.h>\n], [\n  pthread_mutexattr_t attr;\n  pthread_mutexattr_init(&attr);\n  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);\n  pthread_mutexattr_destroy(&attr);\n], [je_cv_pthread_mutex_adaptive_np])\nif test \"x${je_cv_pthread_mutex_adaptive_np}\" = \"xyes\" ; then\n  AC_DEFINE([JEMALLOC_HAVE_PTHREAD_MUTEX_ADAPTIVE_NP], [ ])\nfi\n\ndnl ============================================================================\ndnl Check for typedefs, structures, and compiler characteristics.\nAC_HEADER_STDBOOL\n\ndnl ============================================================================\ndnl Define commands that generate output files.\n\nAC_CONFIG_COMMANDS([include/jemalloc/internal/private_namespace.h], [\n  mkdir -p \"${objroot}include/jemalloc/internal\"\n  \"${srcdir}/include/jemalloc/internal/private_namespace.sh\" \"${srcdir}/include/jemalloc/internal/private_symbols.txt\" > \"${objroot}include/jemalloc/internal/private_namespace.h\"\n], [\n  srcdir=\"${srcdir}\"\n  objroot=\"${objroot}\"\n])\nAC_CONFIG_COMMANDS([include/jemalloc/internal/private_unnamespace.h], [\n  mkdir -p \"${objroot}include/jemalloc/internal\"\n  \"${srcdir}/include/jemalloc/internal/private_unnamespace.sh\" \"${srcdir}/include/jemalloc/internal/private_symbols.txt\" > \"${objroot}include/jemalloc/internal/private_unnamespace.h\"\n], [\n  srcdir=\"${srcdir}\"\n  objroot=\"${objroot}\"\n])\nAC_CONFIG_COMMANDS([include/jemalloc/internal/public_symbols.txt], [\n  f=\"${objroot}include/jemalloc/internal/public_symbols.txt\"\n  mkdir -p \"${objroot}include/jemalloc/internal\"\n  cp /dev/null \"${f}\"\n  for nm in `echo ${mangling_map} |tr ',' ' '` ; do\n    n=`echo ${nm} |tr ':' ' ' |awk '{print $[]1}'`\n    m=`echo ${nm} |tr ':' ' ' |awk '{print $[]2}'`\n    echo \"${n}:${m}\" >> \"${f}\"\n    dnl Remove name from public_syms so that it isn't redefined later.\n    public_syms=`for sym in ${public_syms}; do echo \"${sym}\"; done |grep -v \"^${n}\\$\" |tr '\\n' ' '`\n  done\n  for sym in ${public_syms} ; do\n    n=\"${sym}\"\n    m=\"${JEMALLOC_PREFIX}${sym}\"\n    echo \"${n}:${m}\" >> \"${f}\"\n  done\n], [\n  srcdir=\"${srcdir}\"\n  objroot=\"${objroot}\"\n  mangling_map=\"${mangling_map}\"\n  public_syms=\"${public_syms}\"\n  JEMALLOC_PREFIX=\"${JEMALLOC_PREFIX}\"\n])\nAC_CONFIG_COMMANDS([include/jemalloc/internal/public_namespace.h], [\n  mkdir -p \"${objroot}include/jemalloc/internal\"\n  \"${srcdir}/include/jemalloc/internal/public_namespace.sh\" \"${objroot}include/jemalloc/internal/public_symbols.txt\" > \"${objroot}include/jemalloc/internal/public_namespace.h\"\n], [\n  srcdir=\"${srcdir}\"\n  objroot=\"${objroot}\"\n])\nAC_CONFIG_COMMANDS([include/jemalloc/internal/public_unnamespace.h], [\n  mkdir -p \"${objroot}include/jemalloc/internal\"\n  \"${srcdir}/include/jemalloc/internal/public_unnamespace.sh\" \"${objroot}include/jemalloc/internal/public_symbols.txt\" > \"${objroot}include/jemalloc/internal/public_unnamespace.h\"\n], [\n  srcdir=\"${srcdir}\"\n  objroot=\"${objroot}\"\n])\nAC_CONFIG_COMMANDS([include/jemalloc/internal/size_classes.h], [\n  mkdir -p \"${objroot}include/jemalloc/internal\"\n  \"${SHELL}\" \"${srcdir}/include/jemalloc/internal/size_classes.sh\" \"${LG_QUANTA}\" ${LG_TINY_MIN} \"${LG_PAGE_SIZES}\" ${LG_SIZE_CLASS_GROUP} > \"${objroot}include/jemalloc/internal/size_classes.h\"\n], [\n  SHELL=\"${SHELL}\"\n  srcdir=\"${srcdir}\"\n  objroot=\"${objroot}\"\n  LG_QUANTA=\"${LG_QUANTA}\"\n  LG_TINY_MIN=${LG_TINY_MIN}\n  LG_PAGE_SIZES=\"${LG_PAGE_SIZES}\"\n  LG_SIZE_CLASS_GROUP=${LG_SIZE_CLASS_GROUP}\n])\nAC_CONFIG_COMMANDS([include/jemalloc/jemalloc_protos_jet.h], [\n  mkdir -p \"${objroot}include/jemalloc\"\n  cat \"${srcdir}/include/jemalloc/jemalloc_protos.h.in\" | sed -e 's/@je_@/jet_/g' > \"${objroot}include/jemalloc/jemalloc_protos_jet.h\"\n], [\n  srcdir=\"${srcdir}\"\n  objroot=\"${objroot}\"\n])\nAC_CONFIG_COMMANDS([include/jemalloc/jemalloc_rename.h], [\n  mkdir -p \"${objroot}include/jemalloc\"\n  \"${srcdir}/include/jemalloc/jemalloc_rename.sh\" \"${objroot}include/jemalloc/internal/public_symbols.txt\" > \"${objroot}include/jemalloc/jemalloc_rename.h\"\n], [\n  srcdir=\"${srcdir}\"\n  objroot=\"${objroot}\"\n])\nAC_CONFIG_COMMANDS([include/jemalloc/jemalloc_mangle.h], [\n  mkdir -p \"${objroot}include/jemalloc\"\n  \"${srcdir}/include/jemalloc/jemalloc_mangle.sh\" \"${objroot}include/jemalloc/internal/public_symbols.txt\" je_ > \"${objroot}include/jemalloc/jemalloc_mangle.h\"\n], [\n  srcdir=\"${srcdir}\"\n  objroot=\"${objroot}\"\n])\nAC_CONFIG_COMMANDS([include/jemalloc/jemalloc_mangle_jet.h], [\n  mkdir -p \"${objroot}include/jemalloc\"\n  \"${srcdir}/include/jemalloc/jemalloc_mangle.sh\" \"${objroot}include/jemalloc/internal/public_symbols.txt\" jet_ > \"${objroot}include/jemalloc/jemalloc_mangle_jet.h\"\n], [\n  srcdir=\"${srcdir}\"\n  objroot=\"${objroot}\"\n])\nAC_CONFIG_COMMANDS([include/jemalloc/jemalloc.h], [\n  mkdir -p \"${objroot}include/jemalloc\"\n  \"${srcdir}/include/jemalloc/jemalloc.sh\" \"${objroot}\" > \"${objroot}include/jemalloc/jemalloc${install_suffix}.h\"\n], [\n  srcdir=\"${srcdir}\"\n  objroot=\"${objroot}\"\n  install_suffix=\"${install_suffix}\"\n])\n\ndnl Process .in files.\nAC_SUBST([cfghdrs_in])\nAC_SUBST([cfghdrs_out])\nAC_CONFIG_HEADERS([$cfghdrs_tup])\n\ndnl ============================================================================\ndnl Generate outputs.\n\nAC_CONFIG_FILES([$cfgoutputs_tup config.stamp bin/jemalloc-config bin/jemalloc.sh bin/jeprof])\nAC_SUBST([cfgoutputs_in])\nAC_SUBST([cfgoutputs_out])\nAC_OUTPUT\n\ndnl ============================================================================\ndnl Print out the results of configuration.\nAC_MSG_RESULT([===============================================================================])\nAC_MSG_RESULT([jemalloc version   : ${jemalloc_version}])\nAC_MSG_RESULT([library revision   : ${rev}])\nAC_MSG_RESULT([])\nAC_MSG_RESULT([CONFIG             : ${CONFIG}])\nAC_MSG_RESULT([CC                 : ${CC}])\nAC_MSG_RESULT([CFLAGS             : ${CFLAGS}])\nAC_MSG_RESULT([CPPFLAGS           : ${CPPFLAGS}])\nAC_MSG_RESULT([LDFLAGS            : ${LDFLAGS}])\nAC_MSG_RESULT([EXTRA_LDFLAGS      : ${EXTRA_LDFLAGS}])\nAC_MSG_RESULT([LIBS               : ${LIBS}])\nAC_MSG_RESULT([TESTLIBS           : ${TESTLIBS}])\nAC_MSG_RESULT([RPATH_EXTRA        : ${RPATH_EXTRA}])\nAC_MSG_RESULT([])\nAC_MSG_RESULT([XSLTPROC           : ${XSLTPROC}])\nAC_MSG_RESULT([XSLROOT            : ${XSLROOT}])\nAC_MSG_RESULT([])\nAC_MSG_RESULT([PREFIX             : ${PREFIX}])\nAC_MSG_RESULT([BINDIR             : ${BINDIR}])\nAC_MSG_RESULT([DATADIR            : ${DATADIR}])\nAC_MSG_RESULT([INCLUDEDIR         : ${INCLUDEDIR}])\nAC_MSG_RESULT([LIBDIR             : ${LIBDIR}])\nAC_MSG_RESULT([MANDIR             : ${MANDIR}])\nAC_MSG_RESULT([])\nAC_MSG_RESULT([srcroot            : ${srcroot}])\nAC_MSG_RESULT([abs_srcroot        : ${abs_srcroot}])\nAC_MSG_RESULT([objroot            : ${objroot}])\nAC_MSG_RESULT([abs_objroot        : ${abs_objroot}])\nAC_MSG_RESULT([])\nAC_MSG_RESULT([JEMALLOC_PREFIX    : ${JEMALLOC_PREFIX}])\nAC_MSG_RESULT([JEMALLOC_PRIVATE_NAMESPACE])\nAC_MSG_RESULT([                   : ${JEMALLOC_PRIVATE_NAMESPACE}])\nAC_MSG_RESULT([install_suffix     : ${install_suffix}])\nAC_MSG_RESULT([malloc_conf        : ${config_malloc_conf}])\nAC_MSG_RESULT([autogen            : ${enable_autogen}])\nAC_MSG_RESULT([cc-silence         : ${enable_cc_silence}])\nAC_MSG_RESULT([debug              : ${enable_debug}])\nAC_MSG_RESULT([code-coverage      : ${enable_code_coverage}])\nAC_MSG_RESULT([stats              : ${enable_stats}])\nAC_MSG_RESULT([prof               : ${enable_prof}])\nAC_MSG_RESULT([prof-libunwind     : ${enable_prof_libunwind}])\nAC_MSG_RESULT([prof-libgcc        : ${enable_prof_libgcc}])\nAC_MSG_RESULT([prof-gcc           : ${enable_prof_gcc}])\nAC_MSG_RESULT([tcache             : ${enable_tcache}])\nAC_MSG_RESULT([fill               : ${enable_fill}])\nAC_MSG_RESULT([utrace             : ${enable_utrace}])\nAC_MSG_RESULT([valgrind           : ${enable_valgrind}])\nAC_MSG_RESULT([xmalloc            : ${enable_xmalloc}])\nAC_MSG_RESULT([munmap             : ${enable_munmap}])\nAC_MSG_RESULT([lazy_lock          : ${enable_lazy_lock}])\nAC_MSG_RESULT([tls                : ${enable_tls}])\nAC_MSG_RESULT([cache-oblivious    : ${enable_cache_oblivious}])\nAC_MSG_RESULT([===============================================================================])\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/coverage.sh",
    "content": "#!/bin/sh\n\nset -e\n\nobjdir=$1\nsuffix=$2\nshift 2\nobjs=$@\n\ngcov -b -p -f -o \"${objdir}\" ${objs}\n\n# Move gcov outputs so that subsequent gcov invocations won't clobber results\n# for the same sources with different compilation flags.\nfor f in `find . -maxdepth 1 -type f -name '*.gcov'` ; do\n  mv \"${f}\" \"${f}.${suffix}\"\ndone\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/doc/html.xsl.in",
    "content": "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n  <xsl:import href=\"@XSLROOT@/html/docbook.xsl\"/>\n  <xsl:import href=\"@abs_srcroot@doc/stylesheet.xsl\"/>\n</xsl:stylesheet>\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/doc/jemalloc.xml.in",
    "content": "<?xml version='1.0' encoding='UTF-8'?>\n<?xml-stylesheet type=\"text/xsl\"\n        href=\"http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl\"?>\n<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.4//EN\"\n        \"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd\" [\n]>\n\n<refentry>\n  <refentryinfo>\n    <title>User Manual</title>\n    <productname>jemalloc</productname>\n    <releaseinfo role=\"version\">@jemalloc_version@</releaseinfo>\n    <authorgroup>\n      <author>\n        <firstname>Jason</firstname>\n        <surname>Evans</surname>\n        <personblurb>Author</personblurb>\n      </author>\n    </authorgroup>\n  </refentryinfo>\n  <refmeta>\n    <refentrytitle>JEMALLOC</refentrytitle>\n    <manvolnum>3</manvolnum>\n  </refmeta>\n  <refnamediv>\n    <refdescriptor>jemalloc</refdescriptor>\n    <refname>jemalloc</refname>\n    <!-- Each refname causes a man page file to be created.  Only if this were\n         the system malloc(3) implementation would these files be appropriate.\n    <refname>malloc</refname>\n    <refname>calloc</refname>\n    <refname>posix_memalign</refname>\n    <refname>aligned_alloc</refname>\n    <refname>realloc</refname>\n    <refname>free</refname>\n    <refname>mallocx</refname>\n    <refname>rallocx</refname>\n    <refname>xallocx</refname>\n    <refname>sallocx</refname>\n    <refname>dallocx</refname>\n    <refname>sdallocx</refname>\n    <refname>nallocx</refname>\n    <refname>mallctl</refname>\n    <refname>mallctlnametomib</refname>\n    <refname>mallctlbymib</refname>\n    <refname>malloc_stats_print</refname>\n    <refname>malloc_usable_size</refname>\n    -->\n    <refpurpose>general purpose memory allocation functions</refpurpose>\n  </refnamediv>\n  <refsect1 id=\"library\">\n    <title>LIBRARY</title>\n    <para>This manual describes jemalloc @jemalloc_version@.  More information\n    can be found at the <ulink\n    url=\"http://www.canonware.com/jemalloc/\">jemalloc website</ulink>.</para>\n  </refsect1>\n  <refsynopsisdiv>\n    <title>SYNOPSIS</title>\n    <funcsynopsis>\n      <funcsynopsisinfo>#include &lt;<filename class=\"headerfile\">jemalloc/jemalloc.h</filename>&gt;</funcsynopsisinfo>\n      <refsect2>\n        <title>Standard API</title>\n        <funcprototype>\n          <funcdef>void *<function>malloc</function></funcdef>\n          <paramdef>size_t <parameter>size</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>void *<function>calloc</function></funcdef>\n          <paramdef>size_t <parameter>number</parameter></paramdef>\n          <paramdef>size_t <parameter>size</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>int <function>posix_memalign</function></funcdef>\n          <paramdef>void **<parameter>ptr</parameter></paramdef>\n          <paramdef>size_t <parameter>alignment</parameter></paramdef>\n          <paramdef>size_t <parameter>size</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>void *<function>aligned_alloc</function></funcdef>\n          <paramdef>size_t <parameter>alignment</parameter></paramdef>\n          <paramdef>size_t <parameter>size</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>void *<function>realloc</function></funcdef>\n          <paramdef>void *<parameter>ptr</parameter></paramdef>\n          <paramdef>size_t <parameter>size</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>void <function>free</function></funcdef>\n          <paramdef>void *<parameter>ptr</parameter></paramdef>\n        </funcprototype>\n      </refsect2>\n      <refsect2>\n        <title>Non-standard API</title>\n        <funcprototype>\n          <funcdef>void *<function>mallocx</function></funcdef>\n          <paramdef>size_t <parameter>size</parameter></paramdef>\n          <paramdef>int <parameter>flags</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>void *<function>rallocx</function></funcdef>\n          <paramdef>void *<parameter>ptr</parameter></paramdef>\n          <paramdef>size_t <parameter>size</parameter></paramdef>\n          <paramdef>int <parameter>flags</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>size_t <function>xallocx</function></funcdef>\n          <paramdef>void *<parameter>ptr</parameter></paramdef>\n          <paramdef>size_t <parameter>size</parameter></paramdef>\n          <paramdef>size_t <parameter>extra</parameter></paramdef>\n          <paramdef>int <parameter>flags</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>size_t <function>sallocx</function></funcdef>\n          <paramdef>void *<parameter>ptr</parameter></paramdef>\n          <paramdef>int <parameter>flags</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>void <function>dallocx</function></funcdef>\n          <paramdef>void *<parameter>ptr</parameter></paramdef>\n          <paramdef>int <parameter>flags</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>void <function>sdallocx</function></funcdef>\n          <paramdef>void *<parameter>ptr</parameter></paramdef>\n          <paramdef>size_t <parameter>size</parameter></paramdef>\n          <paramdef>int <parameter>flags</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>size_t <function>nallocx</function></funcdef>\n          <paramdef>size_t <parameter>size</parameter></paramdef>\n          <paramdef>int <parameter>flags</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>int <function>mallctl</function></funcdef>\n          <paramdef>const char *<parameter>name</parameter></paramdef>\n          <paramdef>void *<parameter>oldp</parameter></paramdef>\n          <paramdef>size_t *<parameter>oldlenp</parameter></paramdef>\n          <paramdef>void *<parameter>newp</parameter></paramdef>\n          <paramdef>size_t <parameter>newlen</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>int <function>mallctlnametomib</function></funcdef>\n          <paramdef>const char *<parameter>name</parameter></paramdef>\n          <paramdef>size_t *<parameter>mibp</parameter></paramdef>\n          <paramdef>size_t *<parameter>miblenp</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>int <function>mallctlbymib</function></funcdef>\n          <paramdef>const size_t *<parameter>mib</parameter></paramdef>\n          <paramdef>size_t <parameter>miblen</parameter></paramdef>\n          <paramdef>void *<parameter>oldp</parameter></paramdef>\n          <paramdef>size_t *<parameter>oldlenp</parameter></paramdef>\n          <paramdef>void *<parameter>newp</parameter></paramdef>\n          <paramdef>size_t <parameter>newlen</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>void <function>malloc_stats_print</function></funcdef>\n          <paramdef>void <parameter>(*write_cb)</parameter>\n            <funcparams>void *, const char *</funcparams>\n          </paramdef>\n          <paramdef>void *<parameter>cbopaque</parameter></paramdef>\n          <paramdef>const char *<parameter>opts</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>size_t <function>malloc_usable_size</function></funcdef>\n          <paramdef>const void *<parameter>ptr</parameter></paramdef>\n        </funcprototype>\n        <funcprototype>\n          <funcdef>void <function>(*malloc_message)</function></funcdef>\n          <paramdef>void *<parameter>cbopaque</parameter></paramdef>\n          <paramdef>const char *<parameter>s</parameter></paramdef>\n        </funcprototype>\n        <para><type>const char *</type><varname>malloc_conf</varname>;</para>\n      </refsect2>\n    </funcsynopsis>\n  </refsynopsisdiv>\n  <refsect1 id=\"description\">\n    <title>DESCRIPTION</title>\n    <refsect2>\n      <title>Standard API</title>\n\n      <para>The <function>malloc<parameter/></function> function allocates\n      <parameter>size</parameter> bytes of uninitialized memory.  The allocated\n      space is suitably aligned (after possible pointer coercion) for storage\n      of any type of object.</para>\n\n      <para>The <function>calloc<parameter/></function> function allocates\n      space for <parameter>number</parameter> objects, each\n      <parameter>size</parameter> bytes in length.  The result is identical to\n      calling <function>malloc<parameter/></function> with an argument of\n      <parameter>number</parameter> * <parameter>size</parameter>, with the\n      exception that the allocated memory is explicitly initialized to zero\n      bytes.</para>\n\n      <para>The <function>posix_memalign<parameter/></function> function\n      allocates <parameter>size</parameter> bytes of memory such that the\n      allocation's base address is a multiple of\n      <parameter>alignment</parameter>, and returns the allocation in the value\n      pointed to by <parameter>ptr</parameter>.  The requested\n      <parameter>alignment</parameter> must be a power of 2 at least as large as\n      <code language=\"C\">sizeof(<type>void *</type>)</code>.</para>\n\n      <para>The <function>aligned_alloc<parameter/></function> function\n      allocates <parameter>size</parameter> bytes of memory such that the\n      allocation's base address is a multiple of\n      <parameter>alignment</parameter>.  The requested\n      <parameter>alignment</parameter> must be a power of 2.  Behavior is\n      undefined if <parameter>size</parameter> is not an integral multiple of\n      <parameter>alignment</parameter>.</para>\n\n      <para>The <function>realloc<parameter/></function> function changes the\n      size of the previously allocated memory referenced by\n      <parameter>ptr</parameter> to <parameter>size</parameter> bytes.  The\n      contents of the memory are unchanged up to the lesser of the new and old\n      sizes.  If the new size is larger, the contents of the newly allocated\n      portion of the memory are undefined.  Upon success, the memory referenced\n      by <parameter>ptr</parameter> is freed and a pointer to the newly\n      allocated memory is returned.  Note that\n      <function>realloc<parameter/></function> may move the memory allocation,\n      resulting in a different return value than <parameter>ptr</parameter>.\n      If <parameter>ptr</parameter> is <constant>NULL</constant>, the\n      <function>realloc<parameter/></function> function behaves identically to\n      <function>malloc<parameter/></function> for the specified size.</para>\n\n      <para>The <function>free<parameter/></function> function causes the\n      allocated memory referenced by <parameter>ptr</parameter> to be made\n      available for future allocations.  If <parameter>ptr</parameter> is\n      <constant>NULL</constant>, no action occurs.</para>\n    </refsect2>\n    <refsect2>\n      <title>Non-standard API</title>\n      <para>The <function>mallocx<parameter/></function>,\n      <function>rallocx<parameter/></function>,\n      <function>xallocx<parameter/></function>,\n      <function>sallocx<parameter/></function>,\n      <function>dallocx<parameter/></function>,\n      <function>sdallocx<parameter/></function>, and\n      <function>nallocx<parameter/></function> functions all have a\n      <parameter>flags</parameter> argument that can be used to specify\n      options.  The functions only check the options that are contextually\n      relevant.  Use bitwise or (<code language=\"C\">|</code>) operations to\n      specify one or more of the following:\n        <variablelist>\n          <varlistentry id=\"MALLOCX_LG_ALIGN\">\n            <term><constant>MALLOCX_LG_ALIGN(<parameter>la</parameter>)\n            </constant></term>\n\n            <listitem><para>Align the memory allocation to start at an address\n            that is a multiple of <code language=\"C\">(1 &lt;&lt;\n            <parameter>la</parameter>)</code>.  This macro does not validate\n            that <parameter>la</parameter> is within the valid\n            range.</para></listitem>\n          </varlistentry>\n          <varlistentry id=\"MALLOCX_ALIGN\">\n            <term><constant>MALLOCX_ALIGN(<parameter>a</parameter>)\n            </constant></term>\n\n            <listitem><para>Align the memory allocation to start at an address\n            that is a multiple of <parameter>a</parameter>, where\n            <parameter>a</parameter> is a power of two.  This macro does not\n            validate that <parameter>a</parameter> is a power of 2.\n            </para></listitem>\n          </varlistentry>\n          <varlistentry id=\"MALLOCX_ZERO\">\n            <term><constant>MALLOCX_ZERO</constant></term>\n\n            <listitem><para>Initialize newly allocated memory to contain zero\n            bytes.  In the growing reallocation case, the real size prior to\n            reallocation defines the boundary between untouched bytes and those\n            that are initialized to contain zero bytes.  If this macro is\n            absent, newly allocated memory is uninitialized.</para></listitem>\n          </varlistentry>\n          <varlistentry id=\"MALLOCX_TCACHE\">\n            <term><constant>MALLOCX_TCACHE(<parameter>tc</parameter>)\n            </constant></term>\n\n            <listitem><para>Use the thread-specific cache (tcache) specified by\n            the identifier <parameter>tc</parameter>, which must have been\n            acquired via the <link\n            linkend=\"tcache.create\"><mallctl>tcache.create</mallctl></link>\n            mallctl.  This macro does not validate that\n            <parameter>tc</parameter> specifies a valid\n            identifier.</para></listitem>\n          </varlistentry>\n          <varlistentry id=\"MALLOC_TCACHE_NONE\">\n            <term><constant>MALLOCX_TCACHE_NONE</constant></term>\n\n            <listitem><para>Do not use a thread-specific cache (tcache).  Unless\n            <constant>MALLOCX_TCACHE(<parameter>tc</parameter>)</constant> or\n            <constant>MALLOCX_TCACHE_NONE</constant> is specified, an\n            automatically managed tcache will be used under many circumstances.\n            This macro cannot be used in the same <parameter>flags</parameter>\n            argument as\n            <constant>MALLOCX_TCACHE(<parameter>tc</parameter>)</constant>.</para></listitem>\n          </varlistentry>\n          <varlistentry id=\"MALLOCX_ARENA\">\n            <term><constant>MALLOCX_ARENA(<parameter>a</parameter>)\n            </constant></term>\n\n            <listitem><para>Use the arena specified by the index\n            <parameter>a</parameter>.  This macro has no effect for regions that\n            were allocated via an arena other than the one specified.  This\n            macro does not validate that <parameter>a</parameter> specifies an\n            arena index in the valid range.</para></listitem>\n          </varlistentry>\n        </variablelist>\n      </para>\n\n      <para>The <function>mallocx<parameter/></function> function allocates at\n      least <parameter>size</parameter> bytes of memory, and returns a pointer\n      to the base address of the allocation.  Behavior is undefined if\n      <parameter>size</parameter> is <constant>0</constant>.</para>\n\n      <para>The <function>rallocx<parameter/></function> function resizes the\n      allocation at <parameter>ptr</parameter> to be at least\n      <parameter>size</parameter> bytes, and returns a pointer to the base\n      address of the resulting allocation, which may or may not have moved from\n      its original location.  Behavior is undefined if\n      <parameter>size</parameter> is <constant>0</constant>.</para>\n\n      <para>The <function>xallocx<parameter/></function> function resizes the\n      allocation at <parameter>ptr</parameter> in place to be at least\n      <parameter>size</parameter> bytes, and returns the real size of the\n      allocation.  If <parameter>extra</parameter> is non-zero, an attempt is\n      made to resize the allocation to be at least <code\n      language=\"C\">(<parameter>size</parameter> +\n      <parameter>extra</parameter>)</code> bytes, though inability to allocate\n      the extra byte(s) will not by itself result in failure to resize.\n      Behavior is undefined if <parameter>size</parameter> is\n      <constant>0</constant>, or if <code\n      language=\"C\">(<parameter>size</parameter> + <parameter>extra</parameter>\n      &gt; <constant>SIZE_T_MAX</constant>)</code>.</para>\n\n      <para>The <function>sallocx<parameter/></function> function returns the\n      real size of the allocation at <parameter>ptr</parameter>.</para>\n\n      <para>The <function>dallocx<parameter/></function> function causes the\n      memory referenced by <parameter>ptr</parameter> to be made available for\n      future allocations.</para>\n\n      <para>The <function>sdallocx<parameter/></function> function is an\n      extension of <function>dallocx<parameter/></function> with a\n      <parameter>size</parameter> parameter to allow the caller to pass in the\n      allocation size as an optimization.  The minimum valid input size is the\n      original requested size of the allocation, and the maximum valid input\n      size is the corresponding value returned by\n      <function>nallocx<parameter/></function> or\n      <function>sallocx<parameter/></function>.</para>\n\n      <para>The <function>nallocx<parameter/></function> function allocates no\n      memory, but it performs the same size computation as the\n      <function>mallocx<parameter/></function> function, and returns the real\n      size of the allocation that would result from the equivalent\n      <function>mallocx<parameter/></function> function call, or\n      <constant>0</constant> if the inputs exceed the maximum supported size\n      class and/or alignment.  Behavior is undefined if\n      <parameter>size</parameter> is <constant>0</constant>.</para>\n\n      <para>The <function>mallctl<parameter/></function> function provides a\n      general interface for introspecting the memory allocator, as well as\n      setting modifiable parameters and triggering actions.  The\n      period-separated <parameter>name</parameter> argument specifies a\n      location in a tree-structured namespace; see the <xref\n      linkend=\"mallctl_namespace\" xrefstyle=\"template:%t\"/> section for\n      documentation on the tree contents.  To read a value, pass a pointer via\n      <parameter>oldp</parameter> to adequate space to contain the value, and a\n      pointer to its length via <parameter>oldlenp</parameter>; otherwise pass\n      <constant>NULL</constant> and <constant>NULL</constant>.  Similarly, to\n      write a value, pass a pointer to the value via\n      <parameter>newp</parameter>, and its length via\n      <parameter>newlen</parameter>; otherwise pass <constant>NULL</constant>\n      and <constant>0</constant>.</para>\n\n      <para>The <function>mallctlnametomib<parameter/></function> function\n      provides a way to avoid repeated name lookups for applications that\n      repeatedly query the same portion of the namespace, by translating a name\n      to a &ldquo;Management Information Base&rdquo; (MIB) that can be passed\n      repeatedly to <function>mallctlbymib<parameter/></function>.  Upon\n      successful return from <function>mallctlnametomib<parameter/></function>,\n      <parameter>mibp</parameter> contains an array of\n      <parameter>*miblenp</parameter> integers, where\n      <parameter>*miblenp</parameter> is the lesser of the number of components\n      in <parameter>name</parameter> and the input value of\n      <parameter>*miblenp</parameter>.  Thus it is possible to pass a\n      <parameter>*miblenp</parameter> that is smaller than the number of\n      period-separated name components, which results in a partial MIB that can\n      be used as the basis for constructing a complete MIB.  For name\n      components that are integers (e.g. the 2 in\n      <link\n      linkend=\"arenas.bin.i.size\"><mallctl>arenas.bin.2.size</mallctl></link>),\n      the corresponding MIB component will always be that integer.  Therefore,\n      it is legitimate to construct code like the following: <programlisting\n      language=\"C\"><![CDATA[\nunsigned nbins, i;\nsize_t mib[4];\nsize_t len, miblen;\n\nlen = sizeof(nbins);\nmallctl(\"arenas.nbins\", &nbins, &len, NULL, 0);\n\nmiblen = 4;\nmallctlnametomib(\"arenas.bin.0.size\", mib, &miblen);\nfor (i = 0; i < nbins; i++) {\n\tsize_t bin_size;\n\n\tmib[2] = i;\n\tlen = sizeof(bin_size);\n\tmallctlbymib(mib, miblen, &bin_size, &len, NULL, 0);\n\t/* Do something with bin_size... */\n}]]></programlisting></para>\n\n      <para>The <function>malloc_stats_print<parameter/></function> function\n      writes human-readable summary statistics via the\n      <parameter>write_cb</parameter> callback function pointer and\n      <parameter>cbopaque</parameter> data passed to\n      <parameter>write_cb</parameter>, or\n      <function>malloc_message<parameter/></function> if\n      <parameter>write_cb</parameter> is <constant>NULL</constant>.  This\n      function can be called repeatedly.  General information that never\n      changes during execution can be omitted by specifying \"g\" as a character\n      within the <parameter>opts</parameter> string.  Note that\n      <function>malloc_message<parameter/></function> uses the\n      <function>mallctl*<parameter/></function> functions internally, so\n      inconsistent statistics can be reported if multiple threads use these\n      functions simultaneously.  If <option>--enable-stats</option> is\n      specified during configuration, &ldquo;m&rdquo; and &ldquo;a&rdquo; can\n      be specified to omit merged arena and per arena statistics, respectively;\n      &ldquo;b&rdquo;, &ldquo;l&rdquo;, and &ldquo;h&rdquo; can be specified to\n      omit per size class statistics for bins, large objects, and huge objects,\n      respectively.  Unrecognized characters are silently ignored.  Note that\n      thread caching may prevent some statistics from being completely up to\n      date, since extra locking would be required to merge counters that track\n      thread cache operations.\n      </para>\n\n      <para>The <function>malloc_usable_size<parameter/></function> function\n      returns the usable size of the allocation pointed to by\n      <parameter>ptr</parameter>.  The return value may be larger than the size\n      that was requested during allocation.  The\n      <function>malloc_usable_size<parameter/></function> function is not a\n      mechanism for in-place <function>realloc<parameter/></function>; rather\n      it is provided solely as a tool for introspection purposes.  Any\n      discrepancy between the requested allocation size and the size reported\n      by <function>malloc_usable_size<parameter/></function> should not be\n      depended on, since such behavior is entirely implementation-dependent.\n      </para>\n    </refsect2>\n  </refsect1>\n  <refsect1 id=\"tuning\">\n    <title>TUNING</title>\n    <para>Once, when the first call is made to one of the memory allocation\n    routines, the allocator initializes its internals based in part on various\n    options that can be specified at compile- or run-time.</para>\n\n    <para>The string specified via <option>--with-malloc-conf</option>, the\n    string pointed to by the global variable <varname>malloc_conf</varname>, the\n    &ldquo;name&rdquo; of the file referenced by the symbolic link named\n    <filename class=\"symlink\">/etc/malloc.conf</filename>, and the value of the\n    environment variable <envar>MALLOC_CONF</envar>, will be interpreted, in\n    that order, from left to right as options.  Note that\n    <varname>malloc_conf</varname> may be read before\n    <function>main<parameter/></function> is entered, so the declaration of\n    <varname>malloc_conf</varname> should specify an initializer that contains\n    the final value to be read by jemalloc.  <option>--with-malloc-conf</option>\n    and <varname>malloc_conf</varname> are compile-time mechanisms, whereas\n    <filename class=\"symlink\">/etc/malloc.conf</filename> and\n    <envar>MALLOC_CONF</envar> can be safely set any time prior to program\n    invocation.</para>\n\n    <para>An options string is a comma-separated list of option:value pairs.\n    There is one key corresponding to each <link\n    linkend=\"opt.abort\"><mallctl>opt.*</mallctl></link> mallctl (see the <xref\n    linkend=\"mallctl_namespace\" xrefstyle=\"template:%t\"/> section for options\n    documentation).  For example, <literal>abort:true,narenas:1</literal> sets\n    the <link linkend=\"opt.abort\"><mallctl>opt.abort</mallctl></link> and <link\n    linkend=\"opt.narenas\"><mallctl>opt.narenas</mallctl></link> options.  Some\n    options have boolean values (true/false), others have integer values (base\n    8, 10, or 16, depending on prefix), and yet others have raw string\n    values.</para>\n  </refsect1>\n  <refsect1 id=\"implementation_notes\">\n    <title>IMPLEMENTATION NOTES</title>\n    <para>Traditionally, allocators have used\n    <citerefentry><refentrytitle>sbrk</refentrytitle>\n    <manvolnum>2</manvolnum></citerefentry> to obtain memory, which is\n    suboptimal for several reasons, including race conditions, increased\n    fragmentation, and artificial limitations on maximum usable memory.  If\n    <citerefentry><refentrytitle>sbrk</refentrytitle>\n    <manvolnum>2</manvolnum></citerefentry> is supported by the operating\n    system, this allocator uses both\n    <citerefentry><refentrytitle>mmap</refentrytitle>\n    <manvolnum>2</manvolnum></citerefentry> and\n    <citerefentry><refentrytitle>sbrk</refentrytitle>\n    <manvolnum>2</manvolnum></citerefentry>, in that order of preference;\n    otherwise only <citerefentry><refentrytitle>mmap</refentrytitle>\n    <manvolnum>2</manvolnum></citerefentry> is used.</para>\n\n    <para>This allocator uses multiple arenas in order to reduce lock\n    contention for threaded programs on multi-processor systems.  This works\n    well with regard to threading scalability, but incurs some costs.  There is\n    a small fixed per-arena overhead, and additionally, arenas manage memory\n    completely independently of each other, which means a small fixed increase\n    in overall memory fragmentation.  These overheads are not generally an\n    issue, given the number of arenas normally used.  Note that using\n    substantially more arenas than the default is not likely to improve\n    performance, mainly due to reduced cache performance.  However, it may make\n    sense to reduce the number of arenas if an application does not make much\n    use of the allocation functions.</para>\n\n    <para>In addition to multiple arenas, unless\n    <option>--disable-tcache</option> is specified during configuration, this\n    allocator supports thread-specific caching for small and large objects, in\n    order to make it possible to completely avoid synchronization for most\n    allocation requests.  Such caching allows very fast allocation in the\n    common case, but it increases memory usage and fragmentation, since a\n    bounded number of objects can remain allocated in each thread cache.</para>\n\n    <para>Memory is conceptually broken into equal-sized chunks, where the chunk\n    size is a power of two that is greater than the page size.  Chunks are\n    always aligned to multiples of the chunk size.  This alignment makes it\n    possible to find metadata for user objects very quickly.  User objects are\n    broken into three categories according to size: small, large, and huge.\n    Multiple small and large objects can reside within a single chunk, whereas\n    huge objects each have one or more chunks backing them.  Each chunk that\n    contains small and/or large objects tracks its contents as runs of\n    contiguous pages (unused, backing a set of small objects, or backing one\n    large object).  The combination of chunk alignment and chunk page maps makes\n    it possible to determine all metadata regarding small and large allocations\n    in constant time.</para>\n\n    <para>Small objects are managed in groups by page runs.  Each run maintains\n    a bitmap to track which regions are in use.  Allocation requests that are no\n    more than half the quantum (8 or 16, depending on architecture) are rounded\n    up to the nearest power of two that is at least <code\n    language=\"C\">sizeof(<type>double</type>)</code>.  All other object size\n    classes are multiples of the quantum, spaced such that there are four size\n    classes for each doubling in size, which limits internal fragmentation to\n    approximately 20% for all but the smallest size classes.  Small size classes\n    are smaller than four times the page size, large size classes are smaller\n    than the chunk size (see the <link\n    linkend=\"opt.lg_chunk\"><mallctl>opt.lg_chunk</mallctl></link> option), and\n    huge size classes extend from the chunk size up to one size class less than\n    the full address space size.</para>\n\n    <para>Allocations are packed tightly together, which can be an issue for\n    multi-threaded applications.  If you need to assure that allocations do not\n    suffer from cacheline sharing, round your allocation requests up to the\n    nearest multiple of the cacheline size, or specify cacheline alignment when\n    allocating.</para>\n\n    <para>The <function>realloc<parameter/></function>,\n    <function>rallocx<parameter/></function>, and\n    <function>xallocx<parameter/></function> functions may resize allocations\n    without moving them under limited circumstances.  Unlike the\n    <function>*allocx<parameter/></function> API, the standard API does not\n    officially round up the usable size of an allocation to the nearest size\n    class, so technically it is necessary to call\n    <function>realloc<parameter/></function> to grow e.g. a 9-byte allocation to\n    16 bytes, or shrink a 16-byte allocation to 9 bytes.  Growth and shrinkage\n    trivially succeeds in place as long as the pre-size and post-size both round\n    up to the same size class.  No other API guarantees are made regarding\n    in-place resizing, but the current implementation also tries to resize large\n    and huge allocations in place, as long as the pre-size and post-size are\n    both large or both huge.  In such cases shrinkage always succeeds for large\n    size classes, but for huge size classes the chunk allocator must support\n    splitting (see <link\n    linkend=\"arena.i.chunk_hooks\"><mallctl>arena.&lt;i&gt;.chunk_hooks</mallctl></link>).\n    Growth only succeeds if the trailing memory is currently available, and\n    additionally for huge size classes the chunk allocator must support\n    merging.</para>\n\n    <para>Assuming 2 MiB chunks, 4 KiB pages, and a 16-byte quantum on a\n    64-bit system, the size classes in each category are as shown in <xref\n    linkend=\"size_classes\" xrefstyle=\"template:Table %n\"/>.</para>\n\n    <table xml:id=\"size_classes\" frame=\"all\">\n      <title>Size classes</title>\n      <tgroup cols=\"3\" colsep=\"1\" rowsep=\"1\">\n      <colspec colname=\"c1\" align=\"left\"/>\n      <colspec colname=\"c2\" align=\"right\"/>\n      <colspec colname=\"c3\" align=\"left\"/>\n      <thead>\n        <row>\n          <entry>Category</entry>\n          <entry>Spacing</entry>\n          <entry>Size</entry>\n        </row>\n      </thead>\n      <tbody>\n        <row>\n          <entry morerows=\"8\">Small</entry>\n          <entry>lg</entry>\n          <entry>[8]</entry>\n        </row>\n        <row>\n          <entry>16</entry>\n          <entry>[16, 32, 48, 64, 80, 96, 112, 128]</entry>\n        </row>\n        <row>\n          <entry>32</entry>\n          <entry>[160, 192, 224, 256]</entry>\n        </row>\n        <row>\n          <entry>64</entry>\n          <entry>[320, 384, 448, 512]</entry>\n        </row>\n        <row>\n          <entry>128</entry>\n          <entry>[640, 768, 896, 1024]</entry>\n        </row>\n        <row>\n          <entry>256</entry>\n          <entry>[1280, 1536, 1792, 2048]</entry>\n        </row>\n        <row>\n          <entry>512</entry>\n          <entry>[2560, 3072, 3584, 4096]</entry>\n        </row>\n        <row>\n          <entry>1 KiB</entry>\n          <entry>[5 KiB, 6 KiB, 7 KiB, 8 KiB]</entry>\n        </row>\n        <row>\n          <entry>2 KiB</entry>\n          <entry>[10 KiB, 12 KiB, 14 KiB]</entry>\n        </row>\n        <row>\n          <entry morerows=\"7\">Large</entry>\n          <entry>2 KiB</entry>\n          <entry>[16 KiB]</entry>\n        </row>\n        <row>\n          <entry>4 KiB</entry>\n          <entry>[20 KiB, 24 KiB, 28 KiB, 32 KiB]</entry>\n        </row>\n        <row>\n          <entry>8 KiB</entry>\n          <entry>[40 KiB, 48 KiB, 54 KiB, 64 KiB]</entry>\n        </row>\n        <row>\n          <entry>16 KiB</entry>\n          <entry>[80 KiB, 96 KiB, 112 KiB, 128 KiB]</entry>\n        </row>\n        <row>\n          <entry>32 KiB</entry>\n          <entry>[160 KiB, 192 KiB, 224 KiB, 256 KiB]</entry>\n        </row>\n        <row>\n          <entry>64 KiB</entry>\n          <entry>[320 KiB, 384 KiB, 448 KiB, 512 KiB]</entry>\n        </row>\n        <row>\n          <entry>128 KiB</entry>\n          <entry>[640 KiB, 768 KiB, 896 KiB, 1 MiB]</entry>\n        </row>\n        <row>\n          <entry>256 KiB</entry>\n          <entry>[1280 KiB, 1536 KiB, 1792 KiB]</entry>\n        </row>\n        <row>\n          <entry morerows=\"6\">Huge</entry>\n          <entry>256 KiB</entry>\n          <entry>[2 MiB]</entry>\n        </row>\n        <row>\n          <entry>512 KiB</entry>\n          <entry>[2560 KiB, 3 MiB, 3584 KiB, 4 MiB]</entry>\n        </row>\n        <row>\n          <entry>1 MiB</entry>\n          <entry>[5 MiB, 6 MiB, 7 MiB, 8 MiB]</entry>\n        </row>\n        <row>\n          <entry>2 MiB</entry>\n          <entry>[10 MiB, 12 MiB, 14 MiB, 16 MiB]</entry>\n        </row>\n        <row>\n          <entry>4 MiB</entry>\n          <entry>[20 MiB, 24 MiB, 28 MiB, 32 MiB]</entry>\n        </row>\n        <row>\n          <entry>8 MiB</entry>\n          <entry>[40 MiB, 48 MiB, 56 MiB, 64 MiB]</entry>\n        </row>\n        <row>\n          <entry>...</entry>\n          <entry>...</entry>\n        </row>\n      </tbody>\n      </tgroup>\n    </table>\n  </refsect1>\n  <refsect1 id=\"mallctl_namespace\">\n    <title>MALLCTL NAMESPACE</title>\n    <para>The following names are defined in the namespace accessible via the\n    <function>mallctl*<parameter/></function> functions.  Value types are\n    specified in parentheses, their readable/writable statuses are encoded as\n    <literal>rw</literal>, <literal>r-</literal>, <literal>-w</literal>, or\n    <literal>--</literal>, and required build configuration flags follow, if\n    any.  A name element encoded as <literal>&lt;i&gt;</literal> or\n    <literal>&lt;j&gt;</literal> indicates an integer component, where the\n    integer varies from 0 to some upper value that must be determined via\n    introspection.  In the case of <mallctl>stats.arenas.&lt;i&gt;.*</mallctl>,\n    <literal>&lt;i&gt;</literal> equal to <link\n    linkend=\"arenas.narenas\"><mallctl>arenas.narenas</mallctl></link> can be\n    used to access the summation of statistics from all arenas.  Take special\n    note of the <link linkend=\"epoch\"><mallctl>epoch</mallctl></link> mallctl,\n    which controls refreshing of cached dynamic statistics.</para>\n\n    <variablelist>\n      <varlistentry id=\"version\">\n        <term>\n          <mallctl>version</mallctl>\n          (<type>const char *</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Return the jemalloc version string.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"epoch\">\n        <term>\n          <mallctl>epoch</mallctl>\n          (<type>uint64_t</type>)\n          <literal>rw</literal>\n        </term>\n        <listitem><para>If a value is passed in, refresh the data from which\n        the <function>mallctl*<parameter/></function> functions report values,\n        and increment the epoch.  Return the current epoch.  This is useful for\n        detecting whether another thread caused a refresh.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"config.cache_oblivious\">\n        <term>\n          <mallctl>config.cache_oblivious</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para><option>--enable-cache-oblivious</option> was specified\n        during build configuration.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"config.debug\">\n        <term>\n          <mallctl>config.debug</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para><option>--enable-debug</option> was specified during\n        build configuration.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"config.fill\">\n        <term>\n          <mallctl>config.fill</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para><option>--enable-fill</option> was specified during\n        build configuration.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"config.lazy_lock\">\n        <term>\n          <mallctl>config.lazy_lock</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para><option>--enable-lazy-lock</option> was specified\n        during build configuration.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"config.malloc_conf\">\n        <term>\n          <mallctl>config.malloc_conf</mallctl>\n          (<type>const char *</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Embedded configure-time-specified run-time options\n        string, empty unless <option>--with-malloc-conf</option> was specified\n        during build configuration.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"config.munmap\">\n        <term>\n          <mallctl>config.munmap</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para><option>--enable-munmap</option> was specified during\n        build configuration.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"config.prof\">\n        <term>\n          <mallctl>config.prof</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para><option>--enable-prof</option> was specified during\n        build configuration.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"config.prof_libgcc\">\n        <term>\n          <mallctl>config.prof_libgcc</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para><option>--disable-prof-libgcc</option> was not\n        specified during build configuration.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"config.prof_libunwind\">\n        <term>\n          <mallctl>config.prof_libunwind</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para><option>--enable-prof-libunwind</option> was specified\n        during build configuration.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"config.stats\">\n        <term>\n          <mallctl>config.stats</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para><option>--enable-stats</option> was specified during\n        build configuration.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"config.tcache\">\n        <term>\n          <mallctl>config.tcache</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para><option>--disable-tcache</option> was not specified\n        during build configuration.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"config.tls\">\n        <term>\n          <mallctl>config.tls</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para><option>--disable-tls</option> was not specified during\n        build configuration.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"config.utrace\">\n        <term>\n          <mallctl>config.utrace</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para><option>--enable-utrace</option> was specified during\n        build configuration.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"config.valgrind\">\n        <term>\n          <mallctl>config.valgrind</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para><option>--enable-valgrind</option> was specified during\n        build configuration.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"config.xmalloc\">\n        <term>\n          <mallctl>config.xmalloc</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para><option>--enable-xmalloc</option> was specified during\n        build configuration.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.abort\">\n        <term>\n          <mallctl>opt.abort</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Abort-on-warning enabled/disabled.  If true, most\n        warnings are fatal.  The process will call\n        <citerefentry><refentrytitle>abort</refentrytitle>\n        <manvolnum>3</manvolnum></citerefentry> in these cases.  This option is\n        disabled by default unless <option>--enable-debug</option> is\n        specified during configuration, in which case it is enabled by default.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.dss\">\n        <term>\n          <mallctl>opt.dss</mallctl>\n          (<type>const char *</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>dss (<citerefentry><refentrytitle>sbrk</refentrytitle>\n        <manvolnum>2</manvolnum></citerefentry>) allocation precedence as\n        related to <citerefentry><refentrytitle>mmap</refentrytitle>\n        <manvolnum>2</manvolnum></citerefentry> allocation.  The following\n        settings are supported if\n        <citerefentry><refentrytitle>sbrk</refentrytitle>\n        <manvolnum>2</manvolnum></citerefentry> is supported by the operating\n        system: &ldquo;disabled&rdquo;, &ldquo;primary&rdquo;, and\n        &ldquo;secondary&rdquo;; otherwise only &ldquo;disabled&rdquo; is\n        supported.  The default is &ldquo;secondary&rdquo; if\n        <citerefentry><refentrytitle>sbrk</refentrytitle>\n        <manvolnum>2</manvolnum></citerefentry> is supported by the operating\n        system; &ldquo;disabled&rdquo; otherwise.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.lg_chunk\">\n        <term>\n          <mallctl>opt.lg_chunk</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Virtual memory chunk size (log base 2).  If a chunk\n        size outside the supported size range is specified, the size is\n        silently clipped to the minimum/maximum supported size.  The default\n        chunk size is 2 MiB (2^21).\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.narenas\">\n        <term>\n          <mallctl>opt.narenas</mallctl>\n          (<type>unsigned</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Maximum number of arenas to use for automatic\n        multiplexing of threads and arenas.  The default is four times the\n        number of CPUs, or one if there is a single CPU.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.purge\">\n        <term>\n          <mallctl>opt.purge</mallctl>\n          (<type>const char *</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Purge mode is &ldquo;ratio&rdquo; (default) or\n        &ldquo;decay&rdquo;.  See <link\n        linkend=\"opt.lg_dirty_mult\"><mallctl>opt.lg_dirty_mult</mallctl></link>\n        for details of the ratio mode.  See <link\n        linkend=\"opt.decay_time\"><mallctl>opt.decay_time</mallctl></link> for\n        details of the decay mode.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.lg_dirty_mult\">\n        <term>\n          <mallctl>opt.lg_dirty_mult</mallctl>\n          (<type>ssize_t</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Per-arena minimum ratio (log base 2) of active to dirty\n        pages.  Some dirty unused pages may be allowed to accumulate, within\n        the limit set by the ratio (or one chunk worth of dirty pages,\n        whichever is greater), before informing the kernel about some of those\n        pages via <citerefentry><refentrytitle>madvise</refentrytitle>\n        <manvolnum>2</manvolnum></citerefentry> or a similar system call.  This\n        provides the kernel with sufficient information to recycle dirty pages\n        if physical memory becomes scarce and the pages remain unused.  The\n        default minimum ratio is 8:1 (2^3:1); an option value of -1 will\n        disable dirty page purging.  See <link\n        linkend=\"arenas.lg_dirty_mult\"><mallctl>arenas.lg_dirty_mult</mallctl></link>\n        and <link\n        linkend=\"arena.i.lg_dirty_mult\"><mallctl>arena.&lt;i&gt;.lg_dirty_mult</mallctl></link>\n        for related dynamic control options.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.decay_time\">\n        <term>\n          <mallctl>opt.decay_time</mallctl>\n          (<type>ssize_t</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Approximate time in seconds from the creation of a set\n        of unused dirty pages until an equivalent set of unused dirty pages is\n        purged and/or reused.  The pages are incrementally purged according to a\n        sigmoidal decay curve that starts and ends with zero purge rate.  A\n        decay time of 0 causes all unused dirty pages to be purged immediately\n        upon creation.  A decay time of -1 disables purging.  The default decay\n        time is 10 seconds.  See <link\n        linkend=\"arenas.decay_time\"><mallctl>arenas.decay_time</mallctl></link>\n        and <link\n        linkend=\"arena.i.decay_time\"><mallctl>arena.&lt;i&gt;.decay_time</mallctl></link>\n        for related dynamic control options.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.stats_print\">\n        <term>\n          <mallctl>opt.stats_print</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Enable/disable statistics printing at exit.  If\n        enabled, the <function>malloc_stats_print<parameter/></function>\n        function is called at program exit via an\n        <citerefentry><refentrytitle>atexit</refentrytitle>\n        <manvolnum>3</manvolnum></citerefentry> function.  If\n        <option>--enable-stats</option> is specified during configuration, this\n        has the potential to cause deadlock for a multi-threaded process that\n        exits while one or more threads are executing in the memory allocation\n        functions.  Furthermore, <function>atexit<parameter/></function> may\n        allocate memory during application initialization and then deadlock\n        internally when jemalloc in turn calls\n        <function>atexit<parameter/></function>, so this option is not\n        univerally usable (though the application can register its own\n        <function>atexit<parameter/></function> function with equivalent\n        functionality).  Therefore, this option should only be used with care;\n        it is primarily intended as a performance tuning aid during application\n        development.  This option is disabled by default.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.junk\">\n        <term>\n          <mallctl>opt.junk</mallctl>\n          (<type>const char *</type>)\n          <literal>r-</literal>\n          [<option>--enable-fill</option>]\n        </term>\n        <listitem><para>Junk filling.  If set to \"alloc\", each byte of\n        uninitialized allocated memory will be initialized to\n        <literal>0xa5</literal>.  If set to \"free\", all deallocated memory will\n        be initialized to <literal>0x5a</literal>.  If set to \"true\", both\n        allocated and deallocated memory will be initialized, and if set to\n        \"false\", junk filling be disabled entirely.  This is intended for\n        debugging and will impact performance negatively.  This option is\n        \"false\" by default unless <option>--enable-debug</option> is specified\n        during configuration, in which case it is \"true\" by default unless\n        running inside <ulink\n        url=\"http://valgrind.org/\">Valgrind</ulink>.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.quarantine\">\n        <term>\n          <mallctl>opt.quarantine</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-fill</option>]\n        </term>\n        <listitem><para>Per thread quarantine size in bytes.  If non-zero, each\n        thread maintains a FIFO object quarantine that stores up to the\n        specified number of bytes of memory.  The quarantined memory is not\n        freed until it is released from quarantine, though it is immediately\n        junk-filled if the <link\n        linkend=\"opt.junk\"><mallctl>opt.junk</mallctl></link> option is\n        enabled.  This feature is of particular use in combination with <ulink\n        url=\"http://valgrind.org/\">Valgrind</ulink>, which can detect attempts\n        to access quarantined objects.  This is intended for debugging and will\n        impact performance negatively.  The default quarantine size is 0 unless\n        running inside Valgrind, in which case the default is 16\n        MiB.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.redzone\">\n        <term>\n          <mallctl>opt.redzone</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n          [<option>--enable-fill</option>]\n        </term>\n        <listitem><para>Redzones enabled/disabled.  If enabled, small\n        allocations have redzones before and after them.  Furthermore, if the\n        <link linkend=\"opt.junk\"><mallctl>opt.junk</mallctl></link> option is\n        enabled, the redzones are checked for corruption during deallocation.\n        However, the primary intended purpose of this feature is to be used in\n        combination with <ulink url=\"http://valgrind.org/\">Valgrind</ulink>,\n        which needs redzones in order to do effective buffer overflow/underflow\n        detection.  This option is intended for debugging and will impact\n        performance negatively.  This option is disabled by\n        default unless running inside Valgrind.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.zero\">\n        <term>\n          <mallctl>opt.zero</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n          [<option>--enable-fill</option>]\n        </term>\n        <listitem><para>Zero filling enabled/disabled.  If enabled, each byte\n        of uninitialized allocated memory will be initialized to 0.  Note that\n        this initialization only happens once for each byte, so\n        <function>realloc<parameter/></function> and\n        <function>rallocx<parameter/></function> calls do not zero memory that\n        was previously allocated.  This is intended for debugging and will\n        impact performance negatively.  This option is disabled by default.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.utrace\">\n        <term>\n          <mallctl>opt.utrace</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n          [<option>--enable-utrace</option>]\n        </term>\n        <listitem><para>Allocation tracing based on\n        <citerefentry><refentrytitle>utrace</refentrytitle>\n        <manvolnum>2</manvolnum></citerefentry> enabled/disabled.  This option\n        is disabled by default.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.xmalloc\">\n        <term>\n          <mallctl>opt.xmalloc</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n          [<option>--enable-xmalloc</option>]\n        </term>\n        <listitem><para>Abort-on-out-of-memory enabled/disabled.  If enabled,\n        rather than returning failure for any allocation function, display a\n        diagnostic message on <constant>STDERR_FILENO</constant> and cause the\n        program to drop core (using\n        <citerefentry><refentrytitle>abort</refentrytitle>\n        <manvolnum>3</manvolnum></citerefentry>).  If an application is\n        designed to depend on this behavior, set the option at compile time by\n        including the following in the source code:\n        <programlisting language=\"C\"><![CDATA[\nmalloc_conf = \"xmalloc:true\";]]></programlisting>\n        This option is disabled by default.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.tcache\">\n        <term>\n          <mallctl>opt.tcache</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n          [<option>--enable-tcache</option>]\n        </term>\n        <listitem><para>Thread-specific caching (tcache) enabled/disabled.  When\n        there are multiple threads, each thread uses a tcache for objects up to\n        a certain size.  Thread-specific caching allows many allocations to be\n        satisfied without performing any thread synchronization, at the cost of\n        increased memory use.  See the <link\n        linkend=\"opt.lg_tcache_max\"><mallctl>opt.lg_tcache_max</mallctl></link>\n        option for related tuning information.  This option is enabled by\n        default unless running inside <ulink\n        url=\"http://valgrind.org/\">Valgrind</ulink>, in which case it is\n        forcefully disabled.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.lg_tcache_max\">\n        <term>\n          <mallctl>opt.lg_tcache_max</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-tcache</option>]\n        </term>\n        <listitem><para>Maximum size class (log base 2) to cache in the\n        thread-specific cache (tcache).  At a minimum, all small size classes\n        are cached, and at a maximum all large size classes are cached.  The\n        default maximum is 32 KiB (2^15).</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.prof\">\n        <term>\n          <mallctl>opt.prof</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Memory profiling enabled/disabled.  If enabled, profile\n        memory allocation activity.  See the <link\n        linkend=\"opt.prof_active\"><mallctl>opt.prof_active</mallctl></link>\n        option for on-the-fly activation/deactivation.  See the <link\n        linkend=\"opt.lg_prof_sample\"><mallctl>opt.lg_prof_sample</mallctl></link>\n        option for probabilistic sampling control.  See the <link\n        linkend=\"opt.prof_accum\"><mallctl>opt.prof_accum</mallctl></link>\n        option for control of cumulative sample reporting.  See the <link\n        linkend=\"opt.lg_prof_interval\"><mallctl>opt.lg_prof_interval</mallctl></link>\n        option for information on interval-triggered profile dumping, the <link\n        linkend=\"opt.prof_gdump\"><mallctl>opt.prof_gdump</mallctl></link>\n        option for information on high-water-triggered profile dumping, and the\n        <link linkend=\"opt.prof_final\"><mallctl>opt.prof_final</mallctl></link>\n        option for final profile dumping.  Profile output is compatible with\n        the <command>jeprof</command> command, which is based on the\n        <command>pprof</command> that is developed as part of the <ulink\n        url=\"http://code.google.com/p/gperftools/\">gperftools\n        package</ulink>.  See <link linkend=\"heap_profile_format\">HEAP PROFILE\n        FORMAT</link> for heap profile format documentation.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.prof_prefix\">\n        <term>\n          <mallctl>opt.prof_prefix</mallctl>\n          (<type>const char *</type>)\n          <literal>r-</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Filename prefix for profile dumps.  If the prefix is\n        set to the empty string, no automatic dumps will occur; this is\n        primarily useful for disabling the automatic final heap dump (which\n        also disables leak reporting, if enabled).  The default prefix is\n        <filename>jeprof</filename>.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.prof_active\">\n        <term>\n          <mallctl>opt.prof_active</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Profiling activated/deactivated.  This is a secondary\n        control mechanism that makes it possible to start the application with\n        profiling enabled (see the <link\n        linkend=\"opt.prof\"><mallctl>opt.prof</mallctl></link> option) but\n        inactive, then toggle profiling at any time during program execution\n        with the <link\n        linkend=\"prof.active\"><mallctl>prof.active</mallctl></link> mallctl.\n        This option is enabled by default.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.prof_thread_active_init\">\n        <term>\n          <mallctl>opt.prof_thread_active_init</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Initial setting for <link\n        linkend=\"thread.prof.active\"><mallctl>thread.prof.active</mallctl></link>\n        in newly created threads.  The initial setting for newly created threads\n        can also be changed during execution via the <link\n        linkend=\"prof.thread_active_init\"><mallctl>prof.thread_active_init</mallctl></link>\n        mallctl.  This option is enabled by default.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.lg_prof_sample\">\n        <term>\n          <mallctl>opt.lg_prof_sample</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Average interval (log base 2) between allocation\n        samples, as measured in bytes of allocation activity.  Increasing the\n        sampling interval decreases profile fidelity, but also decreases the\n        computational overhead.  The default sample interval is 512 KiB (2^19\n        B).</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.prof_accum\">\n        <term>\n          <mallctl>opt.prof_accum</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Reporting of cumulative object/byte counts in profile\n        dumps enabled/disabled.  If this option is enabled, every unique\n        backtrace must be stored for the duration of execution.  Depending on\n        the application, this can impose a large memory overhead, and the\n        cumulative counts are not always of interest.  This option is disabled\n        by default.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.lg_prof_interval\">\n        <term>\n          <mallctl>opt.lg_prof_interval</mallctl>\n          (<type>ssize_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Average interval (log base 2) between memory profile\n        dumps, as measured in bytes of allocation activity.  The actual\n        interval between dumps may be sporadic because decentralized allocation\n        counters are used to avoid synchronization bottlenecks.  Profiles are\n        dumped to files named according to the pattern\n        <filename>&lt;prefix&gt;.&lt;pid&gt;.&lt;seq&gt;.i&lt;iseq&gt;.heap</filename>,\n        where <literal>&lt;prefix&gt;</literal> is controlled by the\n        <link\n        linkend=\"opt.prof_prefix\"><mallctl>opt.prof_prefix</mallctl></link>\n        option.  By default, interval-triggered profile dumping is disabled\n        (encoded as -1).\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.prof_gdump\">\n        <term>\n          <mallctl>opt.prof_gdump</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Set the initial state of <link\n        linkend=\"prof.gdump\"><mallctl>prof.gdump</mallctl></link>, which when\n        enabled triggers a memory profile dump every time the total virtual\n        memory exceeds the previous maximum.  This option is disabled by\n        default.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.prof_final\">\n        <term>\n          <mallctl>opt.prof_final</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Use an\n        <citerefentry><refentrytitle>atexit</refentrytitle>\n        <manvolnum>3</manvolnum></citerefentry> function to dump final memory\n        usage to a file named according to the pattern\n        <filename>&lt;prefix&gt;.&lt;pid&gt;.&lt;seq&gt;.f.heap</filename>,\n        where <literal>&lt;prefix&gt;</literal> is controlled by the <link\n        linkend=\"opt.prof_prefix\"><mallctl>opt.prof_prefix</mallctl></link>\n        option.  Note that <function>atexit<parameter/></function> may allocate\n        memory during application initialization and then deadlock internally\n        when jemalloc in turn calls <function>atexit<parameter/></function>, so\n        this option is not univerally usable (though the application can\n        register its own <function>atexit<parameter/></function> function with\n        equivalent functionality).  This option is disabled by\n        default.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"opt.prof_leak\">\n        <term>\n          <mallctl>opt.prof_leak</mallctl>\n          (<type>bool</type>)\n          <literal>r-</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Leak reporting enabled/disabled.  If enabled, use an\n        <citerefentry><refentrytitle>atexit</refentrytitle>\n        <manvolnum>3</manvolnum></citerefentry> function to report memory leaks\n        detected by allocation sampling.  See the\n        <link linkend=\"opt.prof\"><mallctl>opt.prof</mallctl></link> option for\n        information on analyzing heap profile output.  This option is disabled\n        by default.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"thread.arena\">\n        <term>\n          <mallctl>thread.arena</mallctl>\n          (<type>unsigned</type>)\n          <literal>rw</literal>\n        </term>\n        <listitem><para>Get or set the arena associated with the calling\n        thread.  If the specified arena was not initialized beforehand (see the\n        <link\n        linkend=\"arenas.initialized\"><mallctl>arenas.initialized</mallctl></link>\n        mallctl), it will be automatically initialized as a side effect of\n        calling this interface.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"thread.allocated\">\n        <term>\n          <mallctl>thread.allocated</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Get the total number of bytes ever allocated by the\n        calling thread.  This counter has the potential to wrap around; it is\n        up to the application to appropriately interpret the counter in such\n        cases.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"thread.allocatedp\">\n        <term>\n          <mallctl>thread.allocatedp</mallctl>\n          (<type>uint64_t *</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Get a pointer to the the value that is returned by the\n        <link\n        linkend=\"thread.allocated\"><mallctl>thread.allocated</mallctl></link>\n        mallctl.  This is useful for avoiding the overhead of repeated\n        <function>mallctl*<parameter/></function> calls.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"thread.deallocated\">\n        <term>\n          <mallctl>thread.deallocated</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Get the total number of bytes ever deallocated by the\n        calling thread.  This counter has the potential to wrap around; it is\n        up to the application to appropriately interpret the counter in such\n        cases.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"thread.deallocatedp\">\n        <term>\n          <mallctl>thread.deallocatedp</mallctl>\n          (<type>uint64_t *</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Get a pointer to the the value that is returned by the\n        <link\n        linkend=\"thread.deallocated\"><mallctl>thread.deallocated</mallctl></link>\n        mallctl.  This is useful for avoiding the overhead of repeated\n        <function>mallctl*<parameter/></function> calls.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"thread.tcache.enabled\">\n        <term>\n          <mallctl>thread.tcache.enabled</mallctl>\n          (<type>bool</type>)\n          <literal>rw</literal>\n          [<option>--enable-tcache</option>]\n        </term>\n        <listitem><para>Enable/disable calling thread's tcache.  The tcache is\n        implicitly flushed as a side effect of becoming\n        disabled (see <link\n        linkend=\"thread.tcache.flush\"><mallctl>thread.tcache.flush</mallctl></link>).\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"thread.tcache.flush\">\n        <term>\n          <mallctl>thread.tcache.flush</mallctl>\n          (<type>void</type>)\n          <literal>--</literal>\n          [<option>--enable-tcache</option>]\n        </term>\n        <listitem><para>Flush calling thread's thread-specific cache (tcache).\n        This interface releases all cached objects and internal data structures\n        associated with the calling thread's tcache.  Ordinarily, this interface\n        need not be called, since automatic periodic incremental garbage\n        collection occurs, and the thread cache is automatically discarded when\n        a thread exits.  However, garbage collection is triggered by allocation\n        activity, so it is possible for a thread that stops\n        allocating/deallocating to retain its cache indefinitely, in which case\n        the developer may find manual flushing useful.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"thread.prof.name\">\n        <term>\n          <mallctl>thread.prof.name</mallctl>\n          (<type>const char *</type>)\n          <literal>r-</literal> or\n          <literal>-w</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Get/set the descriptive name associated with the calling\n        thread in memory profile dumps.  An internal copy of the name string is\n        created, so the input string need not be maintained after this interface\n        completes execution.  The output string of this interface should be\n        copied for non-ephemeral uses, because multiple implementation details\n        can cause asynchronous string deallocation.  Furthermore, each\n        invocation of this interface can only read or write; simultaneous\n        read/write is not supported due to string lifetime limitations.  The\n        name string must be nil-terminated and comprised only of characters in\n        the sets recognized\n        by <citerefentry><refentrytitle>isgraph</refentrytitle>\n        <manvolnum>3</manvolnum></citerefentry> and\n        <citerefentry><refentrytitle>isblank</refentrytitle>\n        <manvolnum>3</manvolnum></citerefentry>.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"thread.prof.active\">\n        <term>\n          <mallctl>thread.prof.active</mallctl>\n          (<type>bool</type>)\n          <literal>rw</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Control whether sampling is currently active for the\n        calling thread.  This is an activation mechanism in addition to <link\n        linkend=\"prof.active\"><mallctl>prof.active</mallctl></link>; both must\n        be active for the calling thread to sample.  This flag is enabled by\n        default.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"tcache.create\">\n        <term>\n          <mallctl>tcache.create</mallctl>\n          (<type>unsigned</type>)\n          <literal>r-</literal>\n          [<option>--enable-tcache</option>]\n        </term>\n        <listitem><para>Create an explicit thread-specific cache (tcache) and\n        return an identifier that can be passed to the <link\n        linkend=\"MALLOCX_TCACHE\"><constant>MALLOCX_TCACHE(<parameter>tc</parameter>)</constant></link>\n        macro to explicitly use the specified cache rather than the\n        automatically managed one that is used by default.  Each explicit cache\n        can be used by only one thread at a time; the application must assure\n        that this constraint holds.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"tcache.flush\">\n        <term>\n          <mallctl>tcache.flush</mallctl>\n          (<type>unsigned</type>)\n          <literal>-w</literal>\n          [<option>--enable-tcache</option>]\n        </term>\n        <listitem><para>Flush the specified thread-specific cache (tcache).  The\n        same considerations apply to this interface as to <link\n        linkend=\"thread.tcache.flush\"><mallctl>thread.tcache.flush</mallctl></link>,\n        except that the tcache will never be automatically discarded.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"tcache.destroy\">\n        <term>\n          <mallctl>tcache.destroy</mallctl>\n          (<type>unsigned</type>)\n          <literal>-w</literal>\n          [<option>--enable-tcache</option>]\n        </term>\n        <listitem><para>Flush the specified thread-specific cache (tcache) and\n        make the identifier available for use during a future tcache creation.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arena.i.purge\">\n        <term>\n          <mallctl>arena.&lt;i&gt;.purge</mallctl>\n          (<type>void</type>)\n          <literal>--</literal>\n        </term>\n        <listitem><para>Purge all unused dirty pages for arena &lt;i&gt;, or for\n        all arenas if &lt;i&gt; equals <link\n        linkend=\"arenas.narenas\"><mallctl>arenas.narenas</mallctl></link>.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arena.i.decay\">\n        <term>\n          <mallctl>arena.&lt;i&gt;.decay</mallctl>\n          (<type>void</type>)\n          <literal>--</literal>\n        </term>\n        <listitem><para>Trigger decay-based purging of unused dirty pages for\n        arena &lt;i&gt;, or for all arenas if &lt;i&gt; equals <link\n        linkend=\"arenas.narenas\"><mallctl>arenas.narenas</mallctl></link>.\n        The proportion of unused dirty pages to be purged depends on the current\n        time; see <link\n        linkend=\"opt.decay_time\"><mallctl>opt.decay_time</mallctl></link> for\n        details.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arena.i.dss\">\n        <term>\n          <mallctl>arena.&lt;i&gt;.dss</mallctl>\n          (<type>const char *</type>)\n          <literal>rw</literal>\n        </term>\n        <listitem><para>Set the precedence of dss allocation as related to mmap\n        allocation for arena &lt;i&gt;, or for all arenas if &lt;i&gt; equals\n        <link\n        linkend=\"arenas.narenas\"><mallctl>arenas.narenas</mallctl></link>.  See\n        <link linkend=\"opt.dss\"><mallctl>opt.dss</mallctl></link> for supported\n        settings.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arena.i.lg_dirty_mult\">\n        <term>\n          <mallctl>arena.&lt;i&gt;.lg_dirty_mult</mallctl>\n          (<type>ssize_t</type>)\n          <literal>rw</literal>\n        </term>\n        <listitem><para>Current per-arena minimum ratio (log base 2) of active\n        to dirty pages for arena &lt;i&gt;.  Each time this interface is set and\n        the ratio is increased, pages are synchronously purged as necessary to\n        impose the new ratio.  See <link\n        linkend=\"opt.lg_dirty_mult\"><mallctl>opt.lg_dirty_mult</mallctl></link>\n        for additional information.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arena.i.decay_time\">\n        <term>\n          <mallctl>arena.&lt;i&gt;.decay_time</mallctl>\n          (<type>ssize_t</type>)\n          <literal>rw</literal>\n        </term>\n        <listitem><para>Current per-arena approximate time in seconds from the\n        creation of a set of unused dirty pages until an equivalent set of\n        unused dirty pages is purged and/or reused.  Each time this interface is\n        set, all currently unused dirty pages are considered to have fully\n        decayed, which causes immediate purging of all unused dirty pages unless\n        the decay time is set to -1 (i.e. purging disabled).  See <link\n        linkend=\"opt.decay_time\"><mallctl>opt.decay_time</mallctl></link> for\n        additional information.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arena.i.chunk_hooks\">\n        <term>\n          <mallctl>arena.&lt;i&gt;.chunk_hooks</mallctl>\n          (<type>chunk_hooks_t</type>)\n          <literal>rw</literal>\n        </term>\n        <listitem><para>Get or set the chunk management hook functions for arena\n        &lt;i&gt;.  The functions must be capable of operating on all extant\n        chunks associated with arena &lt;i&gt;, usually by passing unknown\n        chunks to the replaced functions.  In practice, it is feasible to\n        control allocation for arenas created via <link\n        linkend=\"arenas.extend\"><mallctl>arenas.extend</mallctl></link> such\n        that all chunks originate from an application-supplied chunk allocator\n        (by setting custom chunk hook functions just after arena creation), but\n        the automatically created arenas may have already created chunks prior\n        to the application having an opportunity to take over chunk\n        allocation.</para>\n\n        <programlisting language=\"C\"><![CDATA[\ntypedef struct {\n\tchunk_alloc_t\t\t*alloc;\n\tchunk_dalloc_t\t\t*dalloc;\n\tchunk_commit_t\t\t*commit;\n\tchunk_decommit_t\t*decommit;\n\tchunk_purge_t\t\t*purge;\n\tchunk_split_t\t\t*split;\n\tchunk_merge_t\t\t*merge;\n} chunk_hooks_t;]]></programlisting>\n        <para>The <type>chunk_hooks_t</type> structure comprises function\n        pointers which are described individually below.  jemalloc uses these\n        functions to manage chunk lifetime, which starts off with allocation of\n        mapped committed memory, in the simplest case followed by deallocation.\n        However, there are performance and platform reasons to retain chunks for\n        later reuse.  Cleanup attempts cascade from deallocation to decommit to\n        purging, which gives the chunk management functions opportunities to\n        reject the most permanent cleanup operations in favor of less permanent\n        (and often less costly) operations.  The chunk splitting and merging\n        operations can also be opted out of, but this is mainly intended to\n        support platforms on which virtual memory mappings provided by the\n        operating system kernel do not automatically coalesce and split, e.g.\n        Windows.</para>\n\n        <funcsynopsis><funcprototype>\n          <funcdef>typedef void *<function>(chunk_alloc_t)</function></funcdef>\n          <paramdef>void *<parameter>chunk</parameter></paramdef>\n          <paramdef>size_t <parameter>size</parameter></paramdef>\n          <paramdef>size_t <parameter>alignment</parameter></paramdef>\n          <paramdef>bool *<parameter>zero</parameter></paramdef>\n          <paramdef>bool *<parameter>commit</parameter></paramdef>\n          <paramdef>unsigned <parameter>arena_ind</parameter></paramdef>\n        </funcprototype></funcsynopsis>\n        <literallayout></literallayout>\n        <para>A chunk allocation function conforms to the\n        <type>chunk_alloc_t</type> type and upon success returns a pointer to\n        <parameter>size</parameter> bytes of mapped memory on behalf of arena\n        <parameter>arena_ind</parameter> such that the chunk's base address is a\n        multiple of <parameter>alignment</parameter>, as well as setting\n        <parameter>*zero</parameter> to indicate whether the chunk is zeroed and\n        <parameter>*commit</parameter> to indicate whether the chunk is\n        committed.  Upon error the function returns <constant>NULL</constant>\n        and leaves <parameter>*zero</parameter> and\n        <parameter>*commit</parameter> unmodified.  The\n        <parameter>size</parameter> parameter is always a multiple of the chunk\n        size.  The <parameter>alignment</parameter> parameter is always a power\n        of two at least as large as the chunk size.  Zeroing is mandatory if\n        <parameter>*zero</parameter> is true upon function entry.  Committing is\n        mandatory if <parameter>*commit</parameter> is true upon function entry.\n        If <parameter>chunk</parameter> is not <constant>NULL</constant>, the\n        returned pointer must be <parameter>chunk</parameter> on success or\n        <constant>NULL</constant> on error.  Committed memory may be committed\n        in absolute terms as on a system that does not overcommit, or in\n        implicit terms as on a system that overcommits and satisfies physical\n        memory needs on demand via soft page faults.  Note that replacing the\n        default chunk allocation function makes the arena's <link\n        linkend=\"arena.i.dss\"><mallctl>arena.&lt;i&gt;.dss</mallctl></link>\n        setting irrelevant.</para>\n\n        <funcsynopsis><funcprototype>\n          <funcdef>typedef bool <function>(chunk_dalloc_t)</function></funcdef>\n          <paramdef>void *<parameter>chunk</parameter></paramdef>\n          <paramdef>size_t <parameter>size</parameter></paramdef>\n          <paramdef>bool <parameter>committed</parameter></paramdef>\n          <paramdef>unsigned <parameter>arena_ind</parameter></paramdef>\n        </funcprototype></funcsynopsis>\n        <literallayout></literallayout>\n        <para>\n        A chunk deallocation function conforms to the\n        <type>chunk_dalloc_t</type> type and deallocates a\n        <parameter>chunk</parameter> of given <parameter>size</parameter> with\n        <parameter>committed</parameter>/decommited memory as indicated, on\n        behalf of arena <parameter>arena_ind</parameter>, returning false upon\n        success.  If the function returns true, this indicates opt-out from\n        deallocation; the virtual memory mapping associated with the chunk\n        remains mapped, in the same commit state, and available for future use,\n        in which case it will be automatically retained for later reuse.</para>\n\n        <funcsynopsis><funcprototype>\n          <funcdef>typedef bool <function>(chunk_commit_t)</function></funcdef>\n          <paramdef>void *<parameter>chunk</parameter></paramdef>\n          <paramdef>size_t <parameter>size</parameter></paramdef>\n          <paramdef>size_t <parameter>offset</parameter></paramdef>\n          <paramdef>size_t <parameter>length</parameter></paramdef>\n          <paramdef>unsigned <parameter>arena_ind</parameter></paramdef>\n        </funcprototype></funcsynopsis>\n        <literallayout></literallayout>\n        <para>A chunk commit function conforms to the\n        <type>chunk_commit_t</type> type and commits zeroed physical memory to\n        back pages within a <parameter>chunk</parameter> of given\n        <parameter>size</parameter> at <parameter>offset</parameter> bytes,\n        extending for <parameter>length</parameter> on behalf of arena\n        <parameter>arena_ind</parameter>, returning false upon success.\n        Committed memory may be committed in absolute terms as on a system that\n        does not overcommit, or in implicit terms as on a system that\n        overcommits and satisfies physical memory needs on demand via soft page\n        faults. If the function returns true, this indicates insufficient\n        physical memory to satisfy the request.</para>\n\n        <funcsynopsis><funcprototype>\n          <funcdef>typedef bool <function>(chunk_decommit_t)</function></funcdef>\n          <paramdef>void *<parameter>chunk</parameter></paramdef>\n          <paramdef>size_t <parameter>size</parameter></paramdef>\n          <paramdef>size_t <parameter>offset</parameter></paramdef>\n          <paramdef>size_t <parameter>length</parameter></paramdef>\n          <paramdef>unsigned <parameter>arena_ind</parameter></paramdef>\n        </funcprototype></funcsynopsis>\n        <literallayout></literallayout>\n        <para>A chunk decommit function conforms to the\n        <type>chunk_decommit_t</type> type and decommits any physical memory\n        that is backing pages within a <parameter>chunk</parameter> of given\n        <parameter>size</parameter> at <parameter>offset</parameter> bytes,\n        extending for <parameter>length</parameter> on behalf of arena\n        <parameter>arena_ind</parameter>, returning false upon success, in which\n        case the pages will be committed via the chunk commit function before\n        being reused.  If the function returns true, this indicates opt-out from\n        decommit; the memory remains committed and available for future use, in\n        which case it will be automatically retained for later reuse.</para>\n\n        <funcsynopsis><funcprototype>\n          <funcdef>typedef bool <function>(chunk_purge_t)</function></funcdef>\n          <paramdef>void *<parameter>chunk</parameter></paramdef>\n          <paramdef>size_t<parameter>size</parameter></paramdef>\n          <paramdef>size_t <parameter>offset</parameter></paramdef>\n          <paramdef>size_t <parameter>length</parameter></paramdef>\n          <paramdef>unsigned <parameter>arena_ind</parameter></paramdef>\n        </funcprototype></funcsynopsis>\n        <literallayout></literallayout>\n        <para>A chunk purge function conforms to the <type>chunk_purge_t</type>\n        type and optionally discards physical pages within the virtual memory\n        mapping associated with <parameter>chunk</parameter> of given\n        <parameter>size</parameter> at <parameter>offset</parameter> bytes,\n        extending for <parameter>length</parameter> on behalf of arena\n        <parameter>arena_ind</parameter>, returning false if pages within the\n        purged virtual memory range will be zero-filled the next time they are\n        accessed.</para>\n\n        <funcsynopsis><funcprototype>\n          <funcdef>typedef bool <function>(chunk_split_t)</function></funcdef>\n          <paramdef>void *<parameter>chunk</parameter></paramdef>\n          <paramdef>size_t <parameter>size</parameter></paramdef>\n          <paramdef>size_t <parameter>size_a</parameter></paramdef>\n          <paramdef>size_t <parameter>size_b</parameter></paramdef>\n          <paramdef>bool <parameter>committed</parameter></paramdef>\n          <paramdef>unsigned <parameter>arena_ind</parameter></paramdef>\n        </funcprototype></funcsynopsis>\n        <literallayout></literallayout>\n        <para>A chunk split function conforms to the <type>chunk_split_t</type>\n        type and optionally splits <parameter>chunk</parameter> of given\n        <parameter>size</parameter> into two adjacent chunks, the first of\n        <parameter>size_a</parameter> bytes, and the second of\n        <parameter>size_b</parameter> bytes, operating on\n        <parameter>committed</parameter>/decommitted memory as indicated, on\n        behalf of arena <parameter>arena_ind</parameter>, returning false upon\n        success.  If the function returns true, this indicates that the chunk\n        remains unsplit and therefore should continue to be operated on as a\n        whole.</para>\n\n        <funcsynopsis><funcprototype>\n          <funcdef>typedef bool <function>(chunk_merge_t)</function></funcdef>\n          <paramdef>void *<parameter>chunk_a</parameter></paramdef>\n          <paramdef>size_t <parameter>size_a</parameter></paramdef>\n          <paramdef>void *<parameter>chunk_b</parameter></paramdef>\n          <paramdef>size_t <parameter>size_b</parameter></paramdef>\n          <paramdef>bool <parameter>committed</parameter></paramdef>\n          <paramdef>unsigned <parameter>arena_ind</parameter></paramdef>\n        </funcprototype></funcsynopsis>\n        <literallayout></literallayout>\n        <para>A chunk merge function conforms to the <type>chunk_merge_t</type>\n        type and optionally merges adjacent chunks,\n        <parameter>chunk_a</parameter> of given <parameter>size_a</parameter>\n        and <parameter>chunk_b</parameter> of given\n        <parameter>size_b</parameter> into one contiguous chunk, operating on\n        <parameter>committed</parameter>/decommitted memory as indicated, on\n        behalf of arena <parameter>arena_ind</parameter>, returning false upon\n        success.  If the function returns true, this indicates that the chunks\n        remain distinct mappings and therefore should continue to be operated on\n        independently.</para>\n        </listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.narenas\">\n        <term>\n          <mallctl>arenas.narenas</mallctl>\n          (<type>unsigned</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Current limit on number of arenas.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.initialized\">\n        <term>\n          <mallctl>arenas.initialized</mallctl>\n          (<type>bool *</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>An array of <link\n        linkend=\"arenas.narenas\"><mallctl>arenas.narenas</mallctl></link>\n        booleans.  Each boolean indicates whether the corresponding arena is\n        initialized.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.lg_dirty_mult\">\n        <term>\n          <mallctl>arenas.lg_dirty_mult</mallctl>\n          (<type>ssize_t</type>)\n          <literal>rw</literal>\n        </term>\n        <listitem><para>Current default per-arena minimum ratio (log base 2) of\n        active to dirty pages, used to initialize <link\n        linkend=\"arena.i.lg_dirty_mult\"><mallctl>arena.&lt;i&gt;.lg_dirty_mult</mallctl></link>\n        during arena creation.  See <link\n        linkend=\"opt.lg_dirty_mult\"><mallctl>opt.lg_dirty_mult</mallctl></link>\n        for additional information.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.decay_time\">\n        <term>\n          <mallctl>arenas.decay_time</mallctl>\n          (<type>ssize_t</type>)\n          <literal>rw</literal>\n        </term>\n        <listitem><para>Current default per-arena approximate time in seconds\n        from the creation of a set of unused dirty pages until an equivalent set\n        of unused dirty pages is purged and/or reused, used to initialize <link\n        linkend=\"arena.i.decay_time\"><mallctl>arena.&lt;i&gt;.decay_time</mallctl></link>\n        during arena creation.  See <link\n        linkend=\"opt.decay_time\"><mallctl>opt.decay_time</mallctl></link> for\n        additional information.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.quantum\">\n        <term>\n          <mallctl>arenas.quantum</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Quantum size.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.page\">\n        <term>\n          <mallctl>arenas.page</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Page size.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.tcache_max\">\n        <term>\n          <mallctl>arenas.tcache_max</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-tcache</option>]\n        </term>\n        <listitem><para>Maximum thread-cached size class.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.nbins\">\n        <term>\n          <mallctl>arenas.nbins</mallctl>\n          (<type>unsigned</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Number of bin size classes.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.nhbins\">\n        <term>\n          <mallctl>arenas.nhbins</mallctl>\n          (<type>unsigned</type>)\n          <literal>r-</literal>\n          [<option>--enable-tcache</option>]\n        </term>\n        <listitem><para>Total number of thread cache bin size\n        classes.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.bin.i.size\">\n        <term>\n          <mallctl>arenas.bin.&lt;i&gt;.size</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Maximum size supported by size class.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.bin.i.nregs\">\n        <term>\n          <mallctl>arenas.bin.&lt;i&gt;.nregs</mallctl>\n          (<type>uint32_t</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Number of regions per page run.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.bin.i.run_size\">\n        <term>\n          <mallctl>arenas.bin.&lt;i&gt;.run_size</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Number of bytes per page run.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.nlruns\">\n        <term>\n          <mallctl>arenas.nlruns</mallctl>\n          (<type>unsigned</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Total number of large size classes.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.lrun.i.size\">\n        <term>\n          <mallctl>arenas.lrun.&lt;i&gt;.size</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Maximum size supported by this large size\n        class.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.nhchunks\">\n        <term>\n          <mallctl>arenas.nhchunks</mallctl>\n          (<type>unsigned</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Total number of huge size classes.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.hchunk.i.size\">\n        <term>\n          <mallctl>arenas.hchunk.&lt;i&gt;.size</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Maximum size supported by this huge size\n        class.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"arenas.extend\">\n        <term>\n          <mallctl>arenas.extend</mallctl>\n          (<type>unsigned</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Extend the array of arenas by appending a new arena,\n        and returning the new arena index.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"prof.thread_active_init\">\n        <term>\n          <mallctl>prof.thread_active_init</mallctl>\n          (<type>bool</type>)\n          <literal>rw</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Control the initial setting for <link\n        linkend=\"thread.prof.active\"><mallctl>thread.prof.active</mallctl></link>\n        in newly created threads.  See the <link\n        linkend=\"opt.prof_thread_active_init\"><mallctl>opt.prof_thread_active_init</mallctl></link>\n        option for additional information.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"prof.active\">\n        <term>\n          <mallctl>prof.active</mallctl>\n          (<type>bool</type>)\n          <literal>rw</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Control whether sampling is currently active.  See the\n        <link\n        linkend=\"opt.prof_active\"><mallctl>opt.prof_active</mallctl></link>\n        option for additional information, as well as the interrelated <link\n        linkend=\"thread.prof.active\"><mallctl>thread.prof.active</mallctl></link>\n        mallctl.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"prof.dump\">\n        <term>\n          <mallctl>prof.dump</mallctl>\n          (<type>const char *</type>)\n          <literal>-w</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Dump a memory profile to the specified file, or if NULL\n        is specified, to a file according to the pattern\n        <filename>&lt;prefix&gt;.&lt;pid&gt;.&lt;seq&gt;.m&lt;mseq&gt;.heap</filename>,\n        where <literal>&lt;prefix&gt;</literal> is controlled by the\n        <link\n        linkend=\"opt.prof_prefix\"><mallctl>opt.prof_prefix</mallctl></link>\n        option.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"prof.gdump\">\n        <term>\n          <mallctl>prof.gdump</mallctl>\n          (<type>bool</type>)\n          <literal>rw</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>When enabled, trigger a memory profile dump every time\n        the total virtual memory exceeds the previous maximum.  Profiles are\n        dumped to files named according to the pattern\n        <filename>&lt;prefix&gt;.&lt;pid&gt;.&lt;seq&gt;.u&lt;useq&gt;.heap</filename>,\n        where <literal>&lt;prefix&gt;</literal> is controlled by the <link\n        linkend=\"opt.prof_prefix\"><mallctl>opt.prof_prefix</mallctl></link>\n        option.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"prof.reset\">\n        <term>\n          <mallctl>prof.reset</mallctl>\n          (<type>size_t</type>)\n          <literal>-w</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Reset all memory profile statistics, and optionally\n        update the sample rate (see <link\n        linkend=\"opt.lg_prof_sample\"><mallctl>opt.lg_prof_sample</mallctl></link>\n        and <link\n        linkend=\"prof.lg_sample\"><mallctl>prof.lg_sample</mallctl></link>).\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"prof.lg_sample\">\n        <term>\n          <mallctl>prof.lg_sample</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Get the current sample rate (see <link\n        linkend=\"opt.lg_prof_sample\"><mallctl>opt.lg_prof_sample</mallctl></link>).\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"prof.interval\">\n        <term>\n          <mallctl>prof.interval</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-prof</option>]\n        </term>\n        <listitem><para>Average number of bytes allocated between\n        inverval-based profile dumps.  See the\n        <link\n        linkend=\"opt.lg_prof_interval\"><mallctl>opt.lg_prof_interval</mallctl></link>\n        option for additional information.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.cactive\">\n        <term>\n          <mallctl>stats.cactive</mallctl>\n          (<type>size_t *</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Pointer to a counter that contains an approximate count\n        of the current number of bytes in active pages.  The estimate may be\n        high, but never low, because each arena rounds up when computing its\n        contribution to the counter.  Note that the <link\n        linkend=\"epoch\"><mallctl>epoch</mallctl></link> mallctl has no bearing\n        on this counter.  Furthermore, counter consistency is maintained via\n        atomic operations, so it is necessary to use an atomic operation in\n        order to guarantee a consistent read when dereferencing the pointer.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.allocated\">\n        <term>\n          <mallctl>stats.allocated</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Total number of bytes allocated by the\n        application.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.active\">\n        <term>\n          <mallctl>stats.active</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Total number of bytes in active pages allocated by the\n        application.  This is a multiple of the page size, and greater than or\n        equal to <link\n        linkend=\"stats.allocated\"><mallctl>stats.allocated</mallctl></link>.\n        This does not include <link linkend=\"stats.arenas.i.pdirty\">\n        <mallctl>stats.arenas.&lt;i&gt;.pdirty</mallctl></link>, nor pages\n        entirely devoted to allocator metadata.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.metadata\">\n        <term>\n          <mallctl>stats.metadata</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Total number of bytes dedicated to metadata, which\n        comprise base allocations used for bootstrap-sensitive internal\n        allocator data structures, arena chunk headers (see <link\n        linkend=\"stats.arenas.i.metadata.mapped\"><mallctl>stats.arenas.&lt;i&gt;.metadata.mapped</mallctl></link>),\n        and internal allocations (see <link\n        linkend=\"stats.arenas.i.metadata.allocated\"><mallctl>stats.arenas.&lt;i&gt;.metadata.allocated</mallctl></link>).</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.resident\">\n        <term>\n          <mallctl>stats.resident</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Maximum number of bytes in physically resident data\n        pages mapped by the allocator, comprising all pages dedicated to\n        allocator metadata, pages backing active allocations, and unused dirty\n        pages.  This is a maximum rather than precise because pages may not\n        actually be physically resident if they correspond to demand-zeroed\n        virtual memory that has not yet been touched.  This is a multiple of the\n        page size, and is larger than <link\n        linkend=\"stats.active\"><mallctl>stats.active</mallctl></link>.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.mapped\">\n        <term>\n          <mallctl>stats.mapped</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Total number of bytes in active chunks mapped by the\n        allocator.  This is a multiple of the chunk size, and is larger than\n        <link linkend=\"stats.active\"><mallctl>stats.active</mallctl></link>.\n        This does not include inactive chunks, even those that contain unused\n        dirty pages, which means that there is no strict ordering between this\n        and <link\n        linkend=\"stats.resident\"><mallctl>stats.resident</mallctl></link>.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.dss\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.dss</mallctl>\n          (<type>const char *</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>dss (<citerefentry><refentrytitle>sbrk</refentrytitle>\n        <manvolnum>2</manvolnum></citerefentry>) allocation precedence as\n        related to <citerefentry><refentrytitle>mmap</refentrytitle>\n        <manvolnum>2</manvolnum></citerefentry> allocation.  See <link\n        linkend=\"opt.dss\"><mallctl>opt.dss</mallctl></link> for details.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.lg_dirty_mult\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.lg_dirty_mult</mallctl>\n          (<type>ssize_t</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Minimum ratio (log base 2) of active to dirty pages.\n        See <link\n        linkend=\"opt.lg_dirty_mult\"><mallctl>opt.lg_dirty_mult</mallctl></link>\n        for details.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.decay_time\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.decay_time</mallctl>\n          (<type>ssize_t</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Approximate time in seconds from the creation of a set\n        of unused dirty pages until an equivalent set of unused dirty pages is\n        purged and/or reused.  See <link\n        linkend=\"opt.decay_time\"><mallctl>opt.decay_time</mallctl></link>\n        for details.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.nthreads\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.nthreads</mallctl>\n          (<type>unsigned</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Number of threads currently assigned to\n        arena.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.pactive\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.pactive</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Number of pages in active runs.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.pdirty\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.pdirty</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n        </term>\n        <listitem><para>Number of pages within unused runs that are potentially\n        dirty, and for which <function>madvise<parameter>...</parameter>\n        <parameter><constant>MADV_DONTNEED</constant></parameter></function> or\n        similar has not been called.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.mapped\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.mapped</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Number of mapped bytes.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.metadata.mapped\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.metadata.mapped</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Number of mapped bytes in arena chunk headers, which\n        track the states of the non-metadata pages.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.metadata.allocated\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.metadata.allocated</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Number of bytes dedicated to internal allocations.\n        Internal allocations differ from application-originated allocations in\n        that they are for internal use, and that they are omitted from heap\n        profiles.  This statistic is reported separately from <link\n        linkend=\"stats.metadata\"><mallctl>stats.metadata</mallctl></link> and\n        <link\n        linkend=\"stats.arenas.i.metadata.mapped\"><mallctl>stats.arenas.&lt;i&gt;.metadata.mapped</mallctl></link>\n        because it overlaps with e.g. the <link\n        linkend=\"stats.allocated\"><mallctl>stats.allocated</mallctl></link> and\n        <link linkend=\"stats.active\"><mallctl>stats.active</mallctl></link>\n        statistics, whereas the other metadata statistics do\n        not.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.npurge\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.npurge</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Number of dirty page purge sweeps performed.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.nmadvise\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.nmadvise</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Number of <function>madvise<parameter>...</parameter>\n        <parameter><constant>MADV_DONTNEED</constant></parameter></function> or\n        similar calls made to purge dirty pages.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.purged\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.purged</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Number of pages purged.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.small.allocated\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.small.allocated</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Number of bytes currently allocated by small objects.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.small.nmalloc\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.small.nmalloc</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of allocation requests served by\n        small bins.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.small.ndalloc\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.small.ndalloc</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of small objects returned to bins.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.small.nrequests\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.small.nrequests</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of small allocation requests.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.large.allocated\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.large.allocated</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Number of bytes currently allocated by large objects.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.large.nmalloc\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.large.nmalloc</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of large allocation requests served\n        directly by the arena.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.large.ndalloc\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.large.ndalloc</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of large deallocation requests served\n        directly by the arena.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.large.nrequests\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.large.nrequests</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of large allocation requests.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.huge.allocated\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.huge.allocated</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Number of bytes currently allocated by huge objects.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.huge.nmalloc\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.huge.nmalloc</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of huge allocation requests served\n        directly by the arena.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.huge.ndalloc\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.huge.ndalloc</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of huge deallocation requests served\n        directly by the arena.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.huge.nrequests\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.huge.nrequests</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of huge allocation requests.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.bins.j.nmalloc\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.bins.&lt;j&gt;.nmalloc</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of allocations served by bin.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.bins.j.ndalloc\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.bins.&lt;j&gt;.ndalloc</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of allocations returned to bin.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.bins.j.nrequests\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.bins.&lt;j&gt;.nrequests</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of allocation\n        requests.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.bins.j.curregs\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.bins.&lt;j&gt;.curregs</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Current number of regions for this size\n        class.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.bins.j.nfills\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.bins.&lt;j&gt;.nfills</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option> <option>--enable-tcache</option>]\n        </term>\n        <listitem><para>Cumulative number of tcache fills.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.bins.j.nflushes\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.bins.&lt;j&gt;.nflushes</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option> <option>--enable-tcache</option>]\n        </term>\n        <listitem><para>Cumulative number of tcache flushes.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.bins.j.nruns\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.bins.&lt;j&gt;.nruns</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of runs created.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.bins.j.nreruns\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.bins.&lt;j&gt;.nreruns</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of times the current run from which\n        to allocate changed.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.bins.j.curruns\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.bins.&lt;j&gt;.curruns</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Current number of runs.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.lruns.j.nmalloc\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.lruns.&lt;j&gt;.nmalloc</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of allocation requests for this size\n        class served directly by the arena.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.lruns.j.ndalloc\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.lruns.&lt;j&gt;.ndalloc</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of deallocation requests for this\n        size class served directly by the arena.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.lruns.j.nrequests\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.lruns.&lt;j&gt;.nrequests</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of allocation requests for this size\n        class.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.lruns.j.curruns\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.lruns.&lt;j&gt;.curruns</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Current number of runs for this size class.\n        </para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.hchunks.j.nmalloc\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.hchunks.&lt;j&gt;.nmalloc</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of allocation requests for this size\n        class served directly by the arena.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.hchunks.j.ndalloc\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.hchunks.&lt;j&gt;.ndalloc</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of deallocation requests for this\n        size class served directly by the arena.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.hchunks.j.nrequests\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.hchunks.&lt;j&gt;.nrequests</mallctl>\n          (<type>uint64_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Cumulative number of allocation requests for this size\n        class.</para></listitem>\n      </varlistentry>\n\n      <varlistentry id=\"stats.arenas.i.hchunks.j.curhchunks\">\n        <term>\n          <mallctl>stats.arenas.&lt;i&gt;.hchunks.&lt;j&gt;.curhchunks</mallctl>\n          (<type>size_t</type>)\n          <literal>r-</literal>\n          [<option>--enable-stats</option>]\n        </term>\n        <listitem><para>Current number of huge allocations for this size class.\n        </para></listitem>\n      </varlistentry>\n    </variablelist>\n  </refsect1>\n  <refsect1 id=\"heap_profile_format\">\n    <title>HEAP PROFILE FORMAT</title>\n    <para>Although the heap profiling functionality was originally designed to\n    be compatible with the\n    <command>pprof</command> command that is developed as part of the <ulink\n    url=\"http://code.google.com/p/gperftools/\">gperftools\n    package</ulink>, the addition of per thread heap profiling functionality\n    required a different heap profile format.  The <command>jeprof</command>\n    command is derived from <command>pprof</command>, with enhancements to\n    support the heap profile format described here.</para>\n\n    <para>In the following hypothetical heap profile, <constant>[...]</constant>\n    indicates elision for the sake of compactness.  <programlisting><![CDATA[\nheap_v2/524288\n  t*: 28106: 56637512 [0: 0]\n  [...]\n  t3: 352: 16777344 [0: 0]\n  [...]\n  t99: 17754: 29341640 [0: 0]\n  [...]\n@ 0x5f86da8 0x5f5a1dc [...] 0x29e4d4e 0xa200316 0xabb2988 [...]\n  t*: 13: 6688 [0: 0]\n  t3: 12: 6496 [0: ]\n  t99: 1: 192 [0: 0]\n[...]\n\nMAPPED_LIBRARIES:\n[...]]]></programlisting> The following matches the above heap profile, but most\ntokens are replaced with <constant>&lt;description&gt;</constant> to indicate\ndescriptions of the corresponding fields.  <programlisting><![CDATA[\n<heap_profile_format_version>/<mean_sample_interval>\n  <aggregate>: <curobjs>: <curbytes> [<cumobjs>: <cumbytes>]\n  [...]\n  <thread_3_aggregate>: <curobjs>: <curbytes>[<cumobjs>: <cumbytes>]\n  [...]\n  <thread_99_aggregate>: <curobjs>: <curbytes>[<cumobjs>: <cumbytes>]\n  [...]\n@ <top_frame> <frame> [...] <frame> <frame> <frame> [...]\n  <backtrace_aggregate>: <curobjs>: <curbytes> [<cumobjs>: <cumbytes>]\n  <backtrace_thread_3>: <curobjs>: <curbytes> [<cumobjs>: <cumbytes>]\n  <backtrace_thread_99>: <curobjs>: <curbytes> [<cumobjs>: <cumbytes>]\n[...]\n\nMAPPED_LIBRARIES:\n</proc/<pid>/maps>]]></programlisting></para>\n  </refsect1>\n\n  <refsect1 id=\"debugging_malloc_problems\">\n    <title>DEBUGGING MALLOC PROBLEMS</title>\n    <para>When debugging, it is a good idea to configure/build jemalloc with\n    the <option>--enable-debug</option> and <option>--enable-fill</option>\n    options, and recompile the program with suitable options and symbols for\n    debugger support.  When so configured, jemalloc incorporates a wide variety\n    of run-time assertions that catch application errors such as double-free,\n    write-after-free, etc.</para>\n\n    <para>Programs often accidentally depend on &ldquo;uninitialized&rdquo;\n    memory actually being filled with zero bytes.  Junk filling\n    (see the <link linkend=\"opt.junk\"><mallctl>opt.junk</mallctl></link>\n    option) tends to expose such bugs in the form of obviously incorrect\n    results and/or coredumps.  Conversely, zero\n    filling (see the <link\n    linkend=\"opt.zero\"><mallctl>opt.zero</mallctl></link> option) eliminates\n    the symptoms of such bugs.  Between these two options, it is usually\n    possible to quickly detect, diagnose, and eliminate such bugs.</para>\n\n    <para>This implementation does not provide much detail about the problems\n    it detects, because the performance impact for storing such information\n    would be prohibitive.  However, jemalloc does integrate with the most\n    excellent <ulink url=\"http://valgrind.org/\">Valgrind</ulink> tool if the\n    <option>--enable-valgrind</option> configuration option is enabled.</para>\n  </refsect1>\n  <refsect1 id=\"diagnostic_messages\">\n    <title>DIAGNOSTIC MESSAGES</title>\n    <para>If any of the memory allocation/deallocation functions detect an\n    error or warning condition, a message will be printed to file descriptor\n    <constant>STDERR_FILENO</constant>.  Errors will result in the process\n    dumping core.  If the <link\n    linkend=\"opt.abort\"><mallctl>opt.abort</mallctl></link> option is set, most\n    warnings are treated as errors.</para>\n\n    <para>The <varname>malloc_message</varname> variable allows the programmer\n    to override the function which emits the text strings forming the errors\n    and warnings if for some reason the <constant>STDERR_FILENO</constant> file\n    descriptor is not suitable for this.\n    <function>malloc_message<parameter/></function> takes the\n    <parameter>cbopaque</parameter> pointer argument that is\n    <constant>NULL</constant> unless overridden by the arguments in a call to\n    <function>malloc_stats_print<parameter/></function>, followed by a string\n    pointer.  Please note that doing anything which tries to allocate memory in\n    this function is likely to result in a crash or deadlock.</para>\n\n    <para>All messages are prefixed by\n    &ldquo;<computeroutput>&lt;jemalloc&gt;: </computeroutput>&rdquo;.</para>\n  </refsect1>\n  <refsect1 id=\"return_values\">\n    <title>RETURN VALUES</title>\n    <refsect2>\n      <title>Standard API</title>\n      <para>The <function>malloc<parameter/></function> and\n      <function>calloc<parameter/></function> functions return a pointer to the\n      allocated memory if successful; otherwise a <constant>NULL</constant>\n      pointer is returned and <varname>errno</varname> is set to\n      <errorname>ENOMEM</errorname>.</para>\n\n      <para>The <function>posix_memalign<parameter/></function> function\n      returns the value 0 if successful; otherwise it returns an error value.\n      The <function>posix_memalign<parameter/></function> function will fail\n      if:\n        <variablelist>\n          <varlistentry>\n            <term><errorname>EINVAL</errorname></term>\n\n            <listitem><para>The <parameter>alignment</parameter> parameter is\n            not a power of 2 at least as large as\n            <code language=\"C\">sizeof(<type>void *</type>)</code>.\n            </para></listitem>\n          </varlistentry>\n          <varlistentry>\n            <term><errorname>ENOMEM</errorname></term>\n\n            <listitem><para>Memory allocation error.</para></listitem>\n          </varlistentry>\n        </variablelist>\n      </para>\n\n      <para>The <function>aligned_alloc<parameter/></function> function returns\n      a pointer to the allocated memory if successful; otherwise a\n      <constant>NULL</constant> pointer is returned and\n      <varname>errno</varname> is set.  The\n      <function>aligned_alloc<parameter/></function> function will fail if:\n        <variablelist>\n          <varlistentry>\n            <term><errorname>EINVAL</errorname></term>\n\n            <listitem><para>The <parameter>alignment</parameter> parameter is\n            not a power of 2.\n            </para></listitem>\n          </varlistentry>\n          <varlistentry>\n            <term><errorname>ENOMEM</errorname></term>\n\n            <listitem><para>Memory allocation error.</para></listitem>\n          </varlistentry>\n        </variablelist>\n      </para>\n\n      <para>The <function>realloc<parameter/></function> function returns a\n      pointer, possibly identical to <parameter>ptr</parameter>, to the\n      allocated memory if successful; otherwise a <constant>NULL</constant>\n      pointer is returned, and <varname>errno</varname> is set to\n      <errorname>ENOMEM</errorname> if the error was the result of an\n      allocation failure.  The <function>realloc<parameter/></function>\n      function always leaves the original buffer intact when an error occurs.\n      </para>\n\n      <para>The <function>free<parameter/></function> function returns no\n      value.</para>\n    </refsect2>\n    <refsect2>\n      <title>Non-standard API</title>\n      <para>The <function>mallocx<parameter/></function> and\n      <function>rallocx<parameter/></function> functions return a pointer to\n      the allocated memory if successful; otherwise a <constant>NULL</constant>\n      pointer is returned to indicate insufficient contiguous memory was\n      available to service the allocation request.  </para>\n\n      <para>The <function>xallocx<parameter/></function> function returns the\n      real size of the resulting resized allocation pointed to by\n      <parameter>ptr</parameter>, which is a value less than\n      <parameter>size</parameter> if the allocation could not be adequately\n      grown in place.  </para>\n\n      <para>The <function>sallocx<parameter/></function> function returns the\n      real size of the allocation pointed to by <parameter>ptr</parameter>.\n      </para>\n\n      <para>The <function>nallocx<parameter/></function> returns the real size\n      that would result from a successful equivalent\n      <function>mallocx<parameter/></function> function call, or zero if\n      insufficient memory is available to perform the size computation.  </para>\n\n      <para>The <function>mallctl<parameter/></function>,\n      <function>mallctlnametomib<parameter/></function>, and\n      <function>mallctlbymib<parameter/></function> functions return 0 on\n      success; otherwise they return an error value.  The functions will fail\n      if:\n        <variablelist>\n          <varlistentry>\n            <term><errorname>EINVAL</errorname></term>\n\n            <listitem><para><parameter>newp</parameter> is not\n            <constant>NULL</constant>, and <parameter>newlen</parameter> is too\n            large or too small.  Alternatively, <parameter>*oldlenp</parameter>\n            is too large or too small; in this case as much data as possible\n            are read despite the error.</para></listitem>\n          </varlistentry>\n          <varlistentry>\n            <term><errorname>ENOENT</errorname></term>\n\n            <listitem><para><parameter>name</parameter> or\n            <parameter>mib</parameter> specifies an unknown/invalid\n            value.</para></listitem>\n          </varlistentry>\n          <varlistentry>\n            <term><errorname>EPERM</errorname></term>\n\n            <listitem><para>Attempt to read or write void value, or attempt to\n            write read-only value.</para></listitem>\n          </varlistentry>\n          <varlistentry>\n            <term><errorname>EAGAIN</errorname></term>\n\n            <listitem><para>A memory allocation failure\n            occurred.</para></listitem>\n          </varlistentry>\n          <varlistentry>\n            <term><errorname>EFAULT</errorname></term>\n\n            <listitem><para>An interface with side effects failed in some way\n            not directly related to <function>mallctl*<parameter/></function>\n            read/write processing.</para></listitem>\n          </varlistentry>\n        </variablelist>\n      </para>\n\n      <para>The <function>malloc_usable_size<parameter/></function> function\n      returns the usable size of the allocation pointed to by\n      <parameter>ptr</parameter>.  </para>\n    </refsect2>\n  </refsect1>\n  <refsect1 id=\"environment\">\n    <title>ENVIRONMENT</title>\n    <para>The following environment variable affects the execution of the\n    allocation functions:\n      <variablelist>\n        <varlistentry>\n          <term><envar>MALLOC_CONF</envar></term>\n\n          <listitem><para>If the environment variable\n          <envar>MALLOC_CONF</envar> is set, the characters it contains\n          will be interpreted as options.</para></listitem>\n        </varlistentry>\n      </variablelist>\n    </para>\n  </refsect1>\n  <refsect1 id=\"examples\">\n    <title>EXAMPLES</title>\n    <para>To dump core whenever a problem occurs:\n      <screen>ln -s 'abort:true' /etc/malloc.conf</screen>\n    </para>\n    <para>To specify in the source a chunk size that is 16 MiB:\n      <programlisting language=\"C\"><![CDATA[\nmalloc_conf = \"lg_chunk:24\";]]></programlisting></para>\n  </refsect1>\n  <refsect1 id=\"see_also\">\n    <title>SEE ALSO</title>\n    <para><citerefentry><refentrytitle>madvise</refentrytitle>\n    <manvolnum>2</manvolnum></citerefentry>,\n    <citerefentry><refentrytitle>mmap</refentrytitle>\n    <manvolnum>2</manvolnum></citerefentry>,\n    <citerefentry><refentrytitle>sbrk</refentrytitle>\n    <manvolnum>2</manvolnum></citerefentry>,\n    <citerefentry><refentrytitle>utrace</refentrytitle>\n    <manvolnum>2</manvolnum></citerefentry>,\n    <citerefentry><refentrytitle>alloca</refentrytitle>\n    <manvolnum>3</manvolnum></citerefentry>,\n    <citerefentry><refentrytitle>atexit</refentrytitle>\n    <manvolnum>3</manvolnum></citerefentry>,\n    <citerefentry><refentrytitle>getpagesize</refentrytitle>\n    <manvolnum>3</manvolnum></citerefentry></para>\n  </refsect1>\n  <refsect1 id=\"standards\">\n    <title>STANDARDS</title>\n    <para>The <function>malloc<parameter/></function>,\n    <function>calloc<parameter/></function>,\n    <function>realloc<parameter/></function>, and\n    <function>free<parameter/></function> functions conform to ISO/IEC\n    9899:1990 (&ldquo;ISO C90&rdquo;).</para>\n\n    <para>The <function>posix_memalign<parameter/></function> function conforms\n    to IEEE Std 1003.1-2001 (&ldquo;POSIX.1&rdquo;).</para>\n  </refsect1>\n</refentry>\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/doc/manpages.xsl.in",
    "content": "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n  <xsl:import href=\"@XSLROOT@/manpages/docbook.xsl\"/>\n  <xsl:import href=\"@abs_srcroot@doc/stylesheet.xsl\"/>\n</xsl:stylesheet>\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/doc/stylesheet.xsl",
    "content": "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n  <xsl:param name=\"funcsynopsis.style\">ansi</xsl:param>\n  <xsl:param name=\"function.parens\" select=\"1\"/>\n  <xsl:template match=\"mallctl\">\n    \"<xsl:call-template name=\"inline.monoseq\"/>\"\n  </xsl:template>\n</xsl:stylesheet>\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/arena.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n#define\tLARGE_MINCLASS\t\t(ZU(1) << LG_LARGE_MINCLASS)\n\n/* Maximum number of regions in one run. */\n#define\tLG_RUN_MAXREGS\t\t(LG_PAGE - LG_TINY_MIN)\n#define\tRUN_MAXREGS\t\t(1U << LG_RUN_MAXREGS)\n\n/*\n * Minimum redzone size.  Redzones may be larger than this if necessary to\n * preserve region alignment.\n */\n#define\tREDZONE_MINSIZE\t\t16\n\n/*\n * The minimum ratio of active:dirty pages per arena is computed as:\n *\n *   (nactive >> lg_dirty_mult) >= ndirty\n *\n * So, supposing that lg_dirty_mult is 3, there can be no less than 8 times as\n * many active pages as dirty pages.\n */\n#define\tLG_DIRTY_MULT_DEFAULT\t3\n\ntypedef enum {\n\tpurge_mode_ratio = 0,\n\tpurge_mode_decay = 1,\n\n\tpurge_mode_limit = 2\n} purge_mode_t;\n#define\tPURGE_DEFAULT\t\tpurge_mode_ratio\n/* Default decay time in seconds. */\n#define\tDECAY_TIME_DEFAULT\t10\n/* Number of event ticks between time checks. */\n#define\tDECAY_NTICKS_PER_UPDATE\t1000\n\ntypedef struct arena_runs_dirty_link_s arena_runs_dirty_link_t;\ntypedef struct arena_run_s arena_run_t;\ntypedef struct arena_chunk_map_bits_s arena_chunk_map_bits_t;\ntypedef struct arena_chunk_map_misc_s arena_chunk_map_misc_t;\ntypedef struct arena_chunk_s arena_chunk_t;\ntypedef struct arena_bin_info_s arena_bin_info_t;\ntypedef struct arena_bin_s arena_bin_t;\ntypedef struct arena_s arena_t;\ntypedef struct arena_tdata_s arena_tdata_t;\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n#ifdef JEMALLOC_ARENA_STRUCTS_A\nstruct arena_run_s {\n\t/* Index of bin this run is associated with. */\n\tszind_t\t\tbinind;\n\n\t/* Number of free regions in run. */\n\tunsigned\tnfree;\n\n\t/* Per region allocated/deallocated bitmap. */\n\tbitmap_t\tbitmap[BITMAP_GROUPS_MAX];\n};\n\n/* Each element of the chunk map corresponds to one page within the chunk. */\nstruct arena_chunk_map_bits_s {\n\t/*\n\t * Run address (or size) and various flags are stored together.  The bit\n\t * layout looks like (assuming 32-bit system):\n\t *\n\t *   ???????? ???????? ???nnnnn nnndumla\n\t *\n\t * ? : Unallocated: Run address for first/last pages, unset for internal\n\t *                  pages.\n\t *     Small: Run page offset.\n\t *     Large: Run page count for first page, unset for trailing pages.\n\t * n : binind for small size class, BININD_INVALID for large size class.\n\t * d : dirty?\n\t * u : unzeroed?\n\t * m : decommitted?\n\t * l : large?\n\t * a : allocated?\n\t *\n\t * Following are example bit patterns for the three types of runs.\n\t *\n\t * p : run page offset\n\t * s : run size\n\t * n : binind for size class; large objects set these to BININD_INVALID\n\t * x : don't care\n\t * - : 0\n\t * + : 1\n\t * [DUMLA] : bit set\n\t * [dumla] : bit unset\n\t *\n\t *   Unallocated (clean):\n\t *     ssssssss ssssssss sss+++++ +++dum-a\n\t *     xxxxxxxx xxxxxxxx xxxxxxxx xxx-Uxxx\n\t *     ssssssss ssssssss sss+++++ +++dUm-a\n\t *\n\t *   Unallocated (dirty):\n\t *     ssssssss ssssssss sss+++++ +++D-m-a\n\t *     xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n\t *     ssssssss ssssssss sss+++++ +++D-m-a\n\t *\n\t *   Small:\n\t *     pppppppp pppppppp pppnnnnn nnnd---A\n\t *     pppppppp pppppppp pppnnnnn nnn----A\n\t *     pppppppp pppppppp pppnnnnn nnnd---A\n\t *\n\t *   Large:\n\t *     ssssssss ssssssss sss+++++ +++D--LA\n\t *     xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n\t *     -------- -------- ---+++++ +++D--LA\n\t *\n\t *   Large (sampled, size <= LARGE_MINCLASS):\n\t *     ssssssss ssssssss sssnnnnn nnnD--LA\n\t *     xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n\t *     -------- -------- ---+++++ +++D--LA\n\t *\n\t *   Large (not sampled, size == LARGE_MINCLASS):\n\t *     ssssssss ssssssss sss+++++ +++D--LA\n\t *     xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n\t *     -------- -------- ---+++++ +++D--LA\n\t */\n\tsize_t\t\t\t\tbits;\n#define\tCHUNK_MAP_ALLOCATED\t((size_t)0x01U)\n#define\tCHUNK_MAP_LARGE\t\t((size_t)0x02U)\n#define\tCHUNK_MAP_STATE_MASK\t((size_t)0x3U)\n\n#define\tCHUNK_MAP_DECOMMITTED\t((size_t)0x04U)\n#define\tCHUNK_MAP_UNZEROED\t((size_t)0x08U)\n#define\tCHUNK_MAP_DIRTY\t\t((size_t)0x10U)\n#define\tCHUNK_MAP_FLAGS_MASK\t((size_t)0x1cU)\n\n#define\tCHUNK_MAP_BININD_SHIFT\t5\n#define\tBININD_INVALID\t\t((size_t)0xffU)\n#define\tCHUNK_MAP_BININD_MASK\t(BININD_INVALID << CHUNK_MAP_BININD_SHIFT)\n#define\tCHUNK_MAP_BININD_INVALID CHUNK_MAP_BININD_MASK\n\n#define\tCHUNK_MAP_RUNIND_SHIFT\t(CHUNK_MAP_BININD_SHIFT + 8)\n#define\tCHUNK_MAP_SIZE_SHIFT\t(CHUNK_MAP_RUNIND_SHIFT - LG_PAGE)\n#define\tCHUNK_MAP_SIZE_MASK\t\t\t\t\t\t\\\n    (~(CHUNK_MAP_BININD_MASK | CHUNK_MAP_FLAGS_MASK | CHUNK_MAP_STATE_MASK))\n};\n\nstruct arena_runs_dirty_link_s {\n\tqr(arena_runs_dirty_link_t)\trd_link;\n};\n\n/*\n * Each arena_chunk_map_misc_t corresponds to one page within the chunk, just\n * like arena_chunk_map_bits_t.  Two separate arrays are stored within each\n * chunk header in order to improve cache locality.\n */\nstruct arena_chunk_map_misc_s {\n\t/*\n\t * Linkage for run trees.  There are two disjoint uses:\n\t *\n\t * 1) arena_t's runs_avail tree.\n\t * 2) arena_run_t conceptually uses this linkage for in-use non-full\n\t *    runs, rather than directly embedding linkage.\n\t */\n\trb_node(arena_chunk_map_misc_t)\t\trb_link;\n\n\tunion {\n\t\t/* Linkage for list of dirty runs. */\n\t\tarena_runs_dirty_link_t\t\trd;\n\n\t\t/* Profile counters, used for large object runs. */\n\t\tunion {\n\t\t\tvoid\t\t\t*prof_tctx_pun;\n\t\t\tprof_tctx_t\t\t*prof_tctx;\n\t\t};\n\n\t\t/* Small region run metadata. */\n\t\tarena_run_t\t\t\trun;\n\t};\n};\ntypedef rb_tree(arena_chunk_map_misc_t) arena_run_tree_t;\n#endif /* JEMALLOC_ARENA_STRUCTS_A */\n\n#ifdef JEMALLOC_ARENA_STRUCTS_B\n/* Arena chunk header. */\nstruct arena_chunk_s {\n\t/*\n\t * A pointer to the arena that owns the chunk is stored within the node.\n\t * This field as a whole is used by chunks_rtree to support both\n\t * ivsalloc() and core-based debugging.\n\t */\n\textent_node_t\t\tnode;\n\n\t/*\n\t * Map of pages within chunk that keeps track of free/large/small.  The\n\t * first map_bias entries are omitted, since the chunk header does not\n\t * need to be tracked in the map.  This omission saves a header page\n\t * for common chunk sizes (e.g. 4 MiB).\n\t */\n\tarena_chunk_map_bits_t\tmap_bits[1]; /* Dynamically sized. */\n};\n\n/*\n * Read-only information associated with each element of arena_t's bins array\n * is stored separately, partly to reduce memory usage (only one copy, rather\n * than one per arena), but mainly to avoid false cacheline sharing.\n *\n * Each run has the following layout:\n *\n *               /--------------------\\\n *               | pad?               |\n *               |--------------------|\n *               | redzone            |\n *   reg0_offset | region 0           |\n *               | redzone            |\n *               |--------------------| \\\n *               | redzone            | |\n *               | region 1           |  > reg_interval\n *               | redzone            | /\n *               |--------------------|\n *               | ...                |\n *               | ...                |\n *               | ...                |\n *               |--------------------|\n *               | redzone            |\n *               | region nregs-1     |\n *               | redzone            |\n *               |--------------------|\n *               | alignment pad?     |\n *               \\--------------------/\n *\n * reg_interval has at least the same minimum alignment as reg_size; this\n * preserves the alignment constraint that sa2u() depends on.  Alignment pad is\n * either 0 or redzone_size; it is present only if needed to align reg0_offset.\n */\nstruct arena_bin_info_s {\n\t/* Size of regions in a run for this bin's size class. */\n\tsize_t\t\t\treg_size;\n\n\t/* Redzone size. */\n\tsize_t\t\t\tredzone_size;\n\n\t/* Interval between regions (reg_size + (redzone_size << 1)). */\n\tsize_t\t\t\treg_interval;\n\n\t/* Total size of a run for this bin's size class. */\n\tsize_t\t\t\trun_size;\n\n\t/* Total number of regions in a run for this bin's size class. */\n\tuint32_t\t\tnregs;\n\n\t/*\n\t * Metadata used to manipulate bitmaps for runs associated with this\n\t * bin.\n\t */\n\tbitmap_info_t\t\tbitmap_info;\n\n\t/* Offset of first region in a run for this bin's size class. */\n\tuint32_t\t\treg0_offset;\n};\n\nstruct arena_bin_s {\n\t/*\n\t * All operations on runcur, runs, and stats require that lock be\n\t * locked.  Run allocation/deallocation are protected by the arena lock,\n\t * which may be acquired while holding one or more bin locks, but not\n\t * vise versa.\n\t */\n\tmalloc_mutex_t\t\tlock;\n\n\t/*\n\t * Current run being used to service allocations of this bin's size\n\t * class.\n\t */\n\tarena_run_t\t\t*runcur;\n\n\t/*\n\t * Tree of non-full runs.  This tree is used when looking for an\n\t * existing run when runcur is no longer usable.  We choose the\n\t * non-full run that is lowest in memory; this policy tends to keep\n\t * objects packed well, and it can also help reduce the number of\n\t * almost-empty chunks.\n\t */\n\tarena_run_tree_t\truns;\n\n\t/* Bin statistics. */\n\tmalloc_bin_stats_t\tstats;\n};\n\nstruct arena_s {\n\t/* This arena's index within the arenas array. */\n\tunsigned\t\tind;\n\n\t/*\n\t * Number of threads currently assigned to this arena.  This field is\n\t * synchronized via atomic operations.\n\t */\n\tunsigned\t\tnthreads;\n\n\t/*\n\t * There are three classes of arena operations from a locking\n\t * perspective:\n\t * 1) Thread assignment (modifies nthreads) is synchronized via atomics.\n\t * 2) Bin-related operations are protected by bin locks.\n\t * 3) Chunk- and run-related operations are protected by this mutex.\n\t */\n\tmalloc_mutex_t\t\tlock;\n\n\tarena_stats_t\t\tstats;\n\t/*\n\t * List of tcaches for extant threads associated with this arena.\n\t * Stats from these are merged incrementally, and at exit if\n\t * opt_stats_print is enabled.\n\t */\n\tql_head(tcache_t)\ttcache_ql;\n\n\tuint64_t\t\tprof_accumbytes;\n\n\t/*\n\t * PRNG state for cache index randomization of large allocation base\n\t * pointers.\n\t */\n\tuint64_t\t\toffset_state;\n\n\tdss_prec_t\t\tdss_prec;\n\n\t/*\n\t * In order to avoid rapid chunk allocation/deallocation when an arena\n\t * oscillates right on the cusp of needing a new chunk, cache the most\n\t * recently freed chunk.  The spare is left in the arena's chunk trees\n\t * until it is deleted.\n\t *\n\t * There is one spare chunk per arena, rather than one spare total, in\n\t * order to avoid interactions between multiple threads that could make\n\t * a single spare inadequate.\n\t */\n\tarena_chunk_t\t\t*spare;\n\n\t/* Minimum ratio (log base 2) of nactive:ndirty. */\n\tssize_t\t\t\tlg_dirty_mult;\n\n\t/* True if a thread is currently executing arena_purge_to_limit(). */\n\tbool\t\t\tpurging;\n\n\t/* Number of pages in active runs and huge regions. */\n\tsize_t\t\t\tnactive;\n\n\t/*\n\t * Current count of pages within unused runs that are potentially\n\t * dirty, and for which madvise(... MADV_DONTNEED) has not been called.\n\t * By tracking this, we can institute a limit on how much dirty unused\n\t * memory is mapped for each arena.\n\t */\n\tsize_t\t\t\tndirty;\n\n\t/*\n\t * Unused dirty memory this arena manages.  Dirty memory is conceptually\n\t * tracked as an arbitrarily interleaved LRU of dirty runs and cached\n\t * chunks, but the list linkage is actually semi-duplicated in order to\n\t * avoid extra arena_chunk_map_misc_t space overhead.\n\t *\n\t *   LRU-----------------------------------------------------------MRU\n\t *\n\t *        /-- arena ---\\\n\t *        |            |\n\t *        |            |\n\t *        |------------|                             /- chunk -\\\n\t *   ...->|chunks_cache|<--------------------------->|  /----\\ |<--...\n\t *        |------------|                             |  |node| |\n\t *        |            |                             |  |    | |\n\t *        |            |    /- run -\\    /- run -\\   |  |    | |\n\t *        |            |    |       |    |       |   |  |    | |\n\t *        |            |    |       |    |       |   |  |    | |\n\t *        |------------|    |-------|    |-------|   |  |----| |\n\t *   ...->|runs_dirty  |<-->|rd     |<-->|rd     |<---->|rd  |<----...\n\t *        |------------|    |-------|    |-------|   |  |----| |\n\t *        |            |    |       |    |       |   |  |    | |\n\t *        |            |    |       |    |       |   |  \\----/ |\n\t *        |            |    \\-------/    \\-------/   |         |\n\t *        |            |                             |         |\n\t *        |            |                             |         |\n\t *        \\------------/                             \\---------/\n\t */\n\tarena_runs_dirty_link_t\truns_dirty;\n\textent_node_t\t\tchunks_cache;\n\n\t/*\n\t * Approximate time in seconds from the creation of a set of unused\n\t * dirty pages until an equivalent set of unused dirty pages is purged\n\t * and/or reused.\n\t */\n\tssize_t\t\t\tdecay_time;\n\t/* decay_time / SMOOTHSTEP_NSTEPS. */\n\tnstime_t\t\tdecay_interval;\n\t/*\n\t * Time at which the current decay interval logically started.  We do\n\t * not actually advance to a new epoch until sometime after it starts\n\t * because of scheduling and computation delays, and it is even possible\n\t * to completely skip epochs.  In all cases, during epoch advancement we\n\t * merge all relevant activity into the most recently recorded epoch.\n\t */\n\tnstime_t\t\tdecay_epoch;\n\t/* decay_deadline randomness generator. */\n\tuint64_t\t\tdecay_jitter_state;\n\t/*\n\t * Deadline for current epoch.  This is the sum of decay_interval and\n\t * per epoch jitter which is a uniform random variable in\n\t * [0..decay_interval).  Epochs always advance by precise multiples of\n\t * decay_interval, but we randomize the deadline to reduce the\n\t * likelihood of arenas purging in lockstep.\n\t */\n\tnstime_t\t\tdecay_deadline;\n\t/*\n\t * Number of dirty pages at beginning of current epoch.  During epoch\n\t * advancement we use the delta between decay_ndirty and ndirty to\n\t * determine how many dirty pages, if any, were generated, and record\n\t * the result in decay_backlog.\n\t */\n\tsize_t\t\t\tdecay_ndirty;\n\t/*\n\t * Memoized result of arena_decay_backlog_npages_limit() corresponding\n\t * to the current contents of decay_backlog, i.e. the limit on how many\n\t * pages are allowed to exist for the decay epochs.\n\t */\n\tsize_t\t\t\tdecay_backlog_npages_limit;\n\t/*\n\t * Trailing log of how many unused dirty pages were generated during\n\t * each of the past SMOOTHSTEP_NSTEPS decay epochs, where the last\n\t * element is the most recent epoch.  Corresponding epoch times are\n\t * relative to decay_epoch.\n\t */\n\tsize_t\t\t\tdecay_backlog[SMOOTHSTEP_NSTEPS];\n\n\t/* Extant huge allocations. */\n\tql_head(extent_node_t)\thuge;\n\t/* Synchronizes all huge allocation/update/deallocation. */\n\tmalloc_mutex_t\t\thuge_mtx;\n\n\t/*\n\t * Trees of chunks that were previously allocated (trees differ only in\n\t * node ordering).  These are used when allocating chunks, in an attempt\n\t * to re-use address space.  Depending on function, different tree\n\t * orderings are needed, which is why there are two trees with the same\n\t * contents.\n\t */\n\textent_tree_t\t\tchunks_szad_cached;\n\textent_tree_t\t\tchunks_ad_cached;\n\textent_tree_t\t\tchunks_szad_retained;\n\textent_tree_t\t\tchunks_ad_retained;\n\n\tmalloc_mutex_t\t\tchunks_mtx;\n\t/* Cache of nodes that were allocated via base_alloc(). */\n\tql_head(extent_node_t)\tnode_cache;\n\tmalloc_mutex_t\t\tnode_cache_mtx;\n\n\t/* User-configurable chunk hook functions. */\n\tchunk_hooks_t\t\tchunk_hooks;\n\n\t/* bins is used to store trees of free regions. */\n\tarena_bin_t\t\tbins[NBINS];\n\n\t/*\n\t * Quantized address-ordered trees of this arena's available runs.  The\n\t * trees are used for first-best-fit run allocation.\n\t */\n\tarena_run_tree_t\truns_avail[1]; /* Dynamically sized. */\n};\n\n/* Used in conjunction with tsd for fast arena-related context lookup. */\nstruct arena_tdata_s {\n\tticker_t\t\tdecay_ticker;\n};\n#endif /* JEMALLOC_ARENA_STRUCTS_B */\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nstatic const size_t\tlarge_pad =\n#ifdef JEMALLOC_CACHE_OBLIVIOUS\n    PAGE\n#else\n    0\n#endif\n    ;\n\nextern purge_mode_t\topt_purge;\nextern const char\t*purge_mode_names[];\nextern ssize_t\t\topt_lg_dirty_mult;\nextern ssize_t\t\topt_decay_time;\n\nextern arena_bin_info_t\tarena_bin_info[NBINS];\n\nextern size_t\t\tmap_bias; /* Number of arena chunk header pages. */\nextern size_t\t\tmap_misc_offset;\nextern size_t\t\tarena_maxrun; /* Max run size for arenas. */\nextern size_t\t\tlarge_maxclass; /* Max large size class. */\nextern size_t\t\trun_quantize_max; /* Max run_quantize_*() input. */\nextern unsigned\t\tnlclasses; /* Number of large size classes. */\nextern unsigned\t\tnhclasses; /* Number of huge size classes. */\n\n#ifdef JEMALLOC_JET\ntypedef size_t (run_quantize_t)(size_t);\nextern run_quantize_t *run_quantize_floor;\nextern run_quantize_t *run_quantize_ceil;\n#endif\nvoid\tarena_chunk_cache_maybe_insert(arena_t *arena, extent_node_t *node,\n    bool cache);\nvoid\tarena_chunk_cache_maybe_remove(arena_t *arena, extent_node_t *node,\n    bool cache);\nextent_node_t\t*arena_node_alloc(arena_t *arena);\nvoid\tarena_node_dalloc(arena_t *arena, extent_node_t *node);\nvoid\t*arena_chunk_alloc_huge(arena_t *arena, size_t usize, size_t alignment,\n    bool *zero);\nvoid\tarena_chunk_dalloc_huge(arena_t *arena, void *chunk, size_t usize);\nvoid\tarena_chunk_ralloc_huge_similar(arena_t *arena, void *chunk,\n    size_t oldsize, size_t usize);\nvoid\tarena_chunk_ralloc_huge_shrink(arena_t *arena, void *chunk,\n    size_t oldsize, size_t usize);\nbool\tarena_chunk_ralloc_huge_expand(arena_t *arena, void *chunk,\n    size_t oldsize, size_t usize, bool *zero);\nssize_t\tarena_lg_dirty_mult_get(arena_t *arena);\nbool\tarena_lg_dirty_mult_set(arena_t *arena, ssize_t lg_dirty_mult);\nssize_t\tarena_decay_time_get(arena_t *arena);\nbool\tarena_decay_time_set(arena_t *arena, ssize_t decay_time);\nvoid\tarena_maybe_purge(arena_t *arena);\nvoid\tarena_purge(arena_t *arena, bool all);\nvoid\tarena_tcache_fill_small(tsd_t *tsd, arena_t *arena, tcache_bin_t *tbin,\n    szind_t binind, uint64_t prof_accumbytes);\nvoid\tarena_alloc_junk_small(void *ptr, arena_bin_info_t *bin_info,\n    bool zero);\n#ifdef JEMALLOC_JET\ntypedef void (arena_redzone_corruption_t)(void *, size_t, bool, size_t,\n    uint8_t);\nextern arena_redzone_corruption_t *arena_redzone_corruption;\ntypedef void (arena_dalloc_junk_small_t)(void *, arena_bin_info_t *);\nextern arena_dalloc_junk_small_t *arena_dalloc_junk_small;\n#else\nvoid\tarena_dalloc_junk_small(void *ptr, arena_bin_info_t *bin_info);\n#endif\nvoid\tarena_quarantine_junk_small(void *ptr, size_t usize);\nvoid\t*arena_malloc_large(tsd_t *tsd, arena_t *arena, szind_t ind, bool zero);\nvoid\t*arena_malloc_hard(tsd_t *tsd, arena_t *arena, size_t size, szind_t ind,\n    bool zero, tcache_t *tcache);\nvoid\t*arena_palloc(tsd_t *tsd, arena_t *arena, size_t usize,\n    size_t alignment, bool zero, tcache_t *tcache);\nvoid\tarena_prof_promoted(const void *ptr, size_t size);\nvoid\tarena_dalloc_bin_junked_locked(arena_t *arena, arena_chunk_t *chunk,\n    void *ptr, arena_chunk_map_bits_t *bitselm);\nvoid\tarena_dalloc_bin(arena_t *arena, arena_chunk_t *chunk, void *ptr,\n    size_t pageind, arena_chunk_map_bits_t *bitselm);\nvoid\tarena_dalloc_small(tsd_t *tsd, arena_t *arena, arena_chunk_t *chunk,\n    void *ptr, size_t pageind);\n#ifdef JEMALLOC_JET\ntypedef void (arena_dalloc_junk_large_t)(void *, size_t);\nextern arena_dalloc_junk_large_t *arena_dalloc_junk_large;\n#else\nvoid\tarena_dalloc_junk_large(void *ptr, size_t usize);\n#endif\nvoid\tarena_dalloc_large_junked_locked(arena_t *arena, arena_chunk_t *chunk,\n    void *ptr);\nvoid\tarena_dalloc_large(tsd_t *tsd, arena_t *arena, arena_chunk_t *chunk,\n    void *ptr);\n#ifdef JEMALLOC_JET\ntypedef void (arena_ralloc_junk_large_t)(void *, size_t, size_t);\nextern arena_ralloc_junk_large_t *arena_ralloc_junk_large;\n#endif\nbool\tarena_ralloc_no_move(tsd_t *tsd, void *ptr, size_t oldsize, size_t size,\n    size_t extra, bool zero);\nvoid\t*arena_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize,\n    size_t size, size_t alignment, bool zero, tcache_t *tcache);\ndss_prec_t\tarena_dss_prec_get(arena_t *arena);\nbool\tarena_dss_prec_set(arena_t *arena, dss_prec_t dss_prec);\nssize_t\tarena_lg_dirty_mult_default_get(void);\nbool\tarena_lg_dirty_mult_default_set(ssize_t lg_dirty_mult);\nssize_t\tarena_decay_time_default_get(void);\nbool\tarena_decay_time_default_set(ssize_t decay_time);\nvoid\tarena_basic_stats_merge(arena_t *arena, unsigned *nthreads,\n    const char **dss, ssize_t *lg_dirty_mult, ssize_t *decay_time,\n    size_t *nactive, size_t *ndirty);\nvoid\tarena_stats_merge(arena_t *arena, unsigned *nthreads, const char **dss,\n    ssize_t *lg_dirty_mult, ssize_t *decay_time, size_t *nactive,\n    size_t *ndirty, arena_stats_t *astats, malloc_bin_stats_t *bstats,\n    malloc_large_stats_t *lstats, malloc_huge_stats_t *hstats);\nunsigned\tarena_nthreads_get(arena_t *arena);\nvoid\tarena_nthreads_inc(arena_t *arena);\nvoid\tarena_nthreads_dec(arena_t *arena);\narena_t\t*arena_new(unsigned ind);\nbool\tarena_boot(void);\nvoid\tarena_prefork(arena_t *arena);\nvoid\tarena_postfork_parent(arena_t *arena);\nvoid\tarena_postfork_child(arena_t *arena);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#ifndef JEMALLOC_ENABLE_INLINE\narena_chunk_map_bits_t\t*arena_bitselm_get(arena_chunk_t *chunk,\n    size_t pageind);\narena_chunk_map_misc_t\t*arena_miscelm_get(arena_chunk_t *chunk,\n    size_t pageind);\nsize_t\tarena_miscelm_to_pageind(const arena_chunk_map_misc_t *miscelm);\nvoid\t*arena_miscelm_to_rpages(arena_chunk_map_misc_t *miscelm);\narena_chunk_map_misc_t\t*arena_rd_to_miscelm(arena_runs_dirty_link_t *rd);\narena_chunk_map_misc_t\t*arena_run_to_miscelm(arena_run_t *run);\nsize_t\t*arena_mapbitsp_get(arena_chunk_t *chunk, size_t pageind);\nsize_t\tarena_mapbitsp_read(size_t *mapbitsp);\nsize_t\tarena_mapbits_get(arena_chunk_t *chunk, size_t pageind);\nsize_t\tarena_mapbits_size_decode(size_t mapbits);\nsize_t\tarena_mapbits_unallocated_size_get(arena_chunk_t *chunk,\n    size_t pageind);\nsize_t\tarena_mapbits_large_size_get(arena_chunk_t *chunk, size_t pageind);\nsize_t\tarena_mapbits_small_runind_get(arena_chunk_t *chunk, size_t pageind);\nszind_t\tarena_mapbits_binind_get(arena_chunk_t *chunk, size_t pageind);\nsize_t\tarena_mapbits_dirty_get(arena_chunk_t *chunk, size_t pageind);\nsize_t\tarena_mapbits_unzeroed_get(arena_chunk_t *chunk, size_t pageind);\nsize_t\tarena_mapbits_decommitted_get(arena_chunk_t *chunk, size_t pageind);\nsize_t\tarena_mapbits_large_get(arena_chunk_t *chunk, size_t pageind);\nsize_t\tarena_mapbits_allocated_get(arena_chunk_t *chunk, size_t pageind);\nvoid\tarena_mapbitsp_write(size_t *mapbitsp, size_t mapbits);\nsize_t\tarena_mapbits_size_encode(size_t size);\nvoid\tarena_mapbits_unallocated_set(arena_chunk_t *chunk, size_t pageind,\n    size_t size, size_t flags);\nvoid\tarena_mapbits_unallocated_size_set(arena_chunk_t *chunk, size_t pageind,\n    size_t size);\nvoid\tarena_mapbits_internal_set(arena_chunk_t *chunk, size_t pageind,\n    size_t flags);\nvoid\tarena_mapbits_large_set(arena_chunk_t *chunk, size_t pageind,\n    size_t size, size_t flags);\nvoid\tarena_mapbits_large_binind_set(arena_chunk_t *chunk, size_t pageind,\n    szind_t binind);\nvoid\tarena_mapbits_small_set(arena_chunk_t *chunk, size_t pageind,\n    size_t runind, szind_t binind, size_t flags);\nvoid\tarena_metadata_allocated_add(arena_t *arena, size_t size);\nvoid\tarena_metadata_allocated_sub(arena_t *arena, size_t size);\nsize_t\tarena_metadata_allocated_get(arena_t *arena);\nbool\tarena_prof_accum_impl(arena_t *arena, uint64_t accumbytes);\nbool\tarena_prof_accum_locked(arena_t *arena, uint64_t accumbytes);\nbool\tarena_prof_accum(arena_t *arena, uint64_t accumbytes);\nszind_t\tarena_ptr_small_binind_get(const void *ptr, size_t mapbits);\nszind_t\tarena_bin_index(arena_t *arena, arena_bin_t *bin);\nsize_t\tarena_run_regind(arena_run_t *run, arena_bin_info_t *bin_info,\n    const void *ptr);\nprof_tctx_t\t*arena_prof_tctx_get(const void *ptr);\nvoid\tarena_prof_tctx_set(const void *ptr, size_t usize, prof_tctx_t *tctx);\nvoid\tarena_prof_tctx_reset(const void *ptr, size_t usize,\n    const void *old_ptr, prof_tctx_t *old_tctx);\nvoid\tarena_decay_ticks(tsd_t *tsd, arena_t *arena, unsigned nticks);\nvoid\tarena_decay_tick(tsd_t *tsd, arena_t *arena);\nvoid\t*arena_malloc(tsd_t *tsd, arena_t *arena, size_t size, szind_t ind,\n    bool zero, tcache_t *tcache, bool slow_path);\narena_t\t*arena_aalloc(const void *ptr);\nsize_t\tarena_salloc(const void *ptr, bool demote);\nvoid\tarena_dalloc(tsd_t *tsd, void *ptr, tcache_t *tcache, bool slow_path);\nvoid\tarena_sdalloc(tsd_t *tsd, void *ptr, size_t size, tcache_t *tcache);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_ARENA_C_))\n#  ifdef JEMALLOC_ARENA_INLINE_A\nJEMALLOC_ALWAYS_INLINE arena_chunk_map_bits_t *\narena_bitselm_get(arena_chunk_t *chunk, size_t pageind)\n{\n\n\tassert(pageind >= map_bias);\n\tassert(pageind < chunk_npages);\n\n\treturn (&chunk->map_bits[pageind-map_bias]);\n}\n\nJEMALLOC_ALWAYS_INLINE arena_chunk_map_misc_t *\narena_miscelm_get(arena_chunk_t *chunk, size_t pageind)\n{\n\n\tassert(pageind >= map_bias);\n\tassert(pageind < chunk_npages);\n\n\treturn ((arena_chunk_map_misc_t *)((uintptr_t)chunk +\n\t    (uintptr_t)map_misc_offset) + pageind-map_bias);\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\narena_miscelm_to_pageind(const arena_chunk_map_misc_t *miscelm)\n{\n\tarena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(miscelm);\n\tsize_t pageind = ((uintptr_t)miscelm - ((uintptr_t)chunk +\n\t    map_misc_offset)) / sizeof(arena_chunk_map_misc_t) + map_bias;\n\n\tassert(pageind >= map_bias);\n\tassert(pageind < chunk_npages);\n\n\treturn (pageind);\n}\n\nJEMALLOC_ALWAYS_INLINE void *\narena_miscelm_to_rpages(arena_chunk_map_misc_t *miscelm)\n{\n\tarena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(miscelm);\n\tsize_t pageind = arena_miscelm_to_pageind(miscelm);\n\n\treturn ((void *)((uintptr_t)chunk + (pageind << LG_PAGE)));\n}\n\nJEMALLOC_ALWAYS_INLINE arena_chunk_map_misc_t *\narena_rd_to_miscelm(arena_runs_dirty_link_t *rd)\n{\n\tarena_chunk_map_misc_t *miscelm = (arena_chunk_map_misc_t\n\t    *)((uintptr_t)rd - offsetof(arena_chunk_map_misc_t, rd));\n\n\tassert(arena_miscelm_to_pageind(miscelm) >= map_bias);\n\tassert(arena_miscelm_to_pageind(miscelm) < chunk_npages);\n\n\treturn (miscelm);\n}\n\nJEMALLOC_ALWAYS_INLINE arena_chunk_map_misc_t *\narena_run_to_miscelm(arena_run_t *run)\n{\n\tarena_chunk_map_misc_t *miscelm = (arena_chunk_map_misc_t\n\t    *)((uintptr_t)run - offsetof(arena_chunk_map_misc_t, run));\n\n\tassert(arena_miscelm_to_pageind(miscelm) >= map_bias);\n\tassert(arena_miscelm_to_pageind(miscelm) < chunk_npages);\n\n\treturn (miscelm);\n}\n\nJEMALLOC_ALWAYS_INLINE size_t *\narena_mapbitsp_get(arena_chunk_t *chunk, size_t pageind)\n{\n\n\treturn (&arena_bitselm_get(chunk, pageind)->bits);\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\narena_mapbitsp_read(size_t *mapbitsp)\n{\n\n\treturn (*mapbitsp);\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\narena_mapbits_get(arena_chunk_t *chunk, size_t pageind)\n{\n\n\treturn (arena_mapbitsp_read(arena_mapbitsp_get(chunk, pageind)));\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\narena_mapbits_size_decode(size_t mapbits)\n{\n\tsize_t size;\n\n#if CHUNK_MAP_SIZE_SHIFT > 0\n\tsize = (mapbits & CHUNK_MAP_SIZE_MASK) >> CHUNK_MAP_SIZE_SHIFT;\n#elif CHUNK_MAP_SIZE_SHIFT == 0\n\tsize = mapbits & CHUNK_MAP_SIZE_MASK;\n#else\n\tsize = (mapbits & CHUNK_MAP_SIZE_MASK) << -CHUNK_MAP_SIZE_SHIFT;\n#endif\n\n\treturn (size);\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\narena_mapbits_unallocated_size_get(arena_chunk_t *chunk, size_t pageind)\n{\n\tsize_t mapbits;\n\n\tmapbits = arena_mapbits_get(chunk, pageind);\n\tassert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) == 0);\n\treturn (arena_mapbits_size_decode(mapbits));\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\narena_mapbits_large_size_get(arena_chunk_t *chunk, size_t pageind)\n{\n\tsize_t mapbits;\n\n\tmapbits = arena_mapbits_get(chunk, pageind);\n\tassert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) ==\n\t    (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED));\n\treturn (arena_mapbits_size_decode(mapbits));\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\narena_mapbits_small_runind_get(arena_chunk_t *chunk, size_t pageind)\n{\n\tsize_t mapbits;\n\n\tmapbits = arena_mapbits_get(chunk, pageind);\n\tassert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) ==\n\t    CHUNK_MAP_ALLOCATED);\n\treturn (mapbits >> CHUNK_MAP_RUNIND_SHIFT);\n}\n\nJEMALLOC_ALWAYS_INLINE szind_t\narena_mapbits_binind_get(arena_chunk_t *chunk, size_t pageind)\n{\n\tsize_t mapbits;\n\tszind_t binind;\n\n\tmapbits = arena_mapbits_get(chunk, pageind);\n\tbinind = (mapbits & CHUNK_MAP_BININD_MASK) >> CHUNK_MAP_BININD_SHIFT;\n\tassert(binind < NBINS || binind == BININD_INVALID);\n\treturn (binind);\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\narena_mapbits_dirty_get(arena_chunk_t *chunk, size_t pageind)\n{\n\tsize_t mapbits;\n\n\tmapbits = arena_mapbits_get(chunk, pageind);\n\tassert((mapbits & CHUNK_MAP_DECOMMITTED) == 0 || (mapbits &\n\t    (CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0);\n\treturn (mapbits & CHUNK_MAP_DIRTY);\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\narena_mapbits_unzeroed_get(arena_chunk_t *chunk, size_t pageind)\n{\n\tsize_t mapbits;\n\n\tmapbits = arena_mapbits_get(chunk, pageind);\n\tassert((mapbits & CHUNK_MAP_DECOMMITTED) == 0 || (mapbits &\n\t    (CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0);\n\treturn (mapbits & CHUNK_MAP_UNZEROED);\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\narena_mapbits_decommitted_get(arena_chunk_t *chunk, size_t pageind)\n{\n\tsize_t mapbits;\n\n\tmapbits = arena_mapbits_get(chunk, pageind);\n\tassert((mapbits & CHUNK_MAP_DECOMMITTED) == 0 || (mapbits &\n\t    (CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0);\n\treturn (mapbits & CHUNK_MAP_DECOMMITTED);\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\narena_mapbits_large_get(arena_chunk_t *chunk, size_t pageind)\n{\n\tsize_t mapbits;\n\n\tmapbits = arena_mapbits_get(chunk, pageind);\n\treturn (mapbits & CHUNK_MAP_LARGE);\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\narena_mapbits_allocated_get(arena_chunk_t *chunk, size_t pageind)\n{\n\tsize_t mapbits;\n\n\tmapbits = arena_mapbits_get(chunk, pageind);\n\treturn (mapbits & CHUNK_MAP_ALLOCATED);\n}\n\nJEMALLOC_ALWAYS_INLINE void\narena_mapbitsp_write(size_t *mapbitsp, size_t mapbits)\n{\n\n\t*mapbitsp = mapbits;\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\narena_mapbits_size_encode(size_t size)\n{\n\tsize_t mapbits;\n\n#if CHUNK_MAP_SIZE_SHIFT > 0\n\tmapbits = size << CHUNK_MAP_SIZE_SHIFT;\n#elif CHUNK_MAP_SIZE_SHIFT == 0\n\tmapbits = size;\n#else\n\tmapbits = size >> -CHUNK_MAP_SIZE_SHIFT;\n#endif\n\n\tassert((mapbits & ~CHUNK_MAP_SIZE_MASK) == 0);\n\treturn (mapbits);\n}\n\nJEMALLOC_ALWAYS_INLINE void\narena_mapbits_unallocated_set(arena_chunk_t *chunk, size_t pageind, size_t size,\n    size_t flags)\n{\n\tsize_t *mapbitsp = arena_mapbitsp_get(chunk, pageind);\n\n\tassert((size & PAGE_MASK) == 0);\n\tassert((flags & CHUNK_MAP_FLAGS_MASK) == flags);\n\tassert((flags & CHUNK_MAP_DECOMMITTED) == 0 || (flags &\n\t    (CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0);\n\tarena_mapbitsp_write(mapbitsp, arena_mapbits_size_encode(size) |\n\t    CHUNK_MAP_BININD_INVALID | flags);\n}\n\nJEMALLOC_ALWAYS_INLINE void\narena_mapbits_unallocated_size_set(arena_chunk_t *chunk, size_t pageind,\n    size_t size)\n{\n\tsize_t *mapbitsp = arena_mapbitsp_get(chunk, pageind);\n\tsize_t mapbits = arena_mapbitsp_read(mapbitsp);\n\n\tassert((size & PAGE_MASK) == 0);\n\tassert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) == 0);\n\tarena_mapbitsp_write(mapbitsp, arena_mapbits_size_encode(size) |\n\t    (mapbits & ~CHUNK_MAP_SIZE_MASK));\n}\n\nJEMALLOC_ALWAYS_INLINE void\narena_mapbits_internal_set(arena_chunk_t *chunk, size_t pageind, size_t flags)\n{\n\tsize_t *mapbitsp = arena_mapbitsp_get(chunk, pageind);\n\n\tassert((flags & CHUNK_MAP_UNZEROED) == flags);\n\tarena_mapbitsp_write(mapbitsp, flags);\n}\n\nJEMALLOC_ALWAYS_INLINE void\narena_mapbits_large_set(arena_chunk_t *chunk, size_t pageind, size_t size,\n    size_t flags)\n{\n\tsize_t *mapbitsp = arena_mapbitsp_get(chunk, pageind);\n\n\tassert((size & PAGE_MASK) == 0);\n\tassert((flags & CHUNK_MAP_FLAGS_MASK) == flags);\n\tassert((flags & CHUNK_MAP_DECOMMITTED) == 0 || (flags &\n\t    (CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0);\n\tarena_mapbitsp_write(mapbitsp, arena_mapbits_size_encode(size) |\n\t    CHUNK_MAP_BININD_INVALID | flags | CHUNK_MAP_LARGE |\n\t    CHUNK_MAP_ALLOCATED);\n}\n\nJEMALLOC_ALWAYS_INLINE void\narena_mapbits_large_binind_set(arena_chunk_t *chunk, size_t pageind,\n    szind_t binind)\n{\n\tsize_t *mapbitsp = arena_mapbitsp_get(chunk, pageind);\n\tsize_t mapbits = arena_mapbitsp_read(mapbitsp);\n\n\tassert(binind <= BININD_INVALID);\n\tassert(arena_mapbits_large_size_get(chunk, pageind) == LARGE_MINCLASS +\n\t    large_pad);\n\tarena_mapbitsp_write(mapbitsp, (mapbits & ~CHUNK_MAP_BININD_MASK) |\n\t    (binind << CHUNK_MAP_BININD_SHIFT));\n}\n\nJEMALLOC_ALWAYS_INLINE void\narena_mapbits_small_set(arena_chunk_t *chunk, size_t pageind, size_t runind,\n    szind_t binind, size_t flags)\n{\n\tsize_t *mapbitsp = arena_mapbitsp_get(chunk, pageind);\n\n\tassert(binind < BININD_INVALID);\n\tassert(pageind - runind >= map_bias);\n\tassert((flags & CHUNK_MAP_UNZEROED) == flags);\n\tarena_mapbitsp_write(mapbitsp, (runind << CHUNK_MAP_RUNIND_SHIFT) |\n\t    (binind << CHUNK_MAP_BININD_SHIFT) | flags | CHUNK_MAP_ALLOCATED);\n}\n\nJEMALLOC_INLINE void\narena_metadata_allocated_add(arena_t *arena, size_t size)\n{\n\n\tatomic_add_z(&arena->stats.metadata_allocated, size);\n}\n\nJEMALLOC_INLINE void\narena_metadata_allocated_sub(arena_t *arena, size_t size)\n{\n\n\tatomic_sub_z(&arena->stats.metadata_allocated, size);\n}\n\nJEMALLOC_INLINE size_t\narena_metadata_allocated_get(arena_t *arena)\n{\n\n\treturn (atomic_read_z(&arena->stats.metadata_allocated));\n}\n\nJEMALLOC_INLINE bool\narena_prof_accum_impl(arena_t *arena, uint64_t accumbytes)\n{\n\n\tcassert(config_prof);\n\tassert(prof_interval != 0);\n\n\tarena->prof_accumbytes += accumbytes;\n\tif (arena->prof_accumbytes >= prof_interval) {\n\t\tarena->prof_accumbytes -= prof_interval;\n\t\treturn (true);\n\t}\n\treturn (false);\n}\n\nJEMALLOC_INLINE bool\narena_prof_accum_locked(arena_t *arena, uint64_t accumbytes)\n{\n\n\tcassert(config_prof);\n\n\tif (likely(prof_interval == 0))\n\t\treturn (false);\n\treturn (arena_prof_accum_impl(arena, accumbytes));\n}\n\nJEMALLOC_INLINE bool\narena_prof_accum(arena_t *arena, uint64_t accumbytes)\n{\n\n\tcassert(config_prof);\n\n\tif (likely(prof_interval == 0))\n\t\treturn (false);\n\n\t{\n\t\tbool ret;\n\n\t\tmalloc_mutex_lock(&arena->lock);\n\t\tret = arena_prof_accum_impl(arena, accumbytes);\n\t\tmalloc_mutex_unlock(&arena->lock);\n\t\treturn (ret);\n\t}\n}\n\nJEMALLOC_ALWAYS_INLINE szind_t\narena_ptr_small_binind_get(const void *ptr, size_t mapbits)\n{\n\tszind_t binind;\n\n\tbinind = (mapbits & CHUNK_MAP_BININD_MASK) >> CHUNK_MAP_BININD_SHIFT;\n\n\tif (config_debug) {\n\t\tarena_chunk_t *chunk;\n\t\tarena_t *arena;\n\t\tsize_t pageind;\n\t\tsize_t actual_mapbits;\n\t\tsize_t rpages_ind;\n\t\tarena_run_t *run;\n\t\tarena_bin_t *bin;\n\t\tszind_t run_binind, actual_binind;\n\t\tarena_bin_info_t *bin_info;\n\t\tarena_chunk_map_misc_t *miscelm;\n\t\tvoid *rpages;\n\n\t\tassert(binind != BININD_INVALID);\n\t\tassert(binind < NBINS);\n\t\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);\n\t\tarena = extent_node_arena_get(&chunk->node);\n\t\tpageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;\n\t\tactual_mapbits = arena_mapbits_get(chunk, pageind);\n\t\tassert(mapbits == actual_mapbits);\n\t\tassert(arena_mapbits_large_get(chunk, pageind) == 0);\n\t\tassert(arena_mapbits_allocated_get(chunk, pageind) != 0);\n\t\trpages_ind = pageind - arena_mapbits_small_runind_get(chunk,\n\t\t    pageind);\n\t\tmiscelm = arena_miscelm_get(chunk, rpages_ind);\n\t\trun = &miscelm->run;\n\t\trun_binind = run->binind;\n\t\tbin = &arena->bins[run_binind];\n\t\tactual_binind = (szind_t)(bin - arena->bins);\n\t\tassert(run_binind == actual_binind);\n\t\tbin_info = &arena_bin_info[actual_binind];\n\t\trpages = arena_miscelm_to_rpages(miscelm);\n\t\tassert(((uintptr_t)ptr - ((uintptr_t)rpages +\n\t\t    (uintptr_t)bin_info->reg0_offset)) % bin_info->reg_interval\n\t\t    == 0);\n\t}\n\n\treturn (binind);\n}\n#  endif /* JEMALLOC_ARENA_INLINE_A */\n\n#  ifdef JEMALLOC_ARENA_INLINE_B\nJEMALLOC_INLINE szind_t\narena_bin_index(arena_t *arena, arena_bin_t *bin)\n{\n\tszind_t binind = (szind_t)(bin - arena->bins);\n\tassert(binind < NBINS);\n\treturn (binind);\n}\n\nJEMALLOC_INLINE size_t\narena_run_regind(arena_run_t *run, arena_bin_info_t *bin_info, const void *ptr)\n{\n\tsize_t diff, interval, shift, regind;\n\tarena_chunk_map_misc_t *miscelm = arena_run_to_miscelm(run);\n\tvoid *rpages = arena_miscelm_to_rpages(miscelm);\n\n\t/*\n\t * Freeing a pointer lower than region zero can cause assertion\n\t * failure.\n\t */\n\tassert((uintptr_t)ptr >= (uintptr_t)rpages +\n\t    (uintptr_t)bin_info->reg0_offset);\n\n\t/*\n\t * Avoid doing division with a variable divisor if possible.  Using\n\t * actual division here can reduce allocator throughput by over 20%!\n\t */\n\tdiff = (size_t)((uintptr_t)ptr - (uintptr_t)rpages -\n\t    bin_info->reg0_offset);\n\n\t/* Rescale (factor powers of 2 out of the numerator and denominator). */\n\tinterval = bin_info->reg_interval;\n\tshift = ffs_zu(interval) - 1;\n\tdiff >>= shift;\n\tinterval >>= shift;\n\n\tif (interval == 1) {\n\t\t/* The divisor was a power of 2. */\n\t\tregind = diff;\n\t} else {\n\t\t/*\n\t\t * To divide by a number D that is not a power of two we\n\t\t * multiply by (2^21 / D) and then right shift by 21 positions.\n\t\t *\n\t\t *   X / D\n\t\t *\n\t\t * becomes\n\t\t *\n\t\t *   (X * interval_invs[D - 3]) >> SIZE_INV_SHIFT\n\t\t *\n\t\t * We can omit the first three elements, because we never\n\t\t * divide by 0, and 1 and 2 are both powers of two, which are\n\t\t * handled above.\n\t\t */\n#define\tSIZE_INV_SHIFT\t((sizeof(size_t) << 3) - LG_RUN_MAXREGS)\n#define\tSIZE_INV(s)\t(((ZU(1) << SIZE_INV_SHIFT) / (s)) + 1)\n\t\tstatic const size_t interval_invs[] = {\n\t\t    SIZE_INV(3),\n\t\t    SIZE_INV(4), SIZE_INV(5), SIZE_INV(6), SIZE_INV(7),\n\t\t    SIZE_INV(8), SIZE_INV(9), SIZE_INV(10), SIZE_INV(11),\n\t\t    SIZE_INV(12), SIZE_INV(13), SIZE_INV(14), SIZE_INV(15),\n\t\t    SIZE_INV(16), SIZE_INV(17), SIZE_INV(18), SIZE_INV(19),\n\t\t    SIZE_INV(20), SIZE_INV(21), SIZE_INV(22), SIZE_INV(23),\n\t\t    SIZE_INV(24), SIZE_INV(25), SIZE_INV(26), SIZE_INV(27),\n\t\t    SIZE_INV(28), SIZE_INV(29), SIZE_INV(30), SIZE_INV(31)\n\t\t};\n\n\t\tif (likely(interval <= ((sizeof(interval_invs) / sizeof(size_t))\n\t\t    + 2))) {\n\t\t\tregind = (diff * interval_invs[interval - 3]) >>\n\t\t\t    SIZE_INV_SHIFT;\n\t\t} else\n\t\t\tregind = diff / interval;\n#undef SIZE_INV\n#undef SIZE_INV_SHIFT\n\t}\n\tassert(diff == regind * interval);\n\tassert(regind < bin_info->nregs);\n\n\treturn (regind);\n}\n\nJEMALLOC_INLINE prof_tctx_t *\narena_prof_tctx_get(const void *ptr)\n{\n\tprof_tctx_t *ret;\n\tarena_chunk_t *chunk;\n\n\tcassert(config_prof);\n\tassert(ptr != NULL);\n\n\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);\n\tif (likely(chunk != ptr)) {\n\t\tsize_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;\n\t\tsize_t mapbits = arena_mapbits_get(chunk, pageind);\n\t\tassert((mapbits & CHUNK_MAP_ALLOCATED) != 0);\n\t\tif (likely((mapbits & CHUNK_MAP_LARGE) == 0))\n\t\t\tret = (prof_tctx_t *)(uintptr_t)1U;\n\t\telse {\n\t\t\tarena_chunk_map_misc_t *elm = arena_miscelm_get(chunk,\n\t\t\t    pageind);\n\t\t\tret = atomic_read_p(&elm->prof_tctx_pun);\n\t\t}\n\t} else\n\t\tret = huge_prof_tctx_get(ptr);\n\n\treturn (ret);\n}\n\nJEMALLOC_INLINE void\narena_prof_tctx_set(const void *ptr, size_t usize, prof_tctx_t *tctx)\n{\n\tarena_chunk_t *chunk;\n\n\tcassert(config_prof);\n\tassert(ptr != NULL);\n\n\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);\n\tif (likely(chunk != ptr)) {\n\t\tsize_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;\n\n\t\tassert(arena_mapbits_allocated_get(chunk, pageind) != 0);\n\n\t\tif (unlikely(usize > SMALL_MAXCLASS || (uintptr_t)tctx >\n\t\t    (uintptr_t)1U)) {\n\t\t\tarena_chunk_map_misc_t *elm;\n\n\t\t\tassert(arena_mapbits_large_get(chunk, pageind) != 0);\n\n\t\t\telm = arena_miscelm_get(chunk, pageind);\n\t\t\tatomic_write_p(&elm->prof_tctx_pun, tctx);\n\t\t} else {\n\t\t\t/*\n\t\t\t * tctx must always be initialized for large runs.\n\t\t\t * Assert that the surrounding conditional logic is\n\t\t\t * equivalent to checking whether ptr refers to a large\n\t\t\t * run.\n\t\t\t */\n\t\t\tassert(arena_mapbits_large_get(chunk, pageind) == 0);\n\t\t}\n\t} else\n\t\thuge_prof_tctx_set(ptr, tctx);\n}\n\nJEMALLOC_INLINE void\narena_prof_tctx_reset(const void *ptr, size_t usize, const void *old_ptr,\n    prof_tctx_t *old_tctx)\n{\n\n\tcassert(config_prof);\n\tassert(ptr != NULL);\n\n\tif (unlikely(usize > SMALL_MAXCLASS || (ptr == old_ptr &&\n\t    (uintptr_t)old_tctx > (uintptr_t)1U))) {\n\t\tarena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);\n\t\tif (likely(chunk != ptr)) {\n\t\t\tsize_t pageind;\n\t\t\tarena_chunk_map_misc_t *elm;\n\n\t\t\tpageind = ((uintptr_t)ptr - (uintptr_t)chunk) >>\n\t\t\t    LG_PAGE;\n\t\t\tassert(arena_mapbits_allocated_get(chunk, pageind) !=\n\t\t\t    0);\n\t\t\tassert(arena_mapbits_large_get(chunk, pageind) != 0);\n\n\t\t\telm = arena_miscelm_get(chunk, pageind);\n\t\t\tatomic_write_p(&elm->prof_tctx_pun,\n\t\t\t    (prof_tctx_t *)(uintptr_t)1U);\n\t\t} else\n\t\t\thuge_prof_tctx_reset(ptr);\n\t}\n}\n\nJEMALLOC_ALWAYS_INLINE void\narena_decay_ticks(tsd_t *tsd, arena_t *arena, unsigned nticks)\n{\n\tticker_t *decay_ticker;\n\n\tif (unlikely(tsd == NULL))\n\t\treturn;\n\tdecay_ticker = decay_ticker_get(tsd, arena->ind);\n\tif (unlikely(decay_ticker == NULL))\n\t\treturn;\n\tif (unlikely(ticker_ticks(decay_ticker, nticks)))\n\t\tarena_purge(arena, false);\n}\n\nJEMALLOC_ALWAYS_INLINE void\narena_decay_tick(tsd_t *tsd, arena_t *arena)\n{\n\n\tarena_decay_ticks(tsd, arena, 1);\n}\n\nJEMALLOC_ALWAYS_INLINE void *\narena_malloc(tsd_t *tsd, arena_t *arena, size_t size, szind_t ind, bool zero,\n    tcache_t *tcache, bool slow_path)\n{\n\n\tassert(size != 0);\n\n\tif (likely(tcache != NULL)) {\n\t\tif (likely(size <= SMALL_MAXCLASS)) {\n\t\t\treturn (tcache_alloc_small(tsd, arena, tcache, size,\n\t\t\t    ind, zero, slow_path));\n\t\t}\n\t\tif (likely(size <= tcache_maxclass)) {\n\t\t\treturn (tcache_alloc_large(tsd, arena, tcache, size,\n\t\t\t    ind, zero, slow_path));\n\t\t}\n\t\t/* (size > tcache_maxclass) case falls through. */\n\t\tassert(size > tcache_maxclass);\n\t}\n\n\treturn (arena_malloc_hard(tsd, arena, size, ind, zero, tcache));\n}\n\nJEMALLOC_ALWAYS_INLINE arena_t *\narena_aalloc(const void *ptr)\n{\n\tarena_chunk_t *chunk;\n\n\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);\n\tif (likely(chunk != ptr))\n\t\treturn (extent_node_arena_get(&chunk->node));\n\telse\n\t\treturn (huge_aalloc(ptr));\n}\n\n/* Return the size of the allocation pointed to by ptr. */\nJEMALLOC_ALWAYS_INLINE size_t\narena_salloc(const void *ptr, bool demote)\n{\n\tsize_t ret;\n\tarena_chunk_t *chunk;\n\tsize_t pageind;\n\tszind_t binind;\n\n\tassert(ptr != NULL);\n\n\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);\n\tif (likely(chunk != ptr)) {\n\t\tpageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;\n\t\tassert(arena_mapbits_allocated_get(chunk, pageind) != 0);\n\t\tbinind = arena_mapbits_binind_get(chunk, pageind);\n\t\tif (unlikely(binind == BININD_INVALID || (config_prof && !demote\n\t\t    && arena_mapbits_large_get(chunk, pageind) != 0))) {\n\t\t\t/*\n\t\t\t * Large allocation.  In the common case (demote), and\n\t\t\t * as this is an inline function, most callers will only\n\t\t\t * end up looking at binind to determine that ptr is a\n\t\t\t * small allocation.\n\t\t\t */\n\t\t\tassert(config_cache_oblivious || ((uintptr_t)ptr &\n\t\t\t    PAGE_MASK) == 0);\n\t\t\tret = arena_mapbits_large_size_get(chunk, pageind) -\n\t\t\t    large_pad;\n\t\t\tassert(ret != 0);\n\t\t\tassert(pageind + ((ret+large_pad)>>LG_PAGE) <=\n\t\t\t    chunk_npages);\n\t\t\tassert(arena_mapbits_dirty_get(chunk, pageind) ==\n\t\t\t    arena_mapbits_dirty_get(chunk,\n\t\t\t    pageind+((ret+large_pad)>>LG_PAGE)-1));\n\t\t} else {\n\t\t\t/*\n\t\t\t * Small allocation (possibly promoted to a large\n\t\t\t * object).\n\t\t\t */\n\t\t\tassert(arena_mapbits_large_get(chunk, pageind) != 0 ||\n\t\t\t    arena_ptr_small_binind_get(ptr,\n\t\t\t    arena_mapbits_get(chunk, pageind)) == binind);\n\t\t\tret = index2size(binind);\n\t\t}\n\t} else\n\t\tret = huge_salloc(ptr);\n\n\treturn (ret);\n}\n\nJEMALLOC_ALWAYS_INLINE void\narena_dalloc(tsd_t *tsd, void *ptr, tcache_t *tcache, bool slow_path)\n{\n\tarena_chunk_t *chunk;\n\tsize_t pageind, mapbits;\n\n\tassert(ptr != NULL);\n\n\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);\n\tif (likely(chunk != ptr)) {\n\t\tpageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;\n\t\tmapbits = arena_mapbits_get(chunk, pageind);\n\t\tassert(arena_mapbits_allocated_get(chunk, pageind) != 0);\n\t\tif (likely((mapbits & CHUNK_MAP_LARGE) == 0)) {\n\t\t\t/* Small allocation. */\n\t\t\tif (likely(tcache != NULL)) {\n\t\t\t\tszind_t binind = arena_ptr_small_binind_get(ptr,\n\t\t\t\t    mapbits);\n\t\t\t\ttcache_dalloc_small(tsd, tcache, ptr, binind,\n\t\t\t\t    slow_path);\n\t\t\t} else {\n\t\t\t\tarena_dalloc_small(tsd, extent_node_arena_get(\n\t\t\t\t    &chunk->node), chunk, ptr, pageind);\n\t\t\t}\n\t\t} else {\n\t\t\tsize_t size = arena_mapbits_large_size_get(chunk,\n\t\t\t    pageind);\n\n\t\t\tassert(config_cache_oblivious || ((uintptr_t)ptr &\n\t\t\t    PAGE_MASK) == 0);\n\n\t\t\tif (likely(tcache != NULL) && size - large_pad <=\n\t\t\t    tcache_maxclass) {\n\t\t\t\ttcache_dalloc_large(tsd, tcache, ptr, size -\n\t\t\t\t    large_pad, slow_path);\n\t\t\t} else {\n\t\t\t\tarena_dalloc_large(tsd, extent_node_arena_get(\n\t\t\t\t    &chunk->node), chunk, ptr);\n\t\t\t}\n\t\t}\n\t} else\n\t\thuge_dalloc(tsd, ptr, tcache);\n}\n\nJEMALLOC_ALWAYS_INLINE void\narena_sdalloc(tsd_t *tsd, void *ptr, size_t size, tcache_t *tcache)\n{\n\tarena_chunk_t *chunk;\n\n\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);\n\tif (likely(chunk != ptr)) {\n\t\tif (config_prof && opt_prof) {\n\t\t\tsize_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >>\n\t\t\t    LG_PAGE;\n\t\t\tassert(arena_mapbits_allocated_get(chunk, pageind) !=\n\t\t\t    0);\n\t\t\tif (arena_mapbits_large_get(chunk, pageind) != 0) {\n\t\t\t\t/*\n\t\t\t\t * Make sure to use promoted size, not request\n\t\t\t\t * size.\n\t\t\t\t */\n\t\t\t\tsize = arena_mapbits_large_size_get(chunk,\n\t\t\t\t    pageind) - large_pad;\n\t\t\t}\n\t\t}\n\t\tassert(s2u(size) == s2u(arena_salloc(ptr, false)));\n\n\t\tif (likely(size <= SMALL_MAXCLASS)) {\n\t\t\t/* Small allocation. */\n\t\t\tif (likely(tcache != NULL)) {\n\t\t\t\tszind_t binind = size2index(size);\n\t\t\t\ttcache_dalloc_small(tsd, tcache, ptr, binind,\n\t\t\t\t    true);\n\t\t\t} else {\n\t\t\t\tsize_t pageind = ((uintptr_t)ptr -\n\t\t\t\t    (uintptr_t)chunk) >> LG_PAGE;\n\t\t\t\tarena_dalloc_small(tsd, extent_node_arena_get(\n\t\t\t\t    &chunk->node), chunk, ptr, pageind);\n\t\t\t}\n\t\t} else {\n\t\t\tassert(config_cache_oblivious || ((uintptr_t)ptr &\n\t\t\t    PAGE_MASK) == 0);\n\n\t\t\tif (likely(tcache != NULL) && size <= tcache_maxclass) {\n\t\t\t\ttcache_dalloc_large(tsd, tcache, ptr, size,\n\t\t\t\t    true);\n\t\t\t} else {\n\t\t\t\tarena_dalloc_large(tsd, extent_node_arena_get(\n\t\t\t\t    &chunk->node), chunk, ptr);\n\t\t\t}\n\t\t}\n\t} else\n\t\thuge_dalloc(tsd, ptr, tcache);\n}\n#  endif /* JEMALLOC_ARENA_INLINE_B */\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/assert.h",
    "content": "/*\n * Define a custom assert() in order to reduce the chances of deadlock during\n * assertion failure.\n */\n#ifndef assert\n#define\tassert(e) do {\t\t\t\t\t\t\t\\\n\tif (unlikely(config_debug && !(e))) {\t\t\t\t\\\n\t\tmalloc_printf(\t\t\t\t\t\t\\\n\t\t    \"<jemalloc>: %s:%d: Failed assertion: \\\"%s\\\"\\n\",\t\\\n\t\t    __FILE__, __LINE__, #e);\t\t\t\t\\\n\t\tabort();\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n#endif\n\n#ifndef not_reached\n#define\tnot_reached() do {\t\t\t\t\t\t\\\n\tif (config_debug) {\t\t\t\t\t\t\\\n\t\tmalloc_printf(\t\t\t\t\t\t\\\n\t\t    \"<jemalloc>: %s:%d: Unreachable code reached\\n\",\t\\\n\t\t    __FILE__, __LINE__);\t\t\t\t\\\n\t\tabort();\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tunreachable();\t\t\t\t\t\t\t\\\n} while (0)\n#endif\n\n#ifndef not_implemented\n#define\tnot_implemented() do {\t\t\t\t\t\t\\\n\tif (config_debug) {\t\t\t\t\t\t\\\n\t\tmalloc_printf(\"<jemalloc>: %s:%d: Not implemented\\n\",\t\\\n\t\t    __FILE__, __LINE__);\t\t\t\t\\\n\t\tabort();\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n#endif\n\n#ifndef assert_not_implemented\n#define\tassert_not_implemented(e) do {\t\t\t\t\t\\\n\tif (unlikely(config_debug && !(e)))\t\t\t\t\\\n\t\tnot_implemented();\t\t\t\t\t\\\n} while (0)\n#endif\n\n\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/atomic.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\n#define\tatomic_read_uint64(p)\tatomic_add_uint64(p, 0)\n#define\tatomic_read_uint32(p)\tatomic_add_uint32(p, 0)\n#define\tatomic_read_p(p)\tatomic_add_p(p, NULL)\n#define\tatomic_read_z(p)\tatomic_add_z(p, 0)\n#define\tatomic_read_u(p)\tatomic_add_u(p, 0)\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n/*\n * All arithmetic functions return the arithmetic result of the atomic\n * operation.  Some atomic operation APIs return the value prior to mutation, in\n * which case the following functions must redundantly compute the result so\n * that it can be returned.  These functions are normally inlined, so the extra\n * operations can be optimized away if the return values aren't used by the\n * callers.\n *\n *   <t> atomic_read_<t>(<t> *p) { return (*p); }\n *   <t> atomic_add_<t>(<t> *p, <t> x) { return (*p += x); }\n *   <t> atomic_sub_<t>(<t> *p, <t> x) { return (*p -= x); }\n *   bool atomic_cas_<t>(<t> *p, <t> c, <t> s)\n *   {\n *     if (*p != c)\n *       return (true);\n *     *p = s;\n *     return (false);\n *   }\n *   void atomic_write_<t>(<t> *p, <t> x) { *p = x; }\n */\n\n#ifndef JEMALLOC_ENABLE_INLINE\nuint64_t\tatomic_add_uint64(uint64_t *p, uint64_t x);\nuint64_t\tatomic_sub_uint64(uint64_t *p, uint64_t x);\nbool\tatomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s);\nvoid\tatomic_write_uint64(uint64_t *p, uint64_t x);\nuint32_t\tatomic_add_uint32(uint32_t *p, uint32_t x);\nuint32_t\tatomic_sub_uint32(uint32_t *p, uint32_t x);\nbool\tatomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s);\nvoid\tatomic_write_uint32(uint32_t *p, uint32_t x);\nvoid\t*atomic_add_p(void **p, void *x);\nvoid\t*atomic_sub_p(void **p, void *x);\nbool\tatomic_cas_p(void **p, void *c, void *s);\nvoid\tatomic_write_p(void **p, const void *x);\nsize_t\tatomic_add_z(size_t *p, size_t x);\nsize_t\tatomic_sub_z(size_t *p, size_t x);\nbool\tatomic_cas_z(size_t *p, size_t c, size_t s);\nvoid\tatomic_write_z(size_t *p, size_t x);\nunsigned\tatomic_add_u(unsigned *p, unsigned x);\nunsigned\tatomic_sub_u(unsigned *p, unsigned x);\nbool\tatomic_cas_u(unsigned *p, unsigned c, unsigned s);\nvoid\tatomic_write_u(unsigned *p, unsigned x);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_ATOMIC_C_))\n/******************************************************************************/\n/* 64-bit operations. */\n#if (LG_SIZEOF_PTR == 3 || LG_SIZEOF_INT == 3)\n#  if (defined(__amd64__) || defined(__x86_64__))\nJEMALLOC_INLINE uint64_t\natomic_add_uint64(uint64_t *p, uint64_t x)\n{\n\tuint64_t t = x;\n\n\tasm volatile (\n\t    \"lock; xaddq %0, %1;\"\n\t    : \"+r\" (t), \"=m\" (*p) /* Outputs. */\n\t    : \"m\" (*p) /* Inputs. */\n\t    );\n\n\treturn (t + x);\n}\n\nJEMALLOC_INLINE uint64_t\natomic_sub_uint64(uint64_t *p, uint64_t x)\n{\n\tuint64_t t;\n\n\tx = (uint64_t)(-(int64_t)x);\n\tt = x;\n\tasm volatile (\n\t    \"lock; xaddq %0, %1;\"\n\t    : \"+r\" (t), \"=m\" (*p) /* Outputs. */\n\t    : \"m\" (*p) /* Inputs. */\n\t    );\n\n\treturn (t + x);\n}\n\nJEMALLOC_INLINE bool\natomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s)\n{\n\tuint8_t success;\n\n\tasm volatile (\n\t    \"lock; cmpxchgq %4, %0;\"\n\t    \"sete %1;\"\n\t    : \"=m\" (*p), \"=a\" (success) /* Outputs. */\n\t    : \"m\" (*p), \"a\" (c), \"r\" (s) /* Inputs. */\n\t    : \"memory\" /* Clobbers. */\n\t    );\n\n\treturn (!(bool)success);\n}\n\nJEMALLOC_INLINE void\natomic_write_uint64(uint64_t *p, uint64_t x)\n{\n\n\tasm volatile (\n\t    \"xchgq %1, %0;\" /* Lock is implied by xchgq. */\n\t    : \"=m\" (*p), \"+r\" (x) /* Outputs. */\n\t    : \"m\" (*p) /* Inputs. */\n\t    : \"memory\" /* Clobbers. */\n\t    );\n}\n#  elif (defined(JEMALLOC_C11ATOMICS))\nJEMALLOC_INLINE uint64_t\natomic_add_uint64(uint64_t *p, uint64_t x)\n{\n\tvolatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p;\n\treturn (atomic_fetch_add(a, x) + x);\n}\n\nJEMALLOC_INLINE uint64_t\natomic_sub_uint64(uint64_t *p, uint64_t x)\n{\n\tvolatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p;\n\treturn (atomic_fetch_sub(a, x) - x);\n}\n\nJEMALLOC_INLINE bool\natomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s)\n{\n\tvolatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p;\n\treturn (!atomic_compare_exchange_strong(a, &c, s));\n}\n\nJEMALLOC_INLINE void\natomic_write_uint64(uint64_t *p, uint64_t x)\n{\n\tvolatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p;\n\tatomic_store(a, x);\n}\n#  elif (defined(JEMALLOC_ATOMIC9))\nJEMALLOC_INLINE uint64_t\natomic_add_uint64(uint64_t *p, uint64_t x)\n{\n\n\t/*\n\t * atomic_fetchadd_64() doesn't exist, but we only ever use this\n\t * function on LP64 systems, so atomic_fetchadd_long() will do.\n\t */\n\tassert(sizeof(uint64_t) == sizeof(unsigned long));\n\n\treturn (atomic_fetchadd_long(p, (unsigned long)x) + x);\n}\n\nJEMALLOC_INLINE uint64_t\natomic_sub_uint64(uint64_t *p, uint64_t x)\n{\n\n\tassert(sizeof(uint64_t) == sizeof(unsigned long));\n\n\treturn (atomic_fetchadd_long(p, (unsigned long)(-(long)x)) - x);\n}\n\nJEMALLOC_INLINE bool\natomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s)\n{\n\n\tassert(sizeof(uint64_t) == sizeof(unsigned long));\n\n\treturn (!atomic_cmpset_long(p, (unsigned long)c, (unsigned long)s));\n}\n\nJEMALLOC_INLINE void\natomic_write_uint64(uint64_t *p, uint64_t x)\n{\n\n\tassert(sizeof(uint64_t) == sizeof(unsigned long));\n\n\tatomic_store_rel_long(p, x);\n}\n#  elif (defined(JEMALLOC_OSATOMIC))\nJEMALLOC_INLINE uint64_t\natomic_add_uint64(uint64_t *p, uint64_t x)\n{\n\n\treturn (OSAtomicAdd64((int64_t)x, (int64_t *)p));\n}\n\nJEMALLOC_INLINE uint64_t\natomic_sub_uint64(uint64_t *p, uint64_t x)\n{\n\n\treturn (OSAtomicAdd64(-((int64_t)x), (int64_t *)p));\n}\n\nJEMALLOC_INLINE bool\natomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s)\n{\n\n\treturn (!OSAtomicCompareAndSwap64(c, s, (int64_t *)p));\n}\n\nJEMALLOC_INLINE void\natomic_write_uint64(uint64_t *p, uint64_t x)\n{\n\tuint64_t o;\n\n\t/*The documented OSAtomic*() API does not expose an atomic exchange. */\n\tdo {\n\t\to = atomic_read_uint64(p);\n\t} while (atomic_cas_uint64(p, o, x));\n}\n#  elif (defined(_MSC_VER))\nJEMALLOC_INLINE uint64_t\natomic_add_uint64(uint64_t *p, uint64_t x)\n{\n\n\treturn (InterlockedExchangeAdd64(p, x) + x);\n}\n\nJEMALLOC_INLINE uint64_t\natomic_sub_uint64(uint64_t *p, uint64_t x)\n{\n\n\treturn (InterlockedExchangeAdd64(p, -((int64_t)x)) - x);\n}\n\nJEMALLOC_INLINE bool\natomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s)\n{\n\tuint64_t o;\n\n\to = InterlockedCompareExchange64(p, s, c);\n\treturn (o != c);\n}\n\nJEMALLOC_INLINE void\natomic_write_uint64(uint64_t *p, uint64_t x)\n{\n\n\tInterlockedExchange64(p, x);\n}\n#  elif (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) || \\\n    defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_8))\nJEMALLOC_INLINE uint64_t\natomic_add_uint64(uint64_t *p, uint64_t x)\n{\n\n\treturn (__sync_add_and_fetch(p, x));\n}\n\nJEMALLOC_INLINE uint64_t\natomic_sub_uint64(uint64_t *p, uint64_t x)\n{\n\n\treturn (__sync_sub_and_fetch(p, x));\n}\n\nJEMALLOC_INLINE bool\natomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s)\n{\n\n\treturn (!__sync_bool_compare_and_swap(p, c, s));\n}\n\nJEMALLOC_INLINE void\natomic_write_uint64(uint64_t *p, uint64_t x)\n{\n\n\t__sync_lock_test_and_set(p, x);\n}\n#  else\n#    error \"Missing implementation for 64-bit atomic operations\"\n#  endif\n#endif\n\n/******************************************************************************/\n/* 32-bit operations. */\n#if (defined(__i386__) || defined(__amd64__) || defined(__x86_64__))\nJEMALLOC_INLINE uint32_t\natomic_add_uint32(uint32_t *p, uint32_t x)\n{\n\tuint32_t t = x;\n\n\tasm volatile (\n\t    \"lock; xaddl %0, %1;\"\n\t    : \"+r\" (t), \"=m\" (*p) /* Outputs. */\n\t    : \"m\" (*p) /* Inputs. */\n\t    );\n\n\treturn (t + x);\n}\n\nJEMALLOC_INLINE uint32_t\natomic_sub_uint32(uint32_t *p, uint32_t x)\n{\n\tuint32_t t;\n\n\tx = (uint32_t)(-(int32_t)x);\n\tt = x;\n\tasm volatile (\n\t    \"lock; xaddl %0, %1;\"\n\t    : \"+r\" (t), \"=m\" (*p) /* Outputs. */\n\t    : \"m\" (*p) /* Inputs. */\n\t    );\n\n\treturn (t + x);\n}\n\nJEMALLOC_INLINE bool\natomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s)\n{\n\tuint8_t success;\n\n\tasm volatile (\n\t    \"lock; cmpxchgl %4, %0;\"\n\t    \"sete %1;\"\n\t    : \"=m\" (*p), \"=a\" (success) /* Outputs. */\n\t    : \"m\" (*p), \"a\" (c), \"r\" (s) /* Inputs. */\n\t    : \"memory\"\n\t    );\n\n\treturn (!(bool)success);\n}\n\nJEMALLOC_INLINE void\natomic_write_uint32(uint32_t *p, uint32_t x)\n{\n\n\tasm volatile (\n\t    \"xchgl %1, %0;\" /* Lock is implied by xchgl. */\n\t    : \"=m\" (*p), \"+r\" (x) /* Outputs. */\n\t    : \"m\" (*p) /* Inputs. */\n\t    : \"memory\" /* Clobbers. */\n\t    );\n}\n#  elif (defined(JEMALLOC_C11ATOMICS))\nJEMALLOC_INLINE uint32_t\natomic_add_uint32(uint32_t *p, uint32_t x)\n{\n\tvolatile atomic_uint_least32_t *a = (volatile atomic_uint_least32_t *)p;\n\treturn (atomic_fetch_add(a, x) + x);\n}\n\nJEMALLOC_INLINE uint32_t\natomic_sub_uint32(uint32_t *p, uint32_t x)\n{\n\tvolatile atomic_uint_least32_t *a = (volatile atomic_uint_least32_t *)p;\n\treturn (atomic_fetch_sub(a, x) - x);\n}\n\nJEMALLOC_INLINE bool\natomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s)\n{\n\tvolatile atomic_uint_least32_t *a = (volatile atomic_uint_least32_t *)p;\n\treturn (!atomic_compare_exchange_strong(a, &c, s));\n}\n\nJEMALLOC_INLINE void\natomic_write_uint32(uint32_t *p, uint32_t x)\n{\n\tvolatile atomic_uint_least32_t *a = (volatile atomic_uint_least32_t *)p;\n\tatomic_store(a, x);\n}\n#elif (defined(JEMALLOC_ATOMIC9))\nJEMALLOC_INLINE uint32_t\natomic_add_uint32(uint32_t *p, uint32_t x)\n{\n\n\treturn (atomic_fetchadd_32(p, x) + x);\n}\n\nJEMALLOC_INLINE uint32_t\natomic_sub_uint32(uint32_t *p, uint32_t x)\n{\n\n\treturn (atomic_fetchadd_32(p, (uint32_t)(-(int32_t)x)) - x);\n}\n\nJEMALLOC_INLINE bool\natomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s)\n{\n\n\treturn (!atomic_cmpset_32(p, c, s));\n}\n\nJEMALLOC_INLINE void\natomic_write_uint32(uint32_t *p, uint32_t x)\n{\n\n\tatomic_store_rel_32(p, x);\n}\n#elif (defined(JEMALLOC_OSATOMIC))\nJEMALLOC_INLINE uint32_t\natomic_add_uint32(uint32_t *p, uint32_t x)\n{\n\n\treturn (OSAtomicAdd32((int32_t)x, (int32_t *)p));\n}\n\nJEMALLOC_INLINE uint32_t\natomic_sub_uint32(uint32_t *p, uint32_t x)\n{\n\n\treturn (OSAtomicAdd32(-((int32_t)x), (int32_t *)p));\n}\n\nJEMALLOC_INLINE bool\natomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s)\n{\n\n\treturn (!OSAtomicCompareAndSwap32(c, s, (int32_t *)p));\n}\n\nJEMALLOC_INLINE void\natomic_write_uint32(uint32_t *p, uint32_t x)\n{\n\tuint32_t o;\n\n\t/*The documented OSAtomic*() API does not expose an atomic exchange. */\n\tdo {\n\t\to = atomic_read_uint32(p);\n\t} while (atomic_cas_uint32(p, o, x));\n}\n#elif (defined(_MSC_VER))\nJEMALLOC_INLINE uint32_t\natomic_add_uint32(uint32_t *p, uint32_t x)\n{\n\n\treturn (InterlockedExchangeAdd(p, x) + x);\n}\n\nJEMALLOC_INLINE uint32_t\natomic_sub_uint32(uint32_t *p, uint32_t x)\n{\n\n\treturn (InterlockedExchangeAdd(p, -((int32_t)x)) - x);\n}\n\nJEMALLOC_INLINE bool\natomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s)\n{\n\tuint32_t o;\n\n\to = InterlockedCompareExchange(p, s, c);\n\treturn (o != c);\n}\n\nJEMALLOC_INLINE void\natomic_write_uint32(uint32_t *p, uint32_t x)\n{\n\n\tInterlockedExchange(p, x);\n}\n#elif (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || \\\n defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_4))\nJEMALLOC_INLINE uint32_t\natomic_add_uint32(uint32_t *p, uint32_t x)\n{\n\n\treturn (__sync_add_and_fetch(p, x));\n}\n\nJEMALLOC_INLINE uint32_t\natomic_sub_uint32(uint32_t *p, uint32_t x)\n{\n\n\treturn (__sync_sub_and_fetch(p, x));\n}\n\nJEMALLOC_INLINE bool\natomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s)\n{\n\n\treturn (!__sync_bool_compare_and_swap(p, c, s));\n}\n\nJEMALLOC_INLINE void\natomic_write_uint32(uint32_t *p, uint32_t x)\n{\n\n\t__sync_lock_test_and_set(p, x);\n}\n#else\n#  error \"Missing implementation for 32-bit atomic operations\"\n#endif\n\n/******************************************************************************/\n/* Pointer operations. */\nJEMALLOC_INLINE void *\natomic_add_p(void **p, void *x)\n{\n\n#if (LG_SIZEOF_PTR == 3)\n\treturn ((void *)atomic_add_uint64((uint64_t *)p, (uint64_t)x));\n#elif (LG_SIZEOF_PTR == 2)\n\treturn ((void *)atomic_add_uint32((uint32_t *)p, (uint32_t)x));\n#endif\n}\n\nJEMALLOC_INLINE void *\natomic_sub_p(void **p, void *x)\n{\n\n#if (LG_SIZEOF_PTR == 3)\n\treturn ((void *)atomic_add_uint64((uint64_t *)p,\n\t    (uint64_t)-((int64_t)x)));\n#elif (LG_SIZEOF_PTR == 2)\n\treturn ((void *)atomic_add_uint32((uint32_t *)p,\n\t    (uint32_t)-((int32_t)x)));\n#endif\n}\n\nJEMALLOC_INLINE bool\natomic_cas_p(void **p, void *c, void *s)\n{\n\n#if (LG_SIZEOF_PTR == 3)\n\treturn (atomic_cas_uint64((uint64_t *)p, (uint64_t)c, (uint64_t)s));\n#elif (LG_SIZEOF_PTR == 2)\n\treturn (atomic_cas_uint32((uint32_t *)p, (uint32_t)c, (uint32_t)s));\n#endif\n}\n\nJEMALLOC_INLINE void\natomic_write_p(void **p, const void *x)\n{\n\n#if (LG_SIZEOF_PTR == 3)\n\tatomic_write_uint64((uint64_t *)p, (uint64_t)x);\n#elif (LG_SIZEOF_PTR == 2)\n\tatomic_write_uint32((uint32_t *)p, (uint32_t)x);\n#endif\n}\n\n/******************************************************************************/\n/* size_t operations. */\nJEMALLOC_INLINE size_t\natomic_add_z(size_t *p, size_t x)\n{\n\n#if (LG_SIZEOF_PTR == 3)\n\treturn ((size_t)atomic_add_uint64((uint64_t *)p, (uint64_t)x));\n#elif (LG_SIZEOF_PTR == 2)\n\treturn ((size_t)atomic_add_uint32((uint32_t *)p, (uint32_t)x));\n#endif\n}\n\nJEMALLOC_INLINE size_t\natomic_sub_z(size_t *p, size_t x)\n{\n\n#if (LG_SIZEOF_PTR == 3)\n\treturn ((size_t)atomic_add_uint64((uint64_t *)p,\n\t    (uint64_t)-((int64_t)x)));\n#elif (LG_SIZEOF_PTR == 2)\n\treturn ((size_t)atomic_add_uint32((uint32_t *)p,\n\t    (uint32_t)-((int32_t)x)));\n#endif\n}\n\nJEMALLOC_INLINE bool\natomic_cas_z(size_t *p, size_t c, size_t s)\n{\n\n#if (LG_SIZEOF_PTR == 3)\n\treturn (atomic_cas_uint64((uint64_t *)p, (uint64_t)c, (uint64_t)s));\n#elif (LG_SIZEOF_PTR == 2)\n\treturn (atomic_cas_uint32((uint32_t *)p, (uint32_t)c, (uint32_t)s));\n#endif\n}\n\nJEMALLOC_INLINE void\natomic_write_z(size_t *p, size_t x)\n{\n\n#if (LG_SIZEOF_PTR == 3)\n\tatomic_write_uint64((uint64_t *)p, (uint64_t)x);\n#elif (LG_SIZEOF_PTR == 2)\n\tatomic_write_uint32((uint32_t *)p, (uint32_t)x);\n#endif\n}\n\n/******************************************************************************/\n/* unsigned operations. */\nJEMALLOC_INLINE unsigned\natomic_add_u(unsigned *p, unsigned x)\n{\n\n#if (LG_SIZEOF_INT == 3)\n\treturn ((unsigned)atomic_add_uint64((uint64_t *)p, (uint64_t)x));\n#elif (LG_SIZEOF_INT == 2)\n\treturn ((unsigned)atomic_add_uint32((uint32_t *)p, (uint32_t)x));\n#endif\n}\n\nJEMALLOC_INLINE unsigned\natomic_sub_u(unsigned *p, unsigned x)\n{\n\n#if (LG_SIZEOF_INT == 3)\n\treturn ((unsigned)atomic_add_uint64((uint64_t *)p,\n\t    (uint64_t)-((int64_t)x)));\n#elif (LG_SIZEOF_INT == 2)\n\treturn ((unsigned)atomic_add_uint32((uint32_t *)p,\n\t    (uint32_t)-((int32_t)x)));\n#endif\n}\n\nJEMALLOC_INLINE bool\natomic_cas_u(unsigned *p, unsigned c, unsigned s)\n{\n\n#if (LG_SIZEOF_INT == 3)\n\treturn (atomic_cas_uint64((uint64_t *)p, (uint64_t)c, (uint64_t)s));\n#elif (LG_SIZEOF_INT == 2)\n\treturn (atomic_cas_uint32((uint32_t *)p, (uint32_t)c, (uint32_t)s));\n#endif\n}\n\nJEMALLOC_INLINE void\natomic_write_u(unsigned *p, unsigned x)\n{\n\n#if (LG_SIZEOF_INT == 3)\n\tatomic_write_uint64((uint64_t *)p, (uint64_t)x);\n#elif (LG_SIZEOF_INT == 2)\n\tatomic_write_uint32((uint32_t *)p, (uint32_t)x);\n#endif\n}\n\n/******************************************************************************/\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/base.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nvoid\t*base_alloc(size_t size);\nvoid\tbase_stats_get(size_t *allocated, size_t *resident, size_t *mapped);\nbool\tbase_boot(void);\nvoid\tbase_prefork(void);\nvoid\tbase_postfork_parent(void);\nvoid\tbase_postfork_child(void);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/bitmap.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n/* Maximum bitmap bit count is 2^LG_BITMAP_MAXBITS. */\n#define\tLG_BITMAP_MAXBITS\tLG_RUN_MAXREGS\n#define\tBITMAP_MAXBITS\t\t(ZU(1) << LG_BITMAP_MAXBITS)\n\ntypedef struct bitmap_level_s bitmap_level_t;\ntypedef struct bitmap_info_s bitmap_info_t;\ntypedef unsigned long bitmap_t;\n#define\tLG_SIZEOF_BITMAP\tLG_SIZEOF_LONG\n\n/* Number of bits per group. */\n#define\tLG_BITMAP_GROUP_NBITS\t\t(LG_SIZEOF_BITMAP + 3)\n#define\tBITMAP_GROUP_NBITS\t\t(ZU(1) << LG_BITMAP_GROUP_NBITS)\n#define\tBITMAP_GROUP_NBITS_MASK\t\t(BITMAP_GROUP_NBITS-1)\n\n/*\n * Do some analysis on how big the bitmap is before we use a tree.  For a brute\n * force linear search, if we would have to call ffsl more than 2^3 times, use a\n * tree instead.\n */\n#if LG_BITMAP_MAXBITS - LG_BITMAP_GROUP_NBITS > 3\n#  define USE_TREE\n#endif\n\n/* Number of groups required to store a given number of bits. */\n#define\tBITMAP_BITS2GROUPS(nbits)\t\t\t\t\t\\\n    ((nbits + BITMAP_GROUP_NBITS_MASK) >> LG_BITMAP_GROUP_NBITS)\n\n/*\n * Number of groups required at a particular level for a given number of bits.\n */\n#define\tBITMAP_GROUPS_L0(nbits)\t\t\t\t\t\t\\\n    BITMAP_BITS2GROUPS(nbits)\n#define\tBITMAP_GROUPS_L1(nbits)\t\t\t\t\t\t\\\n    BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(nbits))\n#define\tBITMAP_GROUPS_L2(nbits)\t\t\t\t\t\t\\\n    BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS((nbits))))\n#define\tBITMAP_GROUPS_L3(nbits)\t\t\t\t\t\t\\\n    BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(\t\t\\\n\tBITMAP_BITS2GROUPS((nbits)))))\n\n/*\n * Assuming the number of levels, number of groups required for a given number\n * of bits.\n */\n#define\tBITMAP_GROUPS_1_LEVEL(nbits)\t\t\t\t\t\\\n    BITMAP_GROUPS_L0(nbits)\n#define\tBITMAP_GROUPS_2_LEVEL(nbits)\t\t\t\t\t\\\n    (BITMAP_GROUPS_1_LEVEL(nbits) + BITMAP_GROUPS_L1(nbits))\n#define\tBITMAP_GROUPS_3_LEVEL(nbits)\t\t\t\t\t\\\n    (BITMAP_GROUPS_2_LEVEL(nbits) + BITMAP_GROUPS_L2(nbits))\n#define\tBITMAP_GROUPS_4_LEVEL(nbits)\t\t\t\t\t\\\n    (BITMAP_GROUPS_3_LEVEL(nbits) + BITMAP_GROUPS_L3(nbits))\n\n/*\n * Maximum number of groups required to support LG_BITMAP_MAXBITS.\n */\n#ifdef USE_TREE\n\n#if LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS\n#  define BITMAP_GROUPS_MAX\tBITMAP_GROUPS_1_LEVEL(BITMAP_MAXBITS)\n#elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 2\n#  define BITMAP_GROUPS_MAX\tBITMAP_GROUPS_2_LEVEL(BITMAP_MAXBITS)\n#elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 3\n#  define BITMAP_GROUPS_MAX\tBITMAP_GROUPS_3_LEVEL(BITMAP_MAXBITS)\n#elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 4\n#  define BITMAP_GROUPS_MAX\tBITMAP_GROUPS_4_LEVEL(BITMAP_MAXBITS)\n#else\n#  error \"Unsupported bitmap size\"\n#endif\n\n/* Maximum number of levels possible. */\n#define\tBITMAP_MAX_LEVELS\t\t\t\t\t\t\\\n    (LG_BITMAP_MAXBITS / LG_SIZEOF_BITMAP)\t\t\t\t\\\n    + !!(LG_BITMAP_MAXBITS % LG_SIZEOF_BITMAP)\n\n#else /* USE_TREE */\n\n#define\tBITMAP_GROUPS_MAX BITMAP_BITS2GROUPS(BITMAP_MAXBITS)\n\n#endif /* USE_TREE */\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\nstruct bitmap_level_s {\n\t/* Offset of this level's groups within the array of groups. */\n\tsize_t group_offset;\n};\n\nstruct bitmap_info_s {\n\t/* Logical number of bits in bitmap (stored at bottom level). */\n\tsize_t nbits;\n\n#ifdef USE_TREE\n\t/* Number of levels necessary for nbits. */\n\tunsigned nlevels;\n\n\t/*\n\t * Only the first (nlevels+1) elements are used, and levels are ordered\n\t * bottom to top (e.g. the bottom level is stored in levels[0]).\n\t */\n\tbitmap_level_t levels[BITMAP_MAX_LEVELS+1];\n#else /* USE_TREE */\n\t/* Number of groups necessary for nbits. */\n\tsize_t ngroups;\n#endif /* USE_TREE */\n};\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nvoid\tbitmap_info_init(bitmap_info_t *binfo, size_t nbits);\nvoid\tbitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo);\nsize_t\tbitmap_size(const bitmap_info_t *binfo);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#ifndef JEMALLOC_ENABLE_INLINE\nbool\tbitmap_full(bitmap_t *bitmap, const bitmap_info_t *binfo);\nbool\tbitmap_get(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit);\nvoid\tbitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit);\nsize_t\tbitmap_sfu(bitmap_t *bitmap, const bitmap_info_t *binfo);\nvoid\tbitmap_unset(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_BITMAP_C_))\nJEMALLOC_INLINE bool\nbitmap_full(bitmap_t *bitmap, const bitmap_info_t *binfo)\n{\n#ifdef USE_TREE\n\tsize_t rgoff = binfo->levels[binfo->nlevels].group_offset - 1;\n\tbitmap_t rg = bitmap[rgoff];\n\t/* The bitmap is full iff the root group is 0. */\n\treturn (rg == 0);\n#else\n\tsize_t i;\n\n\tfor (i = 0; i < binfo->ngroups; i++) {\n\t\tif (bitmap[i] != 0)\n\t\t\treturn (false);\n\t}\n\treturn (true);\n#endif\n}\n\nJEMALLOC_INLINE bool\nbitmap_get(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit)\n{\n\tsize_t goff;\n\tbitmap_t g;\n\n\tassert(bit < binfo->nbits);\n\tgoff = bit >> LG_BITMAP_GROUP_NBITS;\n\tg = bitmap[goff];\n\treturn (!(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK))));\n}\n\nJEMALLOC_INLINE void\nbitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit)\n{\n\tsize_t goff;\n\tbitmap_t *gp;\n\tbitmap_t g;\n\n\tassert(bit < binfo->nbits);\n\tassert(!bitmap_get(bitmap, binfo, bit));\n\tgoff = bit >> LG_BITMAP_GROUP_NBITS;\n\tgp = &bitmap[goff];\n\tg = *gp;\n\tassert(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK)));\n\tg ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK);\n\t*gp = g;\n\tassert(bitmap_get(bitmap, binfo, bit));\n#ifdef USE_TREE\n\t/* Propagate group state transitions up the tree. */\n\tif (g == 0) {\n\t\tunsigned i;\n\t\tfor (i = 1; i < binfo->nlevels; i++) {\n\t\t\tbit = goff;\n\t\t\tgoff = bit >> LG_BITMAP_GROUP_NBITS;\n\t\t\tgp = &bitmap[binfo->levels[i].group_offset + goff];\n\t\t\tg = *gp;\n\t\t\tassert(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK)));\n\t\t\tg ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK);\n\t\t\t*gp = g;\n\t\t\tif (g != 0)\n\t\t\t\tbreak;\n\t\t}\n\t}\n#endif\n}\n\n/* sfu: set first unset. */\nJEMALLOC_INLINE size_t\nbitmap_sfu(bitmap_t *bitmap, const bitmap_info_t *binfo)\n{\n\tsize_t bit;\n\tbitmap_t g;\n\tunsigned i;\n\n\tassert(!bitmap_full(bitmap, binfo));\n\n#ifdef USE_TREE\n\ti = binfo->nlevels - 1;\n\tg = bitmap[binfo->levels[i].group_offset];\n\tbit = ffs_lu(g) - 1;\n\twhile (i > 0) {\n\t\ti--;\n\t\tg = bitmap[binfo->levels[i].group_offset + bit];\n\t\tbit = (bit << LG_BITMAP_GROUP_NBITS) + (ffs_lu(g) - 1);\n\t}\n#else\n\ti = 0;\n\tg = bitmap[0];\n\twhile ((bit = ffs_lu(g)) == 0) {\n\t\ti++;\n\t\tg = bitmap[i];\n\t}\n\tbit = (bit - 1) + (i << 6);\n#endif\n\tbitmap_set(bitmap, binfo, bit);\n\treturn (bit);\n}\n\nJEMALLOC_INLINE void\nbitmap_unset(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit)\n{\n\tsize_t goff;\n\tbitmap_t *gp;\n\tbitmap_t g;\n\tUNUSED bool propagate;\n\n\tassert(bit < binfo->nbits);\n\tassert(bitmap_get(bitmap, binfo, bit));\n\tgoff = bit >> LG_BITMAP_GROUP_NBITS;\n\tgp = &bitmap[goff];\n\tg = *gp;\n\tpropagate = (g == 0);\n\tassert((g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK))) == 0);\n\tg ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK);\n\t*gp = g;\n\tassert(!bitmap_get(bitmap, binfo, bit));\n#ifdef USE_TREE\n\t/* Propagate group state transitions up the tree. */\n\tif (propagate) {\n\t\tunsigned i;\n\t\tfor (i = 1; i < binfo->nlevels; i++) {\n\t\t\tbit = goff;\n\t\t\tgoff = bit >> LG_BITMAP_GROUP_NBITS;\n\t\t\tgp = &bitmap[binfo->levels[i].group_offset + goff];\n\t\t\tg = *gp;\n\t\t\tpropagate = (g == 0);\n\t\t\tassert((g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK)))\n\t\t\t    == 0);\n\t\t\tg ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK);\n\t\t\t*gp = g;\n\t\t\tif (!propagate)\n\t\t\t\tbreak;\n\t\t}\n\t}\n#endif /* USE_TREE */\n}\n\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/chunk.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n/*\n * Size and alignment of memory chunks that are allocated by the OS's virtual\n * memory system.\n */\n#define\tLG_CHUNK_DEFAULT\t21\n\n/* Return the chunk address for allocation address a. */\n#define\tCHUNK_ADDR2BASE(a)\t\t\t\t\t\t\\\n\t((void *)((uintptr_t)(a) & ~chunksize_mask))\n\n/* Return the chunk offset of address a. */\n#define\tCHUNK_ADDR2OFFSET(a)\t\t\t\t\t\t\\\n\t((size_t)((uintptr_t)(a) & chunksize_mask))\n\n/* Return the smallest chunk multiple that is >= s. */\n#define\tCHUNK_CEILING(s)\t\t\t\t\t\t\\\n\t(((s) + chunksize_mask) & ~chunksize_mask)\n\n#define\tCHUNK_HOOKS_INITIALIZER {\t\t\t\t\t\\\n    NULL,\t\t\t\t\t\t\t\t\\\n    NULL,\t\t\t\t\t\t\t\t\\\n    NULL,\t\t\t\t\t\t\t\t\\\n    NULL,\t\t\t\t\t\t\t\t\\\n    NULL,\t\t\t\t\t\t\t\t\\\n    NULL,\t\t\t\t\t\t\t\t\\\n    NULL\t\t\t\t\t\t\t\t\\\n}\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nextern size_t\t\topt_lg_chunk;\nextern const char\t*opt_dss;\n\nextern rtree_t\t\tchunks_rtree;\n\nextern size_t\t\tchunksize;\nextern size_t\t\tchunksize_mask; /* (chunksize - 1). */\nextern size_t\t\tchunk_npages;\n\nextern const chunk_hooks_t\tchunk_hooks_default;\n\nchunk_hooks_t\tchunk_hooks_get(arena_t *arena);\nchunk_hooks_t\tchunk_hooks_set(arena_t *arena,\n    const chunk_hooks_t *chunk_hooks);\n\nbool\tchunk_register(const void *chunk, const extent_node_t *node);\nvoid\tchunk_deregister(const void *chunk, const extent_node_t *node);\nvoid\t*chunk_alloc_base(size_t size);\nvoid\t*chunk_alloc_cache(arena_t *arena, chunk_hooks_t *chunk_hooks,\n    void *new_addr, size_t size, size_t alignment, bool *zero,\n    bool dalloc_node);\nvoid\t*chunk_alloc_wrapper(arena_t *arena, chunk_hooks_t *chunk_hooks,\n    void *new_addr, size_t size, size_t alignment, bool *zero, bool *commit);\nvoid\tchunk_dalloc_cache(arena_t *arena, chunk_hooks_t *chunk_hooks,\n    void *chunk, size_t size, bool committed);\nvoid\tchunk_dalloc_arena(arena_t *arena, chunk_hooks_t *chunk_hooks,\n    void *chunk, size_t size, bool zeroed, bool committed);\nvoid\tchunk_dalloc_wrapper(arena_t *arena, chunk_hooks_t *chunk_hooks,\n    void *chunk, size_t size, bool committed);\nbool\tchunk_purge_arena(arena_t *arena, void *chunk, size_t offset,\n    size_t length);\nbool\tchunk_purge_wrapper(arena_t *arena, chunk_hooks_t *chunk_hooks,\n    void *chunk, size_t size, size_t offset, size_t length);\nbool\tchunk_boot(void);\nvoid\tchunk_prefork(void);\nvoid\tchunk_postfork_parent(void);\nvoid\tchunk_postfork_child(void);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#ifndef JEMALLOC_ENABLE_INLINE\nextent_node_t\t*chunk_lookup(const void *chunk, bool dependent);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_CHUNK_C_))\nJEMALLOC_INLINE extent_node_t *\nchunk_lookup(const void *ptr, bool dependent)\n{\n\n\treturn (rtree_get(&chunks_rtree, (uintptr_t)ptr, dependent));\n}\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n\n#include \"jemalloc/internal/chunk_dss.h\"\n#include \"jemalloc/internal/chunk_mmap.h\"\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/chunk_dss.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\ntypedef enum {\n\tdss_prec_disabled  = 0,\n\tdss_prec_primary   = 1,\n\tdss_prec_secondary = 2,\n\n\tdss_prec_limit     = 3\n} dss_prec_t;\n#define\tDSS_PREC_DEFAULT\tdss_prec_secondary\n#define\tDSS_DEFAULT\t\t\"secondary\"\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\nextern const char *dss_prec_names[];\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\ndss_prec_t\tchunk_dss_prec_get(void);\nbool\tchunk_dss_prec_set(dss_prec_t dss_prec);\nvoid\t*chunk_alloc_dss(arena_t *arena, void *new_addr, size_t size,\n    size_t alignment, bool *zero, bool *commit);\nbool\tchunk_in_dss(void *chunk);\nbool\tchunk_dss_boot(void);\nvoid\tchunk_dss_prefork(void);\nvoid\tchunk_dss_postfork_parent(void);\nvoid\tchunk_dss_postfork_child(void);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/chunk_mmap.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nvoid\t*chunk_alloc_mmap(void *new_addr, size_t size, size_t alignment,\n    bool *zero, bool *commit);\nbool\tchunk_dalloc_mmap(void *chunk, size_t size);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/ckh.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\ntypedef struct ckh_s ckh_t;\ntypedef struct ckhc_s ckhc_t;\n\n/* Typedefs to allow easy function pointer passing. */\ntypedef void ckh_hash_t (const void *, size_t[2]);\ntypedef bool ckh_keycomp_t (const void *, const void *);\n\n/* Maintain counters used to get an idea of performance. */\n/* #define\tCKH_COUNT */\n/* Print counter values in ckh_delete() (requires CKH_COUNT). */\n/* #define\tCKH_VERBOSE */\n\n/*\n * There are 2^LG_CKH_BUCKET_CELLS cells in each hash table bucket.  Try to fit\n * one bucket per L1 cache line.\n */\n#define\tLG_CKH_BUCKET_CELLS (LG_CACHELINE - LG_SIZEOF_PTR - 1)\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n/* Hash table cell. */\nstruct ckhc_s {\n\tconst void\t*key;\n\tconst void\t*data;\n};\n\nstruct ckh_s {\n#ifdef CKH_COUNT\n\t/* Counters used to get an idea of performance. */\n\tuint64_t\tngrows;\n\tuint64_t\tnshrinks;\n\tuint64_t\tnshrinkfails;\n\tuint64_t\tninserts;\n\tuint64_t\tnrelocs;\n#endif\n\n\t/* Used for pseudo-random number generation. */\n\tuint64_t\tprng_state;\n\n\t/* Total number of items. */\n\tsize_t\t\tcount;\n\n\t/*\n\t * Minimum and current number of hash table buckets.  There are\n\t * 2^LG_CKH_BUCKET_CELLS cells per bucket.\n\t */\n\tunsigned\tlg_minbuckets;\n\tunsigned\tlg_curbuckets;\n\n\t/* Hash and comparison functions. */\n\tckh_hash_t\t*hash;\n\tckh_keycomp_t\t*keycomp;\n\n\t/* Hash table with 2^lg_curbuckets buckets. */\n\tckhc_t\t\t*tab;\n};\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nbool\tckh_new(tsd_t *tsd, ckh_t *ckh, size_t minitems, ckh_hash_t *hash,\n    ckh_keycomp_t *keycomp);\nvoid\tckh_delete(tsd_t *tsd, ckh_t *ckh);\nsize_t\tckh_count(ckh_t *ckh);\nbool\tckh_iter(ckh_t *ckh, size_t *tabind, void **key, void **data);\nbool\tckh_insert(tsd_t *tsd, ckh_t *ckh, const void *key, const void *data);\nbool\tckh_remove(tsd_t *tsd, ckh_t *ckh, const void *searchkey, void **key,\n    void **data);\nbool\tckh_search(ckh_t *ckh, const void *searchkey, void **key, void **data);\nvoid\tckh_string_hash(const void *key, size_t r_hash[2]);\nbool\tckh_string_keycomp(const void *k1, const void *k2);\nvoid\tckh_pointer_hash(const void *key, size_t r_hash[2]);\nbool\tckh_pointer_keycomp(const void *k1, const void *k2);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/ctl.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\ntypedef struct ctl_node_s ctl_node_t;\ntypedef struct ctl_named_node_s ctl_named_node_t;\ntypedef struct ctl_indexed_node_s ctl_indexed_node_t;\ntypedef struct ctl_arena_stats_s ctl_arena_stats_t;\ntypedef struct ctl_stats_s ctl_stats_t;\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\nstruct ctl_node_s {\n\tbool\t\t\tnamed;\n};\n\nstruct ctl_named_node_s {\n\tstruct ctl_node_s\tnode;\n\tconst char\t\t*name;\n\t/* If (nchildren == 0), this is a terminal node. */\n\tunsigned\t\tnchildren;\n\tconst\t\t\tctl_node_t *children;\n\tint\t\t\t(*ctl)(const size_t *, size_t, void *, size_t *,\n\t    void *, size_t);\n};\n\nstruct ctl_indexed_node_s {\n\tstruct ctl_node_s\tnode;\n\tconst ctl_named_node_t\t*(*index)(const size_t *, size_t, size_t);\n};\n\nstruct ctl_arena_stats_s {\n\tbool\t\t\tinitialized;\n\tunsigned\t\tnthreads;\n\tconst char\t\t*dss;\n\tssize_t\t\t\tlg_dirty_mult;\n\tssize_t\t\t\tdecay_time;\n\tsize_t\t\t\tpactive;\n\tsize_t\t\t\tpdirty;\n\n\t/* The remainder are only populated if config_stats is true. */\n\n\tarena_stats_t\t\tastats;\n\n\t/* Aggregate stats for small size classes, based on bin stats. */\n\tsize_t\t\t\tallocated_small;\n\tuint64_t\t\tnmalloc_small;\n\tuint64_t\t\tndalloc_small;\n\tuint64_t\t\tnrequests_small;\n\n\tmalloc_bin_stats_t\tbstats[NBINS];\n\tmalloc_large_stats_t\t*lstats;\t/* nlclasses elements. */\n\tmalloc_huge_stats_t\t*hstats;\t/* nhclasses elements. */\n};\n\nstruct ctl_stats_s {\n\tsize_t\t\t\tallocated;\n\tsize_t\t\t\tactive;\n\tsize_t\t\t\tmetadata;\n\tsize_t\t\t\tresident;\n\tsize_t\t\t\tmapped;\n\tunsigned\t\tnarenas;\n\tctl_arena_stats_t\t*arenas;\t/* (narenas + 1) elements. */\n};\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nint\tctl_byname(const char *name, void *oldp, size_t *oldlenp, void *newp,\n    size_t newlen);\nint\tctl_nametomib(const char *name, size_t *mibp, size_t *miblenp);\n\nint\tctl_bymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\n    void *newp, size_t newlen);\nbool\tctl_boot(void);\nvoid\tctl_prefork(void);\nvoid\tctl_postfork_parent(void);\nvoid\tctl_postfork_child(void);\n\n#define\txmallctl(name, oldp, oldlenp, newp, newlen) do {\t\t\\\n\tif (je_mallctl(name, oldp, oldlenp, newp, newlen)\t\t\\\n\t    != 0) {\t\t\t\t\t\t\t\\\n\t\tmalloc_printf(\t\t\t\t\t\t\\\n\t\t    \"<jemalloc>: Failure in xmallctl(\\\"%s\\\", ...)\\n\",\t\\\n\t\t    name);\t\t\t\t\t\t\\\n\t\tabort();\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\txmallctlnametomib(name, mibp, miblenp) do {\t\t\t\\\n\tif (je_mallctlnametomib(name, mibp, miblenp) != 0) {\t\t\\\n\t\tmalloc_printf(\"<jemalloc>: Failure in \"\t\t\t\\\n\t\t    \"xmallctlnametomib(\\\"%s\\\", ...)\\n\", name);\t\t\\\n\t\tabort();\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\txmallctlbymib(mib, miblen, oldp, oldlenp, newp, newlen) do {\t\\\n\tif (je_mallctlbymib(mib, miblen, oldp, oldlenp, newp,\t\t\\\n\t    newlen) != 0) {\t\t\t\t\t\t\\\n\t\tmalloc_write(\t\t\t\t\t\t\\\n\t\t    \"<jemalloc>: Failure in xmallctlbymib()\\n\");\t\\\n\t\tabort();\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/extent.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\ntypedef struct extent_node_s extent_node_t;\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n/* Tree of extents.  Use accessor functions for en_* fields. */\nstruct extent_node_s {\n\t/* Arena from which this extent came, if any. */\n\tarena_t\t\t\t*en_arena;\n\n\t/* Pointer to the extent that this tree node is responsible for. */\n\tvoid\t\t\t*en_addr;\n\n\t/* Total region size. */\n\tsize_t\t\t\ten_size;\n\n\t/*\n\t * The zeroed flag is used by chunk recycling code to track whether\n\t * memory is zero-filled.\n\t */\n\tbool\t\t\ten_zeroed;\n\n\t/*\n\t * True if physical memory is committed to the extent, whether\n\t * explicitly or implicitly as on a system that overcommits and\n\t * satisfies physical memory needs on demand via soft page faults.\n\t */\n\tbool\t\t\ten_committed;\n\n\t/*\n\t * The achunk flag is used to validate that huge allocation lookups\n\t * don't return arena chunks.\n\t */\n\tbool\t\t\ten_achunk;\n\n\t/* Profile counters, used for huge objects. */\n\tprof_tctx_t\t\t*en_prof_tctx;\n\n\t/* Linkage for arena's runs_dirty and chunks_cache rings. */\n\tarena_runs_dirty_link_t\trd;\n\tqr(extent_node_t)\tcc_link;\n\n\tunion {\n\t\t/* Linkage for the size/address-ordered tree. */\n\t\trb_node(extent_node_t)\tszad_link;\n\n\t\t/* Linkage for arena's huge and node_cache lists. */\n\t\tql_elm(extent_node_t)\tql_link;\n\t};\n\n\t/* Linkage for the address-ordered tree. */\n\trb_node(extent_node_t)\tad_link;\n};\ntypedef rb_tree(extent_node_t) extent_tree_t;\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nrb_proto(, extent_tree_szad_, extent_tree_t, extent_node_t)\n\nrb_proto(, extent_tree_ad_, extent_tree_t, extent_node_t)\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#ifndef JEMALLOC_ENABLE_INLINE\narena_t\t*extent_node_arena_get(const extent_node_t *node);\nvoid\t*extent_node_addr_get(const extent_node_t *node);\nsize_t\textent_node_size_get(const extent_node_t *node);\nbool\textent_node_zeroed_get(const extent_node_t *node);\nbool\textent_node_committed_get(const extent_node_t *node);\nbool\textent_node_achunk_get(const extent_node_t *node);\nprof_tctx_t\t*extent_node_prof_tctx_get(const extent_node_t *node);\nvoid\textent_node_arena_set(extent_node_t *node, arena_t *arena);\nvoid\textent_node_addr_set(extent_node_t *node, void *addr);\nvoid\textent_node_size_set(extent_node_t *node, size_t size);\nvoid\textent_node_zeroed_set(extent_node_t *node, bool zeroed);\nvoid\textent_node_committed_set(extent_node_t *node, bool committed);\nvoid\textent_node_achunk_set(extent_node_t *node, bool achunk);\nvoid\textent_node_prof_tctx_set(extent_node_t *node, prof_tctx_t *tctx);\nvoid\textent_node_init(extent_node_t *node, arena_t *arena, void *addr,\n    size_t size, bool zeroed, bool committed);\nvoid\textent_node_dirty_linkage_init(extent_node_t *node);\nvoid\textent_node_dirty_insert(extent_node_t *node,\n    arena_runs_dirty_link_t *runs_dirty, extent_node_t *chunks_dirty);\nvoid\textent_node_dirty_remove(extent_node_t *node);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_EXTENT_C_))\nJEMALLOC_INLINE arena_t *\nextent_node_arena_get(const extent_node_t *node)\n{\n\n\treturn (node->en_arena);\n}\n\nJEMALLOC_INLINE void *\nextent_node_addr_get(const extent_node_t *node)\n{\n\n\treturn (node->en_addr);\n}\n\nJEMALLOC_INLINE size_t\nextent_node_size_get(const extent_node_t *node)\n{\n\n\treturn (node->en_size);\n}\n\nJEMALLOC_INLINE bool\nextent_node_zeroed_get(const extent_node_t *node)\n{\n\n\treturn (node->en_zeroed);\n}\n\nJEMALLOC_INLINE bool\nextent_node_committed_get(const extent_node_t *node)\n{\n\n\tassert(!node->en_achunk);\n\treturn (node->en_committed);\n}\n\nJEMALLOC_INLINE bool\nextent_node_achunk_get(const extent_node_t *node)\n{\n\n\treturn (node->en_achunk);\n}\n\nJEMALLOC_INLINE prof_tctx_t *\nextent_node_prof_tctx_get(const extent_node_t *node)\n{\n\n\treturn (node->en_prof_tctx);\n}\n\nJEMALLOC_INLINE void\nextent_node_arena_set(extent_node_t *node, arena_t *arena)\n{\n\n\tnode->en_arena = arena;\n}\n\nJEMALLOC_INLINE void\nextent_node_addr_set(extent_node_t *node, void *addr)\n{\n\n\tnode->en_addr = addr;\n}\n\nJEMALLOC_INLINE void\nextent_node_size_set(extent_node_t *node, size_t size)\n{\n\n\tnode->en_size = size;\n}\n\nJEMALLOC_INLINE void\nextent_node_zeroed_set(extent_node_t *node, bool zeroed)\n{\n\n\tnode->en_zeroed = zeroed;\n}\n\nJEMALLOC_INLINE void\nextent_node_committed_set(extent_node_t *node, bool committed)\n{\n\n\tnode->en_committed = committed;\n}\n\nJEMALLOC_INLINE void\nextent_node_achunk_set(extent_node_t *node, bool achunk)\n{\n\n\tnode->en_achunk = achunk;\n}\n\nJEMALLOC_INLINE void\nextent_node_prof_tctx_set(extent_node_t *node, prof_tctx_t *tctx)\n{\n\n\tnode->en_prof_tctx = tctx;\n}\n\nJEMALLOC_INLINE void\nextent_node_init(extent_node_t *node, arena_t *arena, void *addr, size_t size,\n    bool zeroed, bool committed)\n{\n\n\textent_node_arena_set(node, arena);\n\textent_node_addr_set(node, addr);\n\textent_node_size_set(node, size);\n\textent_node_zeroed_set(node, zeroed);\n\textent_node_committed_set(node, committed);\n\textent_node_achunk_set(node, false);\n\tif (config_prof)\n\t\textent_node_prof_tctx_set(node, NULL);\n}\n\nJEMALLOC_INLINE void\nextent_node_dirty_linkage_init(extent_node_t *node)\n{\n\n\tqr_new(&node->rd, rd_link);\n\tqr_new(node, cc_link);\n}\n\nJEMALLOC_INLINE void\nextent_node_dirty_insert(extent_node_t *node,\n    arena_runs_dirty_link_t *runs_dirty, extent_node_t *chunks_dirty)\n{\n\n\tqr_meld(runs_dirty, &node->rd, rd_link);\n\tqr_meld(chunks_dirty, node, cc_link);\n}\n\nJEMALLOC_INLINE void\nextent_node_dirty_remove(extent_node_t *node)\n{\n\n\tqr_remove(&node->rd, rd_link);\n\tqr_remove(node, cc_link);\n}\n\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/hash.h",
    "content": "/*\n * The following hash function is based on MurmurHash3, placed into the public\n * domain by Austin Appleby.  See https://github.com/aappleby/smhasher for\n * details.\n */\n/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#ifndef JEMALLOC_ENABLE_INLINE\nuint32_t\thash_x86_32(const void *key, int len, uint32_t seed);\nvoid\thash_x86_128(const void *key, const int len, uint32_t seed,\n    uint64_t r_out[2]);\nvoid\thash_x64_128(const void *key, const int len, const uint32_t seed,\n    uint64_t r_out[2]);\nvoid\thash(const void *key, size_t len, const uint32_t seed,\n    size_t r_hash[2]);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_HASH_C_))\n/******************************************************************************/\n/* Internal implementation. */\nJEMALLOC_INLINE uint32_t\nhash_rotl_32(uint32_t x, int8_t r)\n{\n\n\treturn ((x << r) | (x >> (32 - r)));\n}\n\nJEMALLOC_INLINE uint64_t\nhash_rotl_64(uint64_t x, int8_t r)\n{\n\n\treturn ((x << r) | (x >> (64 - r)));\n}\n\nJEMALLOC_INLINE uint32_t\nhash_get_block_32(const uint32_t *p, int i)\n{\n\n\t/* Handle unaligned read. */\n\tif (unlikely((uintptr_t)p & (sizeof(uint32_t)-1)) != 0) {\n\t\tuint32_t ret;\n\n\t\tmemcpy(&ret, &p[i], sizeof(uint32_t));\n\t\treturn (ret);\n\t}\n\n\treturn (p[i]);\n}\n\nJEMALLOC_INLINE uint64_t\nhash_get_block_64(const uint64_t *p, int i)\n{\n\n\t/* Handle unaligned read. */\n\tif (unlikely((uintptr_t)p & (sizeof(uint64_t)-1)) != 0) {\n\t\tuint64_t ret;\n\n\t\tmemcpy(&ret, &p[i], sizeof(uint64_t));\n\t\treturn (ret);\n\t}\n\n\treturn (p[i]);\n}\n\nJEMALLOC_INLINE uint32_t\nhash_fmix_32(uint32_t h)\n{\n\n\th ^= h >> 16;\n\th *= 0x85ebca6b;\n\th ^= h >> 13;\n\th *= 0xc2b2ae35;\n\th ^= h >> 16;\n\n\treturn (h);\n}\n\nJEMALLOC_INLINE uint64_t\nhash_fmix_64(uint64_t k)\n{\n\n\tk ^= k >> 33;\n\tk *= KQU(0xff51afd7ed558ccd);\n\tk ^= k >> 33;\n\tk *= KQU(0xc4ceb9fe1a85ec53);\n\tk ^= k >> 33;\n\n\treturn (k);\n}\n\nJEMALLOC_INLINE uint32_t\nhash_x86_32(const void *key, int len, uint32_t seed)\n{\n\tconst uint8_t *data = (const uint8_t *) key;\n\tconst int nblocks = len / 4;\n\n\tuint32_t h1 = seed;\n\n\tconst uint32_t c1 = 0xcc9e2d51;\n\tconst uint32_t c2 = 0x1b873593;\n\n\t/* body */\n\t{\n\t\tconst uint32_t *blocks = (const uint32_t *) (data + nblocks*4);\n\t\tint i;\n\n\t\tfor (i = -nblocks; i; i++) {\n\t\t\tuint32_t k1 = hash_get_block_32(blocks, i);\n\n\t\t\tk1 *= c1;\n\t\t\tk1 = hash_rotl_32(k1, 15);\n\t\t\tk1 *= c2;\n\n\t\t\th1 ^= k1;\n\t\t\th1 = hash_rotl_32(h1, 13);\n\t\t\th1 = h1*5 + 0xe6546b64;\n\t\t}\n\t}\n\n\t/* tail */\n\t{\n\t\tconst uint8_t *tail = (const uint8_t *) (data + nblocks*4);\n\n\t\tuint32_t k1 = 0;\n\n\t\tswitch (len & 3) {\n\t\tcase 3: k1 ^= tail[2] << 16;\n\t\tcase 2: k1 ^= tail[1] << 8;\n\t\tcase 1: k1 ^= tail[0]; k1 *= c1; k1 = hash_rotl_32(k1, 15);\n\t\t\tk1 *= c2; h1 ^= k1;\n\t\t}\n\t}\n\n\t/* finalization */\n\th1 ^= len;\n\n\th1 = hash_fmix_32(h1);\n\n\treturn (h1);\n}\n\nUNUSED JEMALLOC_INLINE void\nhash_x86_128(const void *key, const int len, uint32_t seed,\n    uint64_t r_out[2])\n{\n\tconst uint8_t * data = (const uint8_t *) key;\n\tconst int nblocks = len / 16;\n\n\tuint32_t h1 = seed;\n\tuint32_t h2 = seed;\n\tuint32_t h3 = seed;\n\tuint32_t h4 = seed;\n\n\tconst uint32_t c1 = 0x239b961b;\n\tconst uint32_t c2 = 0xab0e9789;\n\tconst uint32_t c3 = 0x38b34ae5;\n\tconst uint32_t c4 = 0xa1e38b93;\n\n\t/* body */\n\t{\n\t\tconst uint32_t *blocks = (const uint32_t *) (data + nblocks*16);\n\t\tint i;\n\n\t\tfor (i = -nblocks; i; i++) {\n\t\t\tuint32_t k1 = hash_get_block_32(blocks, i*4 + 0);\n\t\t\tuint32_t k2 = hash_get_block_32(blocks, i*4 + 1);\n\t\t\tuint32_t k3 = hash_get_block_32(blocks, i*4 + 2);\n\t\t\tuint32_t k4 = hash_get_block_32(blocks, i*4 + 3);\n\n\t\t\tk1 *= c1; k1 = hash_rotl_32(k1, 15); k1 *= c2; h1 ^= k1;\n\n\t\t\th1 = hash_rotl_32(h1, 19); h1 += h2;\n\t\t\th1 = h1*5 + 0x561ccd1b;\n\n\t\t\tk2 *= c2; k2 = hash_rotl_32(k2, 16); k2 *= c3; h2 ^= k2;\n\n\t\t\th2 = hash_rotl_32(h2, 17); h2 += h3;\n\t\t\th2 = h2*5 + 0x0bcaa747;\n\n\t\t\tk3 *= c3; k3 = hash_rotl_32(k3, 17); k3 *= c4; h3 ^= k3;\n\n\t\t\th3 = hash_rotl_32(h3, 15); h3 += h4;\n\t\t\th3 = h3*5 + 0x96cd1c35;\n\n\t\t\tk4 *= c4; k4 = hash_rotl_32(k4, 18); k4 *= c1; h4 ^= k4;\n\n\t\t\th4 = hash_rotl_32(h4, 13); h4 += h1;\n\t\t\th4 = h4*5 + 0x32ac3b17;\n\t\t}\n\t}\n\n\t/* tail */\n\t{\n\t\tconst uint8_t *tail = (const uint8_t *) (data + nblocks*16);\n\t\tuint32_t k1 = 0;\n\t\tuint32_t k2 = 0;\n\t\tuint32_t k3 = 0;\n\t\tuint32_t k4 = 0;\n\n\t\tswitch (len & 15) {\n\t\tcase 15: k4 ^= tail[14] << 16;\n\t\tcase 14: k4 ^= tail[13] << 8;\n\t\tcase 13: k4 ^= tail[12] << 0;\n\t\t\tk4 *= c4; k4 = hash_rotl_32(k4, 18); k4 *= c1; h4 ^= k4;\n\n\t\tcase 12: k3 ^= tail[11] << 24;\n\t\tcase 11: k3 ^= tail[10] << 16;\n\t\tcase 10: k3 ^= tail[ 9] << 8;\n\t\tcase  9: k3 ^= tail[ 8] << 0;\n\t\t     k3 *= c3; k3 = hash_rotl_32(k3, 17); k3 *= c4; h3 ^= k3;\n\n\t\tcase  8: k2 ^= tail[ 7] << 24;\n\t\tcase  7: k2 ^= tail[ 6] << 16;\n\t\tcase  6: k2 ^= tail[ 5] << 8;\n\t\tcase  5: k2 ^= tail[ 4] << 0;\n\t\t\tk2 *= c2; k2 = hash_rotl_32(k2, 16); k2 *= c3; h2 ^= k2;\n\n\t\tcase  4: k1 ^= tail[ 3] << 24;\n\t\tcase  3: k1 ^= tail[ 2] << 16;\n\t\tcase  2: k1 ^= tail[ 1] << 8;\n\t\tcase  1: k1 ^= tail[ 0] << 0;\n\t\t\tk1 *= c1; k1 = hash_rotl_32(k1, 15); k1 *= c2; h1 ^= k1;\n\t\t}\n\t}\n\n\t/* finalization */\n\th1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;\n\n\th1 += h2; h1 += h3; h1 += h4;\n\th2 += h1; h3 += h1; h4 += h1;\n\n\th1 = hash_fmix_32(h1);\n\th2 = hash_fmix_32(h2);\n\th3 = hash_fmix_32(h3);\n\th4 = hash_fmix_32(h4);\n\n\th1 += h2; h1 += h3; h1 += h4;\n\th2 += h1; h3 += h1; h4 += h1;\n\n\tr_out[0] = (((uint64_t) h2) << 32) | h1;\n\tr_out[1] = (((uint64_t) h4) << 32) | h3;\n}\n\nUNUSED JEMALLOC_INLINE void\nhash_x64_128(const void *key, const int len, const uint32_t seed,\n    uint64_t r_out[2])\n{\n\tconst uint8_t *data = (const uint8_t *) key;\n\tconst int nblocks = len / 16;\n\n\tuint64_t h1 = seed;\n\tuint64_t h2 = seed;\n\n\tconst uint64_t c1 = KQU(0x87c37b91114253d5);\n\tconst uint64_t c2 = KQU(0x4cf5ad432745937f);\n\n\t/* body */\n\t{\n\t\tconst uint64_t *blocks = (const uint64_t *) (data);\n\t\tint i;\n\n\t\tfor (i = 0; i < nblocks; i++) {\n\t\t\tuint64_t k1 = hash_get_block_64(blocks, i*2 + 0);\n\t\t\tuint64_t k2 = hash_get_block_64(blocks, i*2 + 1);\n\n\t\t\tk1 *= c1; k1 = hash_rotl_64(k1, 31); k1 *= c2; h1 ^= k1;\n\n\t\t\th1 = hash_rotl_64(h1, 27); h1 += h2;\n\t\t\th1 = h1*5 + 0x52dce729;\n\n\t\t\tk2 *= c2; k2 = hash_rotl_64(k2, 33); k2 *= c1; h2 ^= k2;\n\n\t\t\th2 = hash_rotl_64(h2, 31); h2 += h1;\n\t\t\th2 = h2*5 + 0x38495ab5;\n\t\t}\n\t}\n\n\t/* tail */\n\t{\n\t\tconst uint8_t *tail = (const uint8_t*)(data + nblocks*16);\n\t\tuint64_t k1 = 0;\n\t\tuint64_t k2 = 0;\n\n\t\tswitch (len & 15) {\n\t\tcase 15: k2 ^= ((uint64_t)(tail[14])) << 48;\n\t\tcase 14: k2 ^= ((uint64_t)(tail[13])) << 40;\n\t\tcase 13: k2 ^= ((uint64_t)(tail[12])) << 32;\n\t\tcase 12: k2 ^= ((uint64_t)(tail[11])) << 24;\n\t\tcase 11: k2 ^= ((uint64_t)(tail[10])) << 16;\n\t\tcase 10: k2 ^= ((uint64_t)(tail[ 9])) << 8;\n\t\tcase  9: k2 ^= ((uint64_t)(tail[ 8])) << 0;\n\t\t\tk2 *= c2; k2 = hash_rotl_64(k2, 33); k2 *= c1; h2 ^= k2;\n\n\t\tcase  8: k1 ^= ((uint64_t)(tail[ 7])) << 56;\n\t\tcase  7: k1 ^= ((uint64_t)(tail[ 6])) << 48;\n\t\tcase  6: k1 ^= ((uint64_t)(tail[ 5])) << 40;\n\t\tcase  5: k1 ^= ((uint64_t)(tail[ 4])) << 32;\n\t\tcase  4: k1 ^= ((uint64_t)(tail[ 3])) << 24;\n\t\tcase  3: k1 ^= ((uint64_t)(tail[ 2])) << 16;\n\t\tcase  2: k1 ^= ((uint64_t)(tail[ 1])) << 8;\n\t\tcase  1: k1 ^= ((uint64_t)(tail[ 0])) << 0;\n\t\t\tk1 *= c1; k1 = hash_rotl_64(k1, 31); k1 *= c2; h1 ^= k1;\n\t\t}\n\t}\n\n\t/* finalization */\n\th1 ^= len; h2 ^= len;\n\n\th1 += h2;\n\th2 += h1;\n\n\th1 = hash_fmix_64(h1);\n\th2 = hash_fmix_64(h2);\n\n\th1 += h2;\n\th2 += h1;\n\n\tr_out[0] = h1;\n\tr_out[1] = h2;\n}\n\n/******************************************************************************/\n/* API. */\nJEMALLOC_INLINE void\nhash(const void *key, size_t len, const uint32_t seed, size_t r_hash[2])\n{\n\n\tassert(len <= INT_MAX); /* Unfortunate implementation limitation. */\n\n#if (LG_SIZEOF_PTR == 3 && !defined(JEMALLOC_BIG_ENDIAN))\n\thash_x64_128(key, (int)len, seed, (uint64_t *)r_hash);\n#else\n\t{\n\t\tuint64_t hashes[2];\n\t\thash_x86_128(key, (int)len, seed, hashes);\n\t\tr_hash[0] = (size_t)hashes[0];\n\t\tr_hash[1] = (size_t)hashes[1];\n\t}\n#endif\n}\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/huge.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nvoid\t*huge_malloc(tsd_t *tsd, arena_t *arena, size_t usize, bool zero,\n    tcache_t *tcache);\nvoid\t*huge_palloc(tsd_t *tsd, arena_t *arena, size_t usize, size_t alignment,\n    bool zero, tcache_t *tcache);\nbool\thuge_ralloc_no_move(tsd_t *tsd, void *ptr, size_t oldsize,\n    size_t usize_min, size_t usize_max, bool zero);\nvoid\t*huge_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize,\n    size_t usize, size_t alignment, bool zero, tcache_t *tcache);\n#ifdef JEMALLOC_JET\ntypedef void (huge_dalloc_junk_t)(void *, size_t);\nextern huge_dalloc_junk_t *huge_dalloc_junk;\n#endif\nvoid\thuge_dalloc(tsd_t *tsd, void *ptr, tcache_t *tcache);\narena_t\t*huge_aalloc(const void *ptr);\nsize_t\thuge_salloc(const void *ptr);\nprof_tctx_t\t*huge_prof_tctx_get(const void *ptr);\nvoid\thuge_prof_tctx_set(const void *ptr, prof_tctx_t *tctx);\nvoid\thuge_prof_tctx_reset(const void *ptr);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/jemalloc_internal.h.in",
    "content": "#ifndef JEMALLOC_INTERNAL_H\n#define\tJEMALLOC_INTERNAL_H\n\n#include \"jemalloc_internal_defs.h\"\n#include \"jemalloc/internal/jemalloc_internal_decls.h\"\n\n#ifdef JEMALLOC_UTRACE\n#include <sys/ktrace.h>\n#endif\n\n#define\tJEMALLOC_NO_DEMANGLE\n#ifdef JEMALLOC_JET\n#  define JEMALLOC_N(n) jet_##n\n#  include \"jemalloc/internal/public_namespace.h\"\n#  define JEMALLOC_NO_RENAME\n#  include \"../jemalloc@install_suffix@.h\"\n#  undef JEMALLOC_NO_RENAME\n#else\n#  define JEMALLOC_N(n) @private_namespace@##n\n#  include \"../jemalloc@install_suffix@.h\"\n#endif\n#include \"jemalloc/internal/private_namespace.h\"\n\nstatic const bool config_debug =\n#ifdef JEMALLOC_DEBUG\n    true\n#else\n    false\n#endif\n    ;\nstatic const bool have_dss =\n#ifdef JEMALLOC_DSS\n    true\n#else\n    false\n#endif\n    ;\nstatic const bool config_fill =\n#ifdef JEMALLOC_FILL\n    true\n#else\n    false\n#endif\n    ;\nstatic const bool config_lazy_lock =\n#ifdef JEMALLOC_LAZY_LOCK\n    true\n#else\n    false\n#endif\n    ;\nstatic const char * const config_malloc_conf = JEMALLOC_CONFIG_MALLOC_CONF;\nstatic const bool config_prof =\n#ifdef JEMALLOC_PROF\n    true\n#else\n    false\n#endif\n    ;\nstatic const bool config_prof_libgcc =\n#ifdef JEMALLOC_PROF_LIBGCC\n    true\n#else\n    false\n#endif\n    ;\nstatic const bool config_prof_libunwind =\n#ifdef JEMALLOC_PROF_LIBUNWIND\n    true\n#else\n    false\n#endif\n    ;\nstatic const bool maps_coalesce =\n#ifdef JEMALLOC_MAPS_COALESCE\n    true\n#else\n    false\n#endif\n    ;\nstatic const bool config_munmap =\n#ifdef JEMALLOC_MUNMAP\n    true\n#else\n    false\n#endif\n    ;\nstatic const bool config_stats =\n#ifdef JEMALLOC_STATS\n    true\n#else\n    false\n#endif\n    ;\nstatic const bool config_tcache =\n#ifdef JEMALLOC_TCACHE\n    true\n#else\n    false\n#endif\n    ;\nstatic const bool config_tls =\n#ifdef JEMALLOC_TLS\n    true\n#else\n    false\n#endif\n    ;\nstatic const bool config_utrace =\n#ifdef JEMALLOC_UTRACE\n    true\n#else\n    false\n#endif\n    ;\nstatic const bool config_valgrind =\n#ifdef JEMALLOC_VALGRIND\n    true\n#else\n    false\n#endif\n    ;\nstatic const bool config_xmalloc =\n#ifdef JEMALLOC_XMALLOC\n    true\n#else\n    false\n#endif\n    ;\nstatic const bool config_ivsalloc =\n#ifdef JEMALLOC_IVSALLOC\n    true\n#else\n    false\n#endif\n    ;\nstatic const bool config_cache_oblivious =\n#ifdef JEMALLOC_CACHE_OBLIVIOUS\n    true\n#else\n    false\n#endif\n    ;\n\n#ifdef JEMALLOC_C11ATOMICS\n#include <stdatomic.h>\n#endif\n\n#ifdef JEMALLOC_ATOMIC9\n#include <machine/atomic.h>\n#endif\n\n#if (defined(JEMALLOC_OSATOMIC) || defined(JEMALLOC_OSSPIN))\n#include <libkern/OSAtomic.h>\n#endif\n\n#ifdef JEMALLOC_ZONE\n#include <mach/mach_error.h>\n#include <mach/mach_init.h>\n#include <mach/vm_map.h>\n#include <malloc/malloc.h>\n#endif\n\n#define\tRB_COMPACT\n#include \"jemalloc/internal/rb.h\"\n#include \"jemalloc/internal/qr.h\"\n#include \"jemalloc/internal/ql.h\"\n\n/*\n * jemalloc can conceptually be broken into components (arena, tcache, etc.),\n * but there are circular dependencies that cannot be broken without\n * substantial performance degradation.  In order to reduce the effect on\n * visual code flow, read the header files in multiple passes, with one of the\n * following cpp variables defined during each pass:\n *\n *   JEMALLOC_H_TYPES   : Preprocessor-defined constants and psuedo-opaque data\n *                        types.\n *   JEMALLOC_H_STRUCTS : Data structures.\n *   JEMALLOC_H_EXTERNS : Extern data declarations and function prototypes.\n *   JEMALLOC_H_INLINES : Inline functions.\n */\n/******************************************************************************/\n#define\tJEMALLOC_H_TYPES\n\n#include \"jemalloc/internal/jemalloc_internal_macros.h\"\n\n/* Size class index type. */\ntypedef unsigned szind_t;\n\n/*\n * Flags bits:\n *\n * a: arena\n * t: tcache\n * 0: unused\n * z: zero\n * n: alignment\n *\n * aaaaaaaa aaaatttt tttttttt 0znnnnnn\n */\n#define\tMALLOCX_ARENA_MASK\t((int)~0xfffff)\n#define\tMALLOCX_ARENA_MAX\t0xffe\n#define\tMALLOCX_TCACHE_MASK\t((int)~0xfff000ffU)\n#define\tMALLOCX_TCACHE_MAX\t0xffd\n#define\tMALLOCX_LG_ALIGN_MASK\t((int)0x3f)\n/* Use MALLOCX_ALIGN_GET() if alignment may not be specified in flags. */\n#define\tMALLOCX_ALIGN_GET_SPECIFIED(flags)\t\t\t\t\\\n    (ZU(1) << (flags & MALLOCX_LG_ALIGN_MASK))\n#define\tMALLOCX_ALIGN_GET(flags)\t\t\t\t\t\\\n    (MALLOCX_ALIGN_GET_SPECIFIED(flags) & (SIZE_T_MAX-1))\n#define\tMALLOCX_ZERO_GET(flags)\t\t\t\t\t\t\\\n    ((bool)(flags & MALLOCX_ZERO))\n\n#define\tMALLOCX_TCACHE_GET(flags)\t\t\t\t\t\\\n    (((unsigned)((flags & MALLOCX_TCACHE_MASK) >> 8)) - 2)\n#define\tMALLOCX_ARENA_GET(flags)\t\t\t\t\t\\\n    (((unsigned)(((unsigned)flags) >> 20)) - 1)\n\n/* Smallest size class to support. */\n#define\tTINY_MIN\t\t(1U << LG_TINY_MIN)\n\n/*\n * Minimum allocation alignment is 2^LG_QUANTUM bytes (ignoring tiny size\n * classes).\n */\n#ifndef LG_QUANTUM\n#  if (defined(__i386__) || defined(_M_IX86))\n#    define LG_QUANTUM\t\t4\n#  endif\n#  ifdef __ia64__\n#    define LG_QUANTUM\t\t4\n#  endif\n#  ifdef __alpha__\n#    define LG_QUANTUM\t\t4\n#  endif\n#  if (defined(__sparc64__) || defined(__sparcv9))\n#    define LG_QUANTUM\t\t4\n#  endif\n#  if (defined(__amd64__) || defined(__x86_64__) || defined(_M_X64))\n#    define LG_QUANTUM\t\t4\n#  endif\n#  ifdef __arm__\n#    define LG_QUANTUM\t\t3\n#  endif\n#  ifdef __aarch64__\n#    define LG_QUANTUM\t\t4\n#  endif\n#  ifdef __hppa__\n#    define LG_QUANTUM\t\t4\n#  endif\n#  ifdef __mips__\n#    define LG_QUANTUM\t\t3\n#  endif\n#  ifdef __or1k__\n#    define LG_QUANTUM\t\t3\n#  endif\n#  ifdef __powerpc__\n#    define LG_QUANTUM\t\t4\n#  endif\n#  ifdef __s390__\n#    define LG_QUANTUM\t\t4\n#  endif\n#  ifdef __SH4__\n#    define LG_QUANTUM\t\t4\n#  endif\n#  ifdef __tile__\n#    define LG_QUANTUM\t\t4\n#  endif\n#  ifdef __le32__\n#    define LG_QUANTUM\t\t4\n#  endif\n#  ifndef LG_QUANTUM\n#    error \"Unknown minimum alignment for architecture; specify via \"\n\t \"--with-lg-quantum\"\n#  endif\n#endif\n\n#define\tQUANTUM\t\t\t((size_t)(1U << LG_QUANTUM))\n#define\tQUANTUM_MASK\t\t(QUANTUM - 1)\n\n/* Return the smallest quantum multiple that is >= a. */\n#define\tQUANTUM_CEILING(a)\t\t\t\t\t\t\\\n\t(((a) + QUANTUM_MASK) & ~QUANTUM_MASK)\n\n#define\tLONG\t\t\t((size_t)(1U << LG_SIZEOF_LONG))\n#define\tLONG_MASK\t\t(LONG - 1)\n\n/* Return the smallest long multiple that is >= a. */\n#define\tLONG_CEILING(a)\t\t\t\t\t\t\t\\\n\t(((a) + LONG_MASK) & ~LONG_MASK)\n\n#define\tSIZEOF_PTR\t\t(1U << LG_SIZEOF_PTR)\n#define\tPTR_MASK\t\t(SIZEOF_PTR - 1)\n\n/* Return the smallest (void *) multiple that is >= a. */\n#define\tPTR_CEILING(a)\t\t\t\t\t\t\t\\\n\t(((a) + PTR_MASK) & ~PTR_MASK)\n\n/*\n * Maximum size of L1 cache line.  This is used to avoid cache line aliasing.\n * In addition, this controls the spacing of cacheline-spaced size classes.\n *\n * CACHELINE cannot be based on LG_CACHELINE because __declspec(align()) can\n * only handle raw constants.\n */\n#define\tLG_CACHELINE\t\t6\n#define\tCACHELINE\t\t64\n#define\tCACHELINE_MASK\t\t(CACHELINE - 1)\n\n/* Return the smallest cacheline multiple that is >= s. */\n#define\tCACHELINE_CEILING(s)\t\t\t\t\t\t\\\n\t(((s) + CACHELINE_MASK) & ~CACHELINE_MASK)\n\n/* Page size.  LG_PAGE is determined by the configure script. */\n#ifdef PAGE_MASK\n#  undef PAGE_MASK\n#endif\n#define\tPAGE\t\t((size_t)(1U << LG_PAGE))\n#define\tPAGE_MASK\t((size_t)(PAGE - 1))\n\n/* Return the page base address for the page containing address a. */\n#define\tPAGE_ADDR2BASE(a)\t\t\t\t\t\t\\\n\t((void *)((uintptr_t)(a) & ~PAGE_MASK))\n\n/* Return the smallest pagesize multiple that is >= s. */\n#define\tPAGE_CEILING(s)\t\t\t\t\t\t\t\\\n\t(((s) + PAGE_MASK) & ~PAGE_MASK)\n\n/* Return the nearest aligned address at or below a. */\n#define\tALIGNMENT_ADDR2BASE(a, alignment)\t\t\t\t\\\n\t((void *)((uintptr_t)(a) & (-(alignment))))\n\n/* Return the offset between a and the nearest aligned address at or below a. */\n#define\tALIGNMENT_ADDR2OFFSET(a, alignment)\t\t\t\t\\\n\t((size_t)((uintptr_t)(a) & (alignment - 1)))\n\n/* Return the smallest alignment multiple that is >= s. */\n#define\tALIGNMENT_CEILING(s, alignment)\t\t\t\t\t\\\n\t(((s) + (alignment - 1)) & (-(alignment)))\n\n/* Declare a variable-length array. */\n#if __STDC_VERSION__ < 199901L\n#  ifdef _MSC_VER\n#    include <malloc.h>\n#    define alloca _alloca\n#  else\n#    ifdef JEMALLOC_HAS_ALLOCA_H\n#      include <alloca.h>\n#    else\n#      include <stdlib.h>\n#    endif\n#  endif\n#  define VARIABLE_ARRAY(type, name, count) \\\n\ttype *name = alloca(sizeof(type) * (count))\n#else\n#  define VARIABLE_ARRAY(type, name, count) type name[(count)]\n#endif\n\n#include \"jemalloc/internal/nstime.h\"\n#include \"jemalloc/internal/valgrind.h\"\n#include \"jemalloc/internal/util.h\"\n#include \"jemalloc/internal/atomic.h\"\n#include \"jemalloc/internal/prng.h\"\n#include \"jemalloc/internal/ticker.h\"\n#include \"jemalloc/internal/ckh.h\"\n#include \"jemalloc/internal/size_classes.h\"\n#include \"jemalloc/internal/smoothstep.h\"\n#include \"jemalloc/internal/stats.h\"\n#include \"jemalloc/internal/ctl.h\"\n#include \"jemalloc/internal/mutex.h\"\n#include \"jemalloc/internal/tsd.h\"\n#include \"jemalloc/internal/mb.h\"\n#include \"jemalloc/internal/extent.h\"\n#include \"jemalloc/internal/arena.h\"\n#include \"jemalloc/internal/bitmap.h\"\n#include \"jemalloc/internal/base.h\"\n#include \"jemalloc/internal/rtree.h\"\n#include \"jemalloc/internal/pages.h\"\n#include \"jemalloc/internal/chunk.h\"\n#include \"jemalloc/internal/huge.h\"\n#include \"jemalloc/internal/tcache.h\"\n#include \"jemalloc/internal/hash.h\"\n#include \"jemalloc/internal/quarantine.h\"\n#include \"jemalloc/internal/prof.h\"\n\n#undef JEMALLOC_H_TYPES\n/******************************************************************************/\n#define\tJEMALLOC_H_STRUCTS\n\n#include \"jemalloc/internal/nstime.h\"\n#include \"jemalloc/internal/valgrind.h\"\n#include \"jemalloc/internal/util.h\"\n#include \"jemalloc/internal/atomic.h\"\n#include \"jemalloc/internal/prng.h\"\n#include \"jemalloc/internal/ticker.h\"\n#include \"jemalloc/internal/ckh.h\"\n#include \"jemalloc/internal/size_classes.h\"\n#include \"jemalloc/internal/smoothstep.h\"\n#include \"jemalloc/internal/stats.h\"\n#include \"jemalloc/internal/ctl.h\"\n#include \"jemalloc/internal/mutex.h\"\n#include \"jemalloc/internal/mb.h\"\n#include \"jemalloc/internal/bitmap.h\"\n#define\tJEMALLOC_ARENA_STRUCTS_A\n#include \"jemalloc/internal/arena.h\"\n#undef JEMALLOC_ARENA_STRUCTS_A\n#include \"jemalloc/internal/extent.h\"\n#define\tJEMALLOC_ARENA_STRUCTS_B\n#include \"jemalloc/internal/arena.h\"\n#undef JEMALLOC_ARENA_STRUCTS_B\n#include \"jemalloc/internal/base.h\"\n#include \"jemalloc/internal/rtree.h\"\n#include \"jemalloc/internal/pages.h\"\n#include \"jemalloc/internal/chunk.h\"\n#include \"jemalloc/internal/huge.h\"\n#include \"jemalloc/internal/tcache.h\"\n#include \"jemalloc/internal/hash.h\"\n#include \"jemalloc/internal/quarantine.h\"\n#include \"jemalloc/internal/prof.h\"\n\n#include \"jemalloc/internal/tsd.h\"\n\n#undef JEMALLOC_H_STRUCTS\n/******************************************************************************/\n#define\tJEMALLOC_H_EXTERNS\n\nextern bool\topt_abort;\nextern const char\t*opt_junk;\nextern bool\topt_junk_alloc;\nextern bool\topt_junk_free;\nextern size_t\topt_quarantine;\nextern bool\topt_redzone;\nextern bool\topt_utrace;\nextern bool\topt_xmalloc;\nextern bool\topt_zero;\nextern unsigned\topt_narenas;\n\nextern bool\tin_valgrind;\n\n/* Number of CPUs. */\nextern unsigned\tncpus;\n\n/*\n * Arenas that are used to service external requests.  Not all elements of the\n * arenas array are necessarily used; arenas are created lazily as needed.\n */\nextern arena_t\t**arenas;\n\n/*\n * index2size_tab encodes the same information as could be computed (at\n * unacceptable cost in some code paths) by index2size_compute().\n */\nextern size_t const\tindex2size_tab[NSIZES+1];\n/*\n * size2index_tab is a compact lookup table that rounds request sizes up to\n * size classes.  In order to reduce cache footprint, the table is compressed,\n * and all accesses are via size2index().\n */\nextern uint8_t const\tsize2index_tab[];\n\nvoid\t*a0malloc(size_t size);\nvoid\ta0dalloc(void *ptr);\nvoid\t*bootstrap_malloc(size_t size);\nvoid\t*bootstrap_calloc(size_t num, size_t size);\nvoid\tbootstrap_free(void *ptr);\narena_t\t*arenas_extend(unsigned ind);\nunsigned\tnarenas_total_get(void);\narena_t\t*arena_init(unsigned ind);\narena_tdata_t\t*arena_tdata_get_hard(tsd_t *tsd, unsigned ind);\narena_t\t*arena_choose_hard(tsd_t *tsd);\nvoid\tarena_migrate(tsd_t *tsd, unsigned oldind, unsigned newind);\nvoid\tthread_allocated_cleanup(tsd_t *tsd);\nvoid\tthread_deallocated_cleanup(tsd_t *tsd);\nvoid\tarena_cleanup(tsd_t *tsd);\nvoid\tarenas_tdata_cleanup(tsd_t *tsd);\nvoid\tnarenas_tdata_cleanup(tsd_t *tsd);\nvoid\tarenas_tdata_bypass_cleanup(tsd_t *tsd);\nvoid\tjemalloc_prefork(void);\nvoid\tjemalloc_postfork_parent(void);\nvoid\tjemalloc_postfork_child(void);\n\n#include \"jemalloc/internal/nstime.h\"\n#include \"jemalloc/internal/valgrind.h\"\n#include \"jemalloc/internal/util.h\"\n#include \"jemalloc/internal/atomic.h\"\n#include \"jemalloc/internal/prng.h\"\n#include \"jemalloc/internal/ticker.h\"\n#include \"jemalloc/internal/ckh.h\"\n#include \"jemalloc/internal/size_classes.h\"\n#include \"jemalloc/internal/smoothstep.h\"\n#include \"jemalloc/internal/stats.h\"\n#include \"jemalloc/internal/ctl.h\"\n#include \"jemalloc/internal/mutex.h\"\n#include \"jemalloc/internal/mb.h\"\n#include \"jemalloc/internal/bitmap.h\"\n#include \"jemalloc/internal/extent.h\"\n#include \"jemalloc/internal/arena.h\"\n#include \"jemalloc/internal/base.h\"\n#include \"jemalloc/internal/rtree.h\"\n#include \"jemalloc/internal/pages.h\"\n#include \"jemalloc/internal/chunk.h\"\n#include \"jemalloc/internal/huge.h\"\n#include \"jemalloc/internal/tcache.h\"\n#include \"jemalloc/internal/hash.h\"\n#include \"jemalloc/internal/quarantine.h\"\n#include \"jemalloc/internal/prof.h\"\n#include \"jemalloc/internal/tsd.h\"\n\n#undef JEMALLOC_H_EXTERNS\n/******************************************************************************/\n#define\tJEMALLOC_H_INLINES\n\n#include \"jemalloc/internal/nstime.h\"\n#include \"jemalloc/internal/valgrind.h\"\n#include \"jemalloc/internal/util.h\"\n#include \"jemalloc/internal/atomic.h\"\n#include \"jemalloc/internal/prng.h\"\n#include \"jemalloc/internal/ticker.h\"\n#include \"jemalloc/internal/ckh.h\"\n#include \"jemalloc/internal/size_classes.h\"\n#include \"jemalloc/internal/smoothstep.h\"\n#include \"jemalloc/internal/stats.h\"\n#include \"jemalloc/internal/ctl.h\"\n#include \"jemalloc/internal/mutex.h\"\n#include \"jemalloc/internal/tsd.h\"\n#include \"jemalloc/internal/mb.h\"\n#include \"jemalloc/internal/extent.h\"\n#include \"jemalloc/internal/base.h\"\n#include \"jemalloc/internal/rtree.h\"\n#include \"jemalloc/internal/pages.h\"\n#include \"jemalloc/internal/chunk.h\"\n#include \"jemalloc/internal/huge.h\"\n\n#ifndef JEMALLOC_ENABLE_INLINE\nszind_t\tsize2index_compute(size_t size);\nszind_t\tsize2index_lookup(size_t size);\nszind_t\tsize2index(size_t size);\nsize_t\tindex2size_compute(szind_t index);\nsize_t\tindex2size_lookup(szind_t index);\nsize_t\tindex2size(szind_t index);\nsize_t\ts2u_compute(size_t size);\nsize_t\ts2u_lookup(size_t size);\nsize_t\ts2u(size_t size);\nsize_t\tsa2u(size_t size, size_t alignment);\narena_t\t*arena_choose(tsd_t *tsd, arena_t *arena);\narena_tdata_t\t*arena_tdata_get(tsd_t *tsd, unsigned ind,\n    bool refresh_if_missing);\narena_t\t*arena_get(unsigned ind, bool init_if_missing);\nticker_t\t*decay_ticker_get(tsd_t *tsd, unsigned ind);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_C_))\nJEMALLOC_INLINE szind_t\nsize2index_compute(size_t size)\n{\n\n#if (NTBINS != 0)\n\tif (size <= (ZU(1) << LG_TINY_MAXCLASS)) {\n\t\tszind_t lg_tmin = LG_TINY_MAXCLASS - NTBINS + 1;\n\t\tszind_t lg_ceil = lg_floor(pow2_ceil_zu(size));\n\t\treturn (lg_ceil < lg_tmin ? 0 : lg_ceil - lg_tmin);\n\t}\n#endif\n\t{\n\t\tszind_t x = unlikely(ZI(size) < 0) ? ((size<<1) ?\n\t\t    (ZU(1)<<(LG_SIZEOF_PTR+3)) : ((ZU(1)<<(LG_SIZEOF_PTR+3))-1))\n\t\t    : lg_floor((size<<1)-1);\n\t\tszind_t shift = (x < LG_SIZE_CLASS_GROUP + LG_QUANTUM) ? 0 :\n\t\t    x - (LG_SIZE_CLASS_GROUP + LG_QUANTUM);\n\t\tszind_t grp = shift << LG_SIZE_CLASS_GROUP;\n\n\t\tszind_t lg_delta = (x < LG_SIZE_CLASS_GROUP + LG_QUANTUM + 1)\n\t\t    ? LG_QUANTUM : x - LG_SIZE_CLASS_GROUP - 1;\n\n\t\tsize_t delta_inverse_mask = ZI(-1) << lg_delta;\n\t\tszind_t mod = ((((size-1) & delta_inverse_mask) >> lg_delta)) &\n\t\t    ((ZU(1) << LG_SIZE_CLASS_GROUP) - 1);\n\n\t\tszind_t index = NTBINS + grp + mod;\n\t\treturn (index);\n\t}\n}\n\nJEMALLOC_ALWAYS_INLINE szind_t\nsize2index_lookup(size_t size)\n{\n\n\tassert(size <= LOOKUP_MAXCLASS);\n\t{\n\t\tszind_t ret = (size2index_tab[(size-1) >> LG_TINY_MIN]);\n\t\tassert(ret == size2index_compute(size));\n\t\treturn (ret);\n\t}\n}\n\nJEMALLOC_ALWAYS_INLINE szind_t\nsize2index(size_t size)\n{\n\n\tassert(size > 0);\n\tif (likely(size <= LOOKUP_MAXCLASS))\n\t\treturn (size2index_lookup(size));\n\treturn (size2index_compute(size));\n}\n\nJEMALLOC_INLINE size_t\nindex2size_compute(szind_t index)\n{\n\n#if (NTBINS > 0)\n\tif (index < NTBINS)\n\t\treturn (ZU(1) << (LG_TINY_MAXCLASS - NTBINS + 1 + index));\n#endif\n\t{\n\t\tsize_t reduced_index = index - NTBINS;\n\t\tsize_t grp = reduced_index >> LG_SIZE_CLASS_GROUP;\n\t\tsize_t mod = reduced_index & ((ZU(1) << LG_SIZE_CLASS_GROUP) -\n\t\t    1);\n\n\t\tsize_t grp_size_mask = ~((!!grp)-1);\n\t\tsize_t grp_size = ((ZU(1) << (LG_QUANTUM +\n\t\t    (LG_SIZE_CLASS_GROUP-1))) << grp) & grp_size_mask;\n\n\t\tsize_t shift = (grp == 0) ? 1 : grp;\n\t\tsize_t lg_delta = shift + (LG_QUANTUM-1);\n\t\tsize_t mod_size = (mod+1) << lg_delta;\n\n\t\tsize_t usize = grp_size + mod_size;\n\t\treturn (usize);\n\t}\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\nindex2size_lookup(szind_t index)\n{\n\tsize_t ret = (size_t)index2size_tab[index];\n\tassert(ret == index2size_compute(index));\n\treturn (ret);\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\nindex2size(szind_t index)\n{\n\n\tassert(index < NSIZES);\n\treturn (index2size_lookup(index));\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\ns2u_compute(size_t size)\n{\n\n#if (NTBINS > 0)\n\tif (size <= (ZU(1) << LG_TINY_MAXCLASS)) {\n\t\tsize_t lg_tmin = LG_TINY_MAXCLASS - NTBINS + 1;\n\t\tsize_t lg_ceil = lg_floor(pow2_ceil_zu(size));\n\t\treturn (lg_ceil < lg_tmin ? (ZU(1) << lg_tmin) :\n\t\t    (ZU(1) << lg_ceil));\n\t}\n#endif\n\t{\n\t\tsize_t x = unlikely(ZI(size) < 0) ? ((size<<1) ?\n\t\t    (ZU(1)<<(LG_SIZEOF_PTR+3)) : ((ZU(1)<<(LG_SIZEOF_PTR+3))-1))\n\t\t    : lg_floor((size<<1)-1);\n\t\tsize_t lg_delta = (x < LG_SIZE_CLASS_GROUP + LG_QUANTUM + 1)\n\t\t    ?  LG_QUANTUM : x - LG_SIZE_CLASS_GROUP - 1;\n\t\tsize_t delta = ZU(1) << lg_delta;\n\t\tsize_t delta_mask = delta - 1;\n\t\tsize_t usize = (size + delta_mask) & ~delta_mask;\n\t\treturn (usize);\n\t}\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\ns2u_lookup(size_t size)\n{\n\tsize_t ret = index2size_lookup(size2index_lookup(size));\n\n\tassert(ret == s2u_compute(size));\n\treturn (ret);\n}\n\n/*\n * Compute usable size that would result from allocating an object with the\n * specified size.\n */\nJEMALLOC_ALWAYS_INLINE size_t\ns2u(size_t size)\n{\n\n\tassert(size > 0);\n\tif (likely(size <= LOOKUP_MAXCLASS))\n\t\treturn (s2u_lookup(size));\n\treturn (s2u_compute(size));\n}\n\n/*\n * Compute usable size that would result from allocating an object with the\n * specified size and alignment.\n */\nJEMALLOC_ALWAYS_INLINE size_t\nsa2u(size_t size, size_t alignment)\n{\n\tsize_t usize;\n\n\tassert(alignment != 0 && ((alignment - 1) & alignment) == 0);\n\n\t/* Try for a small size class. */\n\tif (size <= SMALL_MAXCLASS && alignment < PAGE) {\n\t\t/*\n\t\t * Round size up to the nearest multiple of alignment.\n\t\t *\n\t\t * This done, we can take advantage of the fact that for each\n\t\t * small size class, every object is aligned at the smallest\n\t\t * power of two that is non-zero in the base two representation\n\t\t * of the size.  For example:\n\t\t *\n\t\t *   Size |   Base 2 | Minimum alignment\n\t\t *   -----+----------+------------------\n\t\t *     96 |  1100000 |  32\n\t\t *    144 | 10100000 |  32\n\t\t *    192 | 11000000 |  64\n\t\t */\n\t\tusize = s2u(ALIGNMENT_CEILING(size, alignment));\n\t\tif (usize < LARGE_MINCLASS)\n\t\t\treturn (usize);\n\t}\n\n\t/* Try for a large size class. */\n\tif (likely(size <= large_maxclass) && likely(alignment < chunksize)) {\n\t\t/*\n\t\t * We can't achieve subpage alignment, so round up alignment\n\t\t * to the minimum that can actually be supported.\n\t\t */\n\t\talignment = PAGE_CEILING(alignment);\n\n\t\t/* Make sure result is a large size class. */\n\t\tusize = (size <= LARGE_MINCLASS) ? LARGE_MINCLASS : s2u(size);\n\n\t\t/*\n\t\t * Calculate the size of the over-size run that arena_palloc()\n\t\t * would need to allocate in order to guarantee the alignment.\n\t\t */\n\t\tif (usize + large_pad + alignment - PAGE <= arena_maxrun)\n\t\t\treturn (usize);\n\t}\n\n\t/* Huge size class.  Beware of overflow. */\n\n\tif (unlikely(alignment > HUGE_MAXCLASS))\n\t\treturn (0);\n\n\t/*\n\t * We can't achieve subchunk alignment, so round up alignment to the\n\t * minimum that can actually be supported.\n\t */\n\talignment = CHUNK_CEILING(alignment);\n\n\t/* Make sure result is a huge size class. */\n\tif (size <= chunksize)\n\t\tusize = chunksize;\n\telse {\n\t\tusize = s2u(size);\n\t\tif (usize < size) {\n\t\t\t/* size_t overflow. */\n\t\t\treturn (0);\n\t\t}\n\t}\n\n\t/*\n\t * Calculate the multi-chunk mapping that huge_palloc() would need in\n\t * order to guarantee the alignment.\n\t */\n\tif (usize + alignment - PAGE < usize) {\n\t\t/* size_t overflow. */\n\t\treturn (0);\n\t}\n\treturn (usize);\n}\n\n/* Choose an arena based on a per-thread value. */\nJEMALLOC_INLINE arena_t *\narena_choose(tsd_t *tsd, arena_t *arena)\n{\n\tarena_t *ret;\n\n\tif (arena != NULL)\n\t\treturn (arena);\n\n\tif (unlikely((ret = tsd_arena_get(tsd)) == NULL))\n\t\tret = arena_choose_hard(tsd);\n\n\treturn (ret);\n}\n\nJEMALLOC_INLINE arena_tdata_t *\narena_tdata_get(tsd_t *tsd, unsigned ind, bool refresh_if_missing)\n{\n\tarena_tdata_t *tdata;\n\tarena_tdata_t *arenas_tdata = tsd_arenas_tdata_get(tsd);\n\n\tif (unlikely(arenas_tdata == NULL)) {\n\t\t/* arenas_tdata hasn't been initialized yet. */\n\t\treturn (arena_tdata_get_hard(tsd, ind));\n\t}\n\tif (unlikely(ind >= tsd_narenas_tdata_get(tsd))) {\n\t\t/*\n\t\t * ind is invalid, cache is old (too small), or tdata to be\n\t\t * initialized.\n\t\t */\n\t\treturn (refresh_if_missing ? arena_tdata_get_hard(tsd, ind) :\n\t\t    NULL);\n\t}\n\n\ttdata = &arenas_tdata[ind];\n\tif (likely(tdata != NULL) || !refresh_if_missing)\n\t\treturn (tdata);\n\treturn (arena_tdata_get_hard(tsd, ind));\n}\n\nJEMALLOC_INLINE arena_t *\narena_get(unsigned ind, bool init_if_missing)\n{\n\tarena_t *ret;\n\n\tassert(ind <= MALLOCX_ARENA_MAX);\n\n\tret = arenas[ind];\n\tif (unlikely(ret == NULL)) {\n\t\tret = atomic_read_p((void *)&arenas[ind]);\n\t\tif (init_if_missing && unlikely(ret == NULL))\n\t\t\tret = arena_init(ind);\n\t}\n\treturn (ret);\n}\n\nJEMALLOC_INLINE ticker_t *\ndecay_ticker_get(tsd_t *tsd, unsigned ind)\n{\n\tarena_tdata_t *tdata;\n\n\ttdata = arena_tdata_get(tsd, ind, true);\n\tif (unlikely(tdata == NULL))\n\t\treturn (NULL);\n\treturn (&tdata->decay_ticker);\n}\n#endif\n\n#include \"jemalloc/internal/bitmap.h\"\n/*\n * Include portions of arena.h interleaved with tcache.h in order to resolve\n * circular dependencies.\n */\n#define\tJEMALLOC_ARENA_INLINE_A\n#include \"jemalloc/internal/arena.h\"\n#undef JEMALLOC_ARENA_INLINE_A\n#include \"jemalloc/internal/tcache.h\"\n#define\tJEMALLOC_ARENA_INLINE_B\n#include \"jemalloc/internal/arena.h\"\n#undef JEMALLOC_ARENA_INLINE_B\n#include \"jemalloc/internal/hash.h\"\n#include \"jemalloc/internal/quarantine.h\"\n\n#ifndef JEMALLOC_ENABLE_INLINE\narena_t\t*iaalloc(const void *ptr);\nsize_t\tisalloc(const void *ptr, bool demote);\nvoid\t*iallocztm(tsd_t *tsd, size_t size, szind_t ind, bool zero,\n    tcache_t *tcache, bool is_metadata, arena_t *arena, bool slow_path);\nvoid\t*imalloct(tsd_t *tsd, size_t size, szind_t ind, tcache_t *tcache,\n    arena_t *arena);\nvoid\t*imalloc(tsd_t *tsd, size_t size, szind_t ind, bool slow_path);\nvoid\t*icalloct(tsd_t *tsd, size_t size, szind_t ind, tcache_t *tcache,\n    arena_t *arena);\nvoid\t*icalloc(tsd_t *tsd, size_t size, szind_t ind);\nvoid\t*ipallocztm(tsd_t *tsd, size_t usize, size_t alignment, bool zero,\n    tcache_t *tcache, bool is_metadata, arena_t *arena);\nvoid\t*ipalloct(tsd_t *tsd, size_t usize, size_t alignment, bool zero,\n    tcache_t *tcache, arena_t *arena);\nvoid\t*ipalloc(tsd_t *tsd, size_t usize, size_t alignment, bool zero);\nsize_t\tivsalloc(const void *ptr, bool demote);\nsize_t\tu2rz(size_t usize);\nsize_t\tp2rz(const void *ptr);\nvoid\tidalloctm(tsd_t *tsd, void *ptr, tcache_t *tcache, bool is_metadata,\n    bool slow_path);\nvoid\tidalloct(tsd_t *tsd, void *ptr, tcache_t *tcache);\nvoid\tidalloc(tsd_t *tsd, void *ptr);\nvoid\tiqalloc(tsd_t *tsd, void *ptr, tcache_t *tcache, bool slow_path);\nvoid\tisdalloct(tsd_t *tsd, void *ptr, size_t size, tcache_t *tcache);\nvoid\tisqalloc(tsd_t *tsd, void *ptr, size_t size, tcache_t *tcache);\nvoid\t*iralloct_realign(tsd_t *tsd, void *ptr, size_t oldsize, size_t size,\n    size_t extra, size_t alignment, bool zero, tcache_t *tcache,\n    arena_t *arena);\nvoid\t*iralloct(tsd_t *tsd, void *ptr, size_t oldsize, size_t size,\n    size_t alignment, bool zero, tcache_t *tcache, arena_t *arena);\nvoid\t*iralloc(tsd_t *tsd, void *ptr, size_t oldsize, size_t size,\n    size_t alignment, bool zero);\nbool\tixalloc(tsd_t *tsd, void *ptr, size_t oldsize, size_t size,\n    size_t extra, size_t alignment, bool zero);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_C_))\nJEMALLOC_ALWAYS_INLINE arena_t *\niaalloc(const void *ptr)\n{\n\n\tassert(ptr != NULL);\n\n\treturn (arena_aalloc(ptr));\n}\n\n/*\n * Typical usage:\n *   void *ptr = [...]\n *   size_t sz = isalloc(ptr, config_prof);\n */\nJEMALLOC_ALWAYS_INLINE size_t\nisalloc(const void *ptr, bool demote)\n{\n\n\tassert(ptr != NULL);\n\t/* Demotion only makes sense if config_prof is true. */\n\tassert(config_prof || !demote);\n\n\treturn (arena_salloc(ptr, demote));\n}\n\nJEMALLOC_ALWAYS_INLINE void *\niallocztm(tsd_t *tsd, size_t size, szind_t ind, bool zero, tcache_t *tcache,\n    bool is_metadata, arena_t *arena, bool slow_path)\n{\n\tvoid *ret;\n\n\tassert(size != 0);\n\n\tret = arena_malloc(tsd, arena, size, ind, zero, tcache, slow_path);\n\tif (config_stats && is_metadata && likely(ret != NULL)) {\n\t\tarena_metadata_allocated_add(iaalloc(ret), isalloc(ret,\n\t\t    config_prof));\n\t}\n\treturn (ret);\n}\n\nJEMALLOC_ALWAYS_INLINE void *\nimalloct(tsd_t *tsd, size_t size, szind_t ind, tcache_t *tcache, arena_t *arena)\n{\n\n\treturn (iallocztm(tsd, size, ind, false, tcache, false, arena, true));\n}\n\nJEMALLOC_ALWAYS_INLINE void *\nimalloc(tsd_t *tsd, size_t size, szind_t ind, bool slow_path)\n{\n\n\treturn (iallocztm(tsd, size, ind, false, tcache_get(tsd, true), false,\n\t    NULL, slow_path));\n}\n\nJEMALLOC_ALWAYS_INLINE void *\nicalloct(tsd_t *tsd, size_t size, szind_t ind, tcache_t *tcache, arena_t *arena)\n{\n\n\treturn (iallocztm(tsd, size, ind, true, tcache, false, arena, true));\n}\n\nJEMALLOC_ALWAYS_INLINE void *\nicalloc(tsd_t *tsd, size_t size, szind_t ind)\n{\n\n\treturn (iallocztm(tsd, size, ind, true, tcache_get(tsd, true), false,\n\t    NULL, true));\n}\n\nJEMALLOC_ALWAYS_INLINE void *\nipallocztm(tsd_t *tsd, size_t usize, size_t alignment, bool zero,\n    tcache_t *tcache, bool is_metadata, arena_t *arena)\n{\n\tvoid *ret;\n\n\tassert(usize != 0);\n\tassert(usize == sa2u(usize, alignment));\n\n\tret = arena_palloc(tsd, arena, usize, alignment, zero, tcache);\n\tassert(ALIGNMENT_ADDR2BASE(ret, alignment) == ret);\n\tif (config_stats && is_metadata && likely(ret != NULL)) {\n\t\tarena_metadata_allocated_add(iaalloc(ret), isalloc(ret,\n\t\t    config_prof));\n\t}\n\treturn (ret);\n}\n\nJEMALLOC_ALWAYS_INLINE void *\nipalloct(tsd_t *tsd, size_t usize, size_t alignment, bool zero,\n    tcache_t *tcache, arena_t *arena)\n{\n\n\treturn (ipallocztm(tsd, usize, alignment, zero, tcache, false, arena));\n}\n\nJEMALLOC_ALWAYS_INLINE void *\nipalloc(tsd_t *tsd, size_t usize, size_t alignment, bool zero)\n{\n\n\treturn (ipallocztm(tsd, usize, alignment, zero, tcache_get(tsd, true),\n\t    false, NULL));\n}\n\nJEMALLOC_ALWAYS_INLINE size_t\nivsalloc(const void *ptr, bool demote)\n{\n\textent_node_t *node;\n\n\t/* Return 0 if ptr is not within a chunk managed by jemalloc. */\n\tnode = chunk_lookup(ptr, false);\n\tif (node == NULL)\n\t\treturn (0);\n\t/* Only arena chunks should be looked up via interior pointers. */\n\tassert(extent_node_addr_get(node) == ptr ||\n\t    extent_node_achunk_get(node));\n\n\treturn (isalloc(ptr, demote));\n}\n\nJEMALLOC_INLINE size_t\nu2rz(size_t usize)\n{\n\tsize_t ret;\n\n\tif (usize <= SMALL_MAXCLASS) {\n\t\tszind_t binind = size2index(usize);\n\t\tret = arena_bin_info[binind].redzone_size;\n\t} else\n\t\tret = 0;\n\n\treturn (ret);\n}\n\nJEMALLOC_INLINE size_t\np2rz(const void *ptr)\n{\n\tsize_t usize = isalloc(ptr, false);\n\n\treturn (u2rz(usize));\n}\n\nJEMALLOC_ALWAYS_INLINE void\nidalloctm(tsd_t *tsd, void *ptr, tcache_t *tcache, bool is_metadata,\n    bool slow_path)\n{\n\n\tassert(ptr != NULL);\n\tif (config_stats && is_metadata) {\n\t\tarena_metadata_allocated_sub(iaalloc(ptr), isalloc(ptr,\n\t\t    config_prof));\n\t}\n\n\tarena_dalloc(tsd, ptr, tcache, slow_path);\n}\n\nJEMALLOC_ALWAYS_INLINE void\nidalloct(tsd_t *tsd, void *ptr, tcache_t *tcache)\n{\n\n\tidalloctm(tsd, ptr, tcache, false, true);\n}\n\nJEMALLOC_ALWAYS_INLINE void\nidalloc(tsd_t *tsd, void *ptr)\n{\n\n\tidalloctm(tsd, ptr, tcache_get(tsd, false), false, true);\n}\n\nJEMALLOC_ALWAYS_INLINE void\niqalloc(tsd_t *tsd, void *ptr, tcache_t *tcache, bool slow_path)\n{\n\n\tif (slow_path && config_fill && unlikely(opt_quarantine))\n\t\tquarantine(tsd, ptr);\n\telse\n\t\tidalloctm(tsd, ptr, tcache, false, slow_path);\n}\n\nJEMALLOC_ALWAYS_INLINE void\nisdalloct(tsd_t *tsd, void *ptr, size_t size, tcache_t *tcache)\n{\n\n\tarena_sdalloc(tsd, ptr, size, tcache);\n}\n\nJEMALLOC_ALWAYS_INLINE void\nisqalloc(tsd_t *tsd, void *ptr, size_t size, tcache_t *tcache)\n{\n\n\tif (config_fill && unlikely(opt_quarantine))\n\t\tquarantine(tsd, ptr);\n\telse\n\t\tisdalloct(tsd, ptr, size, tcache);\n}\n\nJEMALLOC_ALWAYS_INLINE void *\niralloct_realign(tsd_t *tsd, void *ptr, size_t oldsize, size_t size,\n    size_t extra, size_t alignment, bool zero, tcache_t *tcache, arena_t *arena)\n{\n\tvoid *p;\n\tsize_t usize, copysize;\n\n\tusize = sa2u(size + extra, alignment);\n\tif (unlikely(usize == 0 || usize > HUGE_MAXCLASS))\n\t\treturn (NULL);\n\tp = ipalloct(tsd, usize, alignment, zero, tcache, arena);\n\tif (p == NULL) {\n\t\tif (extra == 0)\n\t\t\treturn (NULL);\n\t\t/* Try again, without extra this time. */\n\t\tusize = sa2u(size, alignment);\n\t\tif (unlikely(usize == 0 || usize > HUGE_MAXCLASS))\n\t\t\treturn (NULL);\n\t\tp = ipalloct(tsd, usize, alignment, zero, tcache, arena);\n\t\tif (p == NULL)\n\t\t\treturn (NULL);\n\t}\n\t/*\n\t * Copy at most size bytes (not size+extra), since the caller has no\n\t * expectation that the extra bytes will be reliably preserved.\n\t */\n\tcopysize = (size < oldsize) ? size : oldsize;\n\tmemcpy(p, ptr, copysize);\n\tisqalloc(tsd, ptr, oldsize, tcache);\n\treturn (p);\n}\n\nJEMALLOC_ALWAYS_INLINE void *\niralloct(tsd_t *tsd, void *ptr, size_t oldsize, size_t size, size_t alignment,\n    bool zero, tcache_t *tcache, arena_t *arena)\n{\n\n\tassert(ptr != NULL);\n\tassert(size != 0);\n\n\tif (alignment != 0 && ((uintptr_t)ptr & ((uintptr_t)alignment-1))\n\t    != 0) {\n\t\t/*\n\t\t * Existing object alignment is inadequate; allocate new space\n\t\t * and copy.\n\t\t */\n\t\treturn (iralloct_realign(tsd, ptr, oldsize, size, 0, alignment,\n\t\t    zero, tcache, arena));\n\t}\n\n\treturn (arena_ralloc(tsd, arena, ptr, oldsize, size, alignment, zero,\n\t    tcache));\n}\n\nJEMALLOC_ALWAYS_INLINE void *\niralloc(tsd_t *tsd, void *ptr, size_t oldsize, size_t size, size_t alignment,\n    bool zero)\n{\n\n\treturn (iralloct(tsd, ptr, oldsize, size, alignment, zero,\n\t    tcache_get(tsd, true), NULL));\n}\n\nJEMALLOC_ALWAYS_INLINE bool\nixalloc(tsd_t *tsd, void *ptr, size_t oldsize, size_t size, size_t extra,\n    size_t alignment, bool zero)\n{\n\n\tassert(ptr != NULL);\n\tassert(size != 0);\n\n\tif (alignment != 0 && ((uintptr_t)ptr & ((uintptr_t)alignment-1))\n\t    != 0) {\n\t\t/* Existing object alignment is inadequate. */\n\t\treturn (true);\n\t}\n\n\treturn (arena_ralloc_no_move(tsd, ptr, oldsize, size, extra, zero));\n}\n#endif\n\n#include \"jemalloc/internal/prof.h\"\n\n#undef JEMALLOC_H_INLINES\n/******************************************************************************/\n#endif /* JEMALLOC_INTERNAL_H */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/jemalloc_internal_decls.h",
    "content": "#ifndef JEMALLOC_INTERNAL_DECLS_H\n#define\tJEMALLOC_INTERNAL_DECLS_H\n\n#include <math.h>\n#ifdef _WIN32\n#  include <windows.h>\n#  include \"msvc_compat/windows_extra.h\"\n\n#else\n#  include <sys/param.h>\n#  include <sys/mman.h>\n#  if !defined(__pnacl__) && !defined(__native_client__)\n#    include <sys/syscall.h>\n#    if !defined(SYS_write) && defined(__NR_write)\n#      define SYS_write __NR_write\n#    endif\n#    include <sys/uio.h>\n#  endif\n#  include <pthread.h>\n#  include <errno.h>\n#  include <sys/time.h>\n#endif\n#include <sys/types.h>\n\n#include <limits.h>\n#ifndef SIZE_T_MAX\n#  define SIZE_T_MAX\tSIZE_MAX\n#endif\n#include <stdarg.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <stddef.h>\n#ifndef offsetof\n#  define offsetof(type, member)\t((size_t)&(((type *)NULL)->member))\n#endif\n#include <string.h>\n#include <strings.h>\n#include <ctype.h>\n#ifdef _MSC_VER\n#  include <io.h>\ntypedef intptr_t ssize_t;\n#  define PATH_MAX 1024\n#  define STDERR_FILENO 2\n#  define __func__ __FUNCTION__\n#  ifdef JEMALLOC_HAS_RESTRICT\n#    define restrict __restrict\n#  endif\n/* Disable warnings about deprecated system functions. */\n#  pragma warning(disable: 4996)\n#if _MSC_VER < 1800\nstatic int\nisblank(int c)\n{\n\n\treturn (c == '\\t' || c == ' ');\n}\n#endif\n#else\n#  include <unistd.h>\n#endif\n#include <fcntl.h>\n\n#endif /* JEMALLOC_INTERNAL_H */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/jemalloc_internal_defs.h.in",
    "content": "#ifndef JEMALLOC_INTERNAL_DEFS_H_\n#define\tJEMALLOC_INTERNAL_DEFS_H_\n/*\n * If JEMALLOC_PREFIX is defined via --with-jemalloc-prefix, it will cause all\n * public APIs to be prefixed.  This makes it possible, with some care, to use\n * multiple allocators simultaneously.\n */\n#undef JEMALLOC_PREFIX\n#undef JEMALLOC_CPREFIX\n\n/*\n * JEMALLOC_PRIVATE_NAMESPACE is used as a prefix for all library-private APIs.\n * For shared libraries, symbol visibility mechanisms prevent these symbols\n * from being exported, but for static libraries, naming collisions are a real\n * possibility.\n */\n#undef JEMALLOC_PRIVATE_NAMESPACE\n\n/*\n * Hyper-threaded CPUs may need a special instruction inside spin loops in\n * order to yield to another virtual CPU.\n */\n#undef CPU_SPINWAIT\n\n/* Defined if C11 atomics are available. */\n#undef JEMALLOC_C11ATOMICS\n\n/* Defined if the equivalent of FreeBSD's atomic(9) functions are available. */\n#undef JEMALLOC_ATOMIC9\n\n/*\n * Defined if OSAtomic*() functions are available, as provided by Darwin, and\n * documented in the atomic(3) manual page.\n */\n#undef JEMALLOC_OSATOMIC\n\n/*\n * Defined if __sync_add_and_fetch(uint32_t *, uint32_t) and\n * __sync_sub_and_fetch(uint32_t *, uint32_t) are available, despite\n * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 not being defined (which means the\n * functions are defined in libgcc instead of being inlines).\n */\n#undef JE_FORCE_SYNC_COMPARE_AND_SWAP_4\n\n/*\n * Defined if __sync_add_and_fetch(uint64_t *, uint64_t) and\n * __sync_sub_and_fetch(uint64_t *, uint64_t) are available, despite\n * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 not being defined (which means the\n * functions are defined in libgcc instead of being inlines).\n */\n#undef JE_FORCE_SYNC_COMPARE_AND_SWAP_8\n\n/*\n * Defined if __builtin_clz() and __builtin_clzl() are available.\n */\n#undef JEMALLOC_HAVE_BUILTIN_CLZ\n\n/*\n * Defined if madvise(2) is available.\n */\n#undef JEMALLOC_HAVE_MADVISE\n\n/*\n * Defined if OSSpin*() functions are available, as provided by Darwin, and\n * documented in the spinlock(3) manual page.\n */\n#undef JEMALLOC_OSSPIN\n\n/*\n * Defined if secure_getenv(3) is available.\n */\n#undef JEMALLOC_HAVE_SECURE_GETENV\n\n/*\n * Defined if issetugid(2) is available.\n */\n#undef JEMALLOC_HAVE_ISSETUGID\n\n/*\n * Defined if _malloc_thread_cleanup() exists.  At least in the case of\n * FreeBSD, pthread_key_create() allocates, which if used during malloc\n * bootstrapping will cause recursion into the pthreads library.  Therefore, if\n * _malloc_thread_cleanup() exists, use it as the basis for thread cleanup in\n * malloc_tsd.\n */\n#undef JEMALLOC_MALLOC_THREAD_CLEANUP\n\n/*\n * Defined if threaded initialization is known to be safe on this platform.\n * Among other things, it must be possible to initialize a mutex without\n * triggering allocation in order for threaded allocation to be safe.\n */\n#undef JEMALLOC_THREADED_INIT\n\n/*\n * Defined if the pthreads implementation defines\n * _pthread_mutex_init_calloc_cb(), in which case the function is used in order\n * to avoid recursive allocation during mutex initialization.\n */\n#undef JEMALLOC_MUTEX_INIT_CB\n\n/* Non-empty if the tls_model attribute is supported. */\n#undef JEMALLOC_TLS_MODEL\n\n/* JEMALLOC_CC_SILENCE enables code that silences unuseful compiler warnings. */\n#undef JEMALLOC_CC_SILENCE\n\n/* JEMALLOC_CODE_COVERAGE enables test code coverage analysis. */\n#undef JEMALLOC_CODE_COVERAGE\n\n/*\n * JEMALLOC_DEBUG enables assertions and other sanity checks, and disables\n * inline functions.\n */\n#undef JEMALLOC_DEBUG\n\n/* JEMALLOC_STATS enables statistics calculation. */\n#undef JEMALLOC_STATS\n\n/* JEMALLOC_PROF enables allocation profiling. */\n#undef JEMALLOC_PROF\n\n/* Use libunwind for profile backtracing if defined. */\n#undef JEMALLOC_PROF_LIBUNWIND\n\n/* Use libgcc for profile backtracing if defined. */\n#undef JEMALLOC_PROF_LIBGCC\n\n/* Use gcc intrinsics for profile backtracing if defined. */\n#undef JEMALLOC_PROF_GCC\n\n/*\n * JEMALLOC_TCACHE enables a thread-specific caching layer for small objects.\n * This makes it possible to allocate/deallocate objects without any locking\n * when the cache is in the steady state.\n */\n#undef JEMALLOC_TCACHE\n\n/*\n * JEMALLOC_DSS enables use of sbrk(2) to allocate chunks from the data storage\n * segment (DSS).\n */\n#undef JEMALLOC_DSS\n\n/* Support memory filling (junk/zero/quarantine/redzone). */\n#undef JEMALLOC_FILL\n\n/* Support utrace(2)-based tracing. */\n#undef JEMALLOC_UTRACE\n\n/* Support Valgrind. */\n#undef JEMALLOC_VALGRIND\n\n/* Support optional abort() on OOM. */\n#undef JEMALLOC_XMALLOC\n\n/* Support lazy locking (avoid locking unless a second thread is launched). */\n#undef JEMALLOC_LAZY_LOCK\n\n/* Minimum size class to support is 2^LG_TINY_MIN bytes. */\n#undef LG_TINY_MIN\n\n/*\n * Minimum allocation alignment is 2^LG_QUANTUM bytes (ignoring tiny size\n * classes).\n */\n#undef LG_QUANTUM\n\n/* One page is 2^LG_PAGE bytes. */\n#undef LG_PAGE\n\n/*\n * If defined, adjacent virtual memory mappings with identical attributes\n * automatically coalesce, and they fragment when changes are made to subranges.\n * This is the normal order of things for mmap()/munmap(), but on Windows\n * VirtualAlloc()/VirtualFree() operations must be precisely matched, i.e.\n * mappings do *not* coalesce/fragment.\n */\n#undef JEMALLOC_MAPS_COALESCE\n\n/*\n * If defined, use munmap() to unmap freed chunks, rather than storing them for\n * later reuse.  This is disabled by default on Linux because common sequences\n * of mmap()/munmap() calls will cause virtual memory map holes.\n */\n#undef JEMALLOC_MUNMAP\n\n/* TLS is used to map arenas and magazine caches to threads. */\n#undef JEMALLOC_TLS\n\n/*\n * ffs*() functions to use for bitmapping.  Don't use these directly; instead,\n * use ffs_*() from util.h.\n */\n#undef JEMALLOC_INTERNAL_FFSLL\n#undef JEMALLOC_INTERNAL_FFSL\n#undef JEMALLOC_INTERNAL_FFS\n\n/*\n * JEMALLOC_IVSALLOC enables ivsalloc(), which verifies that pointers reside\n * within jemalloc-owned chunks before dereferencing them.\n */\n#undef JEMALLOC_IVSALLOC\n\n/*\n * If defined, explicitly attempt to more uniformly distribute large allocation\n * pointer alignments across all cache indices.\n */\n#undef JEMALLOC_CACHE_OBLIVIOUS\n\n/*\n * Darwin (OS X) uses zones to work around Mach-O symbol override shortcomings.\n */\n#undef JEMALLOC_ZONE\n#undef JEMALLOC_ZONE_VERSION\n\n/*\n * Methods for purging unused pages differ between operating systems.\n *\n *   madvise(..., MADV_DONTNEED) : On Linux, this immediately discards pages,\n *                                 such that new pages will be demand-zeroed if\n *                                 the address region is later touched.\n *   madvise(..., MADV_FREE) : On FreeBSD and Darwin, this marks pages as being\n *                             unused, such that they will be discarded rather\n *                             than swapped out.\n */\n#undef JEMALLOC_PURGE_MADVISE_DONTNEED\n#undef JEMALLOC_PURGE_MADVISE_FREE\n\n/* Define if operating system has alloca.h header. */\n#undef JEMALLOC_HAS_ALLOCA_H\n\n/* C99 restrict keyword supported. */\n#undef JEMALLOC_HAS_RESTRICT\n\n/* For use by hash code. */\n#undef JEMALLOC_BIG_ENDIAN\n\n/* sizeof(int) == 2^LG_SIZEOF_INT. */\n#undef LG_SIZEOF_INT\n\n/* sizeof(long) == 2^LG_SIZEOF_LONG. */\n#undef LG_SIZEOF_LONG\n\n/* sizeof(long long) == 2^LG_SIZEOF_LONG_LONG. */\n#undef LG_SIZEOF_LONG_LONG\n\n/* sizeof(intmax_t) == 2^LG_SIZEOF_INTMAX_T. */\n#undef LG_SIZEOF_INTMAX_T\n\n/* glibc malloc hooks (__malloc_hook, __realloc_hook, __free_hook). */\n#undef JEMALLOC_GLIBC_MALLOC_HOOK\n\n/* glibc memalign hook. */\n#undef JEMALLOC_GLIBC_MEMALIGN_HOOK\n\n/* Adaptive mutex support in pthreads. */\n#undef JEMALLOC_HAVE_PTHREAD_MUTEX_ADAPTIVE_NP\n\n/*\n * If defined, jemalloc symbols are not exported (doesn't work when\n * JEMALLOC_PREFIX is not defined).\n */\n#undef JEMALLOC_EXPORT\n\n/* config.malloc_conf options string. */\n#undef JEMALLOC_CONFIG_MALLOC_CONF\n\n#endif /* JEMALLOC_INTERNAL_DEFS_H_ */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/jemalloc_internal_macros.h",
    "content": "/*\n * JEMALLOC_ALWAYS_INLINE and JEMALLOC_INLINE are used within header files for\n * functions that are static inline functions if inlining is enabled, and\n * single-definition library-private functions if inlining is disabled.\n *\n * JEMALLOC_ALWAYS_INLINE_C and JEMALLOC_INLINE_C are for use in .c files, in\n * which case the denoted functions are always static, regardless of whether\n * inlining is enabled.\n */\n#if defined(JEMALLOC_DEBUG) || defined(JEMALLOC_CODE_COVERAGE)\n   /* Disable inlining to make debugging/profiling easier. */\n#  define JEMALLOC_ALWAYS_INLINE\n#  define JEMALLOC_ALWAYS_INLINE_C static\n#  define JEMALLOC_INLINE\n#  define JEMALLOC_INLINE_C static\n#  define inline\n#else\n#  define JEMALLOC_ENABLE_INLINE\n#  ifdef JEMALLOC_HAVE_ATTR\n#    define JEMALLOC_ALWAYS_INLINE \\\n\t static inline JEMALLOC_ATTR(unused) JEMALLOC_ATTR(always_inline)\n#    define JEMALLOC_ALWAYS_INLINE_C \\\n\t static inline JEMALLOC_ATTR(always_inline)\n#  else\n#    define JEMALLOC_ALWAYS_INLINE static inline\n#    define JEMALLOC_ALWAYS_INLINE_C static inline\n#  endif\n#  define JEMALLOC_INLINE static inline\n#  define JEMALLOC_INLINE_C static inline\n#  ifdef _MSC_VER\n#    define inline _inline\n#  endif\n#endif\n\n#ifdef JEMALLOC_CC_SILENCE\n#  define UNUSED JEMALLOC_ATTR(unused)\n#else\n#  define UNUSED\n#endif\n\n#define\tZU(z)\t((size_t)z)\n#define\tZI(z)\t((ssize_t)z)\n#define\tQU(q)\t((uint64_t)q)\n#define\tQI(q)\t((int64_t)q)\n\n#define\tKZU(z)\tZU(z##ULL)\n#define\tKZI(z)\tZI(z##LL)\n#define\tKQU(q)\tQU(q##ULL)\n#define\tKQI(q)\tQI(q##LL)\n\n#ifndef __DECONST\n#  define\t__DECONST(type, var)\t((type)(uintptr_t)(const void *)(var))\n#endif\n\n#ifndef JEMALLOC_HAS_RESTRICT\n#  define restrict\n#endif\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/mb.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#ifndef JEMALLOC_ENABLE_INLINE\nvoid\tmb_write(void);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MB_C_))\n#ifdef __i386__\n/*\n * According to the Intel Architecture Software Developer's Manual, current\n * processors execute instructions in order from the perspective of other\n * processors in a multiprocessor system, but 1) Intel reserves the right to\n * change that, and 2) the compiler's optimizer could re-order instructions if\n * there weren't some form of barrier.  Therefore, even if running on an\n * architecture that does not need memory barriers (everything through at least\n * i686), an \"optimizer barrier\" is necessary.\n */\nJEMALLOC_INLINE void\nmb_write(void)\n{\n\n#  if 0\n\t/* This is a true memory barrier. */\n\tasm volatile (\"pusha;\"\n\t    \"xor  %%eax,%%eax;\"\n\t    \"cpuid;\"\n\t    \"popa;\"\n\t    : /* Outputs. */\n\t    : /* Inputs. */\n\t    : \"memory\" /* Clobbers. */\n\t    );\n#else\n\t/*\n\t * This is hopefully enough to keep the compiler from reordering\n\t * instructions around this one.\n\t */\n\tasm volatile (\"nop;\"\n\t    : /* Outputs. */\n\t    : /* Inputs. */\n\t    : \"memory\" /* Clobbers. */\n\t    );\n#endif\n}\n#elif (defined(__amd64__) || defined(__x86_64__))\nJEMALLOC_INLINE void\nmb_write(void)\n{\n\n\tasm volatile (\"sfence\"\n\t    : /* Outputs. */\n\t    : /* Inputs. */\n\t    : \"memory\" /* Clobbers. */\n\t    );\n}\n#elif defined(__powerpc__)\nJEMALLOC_INLINE void\nmb_write(void)\n{\n\n\tasm volatile (\"eieio\"\n\t    : /* Outputs. */\n\t    : /* Inputs. */\n\t    : \"memory\" /* Clobbers. */\n\t    );\n}\n#elif defined(__sparc64__)\nJEMALLOC_INLINE void\nmb_write(void)\n{\n\n\tasm volatile (\"membar #StoreStore\"\n\t    : /* Outputs. */\n\t    : /* Inputs. */\n\t    : \"memory\" /* Clobbers. */\n\t    );\n}\n#elif defined(__tile__)\nJEMALLOC_INLINE void\nmb_write(void)\n{\n\n\t__sync_synchronize();\n}\n#else\n/*\n * This is much slower than a simple memory barrier, but the semantics of mutex\n * unlock make this work.\n */\nJEMALLOC_INLINE void\nmb_write(void)\n{\n\tmalloc_mutex_t mtx;\n\n\tmalloc_mutex_init(&mtx);\n\tmalloc_mutex_lock(&mtx);\n\tmalloc_mutex_unlock(&mtx);\n}\n#endif\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/mutex.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\ntypedef struct malloc_mutex_s malloc_mutex_t;\n\n#ifdef _WIN32\n#  define MALLOC_MUTEX_INITIALIZER\n#elif (defined(JEMALLOC_OSSPIN))\n#  define MALLOC_MUTEX_INITIALIZER {0}\n#elif (defined(JEMALLOC_MUTEX_INIT_CB))\n#  define MALLOC_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER, NULL}\n#else\n#  if (defined(JEMALLOC_HAVE_PTHREAD_MUTEX_ADAPTIVE_NP) &&\t\t\\\n       defined(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP))\n#    define MALLOC_MUTEX_TYPE PTHREAD_MUTEX_ADAPTIVE_NP\n#    define MALLOC_MUTEX_INITIALIZER {PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP}\n#  else\n#    define MALLOC_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT\n#    define MALLOC_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER}\n#  endif\n#endif\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\nstruct malloc_mutex_s {\n#ifdef _WIN32\n#  if _WIN32_WINNT >= 0x0600\n\tSRWLOCK         \tlock;\n#  else\n\tCRITICAL_SECTION\tlock;\n#  endif\n#elif (defined(JEMALLOC_OSSPIN))\n\tOSSpinLock\t\tlock;\n#elif (defined(JEMALLOC_MUTEX_INIT_CB))\n\tpthread_mutex_t\t\tlock;\n\tmalloc_mutex_t\t\t*postponed_next;\n#else\n\tpthread_mutex_t\t\tlock;\n#endif\n};\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\n#ifdef JEMALLOC_LAZY_LOCK\nextern bool isthreaded;\n#else\n#  undef isthreaded /* Undo private_namespace.h definition. */\n#  define isthreaded true\n#endif\n\nbool\tmalloc_mutex_init(malloc_mutex_t *mutex);\nvoid\tmalloc_mutex_prefork(malloc_mutex_t *mutex);\nvoid\tmalloc_mutex_postfork_parent(malloc_mutex_t *mutex);\nvoid\tmalloc_mutex_postfork_child(malloc_mutex_t *mutex);\nbool\tmutex_boot(void);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#ifndef JEMALLOC_ENABLE_INLINE\nvoid\tmalloc_mutex_lock(malloc_mutex_t *mutex);\nvoid\tmalloc_mutex_unlock(malloc_mutex_t *mutex);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MUTEX_C_))\nJEMALLOC_INLINE void\nmalloc_mutex_lock(malloc_mutex_t *mutex)\n{\n\n\tif (isthreaded) {\n#ifdef _WIN32\n#  if _WIN32_WINNT >= 0x0600\n\t\tAcquireSRWLockExclusive(&mutex->lock);\n#  else\n\t\tEnterCriticalSection(&mutex->lock);\n#  endif\n#elif (defined(JEMALLOC_OSSPIN))\n\t\tOSSpinLockLock(&mutex->lock);\n#else\n\t\tpthread_mutex_lock(&mutex->lock);\n#endif\n\t}\n}\n\nJEMALLOC_INLINE void\nmalloc_mutex_unlock(malloc_mutex_t *mutex)\n{\n\n\tif (isthreaded) {\n#ifdef _WIN32\n#  if _WIN32_WINNT >= 0x0600\n\t\tReleaseSRWLockExclusive(&mutex->lock);\n#  else\n\t\tLeaveCriticalSection(&mutex->lock);\n#  endif\n#elif (defined(JEMALLOC_OSSPIN))\n\t\tOSSpinLockUnlock(&mutex->lock);\n#else\n\t\tpthread_mutex_unlock(&mutex->lock);\n#endif\n\t}\n}\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/nstime.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n#define JEMALLOC_CLOCK_GETTIME defined(_POSIX_MONOTONIC_CLOCK) \\\n    && _POSIX_MONOTONIC_CLOCK >= 0\n\ntypedef struct nstime_s nstime_t;\n\n/* Maximum supported number of seconds (~584 years). */\n#define\tNSTIME_SEC_MAX\t18446744072\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\nstruct nstime_s {\n\tuint64_t\tns;\n};\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nvoid\tnstime_init(nstime_t *time, uint64_t ns);\nvoid\tnstime_init2(nstime_t *time, uint64_t sec, uint64_t nsec);\nuint64_t\tnstime_ns(const nstime_t *time);\nuint64_t\tnstime_sec(const nstime_t *time);\nuint64_t\tnstime_nsec(const nstime_t *time);\nvoid\tnstime_copy(nstime_t *time, const nstime_t *source);\nint\tnstime_compare(const nstime_t *a, const nstime_t *b);\nvoid\tnstime_add(nstime_t *time, const nstime_t *addend);\nvoid\tnstime_subtract(nstime_t *time, const nstime_t *subtrahend);\nvoid\tnstime_imultiply(nstime_t *time, uint64_t multiplier);\nvoid\tnstime_idivide(nstime_t *time, uint64_t divisor);\nuint64_t\tnstime_divide(const nstime_t *time, const nstime_t *divisor);\n#ifdef JEMALLOC_JET\ntypedef bool (nstime_update_t)(nstime_t *);\nextern nstime_update_t *nstime_update;\n#else\nbool\tnstime_update(nstime_t *time);\n#endif\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/pages.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nvoid\t*pages_map(void *addr, size_t size);\nvoid\tpages_unmap(void *addr, size_t size);\nvoid\t*pages_trim(void *addr, size_t alloc_size, size_t leadsize,\n    size_t size);\nbool\tpages_commit(void *addr, size_t size);\nbool\tpages_decommit(void *addr, size_t size);\nbool\tpages_purge(void *addr, size_t size);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/private_namespace.sh",
    "content": "#!/bin/sh\n\nfor symbol in `cat $1` ; do\n  echo \"#define\t${symbol} JEMALLOC_N(${symbol})\"\ndone\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/private_symbols.txt",
    "content": "a0dalloc\na0malloc\narena_aalloc\narena_alloc_junk_small\narena_basic_stats_merge\narena_bin_index\narena_bin_info\narena_bitselm_get\narena_boot\narena_choose\narena_choose_hard\narena_chunk_alloc_huge\narena_chunk_cache_maybe_insert\narena_chunk_cache_maybe_remove\narena_chunk_dalloc_huge\narena_chunk_ralloc_huge_expand\narena_chunk_ralloc_huge_shrink\narena_chunk_ralloc_huge_similar\narena_cleanup\narena_dalloc\narena_dalloc_bin\narena_dalloc_bin_junked_locked\narena_dalloc_junk_large\narena_dalloc_junk_small\narena_dalloc_large\narena_dalloc_large_junked_locked\narena_dalloc_small\narena_decay_tick\narena_decay_ticks\narena_decay_time_default_get\narena_decay_time_default_set\narena_decay_time_get\narena_decay_time_set\narena_dss_prec_get\narena_dss_prec_set\narena_get\narena_init\narena_lg_dirty_mult_default_get\narena_lg_dirty_mult_default_set\narena_lg_dirty_mult_get\narena_lg_dirty_mult_set\narena_malloc\narena_malloc_hard\narena_malloc_large\narena_mapbits_allocated_get\narena_mapbits_binind_get\narena_mapbits_decommitted_get\narena_mapbits_dirty_get\narena_mapbits_get\narena_mapbits_internal_set\narena_mapbits_large_binind_set\narena_mapbits_large_get\narena_mapbits_large_set\narena_mapbits_large_size_get\narena_mapbits_size_decode\narena_mapbits_size_encode\narena_mapbits_small_runind_get\narena_mapbits_small_set\narena_mapbits_unallocated_set\narena_mapbits_unallocated_size_get\narena_mapbits_unallocated_size_set\narena_mapbits_unzeroed_get\narena_mapbitsp_get\narena_mapbitsp_read\narena_mapbitsp_write\narena_maxrun\narena_maybe_purge\narena_metadata_allocated_add\narena_metadata_allocated_get\narena_metadata_allocated_sub\narena_migrate\narena_miscelm_get\narena_miscelm_to_pageind\narena_miscelm_to_rpages\narena_new\narena_node_alloc\narena_node_dalloc\narena_nthreads_dec\narena_nthreads_get\narena_nthreads_inc\narena_palloc\narena_postfork_child\narena_postfork_parent\narena_prefork\narena_prof_accum\narena_prof_accum_impl\narena_prof_accum_locked\narena_prof_promoted\narena_prof_tctx_get\narena_prof_tctx_reset\narena_prof_tctx_set\narena_ptr_small_binind_get\narena_purge\narena_quarantine_junk_small\narena_ralloc\narena_ralloc_junk_large\narena_ralloc_no_move\narena_rd_to_miscelm\narena_redzone_corruption\narena_run_regind\narena_run_to_miscelm\narena_salloc\narena_sdalloc\narena_stats_merge\narena_tcache_fill_small\narena_tdata_get\narena_tdata_get_hard\narenas\narenas_tdata_bypass_cleanup\narenas_tdata_cleanup\natomic_add_p\natomic_add_u\natomic_add_uint32\natomic_add_uint64\natomic_add_z\natomic_cas_p\natomic_cas_u\natomic_cas_uint32\natomic_cas_uint64\natomic_cas_z\natomic_sub_p\natomic_sub_u\natomic_sub_uint32\natomic_sub_uint64\natomic_sub_z\nbase_alloc\nbase_boot\nbase_postfork_child\nbase_postfork_parent\nbase_prefork\nbase_stats_get\nbitmap_full\nbitmap_get\nbitmap_info_init\nbitmap_init\nbitmap_set\nbitmap_sfu\nbitmap_size\nbitmap_unset\nbootstrap_calloc\nbootstrap_free\nbootstrap_malloc\nbt_init\nbuferror\nchunk_alloc_base\nchunk_alloc_cache\nchunk_alloc_dss\nchunk_alloc_mmap\nchunk_alloc_wrapper\nchunk_boot\nchunk_dalloc_arena\nchunk_dalloc_cache\nchunk_dalloc_mmap\nchunk_dalloc_wrapper\nchunk_deregister\nchunk_dss_boot\nchunk_dss_postfork_child\nchunk_dss_postfork_parent\nchunk_dss_prec_get\nchunk_dss_prec_set\nchunk_dss_prefork\nchunk_hooks_default\nchunk_hooks_get\nchunk_hooks_set\nchunk_in_dss\nchunk_lookup\nchunk_npages\nchunk_postfork_child\nchunk_postfork_parent\nchunk_prefork\nchunk_purge_arena\nchunk_purge_wrapper\nchunk_register\nchunks_rtree\nchunksize\nchunksize_mask\nckh_count\nckh_delete\nckh_insert\nckh_iter\nckh_new\nckh_pointer_hash\nckh_pointer_keycomp\nckh_remove\nckh_search\nckh_string_hash\nckh_string_keycomp\nctl_boot\nctl_bymib\nctl_byname\nctl_nametomib\nctl_postfork_child\nctl_postfork_parent\nctl_prefork\ndecay_ticker_get\ndss_prec_names\nextent_node_achunk_get\nextent_node_achunk_set\nextent_node_addr_get\nextent_node_addr_set\nextent_node_arena_get\nextent_node_arena_set\nextent_node_dirty_insert\nextent_node_dirty_linkage_init\nextent_node_dirty_remove\nextent_node_init\nextent_node_prof_tctx_get\nextent_node_prof_tctx_set\nextent_node_size_get\nextent_node_size_set\nextent_node_zeroed_get\nextent_node_zeroed_set\nextent_tree_ad_empty\nextent_tree_ad_first\nextent_tree_ad_insert\nextent_tree_ad_iter\nextent_tree_ad_iter_recurse\nextent_tree_ad_iter_start\nextent_tree_ad_last\nextent_tree_ad_new\nextent_tree_ad_next\nextent_tree_ad_nsearch\nextent_tree_ad_prev\nextent_tree_ad_psearch\nextent_tree_ad_remove\nextent_tree_ad_reverse_iter\nextent_tree_ad_reverse_iter_recurse\nextent_tree_ad_reverse_iter_start\nextent_tree_ad_search\nextent_tree_szad_empty\nextent_tree_szad_first\nextent_tree_szad_insert\nextent_tree_szad_iter\nextent_tree_szad_iter_recurse\nextent_tree_szad_iter_start\nextent_tree_szad_last\nextent_tree_szad_new\nextent_tree_szad_next\nextent_tree_szad_nsearch\nextent_tree_szad_prev\nextent_tree_szad_psearch\nextent_tree_szad_remove\nextent_tree_szad_reverse_iter\nextent_tree_szad_reverse_iter_recurse\nextent_tree_szad_reverse_iter_start\nextent_tree_szad_search\nffs_llu\nffs_lu\nffs_u\nffs_u32\nffs_u64\nffs_zu\nget_errno\nhash\nhash_fmix_32\nhash_fmix_64\nhash_get_block_32\nhash_get_block_64\nhash_rotl_32\nhash_rotl_64\nhash_x64_128\nhash_x86_128\nhash_x86_32\nhuge_aalloc\nhuge_dalloc\nhuge_dalloc_junk\nhuge_malloc\nhuge_palloc\nhuge_prof_tctx_get\nhuge_prof_tctx_reset\nhuge_prof_tctx_set\nhuge_ralloc\nhuge_ralloc_no_move\nhuge_salloc\niaalloc\niallocztm\nicalloc\nicalloct\nidalloc\nidalloct\nidalloctm\nimalloc\nimalloct\nin_valgrind\nindex2size\nindex2size_compute\nindex2size_lookup\nindex2size_tab\nipalloc\nipalloct\nipallocztm\niqalloc\niralloc\niralloct\niralloct_realign\nisalloc\nisdalloct\nisqalloc\nisthreaded\nivsalloc\nixalloc\njemalloc_postfork_child\njemalloc_postfork_parent\njemalloc_prefork\nlarge_maxclass\nlg_floor\nmalloc_cprintf\nmalloc_mutex_init\nmalloc_mutex_lock\nmalloc_mutex_postfork_child\nmalloc_mutex_postfork_parent\nmalloc_mutex_prefork\nmalloc_mutex_unlock\nmalloc_printf\nmalloc_snprintf\nmalloc_strtoumax\nmalloc_tsd_boot0\nmalloc_tsd_boot1\nmalloc_tsd_cleanup_register\nmalloc_tsd_dalloc\nmalloc_tsd_malloc\nmalloc_tsd_no_cleanup\nmalloc_vcprintf\nmalloc_vsnprintf\nmalloc_write\nmap_bias\nmap_misc_offset\nmb_write\nmutex_boot\nnarenas_tdata_cleanup\nnarenas_total_get\nncpus\nnhbins\nnstime_add\nnstime_compare\nnstime_copy\nnstime_divide\nnstime_idivide\nnstime_imultiply\nnstime_init\nnstime_init2\nnstime_ns\nnstime_nsec\nnstime_sec\nnstime_subtract\nnstime_update\nopt_abort\nopt_decay_time\nopt_dss\nopt_junk\nopt_junk_alloc\nopt_junk_free\nopt_lg_chunk\nopt_lg_dirty_mult\nopt_lg_prof_interval\nopt_lg_prof_sample\nopt_lg_tcache_max\nopt_narenas\nopt_prof\nopt_prof_accum\nopt_prof_active\nopt_prof_final\nopt_prof_gdump\nopt_prof_leak\nopt_prof_prefix\nopt_prof_thread_active_init\nopt_purge\nopt_quarantine\nopt_redzone\nopt_stats_print\nopt_tcache\nopt_utrace\nopt_xmalloc\nopt_zero\np2rz\npages_commit\npages_decommit\npages_map\npages_purge\npages_trim\npages_unmap\npow2_ceil_u32\npow2_ceil_u64\npow2_ceil_zu\nprng_lg_range\nprng_range\nprof_active_get\nprof_active_get_unlocked\nprof_active_set\nprof_alloc_prep\nprof_alloc_rollback\nprof_backtrace\nprof_boot0\nprof_boot1\nprof_boot2\nprof_dump_header\nprof_dump_open\nprof_free\nprof_free_sampled_object\nprof_gdump\nprof_gdump_get\nprof_gdump_get_unlocked\nprof_gdump_set\nprof_gdump_val\nprof_idump\nprof_interval\nprof_lookup\nprof_malloc\nprof_malloc_sample_object\nprof_mdump\nprof_postfork_child\nprof_postfork_parent\nprof_prefork\nprof_realloc\nprof_reset\nprof_sample_accum_update\nprof_sample_threshold_update\nprof_tctx_get\nprof_tctx_reset\nprof_tctx_set\nprof_tdata_cleanup\nprof_tdata_get\nprof_tdata_init\nprof_tdata_reinit\nprof_thread_active_get\nprof_thread_active_init_get\nprof_thread_active_init_set\nprof_thread_active_set\nprof_thread_name_get\nprof_thread_name_set\npurge_mode_names\nquarantine\nquarantine_alloc_hook\nquarantine_alloc_hook_work\nquarantine_cleanup\nregister_zone\nrtree_child_read\nrtree_child_read_hard\nrtree_child_tryread\nrtree_delete\nrtree_get\nrtree_new\nrtree_node_valid\nrtree_set\nrtree_start_level\nrtree_subkey\nrtree_subtree_read\nrtree_subtree_read_hard\nrtree_subtree_tryread\nrtree_val_read\nrtree_val_write\nrun_quantize_ceil\nrun_quantize_floor\nrun_quantize_max\ns2u\ns2u_compute\ns2u_lookup\nsa2u\nset_errno\nsize2index\nsize2index_compute\nsize2index_lookup\nsize2index_tab\nstats_cactive\nstats_cactive_add\nstats_cactive_get\nstats_cactive_sub\nstats_print\ntcache_alloc_easy\ntcache_alloc_large\ntcache_alloc_small\ntcache_alloc_small_hard\ntcache_arena_associate\ntcache_arena_dissociate\ntcache_arena_reassociate\ntcache_bin_flush_large\ntcache_bin_flush_small\ntcache_bin_info\ntcache_boot\ntcache_cleanup\ntcache_create\ntcache_dalloc_large\ntcache_dalloc_small\ntcache_enabled_cleanup\ntcache_enabled_get\ntcache_enabled_set\ntcache_event\ntcache_event_hard\ntcache_flush\ntcache_get\ntcache_get_hard\ntcache_maxclass\ntcache_salloc\ntcache_stats_merge\ntcaches\ntcaches_create\ntcaches_destroy\ntcaches_flush\ntcaches_get\nthread_allocated_cleanup\nthread_deallocated_cleanup\nticker_copy\nticker_init\nticker_read\nticker_tick\nticker_ticks\ntsd_arena_get\ntsd_arena_set\ntsd_boot\ntsd_boot0\ntsd_boot1\ntsd_booted\ntsd_cleanup\ntsd_cleanup_wrapper\ntsd_fetch\ntsd_get\ntsd_wrapper_get\ntsd_wrapper_set\ntsd_initialized\ntsd_init_check_recursion\ntsd_init_finish\ntsd_init_head\ntsd_nominal\ntsd_prof_tdata_get\ntsd_prof_tdata_set\ntsd_quarantine_get\ntsd_quarantine_set\ntsd_set\ntsd_tcache_enabled_get\ntsd_tcache_enabled_set\ntsd_tcache_get\ntsd_tcache_set\ntsd_thread_allocated_get\ntsd_thread_allocated_set\ntsd_thread_deallocated_get\ntsd_thread_deallocated_set\ntsd_tls\ntsd_tsd\nu2rz\nvalgrind_freelike_block\nvalgrind_make_mem_defined\nvalgrind_make_mem_noaccess\nvalgrind_make_mem_undefined\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/private_unnamespace.sh",
    "content": "#!/bin/sh\n\nfor symbol in `cat $1` ; do\n  echo \"#undef ${symbol}\"\ndone\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/prng.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n/*\n * Simple linear congruential pseudo-random number generator:\n *\n *   prng(y) = (a*x + c) % m\n *\n * where the following constants ensure maximal period:\n *\n *   a == Odd number (relatively prime to 2^n), and (a-1) is a multiple of 4.\n *   c == Odd number (relatively prime to 2^n).\n *   m == 2^32\n *\n * See Knuth's TAOCP 3rd Ed., Vol. 2, pg. 17 for details on these constraints.\n *\n * This choice of m has the disadvantage that the quality of the bits is\n * proportional to bit position.  For example, the lowest bit has a cycle of 2,\n * the next has a cycle of 4, etc.  For this reason, we prefer to use the upper\n * bits.\n */\n#define\tPRNG_A\tUINT64_C(6364136223846793005)\n#define\tPRNG_C\tUINT64_C(1442695040888963407)\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#ifndef JEMALLOC_ENABLE_INLINE\nuint64_t\tprng_lg_range(uint64_t *state, unsigned lg_range);\nuint64_t\tprng_range(uint64_t *state, uint64_t range);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_PRNG_C_))\nJEMALLOC_ALWAYS_INLINE uint64_t\nprng_lg_range(uint64_t *state, unsigned lg_range)\n{\n\tuint64_t ret;\n\n\tassert(lg_range > 0);\n\tassert(lg_range <= 64);\n\n\tret = (*state * PRNG_A) + PRNG_C;\n\t*state = ret;\n\tret >>= (64 - lg_range);\n\n\treturn (ret);\n}\n\nJEMALLOC_ALWAYS_INLINE uint64_t\nprng_range(uint64_t *state, uint64_t range)\n{\n\tuint64_t ret;\n\tunsigned lg_range;\n\n\tassert(range > 1);\n\n\t/* Compute the ceiling of lg(range). */\n\tlg_range = ffs_u64(pow2_ceil_u64(range)) - 1;\n\n\t/* Generate a result in [0..range) via repeated trial. */\n\tdo {\n\t\tret = prng_lg_range(state, lg_range);\n\t} while (ret >= range);\n\n\treturn (ret);\n}\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/prof.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\ntypedef struct prof_bt_s prof_bt_t;\ntypedef struct prof_cnt_s prof_cnt_t;\ntypedef struct prof_tctx_s prof_tctx_t;\ntypedef struct prof_gctx_s prof_gctx_t;\ntypedef struct prof_tdata_s prof_tdata_t;\n\n/* Option defaults. */\n#ifdef JEMALLOC_PROF\n#  define PROF_PREFIX_DEFAULT\t\t\"jeprof\"\n#else\n#  define PROF_PREFIX_DEFAULT\t\t\"\"\n#endif\n#define\tLG_PROF_SAMPLE_DEFAULT\t\t19\n#define\tLG_PROF_INTERVAL_DEFAULT\t-1\n\n/*\n * Hard limit on stack backtrace depth.  The version of prof_backtrace() that\n * is based on __builtin_return_address() necessarily has a hard-coded number\n * of backtrace frame handlers, and should be kept in sync with this setting.\n */\n#define\tPROF_BT_MAX\t\t\t128\n\n/* Initial hash table size. */\n#define\tPROF_CKH_MINITEMS\t\t64\n\n/* Size of memory buffer to use when writing dump files. */\n#define\tPROF_DUMP_BUFSIZE\t\t65536\n\n/* Size of stack-allocated buffer used by prof_printf(). */\n#define\tPROF_PRINTF_BUFSIZE\t\t128\n\n/*\n * Number of mutexes shared among all gctx's.  No space is allocated for these\n * unless profiling is enabled, so it's okay to over-provision.\n */\n#define\tPROF_NCTX_LOCKS\t\t\t1024\n\n/*\n * Number of mutexes shared among all tdata's.  No space is allocated for these\n * unless profiling is enabled, so it's okay to over-provision.\n */\n#define\tPROF_NTDATA_LOCKS\t\t256\n\n/*\n * prof_tdata pointers close to NULL are used to encode state information that\n * is used for cleaning up during thread shutdown.\n */\n#define\tPROF_TDATA_STATE_REINCARNATED\t((prof_tdata_t *)(uintptr_t)1)\n#define\tPROF_TDATA_STATE_PURGATORY\t((prof_tdata_t *)(uintptr_t)2)\n#define\tPROF_TDATA_STATE_MAX\t\tPROF_TDATA_STATE_PURGATORY\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\nstruct prof_bt_s {\n\t/* Backtrace, stored as len program counters. */\n\tvoid\t\t**vec;\n\tunsigned\tlen;\n};\n\n#ifdef JEMALLOC_PROF_LIBGCC\n/* Data structure passed to libgcc _Unwind_Backtrace() callback functions. */\ntypedef struct {\n\tprof_bt_t\t*bt;\n\tunsigned\tmax;\n} prof_unwind_data_t;\n#endif\n\nstruct prof_cnt_s {\n\t/* Profiling counters. */\n\tuint64_t\tcurobjs;\n\tuint64_t\tcurbytes;\n\tuint64_t\taccumobjs;\n\tuint64_t\taccumbytes;\n};\n\ntypedef enum {\n\tprof_tctx_state_initializing,\n\tprof_tctx_state_nominal,\n\tprof_tctx_state_dumping,\n\tprof_tctx_state_purgatory /* Dumper must finish destroying. */\n} prof_tctx_state_t;\n\nstruct prof_tctx_s {\n\t/* Thread data for thread that performed the allocation. */\n\tprof_tdata_t\t\t*tdata;\n\n\t/*\n\t * Copy of tdata->thr_{uid,discrim}, necessary because tdata may be\n\t * defunct during teardown.\n\t */\n\tuint64_t\t\tthr_uid;\n\tuint64_t\t\tthr_discrim;\n\n\t/* Profiling counters, protected by tdata->lock. */\n\tprof_cnt_t\t\tcnts;\n\n\t/* Associated global context. */\n\tprof_gctx_t\t\t*gctx;\n\n\t/*\n\t * UID that distinguishes multiple tctx's created by the same thread,\n\t * but coexisting in gctx->tctxs.  There are two ways that such\n\t * coexistence can occur:\n\t * - A dumper thread can cause a tctx to be retained in the purgatory\n\t *   state.\n\t * - Although a single \"producer\" thread must create all tctx's which\n\t *   share the same thr_uid, multiple \"consumers\" can each concurrently\n\t *   execute portions of prof_tctx_destroy().  prof_tctx_destroy() only\n\t *   gets called once each time cnts.cur{objs,bytes} drop to 0, but this\n\t *   threshold can be hit again before the first consumer finishes\n\t *   executing prof_tctx_destroy().\n\t */\n\tuint64_t\t\ttctx_uid;\n\n\t/* Linkage into gctx's tctxs. */\n\trb_node(prof_tctx_t)\ttctx_link;\n\n\t/*\n\t * True during prof_alloc_prep()..prof_malloc_sample_object(), prevents\n\t * sample vs destroy race.\n\t */\n\tbool\t\t\tprepared;\n\n\t/* Current dump-related state, protected by gctx->lock. */\n\tprof_tctx_state_t\tstate;\n\n\t/*\n\t * Copy of cnts snapshotted during early dump phase, protected by\n\t * dump_mtx.\n\t */\n\tprof_cnt_t\t\tdump_cnts;\n};\ntypedef rb_tree(prof_tctx_t) prof_tctx_tree_t;\n\nstruct prof_gctx_s {\n\t/* Protects nlimbo, cnt_summed, and tctxs. */\n\tmalloc_mutex_t\t\t*lock;\n\n\t/*\n\t * Number of threads that currently cause this gctx to be in a state of\n\t * limbo due to one of:\n\t *   - Initializing this gctx.\n\t *   - Initializing per thread counters associated with this gctx.\n\t *   - Preparing to destroy this gctx.\n\t *   - Dumping a heap profile that includes this gctx.\n\t * nlimbo must be 1 (single destroyer) in order to safely destroy the\n\t * gctx.\n\t */\n\tunsigned\t\tnlimbo;\n\n\t/*\n\t * Tree of profile counters, one for each thread that has allocated in\n\t * this context.\n\t */\n\tprof_tctx_tree_t\ttctxs;\n\n\t/* Linkage for tree of contexts to be dumped. */\n\trb_node(prof_gctx_t)\tdump_link;\n\n\t/* Temporary storage for summation during dump. */\n\tprof_cnt_t\t\tcnt_summed;\n\n\t/* Associated backtrace. */\n\tprof_bt_t\t\tbt;\n\n\t/* Backtrace vector, variable size, referred to by bt. */\n\tvoid\t\t\t*vec[1];\n};\ntypedef rb_tree(prof_gctx_t) prof_gctx_tree_t;\n\nstruct prof_tdata_s {\n\tmalloc_mutex_t\t\t*lock;\n\n\t/* Monotonically increasing unique thread identifier. */\n\tuint64_t\t\tthr_uid;\n\n\t/*\n\t * Monotonically increasing discriminator among tdata structures\n\t * associated with the same thr_uid.\n\t */\n\tuint64_t\t\tthr_discrim;\n\n\t/* Included in heap profile dumps if non-NULL. */\n\tchar\t\t\t*thread_name;\n\n\tbool\t\t\tattached;\n\tbool\t\t\texpired;\n\n\trb_node(prof_tdata_t)\ttdata_link;\n\n\t/*\n\t * Counter used to initialize prof_tctx_t's tctx_uid.  No locking is\n\t * necessary when incrementing this field, because only one thread ever\n\t * does so.\n\t */\n\tuint64_t\t\ttctx_uid_next;\n\n\t/*\n\t * Hash of (prof_bt_t *)-->(prof_tctx_t *).  Each thread tracks\n\t * backtraces for which it has non-zero allocation/deallocation counters\n\t * associated with thread-specific prof_tctx_t objects.  Other threads\n\t * may write to prof_tctx_t contents when freeing associated objects.\n\t */\n\tckh_t\t\t\tbt2tctx;\n\n\t/* Sampling state. */\n\tuint64_t\t\tprng_state;\n\tuint64_t\t\tbytes_until_sample;\n\n\t/* State used to avoid dumping while operating on prof internals. */\n\tbool\t\t\tenq;\n\tbool\t\t\tenq_idump;\n\tbool\t\t\tenq_gdump;\n\n\t/*\n\t * Set to true during an early dump phase for tdata's which are\n\t * currently being dumped.  New threads' tdata's have this initialized\n\t * to false so that they aren't accidentally included in later dump\n\t * phases.\n\t */\n\tbool\t\t\tdumping;\n\n\t/*\n\t * True if profiling is active for this tdata's thread\n\t * (thread.prof.active mallctl).\n\t */\n\tbool\t\t\tactive;\n\n\t/* Temporary storage for summation during dump. */\n\tprof_cnt_t\t\tcnt_summed;\n\n\t/* Backtrace vector, used for calls to prof_backtrace(). */\n\tvoid\t\t\t*vec[PROF_BT_MAX];\n};\ntypedef rb_tree(prof_tdata_t) prof_tdata_tree_t;\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nextern bool\topt_prof;\nextern bool\topt_prof_active;\nextern bool\topt_prof_thread_active_init;\nextern size_t\topt_lg_prof_sample;   /* Mean bytes between samples. */\nextern ssize_t\topt_lg_prof_interval; /* lg(prof_interval). */\nextern bool\topt_prof_gdump;       /* High-water memory dumping. */\nextern bool\topt_prof_final;       /* Final profile dumping. */\nextern bool\topt_prof_leak;        /* Dump leak summary at exit. */\nextern bool\topt_prof_accum;       /* Report cumulative bytes. */\nextern char\topt_prof_prefix[\n    /* Minimize memory bloat for non-prof builds. */\n#ifdef JEMALLOC_PROF\n    PATH_MAX +\n#endif\n    1];\n\n/* Accessed via prof_active_[gs]et{_unlocked,}(). */\nextern bool\tprof_active;\n\n/* Accessed via prof_gdump_[gs]et{_unlocked,}(). */\nextern bool\tprof_gdump_val;\n\n/*\n * Profile dump interval, measured in bytes allocated.  Each arena triggers a\n * profile dump when it reaches this threshold.  The effect is that the\n * interval between profile dumps averages prof_interval, though the actual\n * interval between dumps will tend to be sporadic, and the interval will be a\n * maximum of approximately (prof_interval * narenas).\n */\nextern uint64_t\tprof_interval;\n\n/*\n * Initialized as opt_lg_prof_sample, and potentially modified during profiling\n * resets.\n */\nextern size_t\tlg_prof_sample;\n\nvoid\tprof_alloc_rollback(tsd_t *tsd, prof_tctx_t *tctx, bool updated);\nvoid\tprof_malloc_sample_object(const void *ptr, size_t usize,\n    prof_tctx_t *tctx);\nvoid\tprof_free_sampled_object(tsd_t *tsd, size_t usize, prof_tctx_t *tctx);\nvoid\tbt_init(prof_bt_t *bt, void **vec);\nvoid\tprof_backtrace(prof_bt_t *bt);\nprof_tctx_t\t*prof_lookup(tsd_t *tsd, prof_bt_t *bt);\n#ifdef JEMALLOC_JET\nsize_t\tprof_tdata_count(void);\nsize_t\tprof_bt_count(void);\nconst prof_cnt_t *prof_cnt_all(void);\ntypedef int (prof_dump_open_t)(bool, const char *);\nextern prof_dump_open_t *prof_dump_open;\ntypedef bool (prof_dump_header_t)(bool, const prof_cnt_t *);\nextern prof_dump_header_t *prof_dump_header;\n#endif\nvoid\tprof_idump(void);\nbool\tprof_mdump(const char *filename);\nvoid\tprof_gdump(void);\nprof_tdata_t\t*prof_tdata_init(tsd_t *tsd);\nprof_tdata_t\t*prof_tdata_reinit(tsd_t *tsd, prof_tdata_t *tdata);\nvoid\tprof_reset(tsd_t *tsd, size_t lg_sample);\nvoid\tprof_tdata_cleanup(tsd_t *tsd);\nconst char\t*prof_thread_name_get(void);\nbool\tprof_active_get(void);\nbool\tprof_active_set(bool active);\nint\tprof_thread_name_set(tsd_t *tsd, const char *thread_name);\nbool\tprof_thread_active_get(void);\nbool\tprof_thread_active_set(bool active);\nbool\tprof_thread_active_init_get(void);\nbool\tprof_thread_active_init_set(bool active_init);\nbool\tprof_gdump_get(void);\nbool\tprof_gdump_set(bool active);\nvoid\tprof_boot0(void);\nvoid\tprof_boot1(void);\nbool\tprof_boot2(void);\nvoid\tprof_prefork(void);\nvoid\tprof_postfork_parent(void);\nvoid\tprof_postfork_child(void);\nvoid\tprof_sample_threshold_update(prof_tdata_t *tdata);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#ifndef JEMALLOC_ENABLE_INLINE\nbool\tprof_active_get_unlocked(void);\nbool\tprof_gdump_get_unlocked(void);\nprof_tdata_t\t*prof_tdata_get(tsd_t *tsd, bool create);\nbool\tprof_sample_accum_update(tsd_t *tsd, size_t usize, bool commit,\n    prof_tdata_t **tdata_out);\nprof_tctx_t\t*prof_alloc_prep(tsd_t *tsd, size_t usize, bool prof_active,\n    bool update);\nprof_tctx_t\t*prof_tctx_get(const void *ptr);\nvoid\tprof_tctx_set(const void *ptr, size_t usize, prof_tctx_t *tctx);\nvoid\tprof_tctx_reset(const void *ptr, size_t usize, const void *old_ptr,\n    prof_tctx_t *tctx);\nvoid\tprof_malloc_sample_object(const void *ptr, size_t usize,\n    prof_tctx_t *tctx);\nvoid\tprof_malloc(const void *ptr, size_t usize, prof_tctx_t *tctx);\nvoid\tprof_realloc(tsd_t *tsd, const void *ptr, size_t usize,\n    prof_tctx_t *tctx, bool prof_active, bool updated, const void *old_ptr,\n    size_t old_usize, prof_tctx_t *old_tctx);\nvoid\tprof_free(tsd_t *tsd, const void *ptr, size_t usize);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_PROF_C_))\nJEMALLOC_ALWAYS_INLINE bool\nprof_active_get_unlocked(void)\n{\n\n\t/*\n\t * Even if opt_prof is true, sampling can be temporarily disabled by\n\t * setting prof_active to false.  No locking is used when reading\n\t * prof_active in the fast path, so there are no guarantees regarding\n\t * how long it will take for all threads to notice state changes.\n\t */\n\treturn (prof_active);\n}\n\nJEMALLOC_ALWAYS_INLINE bool\nprof_gdump_get_unlocked(void)\n{\n\n\t/*\n\t * No locking is used when reading prof_gdump_val in the fast path, so\n\t * there are no guarantees regarding how long it will take for all\n\t * threads to notice state changes.\n\t */\n\treturn (prof_gdump_val);\n}\n\nJEMALLOC_ALWAYS_INLINE prof_tdata_t *\nprof_tdata_get(tsd_t *tsd, bool create)\n{\n\tprof_tdata_t *tdata;\n\n\tcassert(config_prof);\n\n\ttdata = tsd_prof_tdata_get(tsd);\n\tif (create) {\n\t\tif (unlikely(tdata == NULL)) {\n\t\t\tif (tsd_nominal(tsd)) {\n\t\t\t\ttdata = prof_tdata_init(tsd);\n\t\t\t\ttsd_prof_tdata_set(tsd, tdata);\n\t\t\t}\n\t\t} else if (unlikely(tdata->expired)) {\n\t\t\ttdata = prof_tdata_reinit(tsd, tdata);\n\t\t\ttsd_prof_tdata_set(tsd, tdata);\n\t\t}\n\t\tassert(tdata == NULL || tdata->attached);\n\t}\n\n\treturn (tdata);\n}\n\nJEMALLOC_ALWAYS_INLINE prof_tctx_t *\nprof_tctx_get(const void *ptr)\n{\n\n\tcassert(config_prof);\n\tassert(ptr != NULL);\n\n\treturn (arena_prof_tctx_get(ptr));\n}\n\nJEMALLOC_ALWAYS_INLINE void\nprof_tctx_set(const void *ptr, size_t usize, prof_tctx_t *tctx)\n{\n\n\tcassert(config_prof);\n\tassert(ptr != NULL);\n\n\tarena_prof_tctx_set(ptr, usize, tctx);\n}\n\nJEMALLOC_ALWAYS_INLINE void\nprof_tctx_reset(const void *ptr, size_t usize, const void *old_ptr,\n    prof_tctx_t *old_tctx)\n{\n\n\tcassert(config_prof);\n\tassert(ptr != NULL);\n\n\tarena_prof_tctx_reset(ptr, usize, old_ptr, old_tctx);\n}\n\nJEMALLOC_ALWAYS_INLINE bool\nprof_sample_accum_update(tsd_t *tsd, size_t usize, bool update,\n    prof_tdata_t **tdata_out)\n{\n\tprof_tdata_t *tdata;\n\n\tcassert(config_prof);\n\n\ttdata = prof_tdata_get(tsd, true);\n\tif (unlikely((uintptr_t)tdata <= (uintptr_t)PROF_TDATA_STATE_MAX))\n\t\ttdata = NULL;\n\n\tif (tdata_out != NULL)\n\t\t*tdata_out = tdata;\n\n\tif (unlikely(tdata == NULL))\n\t\treturn (true);\n\n\tif (likely(tdata->bytes_until_sample >= usize)) {\n\t\tif (update)\n\t\t\ttdata->bytes_until_sample -= usize;\n\t\treturn (true);\n\t} else {\n\t\t/* Compute new sample threshold. */\n\t\tif (update)\n\t\t\tprof_sample_threshold_update(tdata);\n\t\treturn (!tdata->active);\n\t}\n}\n\nJEMALLOC_ALWAYS_INLINE prof_tctx_t *\nprof_alloc_prep(tsd_t *tsd, size_t usize, bool prof_active, bool update)\n{\n\tprof_tctx_t *ret;\n\tprof_tdata_t *tdata;\n\tprof_bt_t bt;\n\n\tassert(usize == s2u(usize));\n\n\tif (!prof_active || likely(prof_sample_accum_update(tsd, usize, update,\n\t    &tdata)))\n\t\tret = (prof_tctx_t *)(uintptr_t)1U;\n\telse {\n\t\tbt_init(&bt, tdata->vec);\n\t\tprof_backtrace(&bt);\n\t\tret = prof_lookup(tsd, &bt);\n\t}\n\n\treturn (ret);\n}\n\nJEMALLOC_ALWAYS_INLINE void\nprof_malloc(const void *ptr, size_t usize, prof_tctx_t *tctx)\n{\n\n\tcassert(config_prof);\n\tassert(ptr != NULL);\n\tassert(usize == isalloc(ptr, true));\n\n\tif (unlikely((uintptr_t)tctx > (uintptr_t)1U))\n\t\tprof_malloc_sample_object(ptr, usize, tctx);\n\telse\n\t\tprof_tctx_set(ptr, usize, (prof_tctx_t *)(uintptr_t)1U);\n}\n\nJEMALLOC_ALWAYS_INLINE void\nprof_realloc(tsd_t *tsd, const void *ptr, size_t usize, prof_tctx_t *tctx,\n    bool prof_active, bool updated, const void *old_ptr, size_t old_usize,\n    prof_tctx_t *old_tctx)\n{\n\tbool sampled, old_sampled;\n\n\tcassert(config_prof);\n\tassert(ptr != NULL || (uintptr_t)tctx <= (uintptr_t)1U);\n\n\tif (prof_active && !updated && ptr != NULL) {\n\t\tassert(usize == isalloc(ptr, true));\n\t\tif (prof_sample_accum_update(tsd, usize, true, NULL)) {\n\t\t\t/*\n\t\t\t * Don't sample.  The usize passed to prof_alloc_prep()\n\t\t\t * was larger than what actually got allocated, so a\n\t\t\t * backtrace was captured for this allocation, even\n\t\t\t * though its actual usize was insufficient to cross the\n\t\t\t * sample threshold.\n\t\t\t */\n\t\t\ttctx = (prof_tctx_t *)(uintptr_t)1U;\n\t\t}\n\t}\n\n\tsampled = ((uintptr_t)tctx > (uintptr_t)1U);\n\told_sampled = ((uintptr_t)old_tctx > (uintptr_t)1U);\n\n\tif (unlikely(sampled))\n\t\tprof_malloc_sample_object(ptr, usize, tctx);\n\telse\n\t\tprof_tctx_reset(ptr, usize, old_ptr, old_tctx);\n\n\tif (unlikely(old_sampled))\n\t\tprof_free_sampled_object(tsd, old_usize, old_tctx);\n}\n\nJEMALLOC_ALWAYS_INLINE void\nprof_free(tsd_t *tsd, const void *ptr, size_t usize)\n{\n\tprof_tctx_t *tctx = prof_tctx_get(ptr);\n\n\tcassert(config_prof);\n\tassert(usize == isalloc(ptr, true));\n\n\tif (unlikely((uintptr_t)tctx > (uintptr_t)1U))\n\t\tprof_free_sampled_object(tsd, usize, tctx);\n}\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/public_namespace.sh",
    "content": "#!/bin/sh\n\nfor nm in `cat $1` ; do\n  n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'`\n  echo \"#define\tje_${n} JEMALLOC_N(${n})\"\ndone\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/public_unnamespace.sh",
    "content": "#!/bin/sh\n\nfor nm in `cat $1` ; do\n  n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'`\n  echo \"#undef je_${n}\"\ndone\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/ql.h",
    "content": "/* List definitions. */\n#define\tql_head(a_type)\t\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\ta_type *qlh_first;\t\t\t\t\t\t\\\n}\n\n#define\tql_head_initializer(a_head) {NULL}\n\n#define\tql_elm(a_type)\tqr(a_type)\n\n/* List functions. */\n#define\tql_new(a_head) do {\t\t\t\t\t\t\\\n\t(a_head)->qlh_first = NULL;\t\t\t\t\t\\\n} while (0)\n\n#define\tql_elm_new(a_elm, a_field) qr_new((a_elm), a_field)\n\n#define\tql_first(a_head) ((a_head)->qlh_first)\n\n#define\tql_last(a_head, a_field)\t\t\t\t\t\\\n\t((ql_first(a_head) != NULL)\t\t\t\t\t\\\n\t    ? qr_prev(ql_first(a_head), a_field) : NULL)\n\n#define\tql_next(a_head, a_elm, a_field)\t\t\t\t\t\\\n\t((ql_last(a_head, a_field) != (a_elm))\t\t\t\t\\\n\t    ? qr_next((a_elm), a_field)\t: NULL)\n\n#define\tql_prev(a_head, a_elm, a_field)\t\t\t\t\t\\\n\t((ql_first(a_head) != (a_elm)) ? qr_prev((a_elm), a_field)\t\\\n\t\t\t\t       : NULL)\n\n#define\tql_before_insert(a_head, a_qlelm, a_elm, a_field) do {\t\t\\\n\tqr_before_insert((a_qlelm), (a_elm), a_field);\t\t\t\\\n\tif (ql_first(a_head) == (a_qlelm)) {\t\t\t\t\\\n\t\tql_first(a_head) = (a_elm);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tql_after_insert(a_qlelm, a_elm, a_field)\t\t\t\\\n\tqr_after_insert((a_qlelm), (a_elm), a_field)\n\n#define\tql_head_insert(a_head, a_elm, a_field) do {\t\t\t\\\n\tif (ql_first(a_head) != NULL) {\t\t\t\t\t\\\n\t\tqr_before_insert(ql_first(a_head), (a_elm), a_field);\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tql_first(a_head) = (a_elm);\t\t\t\t\t\\\n} while (0)\n\n#define\tql_tail_insert(a_head, a_elm, a_field) do {\t\t\t\\\n\tif (ql_first(a_head) != NULL) {\t\t\t\t\t\\\n\t\tqr_before_insert(ql_first(a_head), (a_elm), a_field);\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tql_first(a_head) = qr_next((a_elm), a_field);\t\t\t\\\n} while (0)\n\n#define\tql_remove(a_head, a_elm, a_field) do {\t\t\t\t\\\n\tif (ql_first(a_head) == (a_elm)) {\t\t\t\t\\\n\t\tql_first(a_head) = qr_next(ql_first(a_head), a_field);\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tif (ql_first(a_head) != (a_elm)) {\t\t\t\t\\\n\t\tqr_remove((a_elm), a_field);\t\t\t\t\\\n\t} else {\t\t\t\t\t\t\t\\\n\t\tql_first(a_head) = NULL;\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tql_head_remove(a_head, a_type, a_field) do {\t\t\t\\\n\ta_type *t = ql_first(a_head);\t\t\t\t\t\\\n\tql_remove((a_head), t, a_field);\t\t\t\t\\\n} while (0)\n\n#define\tql_tail_remove(a_head, a_type, a_field) do {\t\t\t\\\n\ta_type *t = ql_last(a_head, a_field);\t\t\t\t\\\n\tql_remove((a_head), t, a_field);\t\t\t\t\\\n} while (0)\n\n#define\tql_foreach(a_var, a_head, a_field)\t\t\t\t\\\n\tqr_foreach((a_var), ql_first(a_head), a_field)\n\n#define\tql_reverse_foreach(a_var, a_head, a_field)\t\t\t\\\n\tqr_reverse_foreach((a_var), ql_first(a_head), a_field)\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/qr.h",
    "content": "/* Ring definitions. */\n#define\tqr(a_type)\t\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\ta_type\t*qre_next;\t\t\t\t\t\t\\\n\ta_type\t*qre_prev;\t\t\t\t\t\t\\\n}\n\n/* Ring functions. */\n#define\tqr_new(a_qr, a_field) do {\t\t\t\t\t\\\n\t(a_qr)->a_field.qre_next = (a_qr);\t\t\t\t\\\n\t(a_qr)->a_field.qre_prev = (a_qr);\t\t\t\t\\\n} while (0)\n\n#define\tqr_next(a_qr, a_field) ((a_qr)->a_field.qre_next)\n\n#define\tqr_prev(a_qr, a_field) ((a_qr)->a_field.qre_prev)\n\n#define\tqr_before_insert(a_qrelm, a_qr, a_field) do {\t\t\t\\\n\t(a_qr)->a_field.qre_prev = (a_qrelm)->a_field.qre_prev;\t\t\\\n\t(a_qr)->a_field.qre_next = (a_qrelm);\t\t\t\t\\\n\t(a_qr)->a_field.qre_prev->a_field.qre_next = (a_qr);\t\t\\\n\t(a_qrelm)->a_field.qre_prev = (a_qr);\t\t\t\t\\\n} while (0)\n\n#define\tqr_after_insert(a_qrelm, a_qr, a_field)\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\t(a_qr)->a_field.qre_next = (a_qrelm)->a_field.qre_next;\t\t\\\n\t(a_qr)->a_field.qre_prev = (a_qrelm);\t\t\t\t\\\n\t(a_qr)->a_field.qre_next->a_field.qre_prev = (a_qr);\t\t\\\n\t(a_qrelm)->a_field.qre_next = (a_qr);\t\t\t\t\\\n    } while (0)\n\n#define\tqr_meld(a_qr_a, a_qr_b, a_field) do {\t\t\t\t\\\n\tvoid *t;\t\t\t\t\t\t\t\\\n\t(a_qr_a)->a_field.qre_prev->a_field.qre_next = (a_qr_b);\t\\\n\t(a_qr_b)->a_field.qre_prev->a_field.qre_next = (a_qr_a);\t\\\n\tt = (a_qr_a)->a_field.qre_prev;\t\t\t\t\t\\\n\t(a_qr_a)->a_field.qre_prev = (a_qr_b)->a_field.qre_prev;\t\\\n\t(a_qr_b)->a_field.qre_prev = t;\t\t\t\t\t\\\n} while (0)\n\n/*\n * qr_meld() and qr_split() are functionally equivalent, so there's no need to\n * have two copies of the code.\n */\n#define\tqr_split(a_qr_a, a_qr_b, a_field)\t\t\t\t\\\n\tqr_meld((a_qr_a), (a_qr_b), a_field)\n\n#define\tqr_remove(a_qr, a_field) do {\t\t\t\t\t\\\n\t(a_qr)->a_field.qre_prev->a_field.qre_next\t\t\t\\\n\t    = (a_qr)->a_field.qre_next;\t\t\t\t\t\\\n\t(a_qr)->a_field.qre_next->a_field.qre_prev\t\t\t\\\n\t    = (a_qr)->a_field.qre_prev;\t\t\t\t\t\\\n\t(a_qr)->a_field.qre_next = (a_qr);\t\t\t\t\\\n\t(a_qr)->a_field.qre_prev = (a_qr);\t\t\t\t\\\n} while (0)\n\n#define\tqr_foreach(var, a_qr, a_field)\t\t\t\t\t\\\n\tfor ((var) = (a_qr);\t\t\t\t\t\t\\\n\t    (var) != NULL;\t\t\t\t\t\t\\\n\t    (var) = (((var)->a_field.qre_next != (a_qr))\t\t\\\n\t    ? (var)->a_field.qre_next : NULL))\n\n#define\tqr_reverse_foreach(var, a_qr, a_field)\t\t\t\t\\\n\tfor ((var) = ((a_qr) != NULL) ? qr_prev(a_qr, a_field) : NULL;\t\\\n\t    (var) != NULL;\t\t\t\t\t\t\\\n\t    (var) = (((var) != (a_qr))\t\t\t\t\t\\\n\t    ? (var)->a_field.qre_prev : NULL))\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/quarantine.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\ntypedef struct quarantine_obj_s quarantine_obj_t;\ntypedef struct quarantine_s quarantine_t;\n\n/* Default per thread quarantine size if valgrind is enabled. */\n#define\tJEMALLOC_VALGRIND_QUARANTINE_DEFAULT\t(ZU(1) << 24)\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\nstruct quarantine_obj_s {\n\tvoid\t*ptr;\n\tsize_t\tusize;\n};\n\nstruct quarantine_s {\n\tsize_t\t\t\tcurbytes;\n\tsize_t\t\t\tcurobjs;\n\tsize_t\t\t\tfirst;\n#define\tLG_MAXOBJS_INIT 10\n\tsize_t\t\t\tlg_maxobjs;\n\tquarantine_obj_t\tobjs[1]; /* Dynamically sized ring buffer. */\n};\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nvoid\tquarantine_alloc_hook_work(tsd_t *tsd);\nvoid\tquarantine(tsd_t *tsd, void *ptr);\nvoid\tquarantine_cleanup(tsd_t *tsd);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#ifndef JEMALLOC_ENABLE_INLINE\nvoid\tquarantine_alloc_hook(void);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_QUARANTINE_C_))\nJEMALLOC_ALWAYS_INLINE void\nquarantine_alloc_hook(void)\n{\n\ttsd_t *tsd;\n\n\tassert(config_fill && opt_quarantine);\n\n\ttsd = tsd_fetch();\n\tif (tsd_quarantine_get(tsd) == NULL)\n\t\tquarantine_alloc_hook_work(tsd);\n}\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/rb.h",
    "content": "/*-\n *******************************************************************************\n *\n * cpp macro implementation of left-leaning 2-3 red-black trees.  Parent\n * pointers are not used, and color bits are stored in the least significant\n * bit of right-child pointers (if RB_COMPACT is defined), thus making node\n * linkage as compact as is possible for red-black trees.\n *\n * Usage:\n *\n *   #include <stdint.h>\n *   #include <stdbool.h>\n *   #define NDEBUG // (Optional, see assert(3).)\n *   #include <assert.h>\n *   #define RB_COMPACT // (Optional, embed color bits in right-child pointers.)\n *   #include <rb.h>\n *   ...\n *\n *******************************************************************************\n */\n\n#ifndef RB_H_\n#define\tRB_H_\n\n#ifdef RB_COMPACT\n/* Node structure. */\n#define\trb_node(a_type)\t\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n    a_type *rbn_left;\t\t\t\t\t\t\t\\\n    a_type *rbn_right_red;\t\t\t\t\t\t\\\n}\n#else\n#define\trb_node(a_type)\t\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n    a_type *rbn_left;\t\t\t\t\t\t\t\\\n    a_type *rbn_right;\t\t\t\t\t\t\t\\\n    bool rbn_red;\t\t\t\t\t\t\t\\\n}\n#endif\n\n/* Root structure. */\n#define\trb_tree(a_type)\t\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n    a_type *rbt_root;\t\t\t\t\t\t\t\\\n}\n\n/* Left accessors. */\n#define\trbtn_left_get(a_type, a_field, a_node)\t\t\t\t\\\n    ((a_node)->a_field.rbn_left)\n#define\trbtn_left_set(a_type, a_field, a_node, a_left) do {\t\t\\\n    (a_node)->a_field.rbn_left = a_left;\t\t\t\t\\\n} while (0)\n\n#ifdef RB_COMPACT\n/* Right accessors. */\n#define\trbtn_right_get(a_type, a_field, a_node)\t\t\t\t\\\n    ((a_type *) (((intptr_t) (a_node)->a_field.rbn_right_red)\t\t\\\n      & ((ssize_t)-2)))\n#define\trbtn_right_set(a_type, a_field, a_node, a_right) do {\t\t\\\n    (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) a_right)\t\\\n      | (((uintptr_t) (a_node)->a_field.rbn_right_red) & ((size_t)1)));\t\\\n} while (0)\n\n/* Color accessors. */\n#define\trbtn_red_get(a_type, a_field, a_node)\t\t\t\t\\\n    ((bool) (((uintptr_t) (a_node)->a_field.rbn_right_red)\t\t\\\n      & ((size_t)1)))\n#define\trbtn_color_set(a_type, a_field, a_node, a_red) do {\t\t\\\n    (a_node)->a_field.rbn_right_red = (a_type *) ((((intptr_t)\t\t\\\n      (a_node)->a_field.rbn_right_red) & ((ssize_t)-2))\t\t\t\\\n      | ((ssize_t)a_red));\t\t\t\t\t\t\\\n} while (0)\n#define\trbtn_red_set(a_type, a_field, a_node) do {\t\t\t\\\n    (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t)\t\t\\\n      (a_node)->a_field.rbn_right_red) | ((size_t)1));\t\t\t\\\n} while (0)\n#define\trbtn_black_set(a_type, a_field, a_node) do {\t\t\t\\\n    (a_node)->a_field.rbn_right_red = (a_type *) (((intptr_t)\t\t\\\n      (a_node)->a_field.rbn_right_red) & ((ssize_t)-2));\t\t\\\n} while (0)\n\n/* Node initializer. */\n#define\trbt_node_new(a_type, a_field, a_rbt, a_node) do {\t\t\\\n    /* Bookkeeping bit cannot be used by node pointer. */\t\t\\\n    assert(((uintptr_t)(a_node) & 0x1) == 0);\t\t\t\t\\\n    rbtn_left_set(a_type, a_field, (a_node), NULL);\t\\\n    rbtn_right_set(a_type, a_field, (a_node), NULL);\t\\\n    rbtn_red_set(a_type, a_field, (a_node));\t\t\t\t\\\n} while (0)\n#else\n/* Right accessors. */\n#define\trbtn_right_get(a_type, a_field, a_node)\t\t\t\t\\\n    ((a_node)->a_field.rbn_right)\n#define\trbtn_right_set(a_type, a_field, a_node, a_right) do {\t\t\\\n    (a_node)->a_field.rbn_right = a_right;\t\t\t\t\\\n} while (0)\n\n/* Color accessors. */\n#define\trbtn_red_get(a_type, a_field, a_node)\t\t\t\t\\\n    ((a_node)->a_field.rbn_red)\n#define\trbtn_color_set(a_type, a_field, a_node, a_red) do {\t\t\\\n    (a_node)->a_field.rbn_red = (a_red);\t\t\t\t\\\n} while (0)\n#define\trbtn_red_set(a_type, a_field, a_node) do {\t\t\t\\\n    (a_node)->a_field.rbn_red = true;\t\t\t\t\t\\\n} while (0)\n#define\trbtn_black_set(a_type, a_field, a_node) do {\t\t\t\\\n    (a_node)->a_field.rbn_red = false;\t\t\t\t\t\\\n} while (0)\n\n/* Node initializer. */\n#define\trbt_node_new(a_type, a_field, a_rbt, a_node) do {\t\t\\\n    rbtn_left_set(a_type, a_field, (a_node), NULL);\t\\\n    rbtn_right_set(a_type, a_field, (a_node), NULL);\t\\\n    rbtn_red_set(a_type, a_field, (a_node));\t\t\t\t\\\n} while (0)\n#endif\n\n/* Tree initializer. */\n#define\trb_new(a_type, a_field, a_rbt) do {\t\t\t\t\\\n    (a_rbt)->rbt_root = NULL;\t\t\t\t\t\t\\\n} while (0)\n\n/* Internal utility macros. */\n#define\trbtn_first(a_type, a_field, a_rbt, a_root, r_node) do {\t\t\\\n    (r_node) = (a_root);\t\t\t\t\t\t\\\n    if ((r_node) != NULL) {\t\t\t\t\t\t\\\n\tfor (;\t\t\t\t\t\t\t\t\\\n\t  rbtn_left_get(a_type, a_field, (r_node)) != NULL;\t\t\\\n\t  (r_node) = rbtn_left_get(a_type, a_field, (r_node))) {\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\trbtn_last(a_type, a_field, a_rbt, a_root, r_node) do {\t\t\\\n    (r_node) = (a_root);\t\t\t\t\t\t\\\n    if ((r_node) != NULL) {\t\t\t\t\t\t\\\n\tfor (; rbtn_right_get(a_type, a_field, (r_node)) != NULL;\t\\\n\t  (r_node) = rbtn_right_get(a_type, a_field, (r_node))) {\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\trbtn_rotate_left(a_type, a_field, a_node, r_node) do {\t\t\\\n    (r_node) = rbtn_right_get(a_type, a_field, (a_node));\t\t\\\n    rbtn_right_set(a_type, a_field, (a_node),\t\t\t\t\\\n      rbtn_left_get(a_type, a_field, (r_node)));\t\t\t\\\n    rbtn_left_set(a_type, a_field, (r_node), (a_node));\t\t\t\\\n} while (0)\n\n#define\trbtn_rotate_right(a_type, a_field, a_node, r_node) do {\t\t\\\n    (r_node) = rbtn_left_get(a_type, a_field, (a_node));\t\t\\\n    rbtn_left_set(a_type, a_field, (a_node),\t\t\t\t\\\n      rbtn_right_get(a_type, a_field, (r_node)));\t\t\t\\\n    rbtn_right_set(a_type, a_field, (r_node), (a_node));\t\t\\\n} while (0)\n\n/*\n * The rb_proto() macro generates function prototypes that correspond to the\n * functions generated by an equivalently parameterized call to rb_gen().\n */\n\n#define\trb_proto(a_attr, a_prefix, a_rbt_type, a_type)\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_prefix##new(a_rbt_type *rbtree);\t\t\t\t\t\\\na_attr bool\t\t\t\t\t\t\t\t\\\na_prefix##empty(a_rbt_type *rbtree);\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##first(a_rbt_type *rbtree);\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##last(a_rbt_type *rbtree);\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##next(a_rbt_type *rbtree, a_type *node);\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##prev(a_rbt_type *rbtree, a_type *node);\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##search(a_rbt_type *rbtree, const a_type *key);\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##nsearch(a_rbt_type *rbtree, const a_type *key);\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##psearch(a_rbt_type *rbtree, const a_type *key);\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_prefix##insert(a_rbt_type *rbtree, a_type *node);\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_prefix##remove(a_rbt_type *rbtree, a_type *node);\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##iter(a_rbt_type *rbtree, a_type *start, a_type *(*cb)(\t\\\n  a_rbt_type *, a_type *, void *), void *arg);\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start,\t\t\\\n  a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg);\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_prefix##destroy(a_rbt_type *rbtree, void (*cb)(a_type *, void *),\t\\\n  void *arg);\n\n/*\n * The rb_gen() macro generates a type-specific red-black tree implementation,\n * based on the above cpp macros.\n *\n * Arguments:\n *\n *   a_attr    : Function attribute for generated functions (ex: static).\n *   a_prefix  : Prefix for generated functions (ex: ex_).\n *   a_rb_type : Type for red-black tree data structure (ex: ex_t).\n *   a_type    : Type for red-black tree node data structure (ex: ex_node_t).\n *   a_field   : Name of red-black tree node linkage (ex: ex_link).\n *   a_cmp     : Node comparison function name, with the following prototype:\n *                 int (a_cmp *)(a_type *a_node, a_type *a_other);\n *                                       ^^^^^^\n *                                    or a_key\n *               Interpretation of comparison function return values:\n *                 -1 : a_node <  a_other\n *                  0 : a_node == a_other\n *                  1 : a_node >  a_other\n *               In all cases, the a_node or a_key macro argument is the first\n *               argument to the comparison function, which makes it possible\n *               to write comparison functions that treat the first argument\n *               specially.\n *\n * Assuming the following setup:\n *\n *   typedef struct ex_node_s ex_node_t;\n *   struct ex_node_s {\n *       rb_node(ex_node_t) ex_link;\n *   };\n *   typedef rb_tree(ex_node_t) ex_t;\n *   rb_gen(static, ex_, ex_t, ex_node_t, ex_link, ex_cmp)\n *\n * The following API is generated:\n *\n *   static void\n *   ex_new(ex_t *tree);\n *       Description: Initialize a red-black tree structure.\n *       Args:\n *         tree: Pointer to an uninitialized red-black tree object.\n *\n *   static bool\n *   ex_empty(ex_t *tree);\n *       Description: Determine whether tree is empty.\n *       Args:\n *         tree: Pointer to an initialized red-black tree object.\n *       Ret: True if tree is empty, false otherwise.\n *\n *   static ex_node_t *\n *   ex_first(ex_t *tree);\n *   static ex_node_t *\n *   ex_last(ex_t *tree);\n *       Description: Get the first/last node in tree.\n *       Args:\n *         tree: Pointer to an initialized red-black tree object.\n *       Ret: First/last node in tree, or NULL if tree is empty.\n *\n *   static ex_node_t *\n *   ex_next(ex_t *tree, ex_node_t *node);\n *   static ex_node_t *\n *   ex_prev(ex_t *tree, ex_node_t *node);\n *       Description: Get node's successor/predecessor.\n *       Args:\n *         tree: Pointer to an initialized red-black tree object.\n *         node: A node in tree.\n *       Ret: node's successor/predecessor in tree, or NULL if node is\n *            last/first.\n *\n *   static ex_node_t *\n *   ex_search(ex_t *tree, const ex_node_t *key);\n *       Description: Search for node that matches key.\n *       Args:\n *         tree: Pointer to an initialized red-black tree object.\n *         key : Search key.\n *       Ret: Node in tree that matches key, or NULL if no match.\n *\n *   static ex_node_t *\n *   ex_nsearch(ex_t *tree, const ex_node_t *key);\n *   static ex_node_t *\n *   ex_psearch(ex_t *tree, const ex_node_t *key);\n *       Description: Search for node that matches key.  If no match is found,\n *                    return what would be key's successor/predecessor, were\n *                    key in tree.\n *       Args:\n *         tree: Pointer to an initialized red-black tree object.\n *         key : Search key.\n *       Ret: Node in tree that matches key, or if no match, hypothetical node's\n *            successor/predecessor (NULL if no successor/predecessor).\n *\n *   static void\n *   ex_insert(ex_t *tree, ex_node_t *node);\n *       Description: Insert node into tree.\n *       Args:\n *         tree: Pointer to an initialized red-black tree object.\n *         node: Node to be inserted into tree.\n *\n *   static void\n *   ex_remove(ex_t *tree, ex_node_t *node);\n *       Description: Remove node from tree.\n *       Args:\n *         tree: Pointer to an initialized red-black tree object.\n *         node: Node in tree to be removed.\n *\n *   static ex_node_t *\n *   ex_iter(ex_t *tree, ex_node_t *start, ex_node_t *(*cb)(ex_t *,\n *     ex_node_t *, void *), void *arg);\n *   static ex_node_t *\n *   ex_reverse_iter(ex_t *tree, ex_node_t *start, ex_node *(*cb)(ex_t *,\n *     ex_node_t *, void *), void *arg);\n *       Description: Iterate forward/backward over tree, starting at node.  If\n *                    tree is modified, iteration must be immediately\n *                    terminated by the callback function that causes the\n *                    modification.\n *       Args:\n *         tree : Pointer to an initialized red-black tree object.\n *         start: Node at which to start iteration, or NULL to start at\n *                first/last node.\n *         cb   : Callback function, which is called for each node during\n *                iteration.  Under normal circumstances the callback function\n *                should return NULL, which causes iteration to continue.  If a\n *                callback function returns non-NULL, iteration is immediately\n *                terminated and the non-NULL return value is returned by the\n *                iterator.  This is useful for re-starting iteration after\n *                modifying tree.\n *         arg  : Opaque pointer passed to cb().\n *       Ret: NULL if iteration completed, or the non-NULL callback return value\n *            that caused termination of the iteration.\n *\n *   static void\n *   ex_destroy(ex_t *tree, void (*cb)(ex_node_t *, void *), void *arg);\n *       Description: Iterate over the tree with post-order traversal, remove\n *                    each node, and run the callback if non-null.  This is\n *                    used for destroying a tree without paying the cost to\n *                    rebalance it.  The tree must not be otherwise altered\n *                    during traversal.\n *       Args:\n *         tree: Pointer to an initialized red-black tree object.\n *         cb  : Callback function, which, if non-null, is called for each node\n *               during iteration.  There is no way to stop iteration once it\n *               has begun.\n *         arg : Opaque pointer passed to cb().\n */\n#define\trb_gen(a_attr, a_prefix, a_rbt_type, a_type, a_field, a_cmp)\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_prefix##new(a_rbt_type *rbtree) {\t\t\t\t\t\\\n    rb_new(a_type, a_field, rbtree);\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr bool\t\t\t\t\t\t\t\t\\\na_prefix##empty(a_rbt_type *rbtree) {\t\t\t\t\t\\\n    return (rbtree->rbt_root == NULL);\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##first(a_rbt_type *rbtree) {\t\t\t\t\t\\\n    a_type *ret;\t\t\t\t\t\t\t\\\n    rbtn_first(a_type, a_field, rbtree, rbtree->rbt_root, ret);\t\t\\\n    return (ret);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##last(a_rbt_type *rbtree) {\t\t\t\t\t\\\n    a_type *ret;\t\t\t\t\t\t\t\\\n    rbtn_last(a_type, a_field, rbtree, rbtree->rbt_root, ret);\t\t\\\n    return (ret);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##next(a_rbt_type *rbtree, a_type *node) {\t\t\t\\\n    a_type *ret;\t\t\t\t\t\t\t\\\n    if (rbtn_right_get(a_type, a_field, node) != NULL) {\t\t\\\n\trbtn_first(a_type, a_field, rbtree, rbtn_right_get(a_type,\t\\\n\t  a_field, node), ret);\t\t\t\t\t\t\\\n    } else {\t\t\t\t\t\t\t\t\\\n\ta_type *tnode = rbtree->rbt_root;\t\t\t\t\\\n\tassert(tnode != NULL);\t\t\t\t\t\t\\\n\tret = NULL;\t\t\t\t\t\t\t\\\n\twhile (true) {\t\t\t\t\t\t\t\\\n\t    int cmp = (a_cmp)(node, tnode);\t\t\t\t\\\n\t    if (cmp < 0) {\t\t\t\t\t\t\\\n\t\tret = tnode;\t\t\t\t\t\t\\\n\t\ttnode = rbtn_left_get(a_type, a_field, tnode);\t\t\\\n\t    } else if (cmp > 0) {\t\t\t\t\t\\\n\t\ttnode = rbtn_right_get(a_type, a_field, tnode);\t\t\\\n\t    } else {\t\t\t\t\t\t\t\\\n\t\tbreak;\t\t\t\t\t\t\t\\\n\t    }\t\t\t\t\t\t\t\t\\\n\t    assert(tnode != NULL);\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    return (ret);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##prev(a_rbt_type *rbtree, a_type *node) {\t\t\t\\\n    a_type *ret;\t\t\t\t\t\t\t\\\n    if (rbtn_left_get(a_type, a_field, node) != NULL) {\t\t\t\\\n\trbtn_last(a_type, a_field, rbtree, rbtn_left_get(a_type,\t\\\n\t  a_field, node), ret);\t\t\t\t\t\t\\\n    } else {\t\t\t\t\t\t\t\t\\\n\ta_type *tnode = rbtree->rbt_root;\t\t\t\t\\\n\tassert(tnode != NULL);\t\t\t\t\t\t\\\n\tret = NULL;\t\t\t\t\t\t\t\\\n\twhile (true) {\t\t\t\t\t\t\t\\\n\t    int cmp = (a_cmp)(node, tnode);\t\t\t\t\\\n\t    if (cmp < 0) {\t\t\t\t\t\t\\\n\t\ttnode = rbtn_left_get(a_type, a_field, tnode);\t\t\\\n\t    } else if (cmp > 0) {\t\t\t\t\t\\\n\t\tret = tnode;\t\t\t\t\t\t\\\n\t\ttnode = rbtn_right_get(a_type, a_field, tnode);\t\t\\\n\t    } else {\t\t\t\t\t\t\t\\\n\t\tbreak;\t\t\t\t\t\t\t\\\n\t    }\t\t\t\t\t\t\t\t\\\n\t    assert(tnode != NULL);\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    return (ret);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##search(a_rbt_type *rbtree, const a_type *key) {\t\t\\\n    a_type *ret;\t\t\t\t\t\t\t\\\n    int cmp;\t\t\t\t\t\t\t\t\\\n    ret = rbtree->rbt_root;\t\t\t\t\t\t\\\n    while (ret != NULL\t\t\t\t\t\t\t\\\n      && (cmp = (a_cmp)(key, ret)) != 0) {\t\t\t\t\\\n\tif (cmp < 0) {\t\t\t\t\t\t\t\\\n\t    ret = rbtn_left_get(a_type, a_field, ret);\t\t\t\\\n\t} else {\t\t\t\t\t\t\t\\\n\t    ret = rbtn_right_get(a_type, a_field, ret);\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\t\\\n    return (ret);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##nsearch(a_rbt_type *rbtree, const a_type *key) {\t\t\\\n    a_type *ret;\t\t\t\t\t\t\t\\\n    a_type *tnode = rbtree->rbt_root;\t\t\t\t\t\\\n    ret = NULL;\t\t\t\t\t\t\t\t\\\n    while (tnode != NULL) {\t\t\t\t\t\t\\\n\tint cmp = (a_cmp)(key, tnode);\t\t\t\t\t\\\n\tif (cmp < 0) {\t\t\t\t\t\t\t\\\n\t    ret = tnode;\t\t\t\t\t\t\\\n\t    tnode = rbtn_left_get(a_type, a_field, tnode);\t\t\\\n\t} else if (cmp > 0) {\t\t\t\t\t\t\\\n\t    tnode = rbtn_right_get(a_type, a_field, tnode);\t\t\\\n\t} else {\t\t\t\t\t\t\t\\\n\t    ret = tnode;\t\t\t\t\t\t\\\n\t    break;\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    return (ret);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##psearch(a_rbt_type *rbtree, const a_type *key) {\t\t\\\n    a_type *ret;\t\t\t\t\t\t\t\\\n    a_type *tnode = rbtree->rbt_root;\t\t\t\t\t\\\n    ret = NULL;\t\t\t\t\t\t\t\t\\\n    while (tnode != NULL) {\t\t\t\t\t\t\\\n\tint cmp = (a_cmp)(key, tnode);\t\t\t\t\t\\\n\tif (cmp < 0) {\t\t\t\t\t\t\t\\\n\t    tnode = rbtn_left_get(a_type, a_field, tnode);\t\t\\\n\t} else if (cmp > 0) {\t\t\t\t\t\t\\\n\t    ret = tnode;\t\t\t\t\t\t\\\n\t    tnode = rbtn_right_get(a_type, a_field, tnode);\t\t\\\n\t} else {\t\t\t\t\t\t\t\\\n\t    ret = tnode;\t\t\t\t\t\t\\\n\t    break;\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    return (ret);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_prefix##insert(a_rbt_type *rbtree, a_type *node) {\t\t\t\\\n    struct {\t\t\t\t\t\t\t\t\\\n\ta_type *node;\t\t\t\t\t\t\t\\\n\tint cmp;\t\t\t\t\t\t\t\\\n    } path[sizeof(void *) << 4], *pathp;\t\t\t\t\\\n    rbt_node_new(a_type, a_field, rbtree, node);\t\t\t\\\n    /* Wind. */\t\t\t\t\t\t\t\t\\\n    path->node = rbtree->rbt_root;\t\t\t\t\t\\\n    for (pathp = path; pathp->node != NULL; pathp++) {\t\t\t\\\n\tint cmp = pathp->cmp = a_cmp(node, pathp->node);\t\t\\\n\tassert(cmp != 0);\t\t\t\t\t\t\\\n\tif (cmp < 0) {\t\t\t\t\t\t\t\\\n\t    pathp[1].node = rbtn_left_get(a_type, a_field,\t\t\\\n\t      pathp->node);\t\t\t\t\t\t\\\n\t} else {\t\t\t\t\t\t\t\\\n\t    pathp[1].node = rbtn_right_get(a_type, a_field,\t\t\\\n\t      pathp->node);\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    pathp->node = node;\t\t\t\t\t\t\t\\\n    /* Unwind. */\t\t\t\t\t\t\t\\\n    for (pathp--; (uintptr_t)pathp >= (uintptr_t)path; pathp--) {\t\\\n\ta_type *cnode = pathp->node;\t\t\t\t\t\\\n\tif (pathp->cmp < 0) {\t\t\t\t\t\t\\\n\t    a_type *left = pathp[1].node;\t\t\t\t\\\n\t    rbtn_left_set(a_type, a_field, cnode, left);\t\t\\\n\t    if (rbtn_red_get(a_type, a_field, left)) {\t\t\t\\\n\t\ta_type *leftleft = rbtn_left_get(a_type, a_field, left);\\\n\t\tif (leftleft != NULL && rbtn_red_get(a_type, a_field,\t\\\n\t\t  leftleft)) {\t\t\t\t\t\t\\\n\t\t    /* Fix up 4-node. */\t\t\t\t\\\n\t\t    a_type *tnode;\t\t\t\t\t\\\n\t\t    rbtn_black_set(a_type, a_field, leftleft);\t\t\\\n\t\t    rbtn_rotate_right(a_type, a_field, cnode, tnode);\t\\\n\t\t    cnode = tnode;\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t    } else {\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t    }\t\t\t\t\t\t\t\t\\\n\t} else {\t\t\t\t\t\t\t\\\n\t    a_type *right = pathp[1].node;\t\t\t\t\\\n\t    rbtn_right_set(a_type, a_field, cnode, right);\t\t\\\n\t    if (rbtn_red_get(a_type, a_field, right)) {\t\t\t\\\n\t\ta_type *left = rbtn_left_get(a_type, a_field, cnode);\t\\\n\t\tif (left != NULL && rbtn_red_get(a_type, a_field,\t\\\n\t\t  left)) {\t\t\t\t\t\t\\\n\t\t    /* Split 4-node. */\t\t\t\t\t\\\n\t\t    rbtn_black_set(a_type, a_field, left);\t\t\\\n\t\t    rbtn_black_set(a_type, a_field, right);\t\t\\\n\t\t    rbtn_red_set(a_type, a_field, cnode);\t\t\\\n\t\t} else {\t\t\t\t\t\t\\\n\t\t    /* Lean left. */\t\t\t\t\t\\\n\t\t    a_type *tnode;\t\t\t\t\t\\\n\t\t    bool tred = rbtn_red_get(a_type, a_field, cnode);\t\\\n\t\t    rbtn_rotate_left(a_type, a_field, cnode, tnode);\t\\\n\t\t    rbtn_color_set(a_type, a_field, tnode, tred);\t\\\n\t\t    rbtn_red_set(a_type, a_field, cnode);\t\t\\\n\t\t    cnode = tnode;\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t    } else {\t\t\t\t\t\t\t\\\n\t\treturn;\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\tpathp->node = cnode;\t\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\t\\\n    /* Set root, and make it black. */\t\t\t\t\t\\\n    rbtree->rbt_root = path->node;\t\t\t\t\t\\\n    rbtn_black_set(a_type, a_field, rbtree->rbt_root);\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_prefix##remove(a_rbt_type *rbtree, a_type *node) {\t\t\t\\\n    struct {\t\t\t\t\t\t\t\t\\\n\ta_type *node;\t\t\t\t\t\t\t\\\n\tint cmp;\t\t\t\t\t\t\t\\\n    } *pathp, *nodep, path[sizeof(void *) << 4];\t\t\t\\\n    /* Wind. */\t\t\t\t\t\t\t\t\\\n    nodep = NULL; /* Silence compiler warning. */\t\t\t\\\n    path->node = rbtree->rbt_root;\t\t\t\t\t\\\n    for (pathp = path; pathp->node != NULL; pathp++) {\t\t\t\\\n\tint cmp = pathp->cmp = a_cmp(node, pathp->node);\t\t\\\n\tif (cmp < 0) {\t\t\t\t\t\t\t\\\n\t    pathp[1].node = rbtn_left_get(a_type, a_field,\t\t\\\n\t      pathp->node);\t\t\t\t\t\t\\\n\t} else {\t\t\t\t\t\t\t\\\n\t    pathp[1].node = rbtn_right_get(a_type, a_field,\t\t\\\n\t      pathp->node);\t\t\t\t\t\t\\\n\t    if (cmp == 0) {\t\t\t\t\t\t\\\n\t        /* Find node's successor, in preparation for swap. */\t\\\n\t\tpathp->cmp = 1;\t\t\t\t\t\t\\\n\t\tnodep = pathp;\t\t\t\t\t\t\\\n\t\tfor (pathp++; pathp->node != NULL;\t\t\t\\\n\t\t  pathp++) {\t\t\t\t\t\t\\\n\t\t    pathp->cmp = -1;\t\t\t\t\t\\\n\t\t    pathp[1].node = rbtn_left_get(a_type, a_field,\t\\\n\t\t      pathp->node);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t\tbreak;\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    }\t\t\t\t\t\t\t\t\t\\\n    assert(nodep->node == node);\t\t\t\t\t\\\n    pathp--;\t\t\t\t\t\t\t\t\\\n    if (pathp->node != node) {\t\t\t\t\t\t\\\n\t/* Swap node with its successor. */\t\t\t\t\\\n\tbool tred = rbtn_red_get(a_type, a_field, pathp->node);\t\t\\\n\trbtn_color_set(a_type, a_field, pathp->node,\t\t\t\\\n\t  rbtn_red_get(a_type, a_field, node));\t\t\t\t\\\n\trbtn_left_set(a_type, a_field, pathp->node,\t\t\t\\\n\t  rbtn_left_get(a_type, a_field, node));\t\t\t\\\n\t/* If node's successor is its right child, the following code */\\\n\t/* will do the wrong thing for the right child pointer.       */\\\n\t/* However, it doesn't matter, because the pointer will be    */\\\n\t/* properly set when the successor is pruned.                 */\\\n\trbtn_right_set(a_type, a_field, pathp->node,\t\t\t\\\n\t  rbtn_right_get(a_type, a_field, node));\t\t\t\\\n\trbtn_color_set(a_type, a_field, node, tred);\t\t\t\\\n\t/* The pruned leaf node's child pointers are never accessed   */\\\n\t/* again, so don't bother setting them to nil.                */\\\n\tnodep->node = pathp->node;\t\t\t\t\t\\\n\tpathp->node = node;\t\t\t\t\t\t\\\n\tif (nodep == path) {\t\t\t\t\t\t\\\n\t    rbtree->rbt_root = nodep->node;\t\t\t\t\\\n\t} else {\t\t\t\t\t\t\t\\\n\t    if (nodep[-1].cmp < 0) {\t\t\t\t\t\\\n\t\trbtn_left_set(a_type, a_field, nodep[-1].node,\t\t\\\n\t\t  nodep->node);\t\t\t\t\t\t\\\n\t    } else {\t\t\t\t\t\t\t\\\n\t\trbtn_right_set(a_type, a_field, nodep[-1].node,\t\t\\\n\t\t  nodep->node);\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    } else {\t\t\t\t\t\t\t\t\\\n\ta_type *left = rbtn_left_get(a_type, a_field, node);\t\t\\\n\tif (left != NULL) {\t\t\t\t\t\t\\\n\t    /* node has no successor, but it has a left child.        */\\\n\t    /* Splice node out, without losing the left child.        */\\\n\t    assert(!rbtn_red_get(a_type, a_field, node));\t\t\\\n\t    assert(rbtn_red_get(a_type, a_field, left));\t\t\\\n\t    rbtn_black_set(a_type, a_field, left);\t\t\t\\\n\t    if (pathp == path) {\t\t\t\t\t\\\n\t\trbtree->rbt_root = left;\t\t\t\t\\\n\t    } else {\t\t\t\t\t\t\t\\\n\t\tif (pathp[-1].cmp < 0) {\t\t\t\t\\\n\t\t    rbtn_left_set(a_type, a_field, pathp[-1].node,\t\\\n\t\t      left);\t\t\t\t\t\t\\\n\t\t} else {\t\t\t\t\t\t\\\n\t\t    rbtn_right_set(a_type, a_field, pathp[-1].node,\t\\\n\t\t      left);\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\t    return;\t\t\t\t\t\t\t\\\n\t} else if (pathp == path) {\t\t\t\t\t\\\n\t    /* The tree only contained one node. */\t\t\t\\\n\t    rbtree->rbt_root = NULL;\t\t\t\t\t\\\n\t    return;\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    if (rbtn_red_get(a_type, a_field, pathp->node)) {\t\t\t\\\n\t/* Prune red node, which requires no fixup. */\t\t\t\\\n\tassert(pathp[-1].cmp < 0);\t\t\t\t\t\\\n\trbtn_left_set(a_type, a_field, pathp[-1].node, NULL);\t\t\\\n\treturn;\t\t\t\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\t\\\n    /* The node to be pruned is black, so unwind until balance is     */\\\n    /* restored.                                                      */\\\n    pathp->node = NULL;\t\t\t\t\t\t\t\\\n    for (pathp--; (uintptr_t)pathp >= (uintptr_t)path; pathp--) {\t\\\n\tassert(pathp->cmp != 0);\t\t\t\t\t\\\n\tif (pathp->cmp < 0) {\t\t\t\t\t\t\\\n\t    rbtn_left_set(a_type, a_field, pathp->node,\t\t\t\\\n\t      pathp[1].node);\t\t\t\t\t\t\\\n\t    if (rbtn_red_get(a_type, a_field, pathp->node)) {\t\t\\\n\t\ta_type *right = rbtn_right_get(a_type, a_field,\t\t\\\n\t\t  pathp->node);\t\t\t\t\t\t\\\n\t\ta_type *rightleft = rbtn_left_get(a_type, a_field,\t\\\n\t\t  right);\t\t\t\t\t\t\\\n\t\ta_type *tnode;\t\t\t\t\t\t\\\n\t\tif (rightleft != NULL && rbtn_red_get(a_type, a_field,\t\\\n\t\t  rightleft)) {\t\t\t\t\t\t\\\n\t\t    /* In the following diagrams, ||, //, and \\\\      */\\\n\t\t    /* indicate the path to the removed node.         */\\\n\t\t    /*                                                */\\\n\t\t    /*      ||                                        */\\\n\t\t    /*    pathp(r)                                    */\\\n\t\t    /*  //        \\                                   */\\\n\t\t    /* (b)        (b)                                 */\\\n\t\t    /*           /                                    */\\\n\t\t    /*          (r)                                   */\\\n\t\t    /*                                                */\\\n\t\t    rbtn_black_set(a_type, a_field, pathp->node);\t\\\n\t\t    rbtn_rotate_right(a_type, a_field, right, tnode);\t\\\n\t\t    rbtn_right_set(a_type, a_field, pathp->node, tnode);\\\n\t\t    rbtn_rotate_left(a_type, a_field, pathp->node,\t\\\n\t\t      tnode);\t\t\t\t\t\t\\\n\t\t} else {\t\t\t\t\t\t\\\n\t\t    /*      ||                                        */\\\n\t\t    /*    pathp(r)                                    */\\\n\t\t    /*  //        \\                                   */\\\n\t\t    /* (b)        (b)                                 */\\\n\t\t    /*           /                                    */\\\n\t\t    /*          (b)                                   */\\\n\t\t    /*                                                */\\\n\t\t    rbtn_rotate_left(a_type, a_field, pathp->node,\t\\\n\t\t      tnode);\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t\t/* Balance restored, but rotation modified subtree    */\\\n\t\t/* root.                                              */\\\n\t\tassert((uintptr_t)pathp > (uintptr_t)path);\t\t\\\n\t\tif (pathp[-1].cmp < 0) {\t\t\t\t\\\n\t\t    rbtn_left_set(a_type, a_field, pathp[-1].node,\t\\\n\t\t      tnode);\t\t\t\t\t\t\\\n\t\t} else {\t\t\t\t\t\t\\\n\t\t    rbtn_right_set(a_type, a_field, pathp[-1].node,\t\\\n\t\t      tnode);\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t    } else {\t\t\t\t\t\t\t\\\n\t\ta_type *right = rbtn_right_get(a_type, a_field,\t\t\\\n\t\t  pathp->node);\t\t\t\t\t\t\\\n\t\ta_type *rightleft = rbtn_left_get(a_type, a_field,\t\\\n\t\t  right);\t\t\t\t\t\t\\\n\t\tif (rightleft != NULL && rbtn_red_get(a_type, a_field,\t\\\n\t\t  rightleft)) {\t\t\t\t\t\t\\\n\t\t    /*      ||                                        */\\\n\t\t    /*    pathp(b)                                    */\\\n\t\t    /*  //        \\                                   */\\\n\t\t    /* (b)        (b)                                 */\\\n\t\t    /*           /                                    */\\\n\t\t    /*          (r)                                   */\\\n\t\t    a_type *tnode;\t\t\t\t\t\\\n\t\t    rbtn_black_set(a_type, a_field, rightleft);\t\t\\\n\t\t    rbtn_rotate_right(a_type, a_field, right, tnode);\t\\\n\t\t    rbtn_right_set(a_type, a_field, pathp->node, tnode);\\\n\t\t    rbtn_rotate_left(a_type, a_field, pathp->node,\t\\\n\t\t      tnode);\t\t\t\t\t\t\\\n\t\t    /* Balance restored, but rotation modified        */\\\n\t\t    /* subtree root, which may actually be the tree   */\\\n\t\t    /* root.                                          */\\\n\t\t    if (pathp == path) {\t\t\t\t\\\n\t\t\t/* Set root. */\t\t\t\t\t\\\n\t\t\trbtree->rbt_root = tnode;\t\t\t\\\n\t\t    } else {\t\t\t\t\t\t\\\n\t\t\tif (pathp[-1].cmp < 0) {\t\t\t\\\n\t\t\t    rbtn_left_set(a_type, a_field,\t\t\\\n\t\t\t      pathp[-1].node, tnode);\t\t\t\\\n\t\t\t} else {\t\t\t\t\t\\\n\t\t\t    rbtn_right_set(a_type, a_field,\t\t\\\n\t\t\t      pathp[-1].node, tnode);\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\\\n\t\t    }\t\t\t\t\t\t\t\\\n\t\t    return;\t\t\t\t\t\t\\\n\t\t} else {\t\t\t\t\t\t\\\n\t\t    /*      ||                                        */\\\n\t\t    /*    pathp(b)                                    */\\\n\t\t    /*  //        \\                                   */\\\n\t\t    /* (b)        (b)                                 */\\\n\t\t    /*           /                                    */\\\n\t\t    /*          (b)                                   */\\\n\t\t    a_type *tnode;\t\t\t\t\t\\\n\t\t    rbtn_red_set(a_type, a_field, pathp->node);\t\t\\\n\t\t    rbtn_rotate_left(a_type, a_field, pathp->node,\t\\\n\t\t      tnode);\t\t\t\t\t\t\\\n\t\t    pathp->node = tnode;\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\t} else {\t\t\t\t\t\t\t\\\n\t    a_type *left;\t\t\t\t\t\t\\\n\t    rbtn_right_set(a_type, a_field, pathp->node,\t\t\\\n\t      pathp[1].node);\t\t\t\t\t\t\\\n\t    left = rbtn_left_get(a_type, a_field, pathp->node);\t\t\\\n\t    if (rbtn_red_get(a_type, a_field, left)) {\t\t\t\\\n\t\ta_type *tnode;\t\t\t\t\t\t\\\n\t\ta_type *leftright = rbtn_right_get(a_type, a_field,\t\\\n\t\t  left);\t\t\t\t\t\t\\\n\t\ta_type *leftrightleft = rbtn_left_get(a_type, a_field,\t\\\n\t\t  leftright);\t\t\t\t\t\t\\\n\t\tif (leftrightleft != NULL && rbtn_red_get(a_type,\t\\\n\t\t  a_field, leftrightleft)) {\t\t\t\t\\\n\t\t    /*      ||                                        */\\\n\t\t    /*    pathp(b)                                    */\\\n\t\t    /*   /        \\\\                                  */\\\n\t\t    /* (r)        (b)                                 */\\\n\t\t    /*   \\                                            */\\\n\t\t    /*   (b)                                          */\\\n\t\t    /*   /                                            */\\\n\t\t    /* (r)                                            */\\\n\t\t    a_type *unode;\t\t\t\t\t\\\n\t\t    rbtn_black_set(a_type, a_field, leftrightleft);\t\\\n\t\t    rbtn_rotate_right(a_type, a_field, pathp->node,\t\\\n\t\t      unode);\t\t\t\t\t\t\\\n\t\t    rbtn_rotate_right(a_type, a_field, pathp->node,\t\\\n\t\t      tnode);\t\t\t\t\t\t\\\n\t\t    rbtn_right_set(a_type, a_field, unode, tnode);\t\\\n\t\t    rbtn_rotate_left(a_type, a_field, unode, tnode);\t\\\n\t\t} else {\t\t\t\t\t\t\\\n\t\t    /*      ||                                        */\\\n\t\t    /*    pathp(b)                                    */\\\n\t\t    /*   /        \\\\                                  */\\\n\t\t    /* (r)        (b)                                 */\\\n\t\t    /*   \\                                            */\\\n\t\t    /*   (b)                                          */\\\n\t\t    /*   /                                            */\\\n\t\t    /* (b)                                            */\\\n\t\t    assert(leftright != NULL);\t\t\t\t\\\n\t\t    rbtn_red_set(a_type, a_field, leftright);\t\t\\\n\t\t    rbtn_rotate_right(a_type, a_field, pathp->node,\t\\\n\t\t      tnode);\t\t\t\t\t\t\\\n\t\t    rbtn_black_set(a_type, a_field, tnode);\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t\t/* Balance restored, but rotation modified subtree    */\\\n\t\t/* root, which may actually be the tree root.         */\\\n\t\tif (pathp == path) {\t\t\t\t\t\\\n\t\t    /* Set root. */\t\t\t\t\t\\\n\t\t    rbtree->rbt_root = tnode;\t\t\t\t\\\n\t\t} else {\t\t\t\t\t\t\\\n\t\t    if (pathp[-1].cmp < 0) {\t\t\t\t\\\n\t\t\trbtn_left_set(a_type, a_field, pathp[-1].node,\t\\\n\t\t\t  tnode);\t\t\t\t\t\\\n\t\t    } else {\t\t\t\t\t\t\\\n\t\t\trbtn_right_set(a_type, a_field, pathp[-1].node,\t\\\n\t\t\t  tnode);\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\t\treturn;\t\t\t\t\t\t\t\\\n\t    } else if (rbtn_red_get(a_type, a_field, pathp->node)) {\t\\\n\t\ta_type *leftleft = rbtn_left_get(a_type, a_field, left);\\\n\t\tif (leftleft != NULL && rbtn_red_get(a_type, a_field,\t\\\n\t\t  leftleft)) {\t\t\t\t\t\t\\\n\t\t    /*        ||                                      */\\\n\t\t    /*      pathp(r)                                  */\\\n\t\t    /*     /        \\\\                                */\\\n\t\t    /*   (b)        (b)                               */\\\n\t\t    /*   /                                            */\\\n\t\t    /* (r)                                            */\\\n\t\t    a_type *tnode;\t\t\t\t\t\\\n\t\t    rbtn_black_set(a_type, a_field, pathp->node);\t\\\n\t\t    rbtn_red_set(a_type, a_field, left);\t\t\\\n\t\t    rbtn_black_set(a_type, a_field, leftleft);\t\t\\\n\t\t    rbtn_rotate_right(a_type, a_field, pathp->node,\t\\\n\t\t      tnode);\t\t\t\t\t\t\\\n\t\t    /* Balance restored, but rotation modified        */\\\n\t\t    /* subtree root.                                  */\\\n\t\t    assert((uintptr_t)pathp > (uintptr_t)path);\t\t\\\n\t\t    if (pathp[-1].cmp < 0) {\t\t\t\t\\\n\t\t\trbtn_left_set(a_type, a_field, pathp[-1].node,\t\\\n\t\t\t  tnode);\t\t\t\t\t\\\n\t\t    } else {\t\t\t\t\t\t\\\n\t\t\trbtn_right_set(a_type, a_field, pathp[-1].node,\t\\\n\t\t\t  tnode);\t\t\t\t\t\\\n\t\t    }\t\t\t\t\t\t\t\\\n\t\t    return;\t\t\t\t\t\t\\\n\t\t} else {\t\t\t\t\t\t\\\n\t\t    /*        ||                                      */\\\n\t\t    /*      pathp(r)                                  */\\\n\t\t    /*     /        \\\\                                */\\\n\t\t    /*   (b)        (b)                               */\\\n\t\t    /*   /                                            */\\\n\t\t    /* (b)                                            */\\\n\t\t    rbtn_red_set(a_type, a_field, left);\t\t\\\n\t\t    rbtn_black_set(a_type, a_field, pathp->node);\t\\\n\t\t    /* Balance restored. */\t\t\t\t\\\n\t\t    return;\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t    } else {\t\t\t\t\t\t\t\\\n\t\ta_type *leftleft = rbtn_left_get(a_type, a_field, left);\\\n\t\tif (leftleft != NULL && rbtn_red_get(a_type, a_field,\t\\\n\t\t  leftleft)) {\t\t\t\t\t\t\\\n\t\t    /*               ||                               */\\\n\t\t    /*             pathp(b)                           */\\\n\t\t    /*            /        \\\\                         */\\\n\t\t    /*          (b)        (b)                        */\\\n\t\t    /*          /                                     */\\\n\t\t    /*        (r)                                     */\\\n\t\t    a_type *tnode;\t\t\t\t\t\\\n\t\t    rbtn_black_set(a_type, a_field, leftleft);\t\t\\\n\t\t    rbtn_rotate_right(a_type, a_field, pathp->node,\t\\\n\t\t      tnode);\t\t\t\t\t\t\\\n\t\t    /* Balance restored, but rotation modified        */\\\n\t\t    /* subtree root, which may actually be the tree   */\\\n\t\t    /* root.                                          */\\\n\t\t    if (pathp == path) {\t\t\t\t\\\n\t\t\t/* Set root. */\t\t\t\t\t\\\n\t\t\trbtree->rbt_root = tnode;\t\t\t\\\n\t\t    } else {\t\t\t\t\t\t\\\n\t\t\tif (pathp[-1].cmp < 0) {\t\t\t\\\n\t\t\t    rbtn_left_set(a_type, a_field,\t\t\\\n\t\t\t      pathp[-1].node, tnode);\t\t\t\\\n\t\t\t} else {\t\t\t\t\t\\\n\t\t\t    rbtn_right_set(a_type, a_field,\t\t\\\n\t\t\t      pathp[-1].node, tnode);\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\\\n\t\t    }\t\t\t\t\t\t\t\\\n\t\t    return;\t\t\t\t\t\t\\\n\t\t} else {\t\t\t\t\t\t\\\n\t\t    /*               ||                               */\\\n\t\t    /*             pathp(b)                           */\\\n\t\t    /*            /        \\\\                         */\\\n\t\t    /*          (b)        (b)                        */\\\n\t\t    /*          /                                     */\\\n\t\t    /*        (b)                                     */\\\n\t\t    rbtn_red_set(a_type, a_field, left);\t\t\\\n\t\t}\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    }\t\t\t\t\t\t\t\t\t\\\n    /* Set root. */\t\t\t\t\t\t\t\\\n    rbtree->rbt_root = path->node;\t\t\t\t\t\\\n    assert(!rbtn_red_get(a_type, a_field, rbtree->rbt_root));\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##iter_recurse(a_rbt_type *rbtree, a_type *node,\t\t\\\n  a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) {\t\t\\\n    if (node == NULL) {\t\t\t\t\t\t\t\\\n\treturn (NULL);\t\t\t\t\t\t\t\\\n    } else {\t\t\t\t\t\t\t\t\\\n\ta_type *ret;\t\t\t\t\t\t\t\\\n\tif ((ret = a_prefix##iter_recurse(rbtree, rbtn_left_get(a_type,\t\\\n\t  a_field, node), cb, arg)) != NULL || (ret = cb(rbtree, node,\t\\\n\t  arg)) != NULL) {\t\t\t\t\t\t\\\n\t    return (ret);\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\treturn (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type,\t\\\n\t  a_field, node), cb, arg));\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\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##iter_start(a_rbt_type *rbtree, a_type *start, a_type *node,\t\\\n  a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) {\t\t\\\n    int cmp = a_cmp(start, node);\t\t\t\t\t\\\n    if (cmp < 0) {\t\t\t\t\t\t\t\\\n\ta_type *ret;\t\t\t\t\t\t\t\\\n\tif ((ret = a_prefix##iter_start(rbtree, start,\t\t\t\\\n\t  rbtn_left_get(a_type, a_field, node), cb, arg)) != NULL ||\t\\\n\t  (ret = cb(rbtree, node, arg)) != NULL) {\t\t\t\\\n\t    return (ret);\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\treturn (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type,\t\\\n\t  a_field, node), cb, arg));\t\t\t\t\t\\\n    } else if (cmp > 0) {\t\t\t\t\t\t\\\n\treturn (a_prefix##iter_start(rbtree, start,\t\t\t\\\n\t  rbtn_right_get(a_type, a_field, node), cb, arg));\t\t\\\n    } else {\t\t\t\t\t\t\t\t\\\n\ta_type *ret;\t\t\t\t\t\t\t\\\n\tif ((ret = cb(rbtree, node, arg)) != NULL) {\t\t\t\\\n\t    return (ret);\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\treturn (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type,\t\\\n\t  a_field, node), cb, arg));\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\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##iter(a_rbt_type *rbtree, a_type *start, a_type *(*cb)(\t\\\n  a_rbt_type *, a_type *, void *), void *arg) {\t\t\t\t\\\n    a_type *ret;\t\t\t\t\t\t\t\\\n    if (start != NULL) {\t\t\t\t\t\t\\\n\tret = a_prefix##iter_start(rbtree, start, rbtree->rbt_root,\t\\\n\t  cb, arg);\t\t\t\t\t\t\t\\\n    } else {\t\t\t\t\t\t\t\t\\\n\tret = a_prefix##iter_recurse(rbtree, rbtree->rbt_root, cb, arg);\\\n    }\t\t\t\t\t\t\t\t\t\\\n    return (ret);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##reverse_iter_recurse(a_rbt_type *rbtree, a_type *node,\t\\\n  a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) {\t\t\\\n    if (node == NULL) {\t\t\t\t\t\t\t\\\n\treturn (NULL);\t\t\t\t\t\t\t\\\n    } else {\t\t\t\t\t\t\t\t\\\n\ta_type *ret;\t\t\t\t\t\t\t\\\n\tif ((ret = a_prefix##reverse_iter_recurse(rbtree,\t\t\\\n\t  rbtn_right_get(a_type, a_field, node), cb, arg)) != NULL ||\t\\\n\t  (ret = cb(rbtree, node, arg)) != NULL) {\t\t\t\\\n\t    return (ret);\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\treturn (a_prefix##reverse_iter_recurse(rbtree,\t\t\t\\\n\t  rbtn_left_get(a_type, a_field, node), cb, arg));\t\t\\\n    }\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##reverse_iter_start(a_rbt_type *rbtree, a_type *start,\t\t\\\n  a_type *node, a_type *(*cb)(a_rbt_type *, a_type *, void *),\t\t\\\n  void *arg) {\t\t\t\t\t\t\t\t\\\n    int cmp = a_cmp(start, node);\t\t\t\t\t\\\n    if (cmp > 0) {\t\t\t\t\t\t\t\\\n\ta_type *ret;\t\t\t\t\t\t\t\\\n\tif ((ret = a_prefix##reverse_iter_start(rbtree, start,\t\t\\\n\t  rbtn_right_get(a_type, a_field, node), cb, arg)) != NULL ||\t\\\n\t  (ret = cb(rbtree, node, arg)) != NULL) {\t\t\t\\\n\t    return (ret);\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\treturn (a_prefix##reverse_iter_recurse(rbtree,\t\t\t\\\n\t  rbtn_left_get(a_type, a_field, node), cb, arg));\t\t\\\n    } else if (cmp < 0) {\t\t\t\t\t\t\\\n\treturn (a_prefix##reverse_iter_start(rbtree, start,\t\t\\\n\t  rbtn_left_get(a_type, a_field, node), cb, arg));\t\t\\\n    } else {\t\t\t\t\t\t\t\t\\\n\ta_type *ret;\t\t\t\t\t\t\t\\\n\tif ((ret = cb(rbtree, node, arg)) != NULL) {\t\t\t\\\n\t    return (ret);\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\treturn (a_prefix##reverse_iter_recurse(rbtree,\t\t\t\\\n\t  rbtn_left_get(a_type, a_field, node), cb, arg));\t\t\\\n    }\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start,\t\t\\\n  a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) {\t\t\\\n    a_type *ret;\t\t\t\t\t\t\t\\\n    if (start != NULL) {\t\t\t\t\t\t\\\n\tret = a_prefix##reverse_iter_start(rbtree, start,\t\t\\\n\t  rbtree->rbt_root, cb, arg);\t\t\t\t\t\\\n    } else {\t\t\t\t\t\t\t\t\\\n\tret = a_prefix##reverse_iter_recurse(rbtree, rbtree->rbt_root,\t\\\n\t  cb, arg);\t\t\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\t\\\n    return (ret);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_prefix##destroy_recurse(a_rbt_type *rbtree, a_type *node, void (*cb)(\t\\\n  a_type *, void *), void *arg) {\t\t\t\t\t\\\n    if (node == NULL) {\t\t\t\t\t\t\t\\\n\treturn;\t\t\t\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\t\\\n    a_prefix##destroy_recurse(rbtree, rbtn_left_get(a_type, a_field,\t\\\n      node), cb, arg);\t\t\t\t\t\t\t\\\n    rbtn_left_set(a_type, a_field, (node), NULL);\t\t\t\\\n    a_prefix##destroy_recurse(rbtree, rbtn_right_get(a_type, a_field,\t\\\n      node), cb, arg);\t\t\t\t\t\t\t\\\n    rbtn_right_set(a_type, a_field, (node), NULL);\t\t\t\\\n    if (cb) {\t\t\t\t\t\t\t\t\\\n\tcb(node, arg);\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\\\na_attr void\t\t\t\t\t\t\t\t\\\na_prefix##destroy(a_rbt_type *rbtree, void (*cb)(a_type *, void *),\t\\\n  void *arg) {\t\t\t\t\t\t\t\t\\\n    a_prefix##destroy_recurse(rbtree, rbtree->rbt_root, cb, arg);\t\\\n    rbtree->rbt_root = NULL;\t\t\t\t\t\t\\\n}\n\n#endif /* RB_H_ */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/rtree.h",
    "content": "/*\n * This radix tree implementation is tailored to the singular purpose of\n * associating metadata with chunks that are currently owned by jemalloc.\n *\n *******************************************************************************\n */\n#ifdef JEMALLOC_H_TYPES\n\ntypedef struct rtree_node_elm_s rtree_node_elm_t;\ntypedef struct rtree_level_s rtree_level_t;\ntypedef struct rtree_s rtree_t;\n\n/*\n * RTREE_BITS_PER_LEVEL must be a power of two that is no larger than the\n * machine address width.\n */\n#define\tLG_RTREE_BITS_PER_LEVEL\t4\n#define\tRTREE_BITS_PER_LEVEL\t(ZU(1) << LG_RTREE_BITS_PER_LEVEL)\n#define\tRTREE_HEIGHT_MAX\t\t\t\t\t\t\\\n    ((ZU(1) << (LG_SIZEOF_PTR+3)) / RTREE_BITS_PER_LEVEL)\n\n/* Used for two-stage lock-free node initialization. */\n#define\tRTREE_NODE_INITIALIZING\t((rtree_node_elm_t *)0x1)\n\n/*\n * The node allocation callback function's argument is the number of contiguous\n * rtree_node_elm_t structures to allocate, and the resulting memory must be\n * zeroed.\n */\ntypedef rtree_node_elm_t *(rtree_node_alloc_t)(size_t);\ntypedef void (rtree_node_dalloc_t)(rtree_node_elm_t *);\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\nstruct rtree_node_elm_s {\n\tunion {\n\t\tvoid\t\t\t*pun;\n\t\trtree_node_elm_t\t*child;\n\t\textent_node_t\t\t*val;\n\t};\n};\n\nstruct rtree_level_s {\n\t/*\n\t * A non-NULL subtree points to a subtree rooted along the hypothetical\n\t * path to the leaf node corresponding to key 0.  Depending on what keys\n\t * have been used to store to the tree, an arbitrary combination of\n\t * subtree pointers may remain NULL.\n\t *\n\t * Suppose keys comprise 48 bits, and LG_RTREE_BITS_PER_LEVEL is 4.\n\t * This results in a 3-level tree, and the leftmost leaf can be directly\n\t * accessed via subtrees[2], the subtree prefixed by 0x0000 (excluding\n\t * 0x00000000) can be accessed via subtrees[1], and the remainder of the\n\t * tree can be accessed via subtrees[0].\n\t *\n\t *   levels[0] : [<unused> | 0x0001******** | 0x0002******** | ...]\n\t *\n\t *   levels[1] : [<unused> | 0x00000001**** | 0x00000002**** | ... ]\n\t *\n\t *   levels[2] : [val(0x000000000000) | val(0x000000000001) | ...]\n\t *\n\t * This has practical implications on x64, which currently uses only the\n\t * lower 47 bits of virtual address space in userland, thus leaving\n\t * subtrees[0] unused and avoiding a level of tree traversal.\n\t */\n\tunion {\n\t\tvoid\t\t\t*subtree_pun;\n\t\trtree_node_elm_t\t*subtree;\n\t};\n\t/* Number of key bits distinguished by this level. */\n\tunsigned\t\tbits;\n\t/*\n\t * Cumulative number of key bits distinguished by traversing to\n\t * corresponding tree level.\n\t */\n\tunsigned\t\tcumbits;\n};\n\nstruct rtree_s {\n\trtree_node_alloc_t\t*alloc;\n\trtree_node_dalloc_t\t*dalloc;\n\tunsigned\t\theight;\n\t/*\n\t * Precomputed table used to convert from the number of leading 0 key\n\t * bits to which subtree level to start at.\n\t */\n\tunsigned\t\tstart_level[RTREE_HEIGHT_MAX];\n\trtree_level_t\t\tlevels[RTREE_HEIGHT_MAX];\n};\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nbool rtree_new(rtree_t *rtree, unsigned bits, rtree_node_alloc_t *alloc,\n    rtree_node_dalloc_t *dalloc);\nvoid\trtree_delete(rtree_t *rtree);\nrtree_node_elm_t\t*rtree_subtree_read_hard(rtree_t *rtree,\n    unsigned level);\nrtree_node_elm_t\t*rtree_child_read_hard(rtree_t *rtree,\n    rtree_node_elm_t *elm, unsigned level);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#ifndef JEMALLOC_ENABLE_INLINE\nunsigned\trtree_start_level(rtree_t *rtree, uintptr_t key);\nuintptr_t\trtree_subkey(rtree_t *rtree, uintptr_t key, unsigned level);\n\nbool\trtree_node_valid(rtree_node_elm_t *node);\nrtree_node_elm_t\t*rtree_child_tryread(rtree_node_elm_t *elm);\nrtree_node_elm_t\t*rtree_child_read(rtree_t *rtree, rtree_node_elm_t *elm,\n    unsigned level);\nextent_node_t\t*rtree_val_read(rtree_t *rtree, rtree_node_elm_t *elm,\n    bool dependent);\nvoid\trtree_val_write(rtree_t *rtree, rtree_node_elm_t *elm,\n    const extent_node_t *val);\nrtree_node_elm_t\t*rtree_subtree_tryread(rtree_t *rtree, unsigned level);\nrtree_node_elm_t\t*rtree_subtree_read(rtree_t *rtree, unsigned level);\n\nextent_node_t\t*rtree_get(rtree_t *rtree, uintptr_t key, bool dependent);\nbool\trtree_set(rtree_t *rtree, uintptr_t key, const extent_node_t *val);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_RTREE_C_))\nJEMALLOC_INLINE unsigned\nrtree_start_level(rtree_t *rtree, uintptr_t key)\n{\n\tunsigned start_level;\n\n\tif (unlikely(key == 0))\n\t\treturn (rtree->height - 1);\n\n\tstart_level = rtree->start_level[lg_floor(key) >>\n\t    LG_RTREE_BITS_PER_LEVEL];\n\tassert(start_level < rtree->height);\n\treturn (start_level);\n}\n\nJEMALLOC_INLINE uintptr_t\nrtree_subkey(rtree_t *rtree, uintptr_t key, unsigned level)\n{\n\n\treturn ((key >> ((ZU(1) << (LG_SIZEOF_PTR+3)) -\n\t    rtree->levels[level].cumbits)) & ((ZU(1) <<\n\t    rtree->levels[level].bits) - 1));\n}\n\nJEMALLOC_INLINE bool\nrtree_node_valid(rtree_node_elm_t *node)\n{\n\n\treturn ((uintptr_t)node > (uintptr_t)RTREE_NODE_INITIALIZING);\n}\n\nJEMALLOC_INLINE rtree_node_elm_t *\nrtree_child_tryread(rtree_node_elm_t *elm)\n{\n\trtree_node_elm_t *child;\n\n\t/* Double-checked read (first read may be stale. */\n\tchild = elm->child;\n\tif (!rtree_node_valid(child))\n\t\tchild = atomic_read_p(&elm->pun);\n\treturn (child);\n}\n\nJEMALLOC_INLINE rtree_node_elm_t *\nrtree_child_read(rtree_t *rtree, rtree_node_elm_t *elm, unsigned level)\n{\n\trtree_node_elm_t *child;\n\n\tchild = rtree_child_tryread(elm);\n\tif (unlikely(!rtree_node_valid(child)))\n\t\tchild = rtree_child_read_hard(rtree, elm, level);\n\treturn (child);\n}\n\nJEMALLOC_INLINE extent_node_t *\nrtree_val_read(rtree_t *rtree, rtree_node_elm_t *elm, bool dependent)\n{\n\n\tif (dependent) {\n\t\t/*\n\t\t * Reading a val on behalf of a pointer to a valid allocation is\n\t\t * guaranteed to be a clean read even without synchronization,\n\t\t * because the rtree update became visible in memory before the\n\t\t * pointer came into existence.\n\t\t */\n\t\treturn (elm->val);\n\t} else {\n\t\t/*\n\t\t * An arbitrary read, e.g. on behalf of ivsalloc(), may not be\n\t\t * dependent on a previous rtree write, which means a stale read\n\t\t * could result if synchronization were omitted here.\n\t\t */\n\t\treturn (atomic_read_p(&elm->pun));\n\t}\n}\n\nJEMALLOC_INLINE void\nrtree_val_write(rtree_t *rtree, rtree_node_elm_t *elm, const extent_node_t *val)\n{\n\n\tatomic_write_p(&elm->pun, val);\n}\n\nJEMALLOC_INLINE rtree_node_elm_t *\nrtree_subtree_tryread(rtree_t *rtree, unsigned level)\n{\n\trtree_node_elm_t *subtree;\n\n\t/* Double-checked read (first read may be stale. */\n\tsubtree = rtree->levels[level].subtree;\n\tif (!rtree_node_valid(subtree))\n\t\tsubtree = atomic_read_p(&rtree->levels[level].subtree_pun);\n\treturn (subtree);\n}\n\nJEMALLOC_INLINE rtree_node_elm_t *\nrtree_subtree_read(rtree_t *rtree, unsigned level)\n{\n\trtree_node_elm_t *subtree;\n\n\tsubtree = rtree_subtree_tryread(rtree, level);\n\tif (unlikely(!rtree_node_valid(subtree)))\n\t\tsubtree = rtree_subtree_read_hard(rtree, level);\n\treturn (subtree);\n}\n\nJEMALLOC_INLINE extent_node_t *\nrtree_get(rtree_t *rtree, uintptr_t key, bool dependent)\n{\n\tuintptr_t subkey;\n\tunsigned i, start_level;\n\trtree_node_elm_t *node, *child;\n\n\tstart_level = rtree_start_level(rtree, key);\n\n\tfor (i = start_level, node = rtree_subtree_tryread(rtree, start_level);\n\t    /**/; i++, node = child) {\n\t\tif (!dependent && unlikely(!rtree_node_valid(node)))\n\t\t\treturn (NULL);\n\t\tsubkey = rtree_subkey(rtree, key, i);\n\t\tif (i == rtree->height - 1) {\n\t\t\t/*\n\t\t\t * node is a leaf, so it contains values rather than\n\t\t\t * child pointers.\n\t\t\t */\n\t\t\treturn (rtree_val_read(rtree, &node[subkey],\n\t\t\t    dependent));\n\t\t}\n\t\tassert(i < rtree->height - 1);\n\t\tchild = rtree_child_tryread(&node[subkey]);\n\t}\n\tnot_reached();\n}\n\nJEMALLOC_INLINE bool\nrtree_set(rtree_t *rtree, uintptr_t key, const extent_node_t *val)\n{\n\tuintptr_t subkey;\n\tunsigned i, start_level;\n\trtree_node_elm_t *node, *child;\n\n\tstart_level = rtree_start_level(rtree, key);\n\n\tnode = rtree_subtree_read(rtree, start_level);\n\tif (node == NULL)\n\t\treturn (true);\n\tfor (i = start_level; /**/; i++, node = child) {\n\t\tsubkey = rtree_subkey(rtree, key, i);\n\t\tif (i == rtree->height - 1) {\n\t\t\t/*\n\t\t\t * node is a leaf, so it contains values rather than\n\t\t\t * child pointers.\n\t\t\t */\n\t\t\trtree_val_write(rtree, &node[subkey], val);\n\t\t\treturn (false);\n\t\t}\n\t\tassert(i + 1 < rtree->height);\n\t\tchild = rtree_child_read(rtree, &node[subkey], i);\n\t\tif (child == NULL)\n\t\t\treturn (true);\n\t}\n\tnot_reached();\n}\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/size_classes.sh",
    "content": "#!/bin/sh\n#\n# Usage: size_classes.sh <lg_qarr> <lg_tmin> <lg_parr> <lg_g>\n\n# The following limits are chosen such that they cover all supported platforms.\n\n# Pointer sizes.\nlg_zarr=\"2 3\"\n\n# Quanta.\nlg_qarr=$1\n\n# The range of tiny size classes is [2^lg_tmin..2^(lg_q-1)].\nlg_tmin=$2\n\n# Maximum lookup size.\nlg_kmax=12\n\n# Page sizes.\nlg_parr=`echo $3 | tr ',' ' '`\n\n# Size class group size (number of size classes for each size doubling).\nlg_g=$4\n\npow2() {\n  e=$1\n  pow2_result=1\n  while [ ${e} -gt 0 ] ; do\n    pow2_result=$((${pow2_result} + ${pow2_result}))\n    e=$((${e} - 1))\n  done\n}\n\nlg() {\n  x=$1\n  lg_result=0\n  while [ ${x} -gt 1 ] ; do\n    lg_result=$((${lg_result} + 1))\n    x=$((${x} / 2))\n  done\n}\n\nsize_class() {\n  index=$1\n  lg_grp=$2\n  lg_delta=$3\n  ndelta=$4\n  lg_p=$5\n  lg_kmax=$6\n\n  lg ${ndelta}; lg_ndelta=${lg_result}; pow2 ${lg_ndelta}\n  if [ ${pow2_result} -lt ${ndelta} ] ; then\n    rem=\"yes\"\n  else\n    rem=\"no\"\n  fi\n\n  lg_size=${lg_grp}\n  if [ $((${lg_delta} + ${lg_ndelta})) -eq ${lg_grp} ] ; then\n    lg_size=$((${lg_grp} + 1))\n  else\n    lg_size=${lg_grp}\n    rem=\"yes\"\n  fi\n\n  if [ ${lg_size} -lt $((${lg_p} + ${lg_g})) ] ; then\n    bin=\"yes\"\n  else\n    bin=\"no\"\n  fi\n  if [ ${lg_size} -lt ${lg_kmax} \\\n      -o ${lg_size} -eq ${lg_kmax} -a ${rem} = \"no\" ] ; then\n    lg_delta_lookup=${lg_delta}\n  else\n    lg_delta_lookup=\"no\"\n  fi\n  printf '    SC(%3d, %6d, %8d, %6d, %3s, %2s) \\\\\\n' ${index} ${lg_grp} ${lg_delta} ${ndelta} ${bin} ${lg_delta_lookup}\n  # Defined upon return:\n  # - lg_delta_lookup (${lg_delta} or \"no\")\n  # - bin (\"yes\" or \"no\")\n}\n\nsep_line() {\n  echo \"                                               \\\\\"\n}\n\nsize_classes() {\n  lg_z=$1\n  lg_q=$2\n  lg_t=$3\n  lg_p=$4\n  lg_g=$5\n\n  pow2 $((${lg_z} + 3)); ptr_bits=${pow2_result}\n  pow2 ${lg_g}; g=${pow2_result}\n\n  echo \"#define\tSIZE_CLASSES \\\\\"\n  echo \"  /* index, lg_grp, lg_delta, ndelta, bin, lg_delta_lookup */ \\\\\"\n\n  ntbins=0\n  nlbins=0\n  lg_tiny_maxclass='\"NA\"'\n  nbins=0\n\n  # Tiny size classes.\n  ndelta=0\n  index=0\n  lg_grp=${lg_t}\n  lg_delta=${lg_grp}\n  while [ ${lg_grp} -lt ${lg_q} ] ; do\n    size_class ${index} ${lg_grp} ${lg_delta} ${ndelta} ${lg_p} ${lg_kmax}\n    if [ ${lg_delta_lookup} != \"no\" ] ; then\n      nlbins=$((${index} + 1))\n    fi\n    if [ ${bin} != \"no\" ] ; then\n      nbins=$((${index} + 1))\n    fi\n    ntbins=$((${ntbins} + 1))\n    lg_tiny_maxclass=${lg_grp} # Final written value is correct.\n    index=$((${index} + 1))\n    lg_delta=${lg_grp}\n    lg_grp=$((${lg_grp} + 1))\n  done\n\n  # First non-tiny group.\n  if [ ${ntbins} -gt 0 ] ; then\n    sep_line\n    # The first size class has an unusual encoding, because the size has to be\n    # split between grp and delta*ndelta.\n    lg_grp=$((${lg_grp} - 1))\n    ndelta=1\n    size_class ${index} ${lg_grp} ${lg_delta} ${ndelta} ${lg_p} ${lg_kmax}\n    index=$((${index} + 1))\n    lg_grp=$((${lg_grp} + 1))\n    lg_delta=$((${lg_delta} + 1))\n  fi\n  while [ ${ndelta} -lt ${g} ] ; do\n    size_class ${index} ${lg_grp} ${lg_delta} ${ndelta} ${lg_p} ${lg_kmax}\n    index=$((${index} + 1))\n    ndelta=$((${ndelta} + 1))\n  done\n\n  # All remaining groups.\n  lg_grp=$((${lg_grp} + ${lg_g}))\n  while [ ${lg_grp} -lt $((${ptr_bits} - 1)) ] ; do\n    sep_line\n    ndelta=1\n    if [ ${lg_grp} -eq $((${ptr_bits} - 2)) ] ; then\n      ndelta_limit=$((${g} - 1))\n    else\n      ndelta_limit=${g}\n    fi\n    while [ ${ndelta} -le ${ndelta_limit} ] ; do\n      size_class ${index} ${lg_grp} ${lg_delta} ${ndelta} ${lg_p} ${lg_kmax}\n      if [ ${lg_delta_lookup} != \"no\" ] ; then\n        nlbins=$((${index} + 1))\n        # Final written value is correct:\n        lookup_maxclass=\"((((size_t)1) << ${lg_grp}) + (((size_t)${ndelta}) << ${lg_delta}))\"\n      fi\n      if [ ${bin} != \"no\" ] ; then\n        nbins=$((${index} + 1))\n        # Final written value is correct:\n        small_maxclass=\"((((size_t)1) << ${lg_grp}) + (((size_t)${ndelta}) << ${lg_delta}))\"\n        if [ ${lg_g} -gt 0 ] ; then\n          lg_large_minclass=$((${lg_grp} + 1))\n        else\n          lg_large_minclass=$((${lg_grp} + 2))\n        fi\n      fi\n      # Final written value is correct:\n      huge_maxclass=\"((((size_t)1) << ${lg_grp}) + (((size_t)${ndelta}) << ${lg_delta}))\"\n      index=$((${index} + 1))\n      ndelta=$((${ndelta} + 1))\n    done\n    lg_grp=$((${lg_grp} + 1))\n    lg_delta=$((${lg_delta} + 1))\n  done\n  echo\n  nsizes=${index}\n\n  # Defined upon completion:\n  # - ntbins\n  # - nlbins\n  # - nbins\n  # - nsizes\n  # - lg_tiny_maxclass\n  # - lookup_maxclass\n  # - small_maxclass\n  # - lg_large_minclass\n  # - huge_maxclass\n}\n\ncat <<EOF\n/* This file was automatically generated by size_classes.sh. */\n/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n/*\n * This header requires LG_SIZEOF_PTR, LG_TINY_MIN, LG_QUANTUM, and LG_PAGE to\n * be defined prior to inclusion, and it in turn defines:\n *\n *   LG_SIZE_CLASS_GROUP: Lg of size class count for each size doubling.\n *   SIZE_CLASSES: Complete table of\n *                 SC(index, lg_grp, lg_delta, ndelta, bin, lg_delta_lookup)\n *                 tuples.\n *     index: Size class index.\n *     lg_grp: Lg group base size (no deltas added).\n *     lg_delta: Lg delta to previous size class.\n *     ndelta: Delta multiplier.  size == 1<<lg_grp + ndelta<<lg_delta\n *     bin: 'yes' if a small bin size class, 'no' otherwise.\n *     lg_delta_lookup: Same as lg_delta if a lookup table size class, 'no'\n *                      otherwise.\n *   NTBINS: Number of tiny bins.\n *   NLBINS: Number of bins supported by the lookup table.\n *   NBINS: Number of small size class bins.\n *   NSIZES: Number of size classes.\n *   LG_TINY_MAXCLASS: Lg of maximum tiny size class.\n *   LOOKUP_MAXCLASS: Maximum size class included in lookup table.\n *   SMALL_MAXCLASS: Maximum small size class.\n *   LG_LARGE_MINCLASS: Lg of minimum large size class.\n *   HUGE_MAXCLASS: Maximum (huge) size class.\n */\n\n#define\tLG_SIZE_CLASS_GROUP\t${lg_g}\n\nEOF\n\nfor lg_z in ${lg_zarr} ; do\n  for lg_q in ${lg_qarr} ; do\n    lg_t=${lg_tmin}\n    while [ ${lg_t} -le ${lg_q} ] ; do\n      # Iterate through page sizes and compute how many bins there are.\n      for lg_p in ${lg_parr} ; do\n        echo \"#if (LG_SIZEOF_PTR == ${lg_z} && LG_TINY_MIN == ${lg_t} && LG_QUANTUM == ${lg_q} && LG_PAGE == ${lg_p})\"\n        size_classes ${lg_z} ${lg_q} ${lg_t} ${lg_p} ${lg_g}\n        echo \"#define\tSIZE_CLASSES_DEFINED\"\n        echo \"#define\tNTBINS\t\t\t${ntbins}\"\n        echo \"#define\tNLBINS\t\t\t${nlbins}\"\n        echo \"#define\tNBINS\t\t\t${nbins}\"\n        echo \"#define\tNSIZES\t\t\t${nsizes}\"\n        echo \"#define\tLG_TINY_MAXCLASS\t${lg_tiny_maxclass}\"\n        echo \"#define\tLOOKUP_MAXCLASS\t\t${lookup_maxclass}\"\n        echo \"#define\tSMALL_MAXCLASS\t\t${small_maxclass}\"\n        echo \"#define\tLG_LARGE_MINCLASS\t${lg_large_minclass}\"\n        echo \"#define\tHUGE_MAXCLASS\t\t${huge_maxclass}\"\n        echo \"#endif\"\n        echo\n      done\n      lg_t=$((${lg_t} + 1))\n    done\n  done\ndone\n\ncat <<EOF\n#ifndef SIZE_CLASSES_DEFINED\n#  error \"No size class definitions match configuration\"\n#endif\n#undef SIZE_CLASSES_DEFINED\n/*\n * The size2index_tab lookup table uses uint8_t to encode each bin index, so we\n * cannot support more than 256 small size classes.  Further constrain NBINS to\n * 255 since all small size classes, plus a \"not small\" size class must be\n * stored in 8 bits of arena_chunk_map_bits_t's bits field.\n */\n#if (NBINS > 255)\n#  error \"Too many small size classes\"\n#endif\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\nEOF\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/smoothstep.h",
    "content": "/*\n * This file was generated by the following command:\n *   sh smoothstep.sh smoother 200 24 3 15\n */\n/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n/*\n * This header defines a precomputed table based on the smoothstep family of\n * sigmoidal curves (https://en.wikipedia.org/wiki/Smoothstep) that grow from 0\n * to 1 in 0 <= x <= 1.  The table is stored as integer fixed point values so\n * that floating point math can be avoided.\n *\n *                      3     2\n *   smoothstep(x) = -2x  + 3x\n *\n *                       5      4      3\n *   smootherstep(x) = 6x  - 15x  + 10x\n *\n *                          7      6      5      4\n *   smootheststep(x) = -20x  + 70x  - 84x  + 35x\n */\n\n#define\tSMOOTHSTEP_VARIANT\t\"smoother\"\n#define\tSMOOTHSTEP_NSTEPS\t200\n#define\tSMOOTHSTEP_BFP\t\t24\n#define\tSMOOTHSTEP \\\n /* STEP(step, h,                            x,     y) */ \\\n    STEP(   1, UINT64_C(0x0000000000000014), 0.005, 0.000001240643750) \\\n    STEP(   2, UINT64_C(0x00000000000000a5), 0.010, 0.000009850600000) \\\n    STEP(   3, UINT64_C(0x0000000000000229), 0.015, 0.000032995181250) \\\n    STEP(   4, UINT64_C(0x0000000000000516), 0.020, 0.000077619200000) \\\n    STEP(   5, UINT64_C(0x00000000000009dc), 0.025, 0.000150449218750) \\\n    STEP(   6, UINT64_C(0x00000000000010e8), 0.030, 0.000257995800000) \\\n    STEP(   7, UINT64_C(0x0000000000001aa4), 0.035, 0.000406555756250) \\\n    STEP(   8, UINT64_C(0x0000000000002777), 0.040, 0.000602214400000) \\\n    STEP(   9, UINT64_C(0x00000000000037c2), 0.045, 0.000850847793750) \\\n    STEP(  10, UINT64_C(0x0000000000004be6), 0.050, 0.001158125000000) \\\n    STEP(  11, UINT64_C(0x000000000000643c), 0.055, 0.001529510331250) \\\n    STEP(  12, UINT64_C(0x000000000000811f), 0.060, 0.001970265600000) \\\n    STEP(  13, UINT64_C(0x000000000000a2e2), 0.065, 0.002485452368750) \\\n    STEP(  14, UINT64_C(0x000000000000c9d8), 0.070, 0.003079934200000) \\\n    STEP(  15, UINT64_C(0x000000000000f64f), 0.075, 0.003758378906250) \\\n    STEP(  16, UINT64_C(0x0000000000012891), 0.080, 0.004525260800000) \\\n    STEP(  17, UINT64_C(0x00000000000160e7), 0.085, 0.005384862943750) \\\n    STEP(  18, UINT64_C(0x0000000000019f95), 0.090, 0.006341279400000) \\\n    STEP(  19, UINT64_C(0x000000000001e4dc), 0.095, 0.007398417481250) \\\n    STEP(  20, UINT64_C(0x00000000000230fc), 0.100, 0.008560000000000) \\\n    STEP(  21, UINT64_C(0x0000000000028430), 0.105, 0.009829567518750) \\\n    STEP(  22, UINT64_C(0x000000000002deb0), 0.110, 0.011210480600000) \\\n    STEP(  23, UINT64_C(0x00000000000340b1), 0.115, 0.012705922056250) \\\n    STEP(  24, UINT64_C(0x000000000003aa67), 0.120, 0.014318899200000) \\\n    STEP(  25, UINT64_C(0x0000000000041c00), 0.125, 0.016052246093750) \\\n    STEP(  26, UINT64_C(0x00000000000495a8), 0.130, 0.017908625800000) \\\n    STEP(  27, UINT64_C(0x000000000005178b), 0.135, 0.019890532631250) \\\n    STEP(  28, UINT64_C(0x000000000005a1cf), 0.140, 0.022000294400000) \\\n    STEP(  29, UINT64_C(0x0000000000063498), 0.145, 0.024240074668750) \\\n    STEP(  30, UINT64_C(0x000000000006d009), 0.150, 0.026611875000000) \\\n    STEP(  31, UINT64_C(0x000000000007743f), 0.155, 0.029117537206250) \\\n    STEP(  32, UINT64_C(0x0000000000082157), 0.160, 0.031758745600000) \\\n    STEP(  33, UINT64_C(0x000000000008d76b), 0.165, 0.034537029243750) \\\n    STEP(  34, UINT64_C(0x0000000000099691), 0.170, 0.037453764200000) \\\n    STEP(  35, UINT64_C(0x00000000000a5edf), 0.175, 0.040510175781250) \\\n    STEP(  36, UINT64_C(0x00000000000b3067), 0.180, 0.043707340800000) \\\n    STEP(  37, UINT64_C(0x00000000000c0b38), 0.185, 0.047046189818750) \\\n    STEP(  38, UINT64_C(0x00000000000cef5e), 0.190, 0.050527509400000) \\\n    STEP(  39, UINT64_C(0x00000000000ddce6), 0.195, 0.054151944356250) \\\n    STEP(  40, UINT64_C(0x00000000000ed3d8), 0.200, 0.057920000000000) \\\n    STEP(  41, UINT64_C(0x00000000000fd439), 0.205, 0.061832044393750) \\\n    STEP(  42, UINT64_C(0x000000000010de0e), 0.210, 0.065888310600000) \\\n    STEP(  43, UINT64_C(0x000000000011f158), 0.215, 0.070088898931250) \\\n    STEP(  44, UINT64_C(0x0000000000130e17), 0.220, 0.074433779200000) \\\n    STEP(  45, UINT64_C(0x0000000000143448), 0.225, 0.078922792968750) \\\n    STEP(  46, UINT64_C(0x00000000001563e7), 0.230, 0.083555655800000) \\\n    STEP(  47, UINT64_C(0x0000000000169cec), 0.235, 0.088331959506250) \\\n    STEP(  48, UINT64_C(0x000000000017df4f), 0.240, 0.093251174400000) \\\n    STEP(  49, UINT64_C(0x0000000000192b04), 0.245, 0.098312651543750) \\\n    STEP(  50, UINT64_C(0x00000000001a8000), 0.250, 0.103515625000000) \\\n    STEP(  51, UINT64_C(0x00000000001bde32), 0.255, 0.108859214081250) \\\n    STEP(  52, UINT64_C(0x00000000001d458b), 0.260, 0.114342425600000) \\\n    STEP(  53, UINT64_C(0x00000000001eb5f8), 0.265, 0.119964156118750) \\\n    STEP(  54, UINT64_C(0x0000000000202f65), 0.270, 0.125723194200000) \\\n    STEP(  55, UINT64_C(0x000000000021b1bb), 0.275, 0.131618222656250) \\\n    STEP(  56, UINT64_C(0x0000000000233ce3), 0.280, 0.137647820800000) \\\n    STEP(  57, UINT64_C(0x000000000024d0c3), 0.285, 0.143810466693750) \\\n    STEP(  58, UINT64_C(0x0000000000266d40), 0.290, 0.150104539400000) \\\n    STEP(  59, UINT64_C(0x000000000028123d), 0.295, 0.156528321231250) \\\n    STEP(  60, UINT64_C(0x000000000029bf9c), 0.300, 0.163080000000000) \\\n    STEP(  61, UINT64_C(0x00000000002b753d), 0.305, 0.169757671268750) \\\n    STEP(  62, UINT64_C(0x00000000002d32fe), 0.310, 0.176559340600000) \\\n    STEP(  63, UINT64_C(0x00000000002ef8bc), 0.315, 0.183482925806250) \\\n    STEP(  64, UINT64_C(0x000000000030c654), 0.320, 0.190526259200000) \\\n    STEP(  65, UINT64_C(0x0000000000329b9f), 0.325, 0.197687089843750) \\\n    STEP(  66, UINT64_C(0x0000000000347875), 0.330, 0.204963085800000) \\\n    STEP(  67, UINT64_C(0x0000000000365cb0), 0.335, 0.212351836381250) \\\n    STEP(  68, UINT64_C(0x0000000000384825), 0.340, 0.219850854400000) \\\n    STEP(  69, UINT64_C(0x00000000003a3aa8), 0.345, 0.227457578418750) \\\n    STEP(  70, UINT64_C(0x00000000003c340f), 0.350, 0.235169375000000) \\\n    STEP(  71, UINT64_C(0x00000000003e342b), 0.355, 0.242983540956250) \\\n    STEP(  72, UINT64_C(0x0000000000403ace), 0.360, 0.250897305600000) \\\n    STEP(  73, UINT64_C(0x00000000004247c8), 0.365, 0.258907832993750) \\\n    STEP(  74, UINT64_C(0x0000000000445ae9), 0.370, 0.267012224200000) \\\n    STEP(  75, UINT64_C(0x0000000000467400), 0.375, 0.275207519531250) \\\n    STEP(  76, UINT64_C(0x00000000004892d8), 0.380, 0.283490700800000) \\\n    STEP(  77, UINT64_C(0x00000000004ab740), 0.385, 0.291858693568750) \\\n    STEP(  78, UINT64_C(0x00000000004ce102), 0.390, 0.300308369400000) \\\n    STEP(  79, UINT64_C(0x00000000004f0fe9), 0.395, 0.308836548106250) \\\n    STEP(  80, UINT64_C(0x00000000005143bf), 0.400, 0.317440000000000) \\\n    STEP(  81, UINT64_C(0x0000000000537c4d), 0.405, 0.326115448143750) \\\n    STEP(  82, UINT64_C(0x000000000055b95b), 0.410, 0.334859570600000) \\\n    STEP(  83, UINT64_C(0x000000000057fab1), 0.415, 0.343669002681250) \\\n    STEP(  84, UINT64_C(0x00000000005a4015), 0.420, 0.352540339200000) \\\n    STEP(  85, UINT64_C(0x00000000005c894e), 0.425, 0.361470136718750) \\\n    STEP(  86, UINT64_C(0x00000000005ed622), 0.430, 0.370454915800000) \\\n    STEP(  87, UINT64_C(0x0000000000612655), 0.435, 0.379491163256250) \\\n    STEP(  88, UINT64_C(0x00000000006379ac), 0.440, 0.388575334400000) \\\n    STEP(  89, UINT64_C(0x000000000065cfeb), 0.445, 0.397703855293750) \\\n    STEP(  90, UINT64_C(0x00000000006828d6), 0.450, 0.406873125000000) \\\n    STEP(  91, UINT64_C(0x00000000006a842f), 0.455, 0.416079517831250) \\\n    STEP(  92, UINT64_C(0x00000000006ce1bb), 0.460, 0.425319385600000) \\\n    STEP(  93, UINT64_C(0x00000000006f413a), 0.465, 0.434589059868750) \\\n    STEP(  94, UINT64_C(0x000000000071a270), 0.470, 0.443884854200000) \\\n    STEP(  95, UINT64_C(0x000000000074051d), 0.475, 0.453203066406250) \\\n    STEP(  96, UINT64_C(0x0000000000766905), 0.480, 0.462539980800000) \\\n    STEP(  97, UINT64_C(0x000000000078cde7), 0.485, 0.471891870443750) \\\n    STEP(  98, UINT64_C(0x00000000007b3387), 0.490, 0.481254999400000) \\\n    STEP(  99, UINT64_C(0x00000000007d99a4), 0.495, 0.490625624981250) \\\n    STEP( 100, UINT64_C(0x0000000000800000), 0.500, 0.500000000000000) \\\n    STEP( 101, UINT64_C(0x000000000082665b), 0.505, 0.509374375018750) \\\n    STEP( 102, UINT64_C(0x000000000084cc78), 0.510, 0.518745000600000) \\\n    STEP( 103, UINT64_C(0x0000000000873218), 0.515, 0.528108129556250) \\\n    STEP( 104, UINT64_C(0x00000000008996fa), 0.520, 0.537460019200000) \\\n    STEP( 105, UINT64_C(0x00000000008bfae2), 0.525, 0.546796933593750) \\\n    STEP( 106, UINT64_C(0x00000000008e5d8f), 0.530, 0.556115145800000) \\\n    STEP( 107, UINT64_C(0x000000000090bec5), 0.535, 0.565410940131250) \\\n    STEP( 108, UINT64_C(0x0000000000931e44), 0.540, 0.574680614400000) \\\n    STEP( 109, UINT64_C(0x0000000000957bd0), 0.545, 0.583920482168750) \\\n    STEP( 110, UINT64_C(0x000000000097d729), 0.550, 0.593126875000000) \\\n    STEP( 111, UINT64_C(0x00000000009a3014), 0.555, 0.602296144706250) \\\n    STEP( 112, UINT64_C(0x00000000009c8653), 0.560, 0.611424665600000) \\\n    STEP( 113, UINT64_C(0x00000000009ed9aa), 0.565, 0.620508836743750) \\\n    STEP( 114, UINT64_C(0x0000000000a129dd), 0.570, 0.629545084200000) \\\n    STEP( 115, UINT64_C(0x0000000000a376b1), 0.575, 0.638529863281250) \\\n    STEP( 116, UINT64_C(0x0000000000a5bfea), 0.580, 0.647459660800000) \\\n    STEP( 117, UINT64_C(0x0000000000a8054e), 0.585, 0.656330997318750) \\\n    STEP( 118, UINT64_C(0x0000000000aa46a4), 0.590, 0.665140429400000) \\\n    STEP( 119, UINT64_C(0x0000000000ac83b2), 0.595, 0.673884551856250) \\\n    STEP( 120, UINT64_C(0x0000000000aebc40), 0.600, 0.682560000000000) \\\n    STEP( 121, UINT64_C(0x0000000000b0f016), 0.605, 0.691163451893750) \\\n    STEP( 122, UINT64_C(0x0000000000b31efd), 0.610, 0.699691630600000) \\\n    STEP( 123, UINT64_C(0x0000000000b548bf), 0.615, 0.708141306431250) \\\n    STEP( 124, UINT64_C(0x0000000000b76d27), 0.620, 0.716509299200000) \\\n    STEP( 125, UINT64_C(0x0000000000b98c00), 0.625, 0.724792480468750) \\\n    STEP( 126, UINT64_C(0x0000000000bba516), 0.630, 0.732987775800000) \\\n    STEP( 127, UINT64_C(0x0000000000bdb837), 0.635, 0.741092167006250) \\\n    STEP( 128, UINT64_C(0x0000000000bfc531), 0.640, 0.749102694400000) \\\n    STEP( 129, UINT64_C(0x0000000000c1cbd4), 0.645, 0.757016459043750) \\\n    STEP( 130, UINT64_C(0x0000000000c3cbf0), 0.650, 0.764830625000000) \\\n    STEP( 131, UINT64_C(0x0000000000c5c557), 0.655, 0.772542421581250) \\\n    STEP( 132, UINT64_C(0x0000000000c7b7da), 0.660, 0.780149145600000) \\\n    STEP( 133, UINT64_C(0x0000000000c9a34f), 0.665, 0.787648163618750) \\\n    STEP( 134, UINT64_C(0x0000000000cb878a), 0.670, 0.795036914200000) \\\n    STEP( 135, UINT64_C(0x0000000000cd6460), 0.675, 0.802312910156250) \\\n    STEP( 136, UINT64_C(0x0000000000cf39ab), 0.680, 0.809473740800000) \\\n    STEP( 137, UINT64_C(0x0000000000d10743), 0.685, 0.816517074193750) \\\n    STEP( 138, UINT64_C(0x0000000000d2cd01), 0.690, 0.823440659400000) \\\n    STEP( 139, UINT64_C(0x0000000000d48ac2), 0.695, 0.830242328731250) \\\n    STEP( 140, UINT64_C(0x0000000000d64063), 0.700, 0.836920000000000) \\\n    STEP( 141, UINT64_C(0x0000000000d7edc2), 0.705, 0.843471678768750) \\\n    STEP( 142, UINT64_C(0x0000000000d992bf), 0.710, 0.849895460600000) \\\n    STEP( 143, UINT64_C(0x0000000000db2f3c), 0.715, 0.856189533306250) \\\n    STEP( 144, UINT64_C(0x0000000000dcc31c), 0.720, 0.862352179200000) \\\n    STEP( 145, UINT64_C(0x0000000000de4e44), 0.725, 0.868381777343750) \\\n    STEP( 146, UINT64_C(0x0000000000dfd09a), 0.730, 0.874276805800000) \\\n    STEP( 147, UINT64_C(0x0000000000e14a07), 0.735, 0.880035843881250) \\\n    STEP( 148, UINT64_C(0x0000000000e2ba74), 0.740, 0.885657574400000) \\\n    STEP( 149, UINT64_C(0x0000000000e421cd), 0.745, 0.891140785918750) \\\n    STEP( 150, UINT64_C(0x0000000000e58000), 0.750, 0.896484375000000) \\\n    STEP( 151, UINT64_C(0x0000000000e6d4fb), 0.755, 0.901687348456250) \\\n    STEP( 152, UINT64_C(0x0000000000e820b0), 0.760, 0.906748825600000) \\\n    STEP( 153, UINT64_C(0x0000000000e96313), 0.765, 0.911668040493750) \\\n    STEP( 154, UINT64_C(0x0000000000ea9c18), 0.770, 0.916444344200000) \\\n    STEP( 155, UINT64_C(0x0000000000ebcbb7), 0.775, 0.921077207031250) \\\n    STEP( 156, UINT64_C(0x0000000000ecf1e8), 0.780, 0.925566220800000) \\\n    STEP( 157, UINT64_C(0x0000000000ee0ea7), 0.785, 0.929911101068750) \\\n    STEP( 158, UINT64_C(0x0000000000ef21f1), 0.790, 0.934111689400000) \\\n    STEP( 159, UINT64_C(0x0000000000f02bc6), 0.795, 0.938167955606250) \\\n    STEP( 160, UINT64_C(0x0000000000f12c27), 0.800, 0.942080000000000) \\\n    STEP( 161, UINT64_C(0x0000000000f22319), 0.805, 0.945848055643750) \\\n    STEP( 162, UINT64_C(0x0000000000f310a1), 0.810, 0.949472490600000) \\\n    STEP( 163, UINT64_C(0x0000000000f3f4c7), 0.815, 0.952953810181250) \\\n    STEP( 164, UINT64_C(0x0000000000f4cf98), 0.820, 0.956292659200000) \\\n    STEP( 165, UINT64_C(0x0000000000f5a120), 0.825, 0.959489824218750) \\\n    STEP( 166, UINT64_C(0x0000000000f6696e), 0.830, 0.962546235800000) \\\n    STEP( 167, UINT64_C(0x0000000000f72894), 0.835, 0.965462970756250) \\\n    STEP( 168, UINT64_C(0x0000000000f7dea8), 0.840, 0.968241254400000) \\\n    STEP( 169, UINT64_C(0x0000000000f88bc0), 0.845, 0.970882462793750) \\\n    STEP( 170, UINT64_C(0x0000000000f92ff6), 0.850, 0.973388125000000) \\\n    STEP( 171, UINT64_C(0x0000000000f9cb67), 0.855, 0.975759925331250) \\\n    STEP( 172, UINT64_C(0x0000000000fa5e30), 0.860, 0.977999705600000) \\\n    STEP( 173, UINT64_C(0x0000000000fae874), 0.865, 0.980109467368750) \\\n    STEP( 174, UINT64_C(0x0000000000fb6a57), 0.870, 0.982091374200000) \\\n    STEP( 175, UINT64_C(0x0000000000fbe400), 0.875, 0.983947753906250) \\\n    STEP( 176, UINT64_C(0x0000000000fc5598), 0.880, 0.985681100800000) \\\n    STEP( 177, UINT64_C(0x0000000000fcbf4e), 0.885, 0.987294077943750) \\\n    STEP( 178, UINT64_C(0x0000000000fd214f), 0.890, 0.988789519400000) \\\n    STEP( 179, UINT64_C(0x0000000000fd7bcf), 0.895, 0.990170432481250) \\\n    STEP( 180, UINT64_C(0x0000000000fdcf03), 0.900, 0.991440000000000) \\\n    STEP( 181, UINT64_C(0x0000000000fe1b23), 0.905, 0.992601582518750) \\\n    STEP( 182, UINT64_C(0x0000000000fe606a), 0.910, 0.993658720600000) \\\n    STEP( 183, UINT64_C(0x0000000000fe9f18), 0.915, 0.994615137056250) \\\n    STEP( 184, UINT64_C(0x0000000000fed76e), 0.920, 0.995474739200000) \\\n    STEP( 185, UINT64_C(0x0000000000ff09b0), 0.925, 0.996241621093750) \\\n    STEP( 186, UINT64_C(0x0000000000ff3627), 0.930, 0.996920065800000) \\\n    STEP( 187, UINT64_C(0x0000000000ff5d1d), 0.935, 0.997514547631250) \\\n    STEP( 188, UINT64_C(0x0000000000ff7ee0), 0.940, 0.998029734400000) \\\n    STEP( 189, UINT64_C(0x0000000000ff9bc3), 0.945, 0.998470489668750) \\\n    STEP( 190, UINT64_C(0x0000000000ffb419), 0.950, 0.998841875000000) \\\n    STEP( 191, UINT64_C(0x0000000000ffc83d), 0.955, 0.999149152206250) \\\n    STEP( 192, UINT64_C(0x0000000000ffd888), 0.960, 0.999397785600000) \\\n    STEP( 193, UINT64_C(0x0000000000ffe55b), 0.965, 0.999593444243750) \\\n    STEP( 194, UINT64_C(0x0000000000ffef17), 0.970, 0.999742004200000) \\\n    STEP( 195, UINT64_C(0x0000000000fff623), 0.975, 0.999849550781250) \\\n    STEP( 196, UINT64_C(0x0000000000fffae9), 0.980, 0.999922380800000) \\\n    STEP( 197, UINT64_C(0x0000000000fffdd6), 0.985, 0.999967004818750) \\\n    STEP( 198, UINT64_C(0x0000000000ffff5a), 0.990, 0.999990149400000) \\\n    STEP( 199, UINT64_C(0x0000000000ffffeb), 0.995, 0.999998759356250) \\\n    STEP( 200, UINT64_C(0x0000000001000000), 1.000, 1.000000000000000) \\\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/smoothstep.sh",
    "content": "#!/bin/sh\n#\n# Generate a discrete lookup table for a sigmoid function in the smoothstep\n# family (https://en.wikipedia.org/wiki/Smoothstep), where the lookup table\n# entries correspond to x in [1/nsteps, 2/nsteps, ..., nsteps/nsteps].  Encode\n# the entries using a binary fixed point representation.\n#\n# Usage: smoothstep.sh <variant> <nsteps> <bfp> <xprec> <yprec>\n#\n#        <variant> is in {smooth, smoother, smoothest}.\n#        <nsteps> must be greater than zero.\n#        <bfp> must be in [0..62]; reasonable values are roughly [10..30].\n#        <xprec> is x decimal precision.\n#        <yprec> is y decimal precision.\n\n#set -x\n\ncmd=\"sh smoothstep.sh $*\"\nvariant=$1\nnsteps=$2\nbfp=$3\nxprec=$4\nyprec=$5\n\ncase \"${variant}\" in\n  smooth)\n    ;;\n  smoother)\n    ;;\n  smoothest)\n    ;;\n  *)\n    echo \"Unsupported variant\"\n    exit 1\n    ;;\nesac\n\nsmooth() {\n  step=$1\n  y=`echo ${yprec} k ${step} ${nsteps} / sx _2 lx 3 ^ '*' 3 lx 2 ^ '*' + p | dc | tr -d '\\\\\\\\\\n' | sed -e 's#^\\.#0.#g'`\n  h=`echo ${yprec} k 2 ${bfp} ^ ${y} '*' p | dc | tr -d '\\\\\\\\\\n' | sed -e 's#^\\.#0.#g' | tr '.' ' ' | awk '{print $1}' `\n}\n\nsmoother() {\n  step=$1\n  y=`echo ${yprec} k ${step} ${nsteps} / sx 6 lx 5 ^ '*' _15 lx 4 ^ '*' + 10 lx 3 ^ '*' + p | dc | tr -d '\\\\\\\\\\n' | sed -e 's#^\\.#0.#g'`\n  h=`echo ${yprec} k 2 ${bfp} ^ ${y} '*' p | dc | tr -d '\\\\\\\\\\n' | sed -e 's#^\\.#0.#g' | tr '.' ' ' | awk '{print $1}' `\n}\n\nsmoothest() {\n  step=$1\n  y=`echo ${yprec} k ${step} ${nsteps} / sx _20 lx 7 ^ '*' 70 lx 6 ^ '*' + _84 lx 5 ^ '*' + 35 lx 4 ^ '*' + p | dc | tr -d '\\\\\\\\\\n' | sed -e 's#^\\.#0.#g'`\n  h=`echo ${yprec} k 2 ${bfp} ^ ${y} '*' p | dc | tr -d '\\\\\\\\\\n' | sed -e 's#^\\.#0.#g' | tr '.' ' ' | awk '{print $1}' `\n}\n\ncat <<EOF\n/*\n * This file was generated by the following command:\n *   $cmd\n */\n/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n/*\n * This header defines a precomputed table based on the smoothstep family of\n * sigmoidal curves (https://en.wikipedia.org/wiki/Smoothstep) that grow from 0\n * to 1 in 0 <= x <= 1.  The table is stored as integer fixed point values so\n * that floating point math can be avoided.\n *\n *                      3     2\n *   smoothstep(x) = -2x  + 3x\n *\n *                       5      4      3\n *   smootherstep(x) = 6x  - 15x  + 10x\n *\n *                          7      6      5      4\n *   smootheststep(x) = -20x  + 70x  - 84x  + 35x\n */\n\n#define\tSMOOTHSTEP_VARIANT\t\"${variant}\"\n#define\tSMOOTHSTEP_NSTEPS\t${nsteps}\n#define\tSMOOTHSTEP_BFP\t\t${bfp}\n#define\tSMOOTHSTEP \\\\\n /* STEP(step, h,                            x,     y) */ \\\\\nEOF\n\ns=1\nwhile [ $s -le $nsteps ] ; do\n  $variant ${s}\n  x=`echo ${xprec} k ${s} ${nsteps} / p | dc | tr -d '\\\\\\\\\\n' | sed -e 's#^\\.#0.#g'`\n  printf '    STEP(%4d, UINT64_C(0x%016x), %s, %s) \\\\\\n' ${s} ${h} ${x} ${y}\n\n  s=$((s+1))\ndone\necho\n\ncat <<EOF\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\nEOF\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/stats.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\ntypedef struct tcache_bin_stats_s tcache_bin_stats_t;\ntypedef struct malloc_bin_stats_s malloc_bin_stats_t;\ntypedef struct malloc_large_stats_s malloc_large_stats_t;\ntypedef struct malloc_huge_stats_s malloc_huge_stats_t;\ntypedef struct arena_stats_s arena_stats_t;\ntypedef struct chunk_stats_s chunk_stats_t;\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\nstruct tcache_bin_stats_s {\n\t/*\n\t * Number of allocation requests that corresponded to the size of this\n\t * bin.\n\t */\n\tuint64_t\tnrequests;\n};\n\nstruct malloc_bin_stats_s {\n\t/*\n\t * Total number of allocation/deallocation requests served directly by\n\t * the bin.  Note that tcache may allocate an object, then recycle it\n\t * many times, resulting many increments to nrequests, but only one\n\t * each to nmalloc and ndalloc.\n\t */\n\tuint64_t\tnmalloc;\n\tuint64_t\tndalloc;\n\n\t/*\n\t * Number of allocation requests that correspond to the size of this\n\t * bin.  This includes requests served by tcache, though tcache only\n\t * periodically merges into this counter.\n\t */\n\tuint64_t\tnrequests;\n\n\t/*\n\t * Current number of regions of this size class, including regions\n\t * currently cached by tcache.\n\t */\n\tsize_t\t\tcurregs;\n\n\t/* Number of tcache fills from this bin. */\n\tuint64_t\tnfills;\n\n\t/* Number of tcache flushes to this bin. */\n\tuint64_t\tnflushes;\n\n\t/* Total number of runs created for this bin's size class. */\n\tuint64_t\tnruns;\n\n\t/*\n\t * Total number of runs reused by extracting them from the runs tree for\n\t * this bin's size class.\n\t */\n\tuint64_t\treruns;\n\n\t/* Current number of runs in this bin. */\n\tsize_t\t\tcurruns;\n};\n\nstruct malloc_large_stats_s {\n\t/*\n\t * Total number of allocation/deallocation requests served directly by\n\t * the arena.  Note that tcache may allocate an object, then recycle it\n\t * many times, resulting many increments to nrequests, but only one\n\t * each to nmalloc and ndalloc.\n\t */\n\tuint64_t\tnmalloc;\n\tuint64_t\tndalloc;\n\n\t/*\n\t * Number of allocation requests that correspond to this size class.\n\t * This includes requests served by tcache, though tcache only\n\t * periodically merges into this counter.\n\t */\n\tuint64_t\tnrequests;\n\n\t/*\n\t * Current number of runs of this size class, including runs currently\n\t * cached by tcache.\n\t */\n\tsize_t\t\tcurruns;\n};\n\nstruct malloc_huge_stats_s {\n\t/*\n\t * Total number of allocation/deallocation requests served directly by\n\t * the arena.\n\t */\n\tuint64_t\tnmalloc;\n\tuint64_t\tndalloc;\n\n\t/* Current number of (multi-)chunk allocations of this size class. */\n\tsize_t\t\tcurhchunks;\n};\n\nstruct arena_stats_s {\n\t/* Number of bytes currently mapped. */\n\tsize_t\t\tmapped;\n\n\t/*\n\t * Total number of purge sweeps, total number of madvise calls made,\n\t * and total pages purged in order to keep dirty unused memory under\n\t * control.\n\t */\n\tuint64_t\tnpurge;\n\tuint64_t\tnmadvise;\n\tuint64_t\tpurged;\n\n\t/*\n\t * Number of bytes currently mapped purely for metadata purposes, and\n\t * number of bytes currently allocated for internal metadata.\n\t */\n\tsize_t\t\tmetadata_mapped;\n\tsize_t\t\tmetadata_allocated; /* Protected via atomic_*_z(). */\n\n\t/* Per-size-category statistics. */\n\tsize_t\t\tallocated_large;\n\tuint64_t\tnmalloc_large;\n\tuint64_t\tndalloc_large;\n\tuint64_t\tnrequests_large;\n\n\tsize_t\t\tallocated_huge;\n\tuint64_t\tnmalloc_huge;\n\tuint64_t\tndalloc_huge;\n\n\t/* One element for each large size class. */\n\tmalloc_large_stats_t\t*lstats;\n\n\t/* One element for each huge size class. */\n\tmalloc_huge_stats_t\t*hstats;\n};\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nextern bool\topt_stats_print;\n\nextern size_t\tstats_cactive;\n\nvoid\tstats_print(void (*write)(void *, const char *), void *cbopaque,\n    const char *opts);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#ifndef JEMALLOC_ENABLE_INLINE\nsize_t\tstats_cactive_get(void);\nvoid\tstats_cactive_add(size_t size);\nvoid\tstats_cactive_sub(size_t size);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_STATS_C_))\nJEMALLOC_INLINE size_t\nstats_cactive_get(void)\n{\n\n\treturn (atomic_read_z(&stats_cactive));\n}\n\nJEMALLOC_INLINE void\nstats_cactive_add(size_t size)\n{\n\tUNUSED size_t cactive;\n\n\tassert(size > 0);\n\tassert((size & chunksize_mask) == 0);\n\n\tcactive = atomic_add_z(&stats_cactive, size);\n\tassert(cactive - size < cactive);\n}\n\nJEMALLOC_INLINE void\nstats_cactive_sub(size_t size)\n{\n\tUNUSED size_t cactive;\n\n\tassert(size > 0);\n\tassert((size & chunksize_mask) == 0);\n\n\tcactive = atomic_sub_z(&stats_cactive, size);\n\tassert(cactive + size > cactive);\n}\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/tcache.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\ntypedef struct tcache_bin_info_s tcache_bin_info_t;\ntypedef struct tcache_bin_s tcache_bin_t;\ntypedef struct tcache_s tcache_t;\ntypedef struct tcaches_s tcaches_t;\n\n/*\n * tcache pointers close to NULL are used to encode state information that is\n * used for two purposes: preventing thread caching on a per thread basis and\n * cleaning up during thread shutdown.\n */\n#define\tTCACHE_STATE_DISABLED\t\t((tcache_t *)(uintptr_t)1)\n#define\tTCACHE_STATE_REINCARNATED\t((tcache_t *)(uintptr_t)2)\n#define\tTCACHE_STATE_PURGATORY\t\t((tcache_t *)(uintptr_t)3)\n#define\tTCACHE_STATE_MAX\t\tTCACHE_STATE_PURGATORY\n\n/*\n * Absolute minimum number of cache slots for each small bin.\n */\n#define\tTCACHE_NSLOTS_SMALL_MIN\t\t20\n\n/*\n * Absolute maximum number of cache slots for each small bin in the thread\n * cache.  This is an additional constraint beyond that imposed as: twice the\n * number of regions per run for this size class.\n *\n * This constant must be an even number.\n */\n#define\tTCACHE_NSLOTS_SMALL_MAX\t\t200\n\n/* Number of cache slots for large size classes. */\n#define\tTCACHE_NSLOTS_LARGE\t\t20\n\n/* (1U << opt_lg_tcache_max) is used to compute tcache_maxclass. */\n#define\tLG_TCACHE_MAXCLASS_DEFAULT\t15\n\n/*\n * TCACHE_GC_SWEEP is the approximate number of allocation events between\n * full GC sweeps.  Integer rounding may cause the actual number to be\n * slightly higher, since GC is performed incrementally.\n */\n#define\tTCACHE_GC_SWEEP\t\t\t8192\n\n/* Number of tcache allocation/deallocation events between incremental GCs. */\n#define\tTCACHE_GC_INCR\t\t\t\t\t\t\t\\\n    ((TCACHE_GC_SWEEP / NBINS) + ((TCACHE_GC_SWEEP / NBINS == 0) ? 0 : 1))\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\ntypedef enum {\n\ttcache_enabled_false   = 0, /* Enable cast to/from bool. */\n\ttcache_enabled_true    = 1,\n\ttcache_enabled_default = 2\n} tcache_enabled_t;\n\n/*\n * Read-only information associated with each element of tcache_t's tbins array\n * is stored separately, mainly to reduce memory usage.\n */\nstruct tcache_bin_info_s {\n\tunsigned\tncached_max;\t/* Upper limit on ncached. */\n};\n\nstruct tcache_bin_s {\n\ttcache_bin_stats_t tstats;\n\tint\t\tlow_water;\t/* Min # cached since last GC. */\n\tunsigned\tlg_fill_div;\t/* Fill (ncached_max >> lg_fill_div). */\n\tunsigned\tncached;\t/* # of cached objects. */\n\t/*\n\t * To make use of adjacent cacheline prefetch, the items in the avail\n\t * stack goes to higher address for newer allocations.  avail points\n\t * just above the available space, which means that\n\t * avail[-ncached, ... -1] are available items and the lowest item will\n\t * be allocated first.\n\t */\n\tvoid\t\t**avail;\t/* Stack of available objects. */\n};\n\nstruct tcache_s {\n\tql_elm(tcache_t) link;\t\t/* Used for aggregating stats. */\n\tuint64_t\tprof_accumbytes;/* Cleared after arena_prof_accum(). */\n\tticker_t\tgc_ticker;\t/* Drives incremental GC. */\n\tszind_t\t\tnext_gc_bin;\t/* Next bin to GC. */\n\ttcache_bin_t\ttbins[1];\t/* Dynamically sized. */\n\t/*\n\t * The pointer stacks associated with tbins follow as a contiguous\n\t * array.  During tcache initialization, the avail pointer in each\n\t * element of tbins is initialized to point to the proper offset within\n\t * this array.\n\t */\n};\n\n/* Linkage for list of available (previously used) explicit tcache IDs. */\nstruct tcaches_s {\n\tunion {\n\t\ttcache_t\t*tcache;\n\t\ttcaches_t\t*next;\n\t};\n};\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nextern bool\topt_tcache;\nextern ssize_t\topt_lg_tcache_max;\n\nextern tcache_bin_info_t\t*tcache_bin_info;\n\n/*\n * Number of tcache bins.  There are NBINS small-object bins, plus 0 or more\n * large-object bins.\n */\nextern unsigned\tnhbins;\n\n/* Maximum cached size class. */\nextern size_t\ttcache_maxclass;\n\n/*\n * Explicit tcaches, managed via the tcache.{create,flush,destroy} mallctls and\n * usable via the MALLOCX_TCACHE() flag.  The automatic per thread tcaches are\n * completely disjoint from this data structure.  tcaches starts off as a sparse\n * array, so it has no physical memory footprint until individual pages are\n * touched.  This allows the entire array to be allocated the first time an\n * explicit tcache is created without a disproportionate impact on memory usage.\n */\nextern tcaches_t\t*tcaches;\n\nsize_t\ttcache_salloc(const void *ptr);\nvoid\ttcache_event_hard(tsd_t *tsd, tcache_t *tcache);\nvoid\t*tcache_alloc_small_hard(tsd_t *tsd, arena_t *arena, tcache_t *tcache,\n    tcache_bin_t *tbin, szind_t binind, bool *tcache_success);\nvoid\ttcache_bin_flush_small(tsd_t *tsd, tcache_t *tcache, tcache_bin_t *tbin,\n    szind_t binind, unsigned rem);\nvoid\ttcache_bin_flush_large(tsd_t *tsd, tcache_bin_t *tbin, szind_t binind,\n    unsigned rem, tcache_t *tcache);\nvoid\ttcache_arena_associate(tcache_t *tcache, arena_t *arena);\nvoid\ttcache_arena_reassociate(tcache_t *tcache, arena_t *oldarena,\n    arena_t *newarena);\nvoid\ttcache_arena_dissociate(tcache_t *tcache, arena_t *arena);\ntcache_t *tcache_get_hard(tsd_t *tsd);\ntcache_t *tcache_create(tsd_t *tsd, arena_t *arena);\nvoid\ttcache_cleanup(tsd_t *tsd);\nvoid\ttcache_enabled_cleanup(tsd_t *tsd);\nvoid\ttcache_stats_merge(tcache_t *tcache, arena_t *arena);\nbool\ttcaches_create(tsd_t *tsd, unsigned *r_ind);\nvoid\ttcaches_flush(tsd_t *tsd, unsigned ind);\nvoid\ttcaches_destroy(tsd_t *tsd, unsigned ind);\nbool\ttcache_boot(void);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#ifndef JEMALLOC_ENABLE_INLINE\nvoid\ttcache_event(tsd_t *tsd, tcache_t *tcache);\nvoid\ttcache_flush(void);\nbool\ttcache_enabled_get(void);\ntcache_t *tcache_get(tsd_t *tsd, bool create);\nvoid\ttcache_enabled_set(bool enabled);\nvoid\t*tcache_alloc_easy(tcache_bin_t *tbin, bool *tcache_success);\nvoid\t*tcache_alloc_small(tsd_t *tsd, arena_t *arena, tcache_t *tcache,\n    size_t size, szind_t ind, bool zero, bool slow_path);\nvoid\t*tcache_alloc_large(tsd_t *tsd, arena_t *arena, tcache_t *tcache,\n    size_t size, szind_t ind, bool zero, bool slow_path);\nvoid\ttcache_dalloc_small(tsd_t *tsd, tcache_t *tcache, void *ptr,\n    szind_t binind, bool slow_path);\nvoid\ttcache_dalloc_large(tsd_t *tsd, tcache_t *tcache, void *ptr,\n    size_t size, bool slow_path);\ntcache_t\t*tcaches_get(tsd_t *tsd, unsigned ind);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_TCACHE_C_))\nJEMALLOC_INLINE void\ntcache_flush(void)\n{\n\ttsd_t *tsd;\n\n\tcassert(config_tcache);\n\n\ttsd = tsd_fetch();\n\ttcache_cleanup(tsd);\n}\n\nJEMALLOC_INLINE bool\ntcache_enabled_get(void)\n{\n\ttsd_t *tsd;\n\ttcache_enabled_t tcache_enabled;\n\n\tcassert(config_tcache);\n\n\ttsd = tsd_fetch();\n\ttcache_enabled = tsd_tcache_enabled_get(tsd);\n\tif (tcache_enabled == tcache_enabled_default) {\n\t\ttcache_enabled = (tcache_enabled_t)opt_tcache;\n\t\ttsd_tcache_enabled_set(tsd, tcache_enabled);\n\t}\n\n\treturn ((bool)tcache_enabled);\n}\n\nJEMALLOC_INLINE void\ntcache_enabled_set(bool enabled)\n{\n\ttsd_t *tsd;\n\ttcache_enabled_t tcache_enabled;\n\n\tcassert(config_tcache);\n\n\ttsd = tsd_fetch();\n\n\ttcache_enabled = (tcache_enabled_t)enabled;\n\ttsd_tcache_enabled_set(tsd, tcache_enabled);\n\n\tif (!enabled)\n\t\ttcache_cleanup(tsd);\n}\n\nJEMALLOC_ALWAYS_INLINE tcache_t *\ntcache_get(tsd_t *tsd, bool create)\n{\n\ttcache_t *tcache;\n\n\tif (!config_tcache)\n\t\treturn (NULL);\n\n\ttcache = tsd_tcache_get(tsd);\n\tif (!create)\n\t\treturn (tcache);\n\tif (unlikely(tcache == NULL) && tsd_nominal(tsd)) {\n\t\ttcache = tcache_get_hard(tsd);\n\t\ttsd_tcache_set(tsd, tcache);\n\t}\n\n\treturn (tcache);\n}\n\nJEMALLOC_ALWAYS_INLINE void\ntcache_event(tsd_t *tsd, tcache_t *tcache)\n{\n\n\tif (TCACHE_GC_INCR == 0)\n\t\treturn;\n\n\tif (unlikely(ticker_tick(&tcache->gc_ticker)))\n\t\ttcache_event_hard(tsd, tcache);\n}\n\nJEMALLOC_ALWAYS_INLINE void *\ntcache_alloc_easy(tcache_bin_t *tbin, bool *tcache_success)\n{\n\tvoid *ret;\n\n\tif (unlikely(tbin->ncached == 0)) {\n\t\ttbin->low_water = -1;\n\t\t*tcache_success = false;\n\t\treturn (NULL);\n\t}\n\t/*\n\t * tcache_success (instead of ret) should be checked upon the return of\n\t * this function.  We avoid checking (ret == NULL) because there is\n\t * never a null stored on the avail stack (which is unknown to the\n\t * compiler), and eagerly checking ret would cause pipeline stall\n\t * (waiting for the cacheline).\n\t */\n\t*tcache_success = true;\n\tret = *(tbin->avail - tbin->ncached);\n\ttbin->ncached--;\n\n\tif (unlikely((int)tbin->ncached < tbin->low_water))\n\t\ttbin->low_water = tbin->ncached;\n\n\treturn (ret);\n}\n\nJEMALLOC_ALWAYS_INLINE void *\ntcache_alloc_small(tsd_t *tsd, arena_t *arena, tcache_t *tcache, size_t size,\n    szind_t binind, bool zero, bool slow_path)\n{\n\tvoid *ret;\n\ttcache_bin_t *tbin;\n\tbool tcache_success;\n\tsize_t usize JEMALLOC_CC_SILENCE_INIT(0);\n\n\tassert(binind < NBINS);\n\ttbin = &tcache->tbins[binind];\n\tret = tcache_alloc_easy(tbin, &tcache_success);\n\tassert(tcache_success == (ret != NULL));\n\tif (unlikely(!tcache_success)) {\n\t\tbool tcache_hard_success;\n\t\tarena = arena_choose(tsd, arena);\n\t\tif (unlikely(arena == NULL))\n\t\t\treturn (NULL);\n\n\t\tret = tcache_alloc_small_hard(tsd, arena, tcache, tbin, binind,\n\t\t\t&tcache_hard_success);\n\t\tif (tcache_hard_success == false)\n\t\t\treturn (NULL);\n\t}\n\n\tassert(ret);\n\t/*\n\t * Only compute usize if required.  The checks in the following if\n\t * statement are all static.\n\t */\n\tif (config_prof || (slow_path && config_fill) || unlikely(zero)) {\n\t\tusize = index2size(binind);\n\t\tassert(tcache_salloc(ret) == usize);\n\t}\n\n\tif (likely(!zero)) {\n\t\tif (slow_path && config_fill) {\n\t\t\tif (unlikely(opt_junk_alloc)) {\n\t\t\t\tarena_alloc_junk_small(ret,\n\t\t\t\t    &arena_bin_info[binind], false);\n\t\t\t} else if (unlikely(opt_zero))\n\t\t\t\tmemset(ret, 0, usize);\n\t\t}\n\t} else {\n\t\tif (slow_path && config_fill && unlikely(opt_junk_alloc)) {\n\t\t\tarena_alloc_junk_small(ret, &arena_bin_info[binind],\n\t\t\t    true);\n\t\t}\n\t\tmemset(ret, 0, usize);\n\t}\n\n\tif (config_stats)\n\t\ttbin->tstats.nrequests++;\n\tif (config_prof)\n\t\ttcache->prof_accumbytes += usize;\n\ttcache_event(tsd, tcache);\n\treturn (ret);\n}\n\nJEMALLOC_ALWAYS_INLINE void *\ntcache_alloc_large(tsd_t *tsd, arena_t *arena, tcache_t *tcache, size_t size,\n    szind_t binind, bool zero, bool slow_path)\n{\n\tvoid *ret;\n\ttcache_bin_t *tbin;\n\tbool tcache_success;\n\n\tassert(binind < nhbins);\n\ttbin = &tcache->tbins[binind];\n\tret = tcache_alloc_easy(tbin, &tcache_success);\n\tassert(tcache_success == (ret != NULL));\n\tif (unlikely(!tcache_success)) {\n\t\t/*\n\t\t * Only allocate one large object at a time, because it's quite\n\t\t * expensive to create one and not use it.\n\t\t */\n\t\tarena = arena_choose(tsd, arena);\n\t\tif (unlikely(arena == NULL))\n\t\t\treturn (NULL);\n\n\t\tret = arena_malloc_large(tsd, arena, binind, zero);\n\t\tif (ret == NULL)\n\t\t\treturn (NULL);\n\t} else {\n\t\tsize_t usize JEMALLOC_CC_SILENCE_INIT(0);\n\n\t\t/* Only compute usize on demand */\n\t\tif (config_prof || (slow_path && config_fill) ||\n\t\t    unlikely(zero)) {\n\t\t\tusize = index2size(binind);\n\t\t\tassert(usize <= tcache_maxclass);\n\t\t}\n\n\t\tif (config_prof && usize == LARGE_MINCLASS) {\n\t\t\tarena_chunk_t *chunk =\n\t\t\t    (arena_chunk_t *)CHUNK_ADDR2BASE(ret);\n\t\t\tsize_t pageind = (((uintptr_t)ret - (uintptr_t)chunk) >>\n\t\t\t    LG_PAGE);\n\t\t\tarena_mapbits_large_binind_set(chunk, pageind,\n\t\t\t    BININD_INVALID);\n\t\t}\n\t\tif (likely(!zero)) {\n\t\t\tif (slow_path && config_fill) {\n\t\t\t\tif (unlikely(opt_junk_alloc))\n\t\t\t\t\tmemset(ret, 0xa5, usize);\n\t\t\t\telse if (unlikely(opt_zero))\n\t\t\t\t\tmemset(ret, 0, usize);\n\t\t\t}\n\t\t} else\n\t\t\tmemset(ret, 0, usize);\n\n\t\tif (config_stats)\n\t\t\ttbin->tstats.nrequests++;\n\t\tif (config_prof)\n\t\t\ttcache->prof_accumbytes += usize;\n\t}\n\n\ttcache_event(tsd, tcache);\n\treturn (ret);\n}\n\nJEMALLOC_ALWAYS_INLINE void\ntcache_dalloc_small(tsd_t *tsd, tcache_t *tcache, void *ptr, szind_t binind,\n    bool slow_path)\n{\n\ttcache_bin_t *tbin;\n\ttcache_bin_info_t *tbin_info;\n\n\tassert(tcache_salloc(ptr) <= SMALL_MAXCLASS);\n\n\tif (slow_path && config_fill && unlikely(opt_junk_free))\n\t\tarena_dalloc_junk_small(ptr, &arena_bin_info[binind]);\n\n\ttbin = &tcache->tbins[binind];\n\ttbin_info = &tcache_bin_info[binind];\n\tif (unlikely(tbin->ncached == tbin_info->ncached_max)) {\n\t\ttcache_bin_flush_small(tsd, tcache, tbin, binind,\n\t\t    (tbin_info->ncached_max >> 1));\n\t}\n\tassert(tbin->ncached < tbin_info->ncached_max);\n\ttbin->ncached++;\n\t*(tbin->avail - tbin->ncached) = ptr;\n\n\ttcache_event(tsd, tcache);\n}\n\nJEMALLOC_ALWAYS_INLINE void\ntcache_dalloc_large(tsd_t *tsd, tcache_t *tcache, void *ptr, size_t size,\n    bool slow_path)\n{\n\tszind_t binind;\n\ttcache_bin_t *tbin;\n\ttcache_bin_info_t *tbin_info;\n\n\tassert((size & PAGE_MASK) == 0);\n\tassert(tcache_salloc(ptr) > SMALL_MAXCLASS);\n\tassert(tcache_salloc(ptr) <= tcache_maxclass);\n\n\tbinind = size2index(size);\n\n\tif (slow_path && config_fill && unlikely(opt_junk_free))\n\t\tarena_dalloc_junk_large(ptr, size);\n\n\ttbin = &tcache->tbins[binind];\n\ttbin_info = &tcache_bin_info[binind];\n\tif (unlikely(tbin->ncached == tbin_info->ncached_max)) {\n\t\ttcache_bin_flush_large(tsd, tbin, binind,\n\t\t    (tbin_info->ncached_max >> 1), tcache);\n\t}\n\tassert(tbin->ncached < tbin_info->ncached_max);\n\ttbin->ncached++;\n\t*(tbin->avail - tbin->ncached) = ptr;\n\n\ttcache_event(tsd, tcache);\n}\n\nJEMALLOC_ALWAYS_INLINE tcache_t *\ntcaches_get(tsd_t *tsd, unsigned ind)\n{\n\ttcaches_t *elm = &tcaches[ind];\n\tif (unlikely(elm->tcache == NULL))\n\t\telm->tcache = tcache_create(tsd, arena_choose(tsd, NULL));\n\treturn (elm->tcache);\n}\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/ticker.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\ntypedef struct ticker_s ticker_t;\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\nstruct ticker_s {\n\tint32_t\ttick;\n\tint32_t\tnticks;\n};\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#ifndef JEMALLOC_ENABLE_INLINE\nvoid\tticker_init(ticker_t *ticker, int32_t nticks);\nvoid\tticker_copy(ticker_t *ticker, const ticker_t *other);\nint32_t\tticker_read(const ticker_t *ticker);\nbool\tticker_ticks(ticker_t *ticker, int32_t nticks);\nbool\tticker_tick(ticker_t *ticker);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_TICKER_C_))\nJEMALLOC_INLINE void\nticker_init(ticker_t *ticker, int32_t nticks)\n{\n\n\tticker->tick = nticks;\n\tticker->nticks = nticks;\n}\n\nJEMALLOC_INLINE void\nticker_copy(ticker_t *ticker, const ticker_t *other)\n{\n\n\t*ticker = *other;\n}\n\nJEMALLOC_INLINE int32_t\nticker_read(const ticker_t *ticker)\n{\n\n\treturn (ticker->tick);\n}\n\nJEMALLOC_INLINE bool\nticker_ticks(ticker_t *ticker, int32_t nticks)\n{\n\n\tif (unlikely(ticker->tick < nticks)) {\n\t\tticker->tick = ticker->nticks;\n\t\treturn (true);\n\t}\n\tticker->tick -= nticks;\n\treturn(false);\n}\n\nJEMALLOC_INLINE bool\nticker_tick(ticker_t *ticker)\n{\n\n\treturn (ticker_ticks(ticker, 1));\n}\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/tsd.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n/* Maximum number of malloc_tsd users with cleanup functions. */\n#define\tMALLOC_TSD_CLEANUPS_MAX\t2\n\ntypedef bool (*malloc_tsd_cleanup_t)(void);\n\n#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \\\n    !defined(_WIN32))\ntypedef struct tsd_init_block_s tsd_init_block_t;\ntypedef struct tsd_init_head_s tsd_init_head_t;\n#endif\n\ntypedef struct tsd_s tsd_t;\n\ntypedef enum {\n\ttsd_state_uninitialized,\n\ttsd_state_nominal,\n\ttsd_state_purgatory,\n\ttsd_state_reincarnated\n} tsd_state_t;\n\n/*\n * TLS/TSD-agnostic macro-based implementation of thread-specific data.  There\n * are five macros that support (at least) three use cases: file-private,\n * library-private, and library-private inlined.  Following is an example\n * library-private tsd variable:\n *\n * In example.h:\n *   typedef struct {\n *           int x;\n *           int y;\n *   } example_t;\n *   #define EX_INITIALIZER JEMALLOC_CONCAT({0, 0})\n *   malloc_tsd_types(example_, example_t)\n *   malloc_tsd_protos(, example_, example_t)\n *   malloc_tsd_externs(example_, example_t)\n * In example.c:\n *   malloc_tsd_data(, example_, example_t, EX_INITIALIZER)\n *   malloc_tsd_funcs(, example_, example_t, EX_INITIALIZER,\n *       example_tsd_cleanup)\n *\n * The result is a set of generated functions, e.g.:\n *\n *   bool example_tsd_boot(void) {...}\n *   example_t *example_tsd_get() {...}\n *   void example_tsd_set(example_t *val) {...}\n *\n * Note that all of the functions deal in terms of (a_type *) rather than\n * (a_type) so that it is possible to support non-pointer types (unlike\n * pthreads TSD).  example_tsd_cleanup() is passed an (a_type *) pointer that is\n * cast to (void *).  This means that the cleanup function needs to cast the\n * function argument to (a_type *), then dereference the resulting pointer to\n * access fields, e.g.\n *\n *   void\n *   example_tsd_cleanup(void *arg)\n *   {\n *           example_t *example = (example_t *)arg;\n *\n *           example->x = 42;\n *           [...]\n *           if ([want the cleanup function to be called again])\n *                   example_tsd_set(example);\n *   }\n *\n * If example_tsd_set() is called within example_tsd_cleanup(), it will be\n * called again.  This is similar to how pthreads TSD destruction works, except\n * that pthreads only calls the cleanup function again if the value was set to\n * non-NULL.\n */\n\n/* malloc_tsd_types(). */\n#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP\n#define\tmalloc_tsd_types(a_name, a_type)\n#elif (defined(JEMALLOC_TLS))\n#define\tmalloc_tsd_types(a_name, a_type)\n#elif (defined(_WIN32))\n#define\tmalloc_tsd_types(a_name, a_type)\t\t\t\t\\\ntypedef struct {\t\t\t\t\t\t\t\\\n\tbool\tinitialized;\t\t\t\t\t\t\\\n\ta_type\tval;\t\t\t\t\t\t\t\\\n} a_name##tsd_wrapper_t;\n#else\n#define\tmalloc_tsd_types(a_name, a_type)\t\t\t\t\\\ntypedef struct {\t\t\t\t\t\t\t\\\n\tbool\tinitialized;\t\t\t\t\t\t\\\n\ta_type\tval;\t\t\t\t\t\t\t\\\n} a_name##tsd_wrapper_t;\n#endif\n\n/* malloc_tsd_protos(). */\n#define\tmalloc_tsd_protos(a_attr, a_name, a_type)\t\t\t\\\na_attr bool\t\t\t\t\t\t\t\t\\\na_name##tsd_boot0(void);\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_name##tsd_boot1(void);\t\t\t\t\t\t\\\na_attr bool\t\t\t\t\t\t\t\t\\\na_name##tsd_boot(void);\t\t\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_name##tsd_get(void);\t\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_name##tsd_set(a_type *val);\n\n/* malloc_tsd_externs(). */\n#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP\n#define\tmalloc_tsd_externs(a_name, a_type)\t\t\t\t\\\nextern __thread a_type\ta_name##tsd_tls;\t\t\t\t\\\nextern __thread bool\ta_name##tsd_initialized;\t\t\t\\\nextern bool\t\ta_name##tsd_booted;\n#elif (defined(JEMALLOC_TLS))\n#define\tmalloc_tsd_externs(a_name, a_type)\t\t\t\t\\\nextern __thread a_type\ta_name##tsd_tls;\t\t\t\t\\\nextern pthread_key_t\ta_name##tsd_tsd;\t\t\t\t\\\nextern bool\t\ta_name##tsd_booted;\n#elif (defined(_WIN32))\n#define\tmalloc_tsd_externs(a_name, a_type)\t\t\t\t\\\nextern DWORD\t\ta_name##tsd_tsd;\t\t\t\t\\\nextern a_name##tsd_wrapper_t\ta_name##tsd_boot_wrapper;\t\t\\\nextern bool\t\ta_name##tsd_booted;\n#else\n#define\tmalloc_tsd_externs(a_name, a_type)\t\t\t\t\\\nextern pthread_key_t\ta_name##tsd_tsd;\t\t\t\t\\\nextern tsd_init_head_t\ta_name##tsd_init_head;\t\t\t\t\\\nextern a_name##tsd_wrapper_t\ta_name##tsd_boot_wrapper;\t\t\\\nextern bool\t\ta_name##tsd_booted;\n#endif\n\n/* malloc_tsd_data(). */\n#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP\n#define\tmalloc_tsd_data(a_attr, a_name, a_type, a_initializer)\t\t\\\na_attr __thread a_type JEMALLOC_TLS_MODEL\t\t\t\t\\\n    a_name##tsd_tls = a_initializer;\t\t\t\t\t\\\na_attr __thread bool JEMALLOC_TLS_MODEL\t\t\t\t\t\\\n    a_name##tsd_initialized = false;\t\t\t\t\t\\\na_attr bool\t\ta_name##tsd_booted = false;\n#elif (defined(JEMALLOC_TLS))\n#define\tmalloc_tsd_data(a_attr, a_name, a_type, a_initializer)\t\t\\\na_attr __thread a_type JEMALLOC_TLS_MODEL\t\t\t\t\\\n    a_name##tsd_tls = a_initializer;\t\t\t\t\t\\\na_attr pthread_key_t\ta_name##tsd_tsd;\t\t\t\t\\\na_attr bool\t\ta_name##tsd_booted = false;\n#elif (defined(_WIN32))\n#define\tmalloc_tsd_data(a_attr, a_name, a_type, a_initializer)\t\t\\\na_attr DWORD\t\ta_name##tsd_tsd;\t\t\t\t\\\na_attr a_name##tsd_wrapper_t a_name##tsd_boot_wrapper = {\t\t\\\n\tfalse,\t\t\t\t\t\t\t\t\\\n\ta_initializer\t\t\t\t\t\t\t\\\n};\t\t\t\t\t\t\t\t\t\\\na_attr bool\t\ta_name##tsd_booted = false;\n#else\n#define\tmalloc_tsd_data(a_attr, a_name, a_type, a_initializer)\t\t\\\na_attr pthread_key_t\ta_name##tsd_tsd;\t\t\t\t\\\na_attr tsd_init_head_t\ta_name##tsd_init_head = {\t\t\t\\\n\tql_head_initializer(blocks),\t\t\t\t\t\\\n\tMALLOC_MUTEX_INITIALIZER\t\t\t\t\t\\\n};\t\t\t\t\t\t\t\t\t\\\na_attr a_name##tsd_wrapper_t a_name##tsd_boot_wrapper = {\t\t\\\n\tfalse,\t\t\t\t\t\t\t\t\\\n\ta_initializer\t\t\t\t\t\t\t\\\n};\t\t\t\t\t\t\t\t\t\\\na_attr bool\t\ta_name##tsd_booted = false;\n#endif\n\n/* malloc_tsd_funcs(). */\n#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP\n#define\tmalloc_tsd_funcs(a_attr, a_name, a_type, a_initializer,\t\t\\\n    a_cleanup)\t\t\t\t\t\t\t\t\\\n/* Initialization/cleanup. */\t\t\t\t\t\t\\\na_attr bool\t\t\t\t\t\t\t\t\\\na_name##tsd_cleanup_wrapper(void)\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\tif (a_name##tsd_initialized) {\t\t\t\t\t\\\n\t\ta_name##tsd_initialized = false;\t\t\t\\\n\t\ta_cleanup(&a_name##tsd_tls);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\treturn (a_name##tsd_initialized);\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr bool\t\t\t\t\t\t\t\t\\\na_name##tsd_boot0(void)\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\tif (a_cleanup != malloc_tsd_no_cleanup) {\t\t\t\\\n\t\tmalloc_tsd_cleanup_register(\t\t\t\t\\\n\t\t    &a_name##tsd_cleanup_wrapper);\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\ta_name##tsd_booted = true;\t\t\t\t\t\\\n\treturn (false);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_name##tsd_boot1(void)\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\t/* Do nothing. */\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr bool\t\t\t\t\t\t\t\t\\\na_name##tsd_boot(void)\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\treturn (a_name##tsd_boot0());\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\n/* Get/set. */\t\t\t\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_name##tsd_get(void)\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\tassert(a_name##tsd_booted);\t\t\t\t\t\\\n\treturn (&a_name##tsd_tls);\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_name##tsd_set(a_type *val)\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\tassert(a_name##tsd_booted);\t\t\t\t\t\\\n\ta_name##tsd_tls = (*val);\t\t\t\t\t\\\n\tif (a_cleanup != malloc_tsd_no_cleanup)\t\t\t\t\\\n\t\ta_name##tsd_initialized = true;\t\t\t\t\\\n}\n#elif (defined(JEMALLOC_TLS))\n#define\tmalloc_tsd_funcs(a_attr, a_name, a_type, a_initializer,\t\t\\\n    a_cleanup)\t\t\t\t\t\t\t\t\\\n/* Initialization/cleanup. */\t\t\t\t\t\t\\\na_attr bool\t\t\t\t\t\t\t\t\\\na_name##tsd_boot0(void)\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\tif (a_cleanup != malloc_tsd_no_cleanup) {\t\t\t\\\n\t\tif (pthread_key_create(&a_name##tsd_tsd, a_cleanup) !=\t\\\n\t\t    0)\t\t\t\t\t\t\t\\\n\t\t\treturn (true);\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\ta_name##tsd_booted = true;\t\t\t\t\t\\\n\treturn (false);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_name##tsd_boot1(void)\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\t/* Do nothing. */\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr bool\t\t\t\t\t\t\t\t\\\na_name##tsd_boot(void)\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\treturn (a_name##tsd_boot0());\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\n/* Get/set. */\t\t\t\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_name##tsd_get(void)\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\tassert(a_name##tsd_booted);\t\t\t\t\t\\\n\treturn (&a_name##tsd_tls);\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_name##tsd_set(a_type *val)\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\tassert(a_name##tsd_booted);\t\t\t\t\t\\\n\ta_name##tsd_tls = (*val);\t\t\t\t\t\\\n\tif (a_cleanup != malloc_tsd_no_cleanup) {\t\t\t\\\n\t\tif (pthread_setspecific(a_name##tsd_tsd,\t\t\\\n\t\t    (void *)(&a_name##tsd_tls))) {\t\t\t\\\n\t\t\tmalloc_write(\"<jemalloc>: Error\"\t\t\\\n\t\t\t    \" setting TSD for \"#a_name\"\\n\");\t\t\\\n\t\t\tif (opt_abort)\t\t\t\t\t\\\n\t\t\t\tabort();\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}\n#elif (defined(_WIN32))\n#define\tmalloc_tsd_funcs(a_attr, a_name, a_type, a_initializer,\t\t\\\n    a_cleanup)\t\t\t\t\t\t\t\t\\\n/* Initialization/cleanup. */\t\t\t\t\t\t\\\na_attr bool\t\t\t\t\t\t\t\t\\\na_name##tsd_cleanup_wrapper(void)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tDWORD error = GetLastError();\t\t\t\t\t\\\n\ta_name##tsd_wrapper_t *wrapper = (a_name##tsd_wrapper_t *)\t\\\n\t    TlsGetValue(a_name##tsd_tsd);\t\t\t\t\\\n\tSetLastError(error);\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tif (wrapper == NULL)\t\t\t\t\t\t\\\n\t\treturn (false);\t\t\t\t\t\t\\\n\tif (a_cleanup != malloc_tsd_no_cleanup &&\t\t\t\\\n\t    wrapper->initialized) {\t\t\t\t\t\\\n\t\twrapper->initialized = false;\t\t\t\t\\\n\t\ta_cleanup(&wrapper->val);\t\t\t\t\\\n\t\tif (wrapper->initialized) {\t\t\t\t\\\n\t\t\t/* Trigger another cleanup round. */\t\t\\\n\t\t\treturn (true);\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\tmalloc_tsd_dalloc(wrapper);\t\t\t\t\t\\\n\treturn (false);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_name##tsd_wrapper_set(a_name##tsd_wrapper_t *wrapper)\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tif (!TlsSetValue(a_name##tsd_tsd, (void *)wrapper)) {\t\t\\\n\t\tmalloc_write(\"<jemalloc>: Error setting\"\t\t\\\n\t\t    \" TSD for \"#a_name\"\\n\");\t\t\t\t\\\n\t\tabort();\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\\\na_attr a_name##tsd_wrapper_t *\t\t\t\t\t\t\\\na_name##tsd_wrapper_get(void)\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tDWORD error = GetLastError();\t\t\t\t\t\\\n\ta_name##tsd_wrapper_t *wrapper = (a_name##tsd_wrapper_t *)\t\\\n\t    TlsGetValue(a_name##tsd_tsd);\t\t\t\t\\\n\tSetLastError(error);\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tif (unlikely(wrapper == NULL)) {\t\t\t\t\\\n\t\twrapper = (a_name##tsd_wrapper_t *)\t\t\t\\\n\t\t    malloc_tsd_malloc(sizeof(a_name##tsd_wrapper_t));\t\\\n\t\tif (wrapper == NULL) {\t\t\t\t\t\\\n\t\t\tmalloc_write(\"<jemalloc>: Error allocating\"\t\\\n\t\t\t    \" TSD for \"#a_name\"\\n\");\t\t\t\\\n\t\t\tabort();\t\t\t\t\t\\\n\t\t} else {\t\t\t\t\t\t\\\n\t\t\twrapper->initialized = false;\t\t\t\\\n\t\t\twrapper->val = a_initializer;\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t\ta_name##tsd_wrapper_set(wrapper);\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\treturn (wrapper);\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr bool\t\t\t\t\t\t\t\t\\\na_name##tsd_boot0(void)\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\ta_name##tsd_tsd = TlsAlloc();\t\t\t\t\t\\\n\tif (a_name##tsd_tsd == TLS_OUT_OF_INDEXES)\t\t\t\\\n\t\treturn (true);\t\t\t\t\t\t\\\n\tif (a_cleanup != malloc_tsd_no_cleanup) {\t\t\t\\\n\t\tmalloc_tsd_cleanup_register(\t\t\t\t\\\n\t\t    &a_name##tsd_cleanup_wrapper);\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\ta_name##tsd_wrapper_set(&a_name##tsd_boot_wrapper);\t\t\\\n\ta_name##tsd_booted = true;\t\t\t\t\t\\\n\treturn (false);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_name##tsd_boot1(void)\t\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\ta_name##tsd_wrapper_t *wrapper;\t\t\t\t\t\\\n\twrapper = (a_name##tsd_wrapper_t *)\t\t\t\t\\\n\t    malloc_tsd_malloc(sizeof(a_name##tsd_wrapper_t));\t\t\\\n\tif (wrapper == NULL) {\t\t\t\t\t\t\\\n\t\tmalloc_write(\"<jemalloc>: Error allocating\"\t\t\\\n\t\t    \" TSD for \"#a_name\"\\n\");\t\t\t\t\\\n\t\tabort();\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tmemcpy(wrapper, &a_name##tsd_boot_wrapper,\t\t\t\\\n\t    sizeof(a_name##tsd_wrapper_t));\t\t\t\t\\\n\ta_name##tsd_wrapper_set(wrapper);\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr bool\t\t\t\t\t\t\t\t\\\na_name##tsd_boot(void)\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\tif (a_name##tsd_boot0())\t\t\t\t\t\\\n\t\treturn (true);\t\t\t\t\t\t\\\n\ta_name##tsd_boot1();\t\t\t\t\t\t\\\n\treturn (false);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\n/* Get/set. */\t\t\t\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_name##tsd_get(void)\t\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\ta_name##tsd_wrapper_t *wrapper;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tassert(a_name##tsd_booted);\t\t\t\t\t\\\n\twrapper = a_name##tsd_wrapper_get();\t\t\t\t\\\n\treturn (&wrapper->val);\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_name##tsd_set(a_type *val)\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\ta_name##tsd_wrapper_t *wrapper;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tassert(a_name##tsd_booted);\t\t\t\t\t\\\n\twrapper = a_name##tsd_wrapper_get();\t\t\t\t\\\n\twrapper->val = *(val);\t\t\t\t\t\t\\\n\tif (a_cleanup != malloc_tsd_no_cleanup)\t\t\t\t\\\n\t\twrapper->initialized = true;\t\t\t\t\\\n}\n#else\n#define\tmalloc_tsd_funcs(a_attr, a_name, a_type, a_initializer,\t\t\\\n    a_cleanup)\t\t\t\t\t\t\t\t\\\n/* Initialization/cleanup. */\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_name##tsd_cleanup_wrapper(void *arg)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\ta_name##tsd_wrapper_t *wrapper = (a_name##tsd_wrapper_t *)arg;\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tif (a_cleanup != malloc_tsd_no_cleanup &&\t\t\t\\\n\t    wrapper->initialized) {\t\t\t\t\t\\\n\t\twrapper->initialized = false;\t\t\t\t\\\n\t\ta_cleanup(&wrapper->val);\t\t\t\t\\\n\t\tif (wrapper->initialized) {\t\t\t\t\\\n\t\t\t/* Trigger another cleanup round. */\t\t\\\n\t\t\tif (pthread_setspecific(a_name##tsd_tsd,\t\\\n\t\t\t    (void *)wrapper)) {\t\t\t\t\\\n\t\t\t\tmalloc_write(\"<jemalloc>: Error\"\t\\\n\t\t\t\t    \" setting TSD for \"#a_name\"\\n\");\t\\\n\t\t\t\tif (opt_abort)\t\t\t\t\\\n\t\t\t\t\tabort();\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\\\n\t\t\treturn;\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\tmalloc_tsd_dalloc(wrapper);\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_name##tsd_wrapper_set(a_name##tsd_wrapper_t *wrapper)\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tif (pthread_setspecific(a_name##tsd_tsd,\t\t\t\\\n\t    (void *)wrapper)) {\t\t\t\t\t\t\\\n\t\tmalloc_write(\"<jemalloc>: Error setting\"\t\t\\\n\t\t    \" TSD for \"#a_name\"\\n\");\t\t\t\t\\\n\t\tabort();\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\\\na_attr a_name##tsd_wrapper_t *\t\t\t\t\t\t\\\na_name##tsd_wrapper_get(void)\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\ta_name##tsd_wrapper_t *wrapper = (a_name##tsd_wrapper_t *)\t\\\n\t    pthread_getspecific(a_name##tsd_tsd);\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tif (unlikely(wrapper == NULL)) {\t\t\t\t\\\n\t\ttsd_init_block_t block;\t\t\t\t\t\\\n\t\twrapper = tsd_init_check_recursion(\t\t\t\\\n\t\t    &a_name##tsd_init_head, &block);\t\t\t\\\n\t\tif (wrapper)\t\t\t\t\t\t\\\n\t\t    return (wrapper);\t\t\t\t\t\\\n\t\twrapper = (a_name##tsd_wrapper_t *)\t\t\t\\\n\t\t    malloc_tsd_malloc(sizeof(a_name##tsd_wrapper_t));\t\\\n\t\tblock.data = wrapper;\t\t\t\t\t\\\n\t\tif (wrapper == NULL) {\t\t\t\t\t\\\n\t\t\tmalloc_write(\"<jemalloc>: Error allocating\"\t\\\n\t\t\t    \" TSD for \"#a_name\"\\n\");\t\t\t\\\n\t\t\tabort();\t\t\t\t\t\\\n\t\t} else {\t\t\t\t\t\t\\\n\t\t\twrapper->initialized = false;\t\t\t\\\n\t\t\twrapper->val = a_initializer;\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t\ta_name##tsd_wrapper_set(wrapper);\t\t\t\\\n\t\ttsd_init_finish(&a_name##tsd_init_head, &block);\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\treturn (wrapper);\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr bool\t\t\t\t\t\t\t\t\\\na_name##tsd_boot0(void)\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\tif (pthread_key_create(&a_name##tsd_tsd,\t\t\t\\\n\t    a_name##tsd_cleanup_wrapper) != 0)\t\t\t\t\\\n\t\treturn (true);\t\t\t\t\t\t\\\n\ta_name##tsd_wrapper_set(&a_name##tsd_boot_wrapper);\t\t\\\n\ta_name##tsd_booted = true;\t\t\t\t\t\\\n\treturn (false);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_name##tsd_boot1(void)\t\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\ta_name##tsd_wrapper_t *wrapper;\t\t\t\t\t\\\n\twrapper = (a_name##tsd_wrapper_t *)\t\t\t\t\\\n\t    malloc_tsd_malloc(sizeof(a_name##tsd_wrapper_t));\t\t\\\n\tif (wrapper == NULL) {\t\t\t\t\t\t\\\n\t\tmalloc_write(\"<jemalloc>: Error allocating\"\t\t\\\n\t\t    \" TSD for \"#a_name\"\\n\");\t\t\t\t\\\n\t\tabort();\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tmemcpy(wrapper, &a_name##tsd_boot_wrapper,\t\t\t\\\n\t    sizeof(a_name##tsd_wrapper_t));\t\t\t\t\\\n\ta_name##tsd_wrapper_set(wrapper);\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr bool\t\t\t\t\t\t\t\t\\\na_name##tsd_boot(void)\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\tif (a_name##tsd_boot0())\t\t\t\t\t\\\n\t\treturn (true);\t\t\t\t\t\t\\\n\ta_name##tsd_boot1();\t\t\t\t\t\t\\\n\treturn (false);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\n/* Get/set. */\t\t\t\t\t\t\t\t\\\na_attr a_type *\t\t\t\t\t\t\t\t\\\na_name##tsd_get(void)\t\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\ta_name##tsd_wrapper_t *wrapper;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tassert(a_name##tsd_booted);\t\t\t\t\t\\\n\twrapper = a_name##tsd_wrapper_get();\t\t\t\t\\\n\treturn (&wrapper->val);\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_name##tsd_set(a_type *val)\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\ta_name##tsd_wrapper_t *wrapper;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tassert(a_name##tsd_booted);\t\t\t\t\t\\\n\twrapper = a_name##tsd_wrapper_get();\t\t\t\t\\\n\twrapper->val = *(val);\t\t\t\t\t\t\\\n\tif (a_cleanup != malloc_tsd_no_cleanup)\t\t\t\t\\\n\t\twrapper->initialized = true;\t\t\t\t\\\n}\n#endif\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \\\n    !defined(_WIN32))\nstruct tsd_init_block_s {\n\tql_elm(tsd_init_block_t)\tlink;\n\tpthread_t\t\t\tthread;\n\tvoid\t\t\t\t*data;\n};\nstruct tsd_init_head_s {\n\tql_head(tsd_init_block_t)\tblocks;\n\tmalloc_mutex_t\t\t\tlock;\n};\n#endif\n\n#define\tMALLOC_TSD\t\t\t\t\t\t\t\\\n/*  O(name,\t\t\ttype) */\t\t\t\t\\\n    O(tcache,\t\t\ttcache_t *)\t\t\t\t\\\n    O(thread_allocated,\t\tuint64_t)\t\t\t\t\\\n    O(thread_deallocated,\tuint64_t)\t\t\t\t\\\n    O(prof_tdata,\t\tprof_tdata_t *)\t\t\t\t\\\n    O(arena,\t\t\tarena_t *)\t\t\t\t\\\n    O(arenas_tdata,\t\tarena_tdata_t *)\t\t\t\\\n    O(narenas_tdata,\t\tunsigned)\t\t\t\t\\\n    O(arenas_tdata_bypass,\tbool)\t\t\t\t\t\\\n    O(tcache_enabled,\t\ttcache_enabled_t)\t\t\t\\\n    O(quarantine,\t\tquarantine_t *)\t\t\t\t\\\n\n#define\tTSD_INITIALIZER {\t\t\t\t\t\t\\\n    tsd_state_uninitialized,\t\t\t\t\t\t\\\n    NULL,\t\t\t\t\t\t\t\t\\\n    0,\t\t\t\t\t\t\t\t\t\\\n    0,\t\t\t\t\t\t\t\t\t\\\n    NULL,\t\t\t\t\t\t\t\t\\\n    NULL,\t\t\t\t\t\t\t\t\\\n    NULL,\t\t\t\t\t\t\t\t\\\n    0,\t\t\t\t\t\t\t\t\t\\\n    false,\t\t\t\t\t\t\t\t\\\n    tcache_enabled_default,\t\t\t\t\t\t\\\n    NULL\t\t\t\t\t\t\t\t\\\n}\n\nstruct tsd_s {\n\ttsd_state_t\tstate;\n#define\tO(n, t)\t\t\t\t\t\t\t\t\\\n\tt\t\tn;\nMALLOC_TSD\n#undef O\n};\n\nstatic const tsd_t tsd_initializer = TSD_INITIALIZER;\n\nmalloc_tsd_types(, tsd_t)\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nvoid\t*malloc_tsd_malloc(size_t size);\nvoid\tmalloc_tsd_dalloc(void *wrapper);\nvoid\tmalloc_tsd_no_cleanup(void *arg);\nvoid\tmalloc_tsd_cleanup_register(bool (*f)(void));\nbool\tmalloc_tsd_boot0(void);\nvoid\tmalloc_tsd_boot1(void);\n#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \\\n    !defined(_WIN32))\nvoid\t*tsd_init_check_recursion(tsd_init_head_t *head,\n    tsd_init_block_t *block);\nvoid\ttsd_init_finish(tsd_init_head_t *head, tsd_init_block_t *block);\n#endif\nvoid\ttsd_cleanup(void *arg);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#ifndef JEMALLOC_ENABLE_INLINE\nmalloc_tsd_protos(JEMALLOC_ATTR(unused), , tsd_t)\n\ntsd_t\t*tsd_fetch(void);\nbool\ttsd_nominal(tsd_t *tsd);\n#define\tO(n, t)\t\t\t\t\t\t\t\t\\\nt\t*tsd_##n##p_get(tsd_t *tsd);\t\t\t\t\t\\\nt\ttsd_##n##_get(tsd_t *tsd);\t\t\t\t\t\\\nvoid\ttsd_##n##_set(tsd_t *tsd, t n);\nMALLOC_TSD\n#undef O\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_TSD_C_))\nmalloc_tsd_externs(, tsd_t)\nmalloc_tsd_funcs(JEMALLOC_ALWAYS_INLINE, , tsd_t, tsd_initializer, tsd_cleanup)\n\nJEMALLOC_ALWAYS_INLINE tsd_t *\ntsd_fetch(void)\n{\n\ttsd_t *tsd = tsd_get();\n\n\tif (unlikely(tsd->state != tsd_state_nominal)) {\n\t\tif (tsd->state == tsd_state_uninitialized) {\n\t\t\ttsd->state = tsd_state_nominal;\n\t\t\t/* Trigger cleanup handler registration. */\n\t\t\ttsd_set(tsd);\n\t\t} else if (tsd->state == tsd_state_purgatory) {\n\t\t\ttsd->state = tsd_state_reincarnated;\n\t\t\ttsd_set(tsd);\n\t\t} else\n\t\t\tassert(tsd->state == tsd_state_reincarnated);\n\t}\n\n\treturn (tsd);\n}\n\nJEMALLOC_INLINE bool\ntsd_nominal(tsd_t *tsd)\n{\n\n\treturn (tsd->state == tsd_state_nominal);\n}\n\n#define\tO(n, t)\t\t\t\t\t\t\t\t\\\nJEMALLOC_ALWAYS_INLINE t *\t\t\t\t\t\t\\\ntsd_##n##p_get(tsd_t *tsd)\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\treturn (&tsd->n);\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\\\nJEMALLOC_ALWAYS_INLINE t\t\t\t\t\t\t\\\ntsd_##n##_get(tsd_t *tsd)\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\treturn (*tsd_##n##p_get(tsd));\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\\\nJEMALLOC_ALWAYS_INLINE void\t\t\t\t\t\t\\\ntsd_##n##_set(tsd_t *tsd, t n)\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\tassert(tsd->state == tsd_state_nominal);\t\t\t\\\n\ttsd->n = n;\t\t\t\t\t\t\t\\\n}\nMALLOC_TSD\n#undef O\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/util.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n#ifdef _WIN32\n#  ifdef _WIN64\n#    define FMT64_PREFIX \"ll\"\n#    define FMTPTR_PREFIX \"ll\"\n#  else\n#    define FMT64_PREFIX \"ll\"\n#    define FMTPTR_PREFIX \"\"\n#  endif\n#  define FMTd32 \"d\"\n#  define FMTu32 \"u\"\n#  define FMTx32 \"x\"\n#  define FMTd64 FMT64_PREFIX \"d\"\n#  define FMTu64 FMT64_PREFIX \"u\"\n#  define FMTx64 FMT64_PREFIX \"x\"\n#  define FMTdPTR FMTPTR_PREFIX \"d\"\n#  define FMTuPTR FMTPTR_PREFIX \"u\"\n#  define FMTxPTR FMTPTR_PREFIX \"x\"\n#else\n#  include <inttypes.h>\n#  define FMTd32 PRId32\n#  define FMTu32 PRIu32\n#  define FMTx32 PRIx32\n#  define FMTd64 PRId64\n#  define FMTu64 PRIu64\n#  define FMTx64 PRIx64\n#  define FMTdPTR PRIdPTR\n#  define FMTuPTR PRIuPTR\n#  define FMTxPTR PRIxPTR\n#endif\n\n/* Size of stack-allocated buffer passed to buferror(). */\n#define\tBUFERROR_BUF\t\t64\n\n/*\n * Size of stack-allocated buffer used by malloc_{,v,vc}printf().  This must be\n * large enough for all possible uses within jemalloc.\n */\n#define\tMALLOC_PRINTF_BUFSIZE\t4096\n\n/*\n * Wrap a cpp argument that contains commas such that it isn't broken up into\n * multiple arguments.\n */\n#define\tJEMALLOC_ARG_CONCAT(...) __VA_ARGS__\n\n/*\n * Silence compiler warnings due to uninitialized values.  This is used\n * wherever the compiler fails to recognize that the variable is never used\n * uninitialized.\n */\n#ifdef JEMALLOC_CC_SILENCE\n#\tdefine JEMALLOC_CC_SILENCE_INIT(v) = v\n#else\n#\tdefine JEMALLOC_CC_SILENCE_INIT(v)\n#endif\n\n#define\tJEMALLOC_GNUC_PREREQ(major, minor)\t\t\t\t\\\n    (!defined(__clang__) &&\t\t\t\t\t\t\\\n    (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))))\n#ifndef __has_builtin\n#  define __has_builtin(builtin) (0)\n#endif\n#define\tJEMALLOC_CLANG_HAS_BUILTIN(builtin)\t\t\t\t\\\n    (defined(__clang__) && __has_builtin(builtin))\n\n#ifdef __GNUC__\n#\tdefine likely(x)   __builtin_expect(!!(x), 1)\n#\tdefine unlikely(x) __builtin_expect(!!(x), 0)\n#  if JEMALLOC_GNUC_PREREQ(4, 6) ||\t\t\t\t\t\\\n      JEMALLOC_CLANG_HAS_BUILTIN(__builtin_unreachable)\n#\tdefine unreachable() __builtin_unreachable()\n#  else\n#\tdefine unreachable()\n#  endif\n#else\n#\tdefine likely(x)   !!(x)\n#\tdefine unlikely(x) !!(x)\n#\tdefine unreachable()\n#endif\n\n#include \"jemalloc/internal/assert.h\"\n\n/* Use to assert a particular configuration, e.g., cassert(config_debug). */\n#define\tcassert(c) do {\t\t\t\t\t\t\t\\\n\tif (unlikely(!(c)))\t\t\t\t\t\t\\\n\t\tnot_reached();\t\t\t\t\t\t\\\n} while (0)\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\nint\tbuferror(int err, char *buf, size_t buflen);\nuintmax_t\tmalloc_strtoumax(const char *restrict nptr,\n    char **restrict endptr, int base);\nvoid\tmalloc_write(const char *s);\n\n/*\n * malloc_vsnprintf() supports a subset of snprintf(3) that avoids floating\n * point math.\n */\nint\tmalloc_vsnprintf(char *str, size_t size, const char *format,\n    va_list ap);\nint\tmalloc_snprintf(char *str, size_t size, const char *format, ...)\n    JEMALLOC_FORMAT_PRINTF(3, 4);\nvoid\tmalloc_vcprintf(void (*write_cb)(void *, const char *), void *cbopaque,\n    const char *format, va_list ap);\nvoid malloc_cprintf(void (*write)(void *, const char *), void *cbopaque,\n    const char *format, ...) JEMALLOC_FORMAT_PRINTF(3, 4);\nvoid\tmalloc_printf(const char *format, ...) JEMALLOC_FORMAT_PRINTF(1, 2);\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#ifndef JEMALLOC_ENABLE_INLINE\nunsigned\tffs_llu(unsigned long long bitmap);\nunsigned\tffs_lu(unsigned long bitmap);\nunsigned\tffs_u(unsigned bitmap);\nunsigned\tffs_zu(size_t bitmap);\nunsigned\tffs_u64(uint64_t bitmap);\nunsigned\tffs_u32(uint32_t bitmap);\nuint64_t\tpow2_ceil_u64(uint64_t x);\nuint32_t\tpow2_ceil_u32(uint32_t x);\nsize_t\tpow2_ceil_zu(size_t x);\nunsigned\tlg_floor(size_t x);\nvoid\tset_errno(int errnum);\nint\tget_errno(void);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_UTIL_C_))\n\n/* Sanity check. */\n#if !defined(JEMALLOC_INTERNAL_FFSLL) || !defined(JEMALLOC_INTERNAL_FFSL) \\\n    || !defined(JEMALLOC_INTERNAL_FFS)\n#  error JEMALLOC_INTERNAL_FFS{,L,LL} should have been defined by configure\n#endif\n\nJEMALLOC_ALWAYS_INLINE unsigned\nffs_llu(unsigned long long bitmap)\n{\n\n\treturn (JEMALLOC_INTERNAL_FFSLL(bitmap));\n}\n\nJEMALLOC_ALWAYS_INLINE unsigned\nffs_lu(unsigned long bitmap)\n{\n\n\treturn (JEMALLOC_INTERNAL_FFSL(bitmap));\n}\n\nJEMALLOC_ALWAYS_INLINE unsigned\nffs_u(unsigned bitmap)\n{\n\n\treturn (JEMALLOC_INTERNAL_FFS(bitmap));\n}\n\nJEMALLOC_ALWAYS_INLINE unsigned\nffs_zu(size_t bitmap)\n{\n\n#if LG_SIZEOF_PTR == LG_SIZEOF_INT\n\treturn (ffs_u(bitmap));\n#elif LG_SIZEOF_PTR == LG_SIZEOF_LONG\n\treturn (ffs_lu(bitmap));\n#elif LG_SIZEOF_PTR == LG_SIZEOF_LONG_LONG\n\treturn (ffs_llu(bitmap));\n#else\n#error No implementation for size_t ffs()\n#endif\n}\n\nJEMALLOC_ALWAYS_INLINE unsigned\nffs_u64(uint64_t bitmap)\n{\n\n#if LG_SIZEOF_LONG == 3\n\treturn (ffs_lu(bitmap));\n#elif LG_SIZEOF_LONG_LONG == 3\n\treturn (ffs_llu(bitmap));\n#else\n#error No implementation for 64-bit ffs()\n#endif\n}\n\nJEMALLOC_ALWAYS_INLINE unsigned\nffs_u32(uint32_t bitmap)\n{\n\n#if LG_SIZEOF_INT == 2\n\treturn (ffs_u(bitmap));\n#else\n#error No implementation for 32-bit ffs()\n#endif\n\treturn (ffs_u(bitmap));\n}\n\nJEMALLOC_INLINE uint64_t\npow2_ceil_u64(uint64_t x)\n{\n\n\tx--;\n\tx |= x >> 1;\n\tx |= x >> 2;\n\tx |= x >> 4;\n\tx |= x >> 8;\n\tx |= x >> 16;\n\tx |= x >> 32;\n\tx++;\n\treturn (x);\n}\n\nJEMALLOC_INLINE uint32_t\npow2_ceil_u32(uint32_t x)\n{\n\n\tx--;\n\tx |= x >> 1;\n\tx |= x >> 2;\n\tx |= x >> 4;\n\tx |= x >> 8;\n\tx |= x >> 16;\n\tx++;\n\treturn (x);\n}\n\n/* Compute the smallest power of 2 that is >= x. */\nJEMALLOC_INLINE size_t\npow2_ceil_zu(size_t x)\n{\n\n#if (LG_SIZEOF_PTR == 3)\n\treturn (pow2_ceil_u64(x));\n#else\n\treturn (pow2_ceil_u32(x));\n#endif\n}\n\n#if (defined(__i386__) || defined(__amd64__) || defined(__x86_64__))\nJEMALLOC_INLINE unsigned\nlg_floor(size_t x)\n{\n\tsize_t ret;\n\n\tassert(x != 0);\n\n\tasm (\"bsr %1, %0\"\n\t    : \"=r\"(ret) // Outputs.\n\t    : \"r\"(x)    // Inputs.\n\t    );\n\tassert(ret < UINT_MAX);\n\treturn ((unsigned)ret);\n}\n#elif (defined(_MSC_VER))\nJEMALLOC_INLINE unsigned\nlg_floor(size_t x)\n{\n\tunsigned long ret;\n\n\tassert(x != 0);\n\n#if (LG_SIZEOF_PTR == 3)\n\t_BitScanReverse64(&ret, x);\n#elif (LG_SIZEOF_PTR == 2)\n\t_BitScanReverse(&ret, x);\n#else\n#  error \"Unsupported type size for lg_floor()\"\n#endif\n\tassert(ret < UINT_MAX);\n\treturn ((unsigned)ret);\n}\n#elif (defined(JEMALLOC_HAVE_BUILTIN_CLZ))\nJEMALLOC_INLINE unsigned\nlg_floor(size_t x)\n{\n\n\tassert(x != 0);\n\n#if (LG_SIZEOF_PTR == LG_SIZEOF_INT)\n\treturn (((8 << LG_SIZEOF_PTR) - 1) - __builtin_clz(x));\n#elif (LG_SIZEOF_PTR == LG_SIZEOF_LONG)\n\treturn (((8 << LG_SIZEOF_PTR) - 1) - __builtin_clzl(x));\n#else\n#  error \"Unsupported type size for lg_floor()\"\n#endif\n}\n#else\nJEMALLOC_INLINE unsigned\nlg_floor(size_t x)\n{\n\n\tassert(x != 0);\n\n\tx |= (x >> 1);\n\tx |= (x >> 2);\n\tx |= (x >> 4);\n\tx |= (x >> 8);\n\tx |= (x >> 16);\n#if (LG_SIZEOF_PTR == 3)\n\tx |= (x >> 32);\n#endif\n\tif (x == SIZE_T_MAX)\n\t\treturn ((8 << LG_SIZEOF_PTR) - 1);\n\tx++;\n\treturn (ffs_zu(x) - 2);\n}\n#endif\n\n/* Set error code. */\nJEMALLOC_INLINE void\nset_errno(int errnum)\n{\n\n#ifdef _WIN32\n\tSetLastError(errnum);\n#else\n\terrno = errnum;\n#endif\n}\n\n/* Get last error code. */\nJEMALLOC_INLINE int\nget_errno(void)\n{\n\n#ifdef _WIN32\n\treturn (GetLastError());\n#else\n\treturn (errno);\n#endif\n}\n#endif\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/internal/valgrind.h",
    "content": "/******************************************************************************/\n#ifdef JEMALLOC_H_TYPES\n\n#ifdef JEMALLOC_VALGRIND\n#include <valgrind/valgrind.h>\n\n/*\n * The size that is reported to Valgrind must be consistent through a chain of\n * malloc..realloc..realloc calls.  Request size isn't recorded anywhere in\n * jemalloc, so it is critical that all callers of these macros provide usize\n * rather than request size.  As a result, buffer overflow detection is\n * technically weakened for the standard API, though it is generally accepted\n * practice to consider any extra bytes reported by malloc_usable_size() as\n * usable space.\n */\n#define\tJEMALLOC_VALGRIND_MAKE_MEM_NOACCESS(ptr, usize) do {\t\t\\\n\tif (unlikely(in_valgrind))\t\t\t\t\t\\\n\t\tvalgrind_make_mem_noaccess(ptr, usize);\t\t\t\\\n} while (0)\n#define\tJEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ptr, usize) do {\t\t\\\n\tif (unlikely(in_valgrind))\t\t\t\t\t\\\n\t\tvalgrind_make_mem_undefined(ptr, usize);\t\t\\\n} while (0)\n#define\tJEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ptr, usize) do {\t\t\\\n\tif (unlikely(in_valgrind))\t\t\t\t\t\\\n\t\tvalgrind_make_mem_defined(ptr, usize);\t\t\t\\\n} while (0)\n/*\n * The VALGRIND_MALLOCLIKE_BLOCK() and VALGRIND_RESIZEINPLACE_BLOCK() macro\n * calls must be embedded in macros rather than in functions so that when\n * Valgrind reports errors, there are no extra stack frames in the backtraces.\n */\n#define\tJEMALLOC_VALGRIND_MALLOC(cond, ptr, usize, zero) do {\t\t\\\n\tif (unlikely(in_valgrind && cond))\t\t\t\t\\\n\t\tVALGRIND_MALLOCLIKE_BLOCK(ptr, usize, p2rz(ptr), zero);\t\\\n} while (0)\n#define\tJEMALLOC_VALGRIND_REALLOC(maybe_moved, ptr, usize,\t\t\\\n    ptr_maybe_null, old_ptr, old_usize, old_rzsize, old_ptr_maybe_null,\t\\\n    zero) do {\t\t\t\t\t\t\t\t\\\n\tif (unlikely(in_valgrind)) {\t\t\t\t\t\\\n\t\tsize_t rzsize = p2rz(ptr);\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\tif (!maybe_moved || ptr == old_ptr) {\t\t\t\\\n\t\t\tVALGRIND_RESIZEINPLACE_BLOCK(ptr, old_usize,\t\\\n\t\t\t    usize, rzsize);\t\t\t\t\\\n\t\t\tif (zero && old_usize < usize) {\t\t\\\n\t\t\t\tvalgrind_make_mem_defined(\t\t\\\n\t\t\t\t    (void *)((uintptr_t)ptr +\t\t\\\n\t\t\t\t    old_usize), usize - old_usize);\t\\\n\t\t\t}\t\t\t\t\t\t\\\n\t\t} else {\t\t\t\t\t\t\\\n\t\t\tif (!old_ptr_maybe_null || old_ptr != NULL) {\t\\\n\t\t\t\tvalgrind_freelike_block(old_ptr,\t\\\n\t\t\t\t    old_rzsize);\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\\\n\t\t\tif (!ptr_maybe_null || ptr != NULL) {\t\t\\\n\t\t\t\tsize_t copy_size = (old_usize < usize)\t\\\n\t\t\t\t    ?  old_usize : usize;\t\t\\\n\t\t\t\tsize_t tail_size = usize - copy_size;\t\\\n\t\t\t\tVALGRIND_MALLOCLIKE_BLOCK(ptr, usize,\t\\\n\t\t\t\t    rzsize, false);\t\t\t\\\n\t\t\t\tif (copy_size > 0) {\t\t\t\\\n\t\t\t\t\tvalgrind_make_mem_defined(ptr,\t\\\n\t\t\t\t\tcopy_size);\t\t\t\\\n\t\t\t\t}\t\t\t\t\t\\\n\t\t\t\tif (zero && tail_size > 0) {\t\t\\\n\t\t\t\t\tvalgrind_make_mem_defined(\t\\\n\t\t\t\t\t    (void *)((uintptr_t)ptr +\t\\\n\t\t\t\t\t    copy_size), tail_size);\t\\\n\t\t\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\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n#define\tJEMALLOC_VALGRIND_FREE(ptr, rzsize) do {\t\t\t\\\n\tif (unlikely(in_valgrind))\t\t\t\t\t\\\n\t\tvalgrind_freelike_block(ptr, rzsize);\t\t\t\\\n} while (0)\n#else\n#define\tRUNNING_ON_VALGRIND\t((unsigned)0)\n#define\tJEMALLOC_VALGRIND_MAKE_MEM_NOACCESS(ptr, usize) do {} while (0)\n#define\tJEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ptr, usize) do {} while (0)\n#define\tJEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ptr, usize) do {} while (0)\n#define\tJEMALLOC_VALGRIND_MALLOC(cond, ptr, usize, zero) do {} while (0)\n#define\tJEMALLOC_VALGRIND_REALLOC(maybe_moved, ptr, usize,\t\t\\\n    ptr_maybe_null, old_ptr, old_usize, old_rzsize, old_ptr_maybe_null,\t\\\n    zero) do {} while (0)\n#define\tJEMALLOC_VALGRIND_FREE(ptr, rzsize) do {} while (0)\n#endif\n\n#endif /* JEMALLOC_H_TYPES */\n/******************************************************************************/\n#ifdef JEMALLOC_H_STRUCTS\n\n#endif /* JEMALLOC_H_STRUCTS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_EXTERNS\n\n#ifdef JEMALLOC_VALGRIND\nvoid\tvalgrind_make_mem_noaccess(void *ptr, size_t usize);\nvoid\tvalgrind_make_mem_undefined(void *ptr, size_t usize);\nvoid\tvalgrind_make_mem_defined(void *ptr, size_t usize);\nvoid\tvalgrind_freelike_block(void *ptr, size_t usize);\n#endif\n\n#endif /* JEMALLOC_H_EXTERNS */\n/******************************************************************************/\n#ifdef JEMALLOC_H_INLINES\n\n#endif /* JEMALLOC_H_INLINES */\n/******************************************************************************/\n\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/jemalloc.sh",
    "content": "#!/bin/sh\n\nobjroot=$1\n\ncat <<EOF\n#ifndef JEMALLOC_H_\n#define\tJEMALLOC_H_\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nEOF\n\nfor hdr in jemalloc_defs.h jemalloc_rename.h jemalloc_macros.h \\\n           jemalloc_protos.h jemalloc_typedefs.h jemalloc_mangle.h ; do\n  cat \"${objroot}include/jemalloc/${hdr}\" \\\n      | grep -v 'Generated from .* by configure\\.' \\\n      | sed -e 's/^#define /#define\t/g' \\\n      | sed -e 's/ $//g'\n  echo\ndone\n\ncat <<EOF\n#ifdef __cplusplus\n}\n#endif\n#endif /* JEMALLOC_H_ */\nEOF\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/jemalloc_defs.h.in",
    "content": "/* Defined if __attribute__((...)) syntax is supported. */\n#undef JEMALLOC_HAVE_ATTR\n\n/* Defined if alloc_size attribute is supported. */\n#undef JEMALLOC_HAVE_ATTR_ALLOC_SIZE\n\n/* Defined if format(gnu_printf, ...) attribute is supported. */\n#undef JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF\n\n/* Defined if format(printf, ...) attribute is supported. */\n#undef JEMALLOC_HAVE_ATTR_FORMAT_PRINTF\n\n/*\n * Define overrides for non-standard allocator-related functions if they are\n * present on the system.\n */\n#undef JEMALLOC_OVERRIDE_MEMALIGN\n#undef JEMALLOC_OVERRIDE_VALLOC\n\n/*\n * At least Linux omits the \"const\" in:\n *\n *   size_t malloc_usable_size(const void *ptr);\n *\n * Match the operating system's prototype.\n */\n#undef JEMALLOC_USABLE_SIZE_CONST\n\n/*\n * If defined, specify throw() for the public function prototypes when compiling\n * with C++.  The only justification for this is to match the prototypes that\n * glibc defines.\n */\n#undef JEMALLOC_USE_CXX_THROW\n\n#ifdef _MSC_VER\n#  ifdef _WIN64\n#    define LG_SIZEOF_PTR_WIN 3\n#  else\n#    define LG_SIZEOF_PTR_WIN 2\n#  endif\n#endif\n\n/* sizeof(void *) == 2^LG_SIZEOF_PTR. */\n#undef LG_SIZEOF_PTR\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/jemalloc_macros.h.in",
    "content": "#include <stdlib.h>\n#include <stdbool.h>\n#include <stdint.h>\n#include <limits.h>\n#include <strings.h>\n\n#define\tJEMALLOC_VERSION \"@jemalloc_version@\"\n#define\tJEMALLOC_VERSION_MAJOR @jemalloc_version_major@\n#define\tJEMALLOC_VERSION_MINOR @jemalloc_version_minor@\n#define\tJEMALLOC_VERSION_BUGFIX @jemalloc_version_bugfix@\n#define\tJEMALLOC_VERSION_NREV @jemalloc_version_nrev@\n#define\tJEMALLOC_VERSION_GID \"@jemalloc_version_gid@\"\n\n#  define MALLOCX_LG_ALIGN(la)\t((int)(la))\n#  if LG_SIZEOF_PTR == 2\n#    define MALLOCX_ALIGN(a)\t((int)(ffs(a)-1))\n#  else\n#    define MALLOCX_ALIGN(a)\t\t\t\t\t\t\\\n       ((int)(((a) < (size_t)INT_MAX) ? ffs((int)(a))-1 :\t\t\\\n       ffs((int)((a)>>32))+31))\n#  endif\n#  define MALLOCX_ZERO\t((int)0x40)\n/*\n * Bias tcache index bits so that 0 encodes \"automatic tcache management\", and 1\n * encodes MALLOCX_TCACHE_NONE.\n */\n#  define MALLOCX_TCACHE(tc)\t((int)(((tc)+2) << 8))\n#  define MALLOCX_TCACHE_NONE\tMALLOCX_TCACHE(-1)\n/*\n * Bias arena index bits so that 0 encodes \"use an automatically chosen arena\".\n */\n#  define MALLOCX_ARENA(a)\t((int)(((a)+1) << 20))\n\n#if defined(__cplusplus) && defined(JEMALLOC_USE_CXX_THROW)\n#  define JEMALLOC_CXX_THROW throw()\n#else\n#  define JEMALLOC_CXX_THROW\n#endif\n\n#if _MSC_VER\n#  define JEMALLOC_ATTR(s)\n#  define JEMALLOC_ALIGNED(s) __declspec(align(s))\n#  define JEMALLOC_ALLOC_SIZE(s)\n#  define JEMALLOC_ALLOC_SIZE2(s1, s2)\n#  ifndef JEMALLOC_EXPORT\n#    ifdef DLLEXPORT\n#      define JEMALLOC_EXPORT __declspec(dllexport)\n#    else\n#      define JEMALLOC_EXPORT __declspec(dllimport)\n#    endif\n#  endif\n#  define JEMALLOC_FORMAT_PRINTF(s, i)\n#  define JEMALLOC_NOINLINE __declspec(noinline)\n#  ifdef __cplusplus\n#    define JEMALLOC_NOTHROW __declspec(nothrow)\n#  else\n#    define JEMALLOC_NOTHROW\n#  endif\n#  define JEMALLOC_SECTION(s) __declspec(allocate(s))\n#  define JEMALLOC_RESTRICT_RETURN __declspec(restrict)\n#  if _MSC_VER >= 1900 && !defined(__EDG__)\n#    define JEMALLOC_ALLOCATOR __declspec(allocator)\n#  else\n#    define JEMALLOC_ALLOCATOR\n#  endif\n#elif defined(JEMALLOC_HAVE_ATTR)\n#  define JEMALLOC_ATTR(s) __attribute__((s))\n#  define JEMALLOC_ALIGNED(s) JEMALLOC_ATTR(aligned(s))\n#  ifdef JEMALLOC_HAVE_ATTR_ALLOC_SIZE\n#    define JEMALLOC_ALLOC_SIZE(s) JEMALLOC_ATTR(alloc_size(s))\n#    define JEMALLOC_ALLOC_SIZE2(s1, s2) JEMALLOC_ATTR(alloc_size(s1, s2))\n#  else\n#    define JEMALLOC_ALLOC_SIZE(s)\n#    define JEMALLOC_ALLOC_SIZE2(s1, s2)\n#  endif\n#  ifndef JEMALLOC_EXPORT\n#    define JEMALLOC_EXPORT JEMALLOC_ATTR(visibility(\"default\"))\n#  endif\n#  ifdef JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF\n#    define JEMALLOC_FORMAT_PRINTF(s, i) JEMALLOC_ATTR(format(gnu_printf, s, i))\n#  elif defined(JEMALLOC_HAVE_ATTR_FORMAT_PRINTF)\n#    define JEMALLOC_FORMAT_PRINTF(s, i) JEMALLOC_ATTR(format(printf, s, i))\n#  else\n#    define JEMALLOC_FORMAT_PRINTF(s, i)\n#  endif\n#  define JEMALLOC_NOINLINE JEMALLOC_ATTR(noinline)\n#  define JEMALLOC_NOTHROW JEMALLOC_ATTR(nothrow)\n#  define JEMALLOC_SECTION(s) JEMALLOC_ATTR(section(s))\n#  define JEMALLOC_RESTRICT_RETURN\n#  define JEMALLOC_ALLOCATOR\n#else\n#  define JEMALLOC_ATTR(s)\n#  define JEMALLOC_ALIGNED(s)\n#  define JEMALLOC_ALLOC_SIZE(s)\n#  define JEMALLOC_ALLOC_SIZE2(s1, s2)\n#  define JEMALLOC_EXPORT\n#  define JEMALLOC_FORMAT_PRINTF(s, i)\n#  define JEMALLOC_NOINLINE\n#  define JEMALLOC_NOTHROW\n#  define JEMALLOC_SECTION(s)\n#  define JEMALLOC_RESTRICT_RETURN\n#  define JEMALLOC_ALLOCATOR\n#endif\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/jemalloc_mangle.sh",
    "content": "#!/bin/sh\n\npublic_symbols_txt=$1\nsymbol_prefix=$2\n\ncat <<EOF\n/*\n * By default application code must explicitly refer to mangled symbol names,\n * so that it is possible to use jemalloc in conjunction with another allocator\n * in the same application.  Define JEMALLOC_MANGLE in order to cause automatic\n * name mangling that matches the API prefixing that happened as a result of\n * --with-mangling and/or --with-jemalloc-prefix configuration settings.\n */\n#ifdef JEMALLOC_MANGLE\n#  ifndef JEMALLOC_NO_DEMANGLE\n#    define JEMALLOC_NO_DEMANGLE\n#  endif\nEOF\n\nfor nm in `cat ${public_symbols_txt}` ; do\n  n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'`\n  echo \"#  define ${n} ${symbol_prefix}${n}\"\ndone\n\ncat <<EOF\n#endif\n\n/*\n * The ${symbol_prefix}* macros can be used as stable alternative names for the\n * public jemalloc API if JEMALLOC_NO_DEMANGLE is defined.  This is primarily\n * meant for use in jemalloc itself, but it can be used by application code to\n * provide isolation from the name mangling specified via --with-mangling\n * and/or --with-jemalloc-prefix.\n */\n#ifndef JEMALLOC_NO_DEMANGLE\nEOF\n\nfor nm in `cat ${public_symbols_txt}` ; do\n  n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'`\n  echo \"#  undef ${symbol_prefix}${n}\"\ndone\n\ncat <<EOF\n#endif\nEOF\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/jemalloc_protos.h.in",
    "content": "/*\n * The @je_@ prefix on the following public symbol declarations is an artifact\n * of namespace management, and should be omitted in application code unless\n * JEMALLOC_NO_DEMANGLE is defined (see jemalloc_mangle@install_suffix@.h).\n */\nextern JEMALLOC_EXPORT const char\t*@je_@malloc_conf;\nextern JEMALLOC_EXPORT void\t\t(*@je_@malloc_message)(void *cbopaque,\n    const char *s);\n\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\n    void JEMALLOC_NOTHROW\t*@je_@malloc(size_t size)\n    JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1);\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\n    void JEMALLOC_NOTHROW\t*@je_@calloc(size_t num, size_t size)\n    JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE2(1, 2);\nJEMALLOC_EXPORT int JEMALLOC_NOTHROW\t@je_@posix_memalign(void **memptr,\n    size_t alignment, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(nonnull(1));\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\n    void JEMALLOC_NOTHROW\t*@je_@aligned_alloc(size_t alignment,\n    size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc)\n    JEMALLOC_ALLOC_SIZE(2);\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\n    void JEMALLOC_NOTHROW\t*@je_@realloc(void *ptr, size_t size)\n    JEMALLOC_CXX_THROW JEMALLOC_ALLOC_SIZE(2);\nJEMALLOC_EXPORT void JEMALLOC_NOTHROW\t@je_@free(void *ptr)\n    JEMALLOC_CXX_THROW;\n\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\n    void JEMALLOC_NOTHROW\t*@je_@mallocx(size_t size, int flags)\n    JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1);\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\n    void JEMALLOC_NOTHROW\t*@je_@rallocx(void *ptr, size_t size,\n    int flags) JEMALLOC_ALLOC_SIZE(2);\nJEMALLOC_EXPORT size_t JEMALLOC_NOTHROW\t@je_@xallocx(void *ptr, size_t size,\n    size_t extra, int flags);\nJEMALLOC_EXPORT size_t JEMALLOC_NOTHROW\t@je_@sallocx(const void *ptr,\n    int flags) JEMALLOC_ATTR(pure);\nJEMALLOC_EXPORT void JEMALLOC_NOTHROW\t@je_@dallocx(void *ptr, int flags);\nJEMALLOC_EXPORT void JEMALLOC_NOTHROW\t@je_@sdallocx(void *ptr, size_t size,\n    int flags);\nJEMALLOC_EXPORT size_t JEMALLOC_NOTHROW\t@je_@nallocx(size_t size, int flags)\n    JEMALLOC_ATTR(pure);\n\nJEMALLOC_EXPORT int JEMALLOC_NOTHROW\t@je_@mallctl(const char *name,\n    void *oldp, size_t *oldlenp, void *newp, size_t newlen);\nJEMALLOC_EXPORT int JEMALLOC_NOTHROW\t@je_@mallctlnametomib(const char *name,\n    size_t *mibp, size_t *miblenp);\nJEMALLOC_EXPORT int JEMALLOC_NOTHROW\t@je_@mallctlbymib(const size_t *mib,\n    size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen);\nJEMALLOC_EXPORT void JEMALLOC_NOTHROW\t@je_@malloc_stats_print(\n    void (*write_cb)(void *, const char *), void *@je_@cbopaque,\n    const char *opts);\nJEMALLOC_EXPORT size_t JEMALLOC_NOTHROW\t@je_@malloc_usable_size(\n    JEMALLOC_USABLE_SIZE_CONST void *ptr) JEMALLOC_CXX_THROW;\n\n#ifdef JEMALLOC_OVERRIDE_MEMALIGN\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\n    void JEMALLOC_NOTHROW\t*@je_@memalign(size_t alignment, size_t size)\n    JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc);\n#endif\n\n#ifdef JEMALLOC_OVERRIDE_VALLOC\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\n    void JEMALLOC_NOTHROW\t*@je_@valloc(size_t size) JEMALLOC_CXX_THROW\n    JEMALLOC_ATTR(malloc);\n#endif\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/jemalloc_rename.sh",
    "content": "#!/bin/sh\n\npublic_symbols_txt=$1\n\ncat <<EOF\n/*\n * Name mangling for public symbols is controlled by --with-mangling and\n * --with-jemalloc-prefix.  With default settings the je_ prefix is stripped by\n * these macro definitions.\n */\n#ifndef JEMALLOC_NO_RENAME\nEOF\n\nfor nm in `cat ${public_symbols_txt}` ; do\n  n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'`\n  m=`echo ${nm} |tr ':' ' ' |awk '{print $2}'`\n  echo \"#  define je_${n} ${m}\"\ndone\n\ncat <<EOF\n#endif\nEOF\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/jemalloc/jemalloc_typedefs.h.in",
    "content": "/*\n * void *\n * chunk_alloc(void *new_addr, size_t size, size_t alignment, bool *zero,\n *     bool *commit, unsigned arena_ind);\n */\ntypedef void *(chunk_alloc_t)(void *, size_t, size_t, bool *, bool *, unsigned);\n\n/*\n * bool\n * chunk_dalloc(void *chunk, size_t size, bool committed, unsigned arena_ind);\n */\ntypedef bool (chunk_dalloc_t)(void *, size_t, bool, unsigned);\n\n/*\n * bool\n * chunk_commit(void *chunk, size_t size, size_t offset, size_t length,\n *     unsigned arena_ind);\n */\ntypedef bool (chunk_commit_t)(void *, size_t, size_t, size_t, unsigned);\n\n/*\n * bool\n * chunk_decommit(void *chunk, size_t size, size_t offset, size_t length,\n *     unsigned arena_ind);\n */\ntypedef bool (chunk_decommit_t)(void *, size_t, size_t, size_t, unsigned);\n\n/*\n * bool\n * chunk_purge(void *chunk, size_t size, size_t offset, size_t length,\n *     unsigned arena_ind);\n */\ntypedef bool (chunk_purge_t)(void *, size_t, size_t, size_t, unsigned);\n\n/*\n * bool\n * chunk_split(void *chunk, size_t size, size_t size_a, size_t size_b,\n *     bool committed, unsigned arena_ind);\n */\ntypedef bool (chunk_split_t)(void *, size_t, size_t, size_t, bool, unsigned);\n\n/*\n * bool\n * chunk_merge(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b,\n *     bool committed, unsigned arena_ind);\n */\ntypedef bool (chunk_merge_t)(void *, size_t, void *, size_t, bool, unsigned);\n\ntypedef struct {\n\tchunk_alloc_t\t\t*alloc;\n\tchunk_dalloc_t\t\t*dalloc;\n\tchunk_commit_t\t\t*commit;\n\tchunk_decommit_t\t*decommit;\n\tchunk_purge_t\t\t*purge;\n\tchunk_split_t\t\t*split;\n\tchunk_merge_t\t\t*merge;\n} chunk_hooks_t;\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/msvc_compat/C99/stdbool.h",
    "content": "#ifndef stdbool_h\n#define stdbool_h\n\n#include <wtypes.h>\n\n/* MSVC doesn't define _Bool or bool in C, but does have BOOL */\n/* Note this doesn't pass autoconf's test because (bool) 0.5 != true */\n/* Clang-cl uses MSVC headers, so needs msvc_compat, but has _Bool as\n * a built-in type. */\n#ifndef __clang__\ntypedef BOOL _Bool;\n#endif\n\n#define bool _Bool\n#define true 1\n#define false 0\n\n#define __bool_true_false_are_defined 1\n\n#endif /* stdbool_h */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/msvc_compat/C99/stdint.h",
    "content": "// ISO C9x  compliant stdint.h for Microsoft Visual Studio\n// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 \n// \n//  Copyright (c) 2006-2008 Alexander Chemeris\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are met:\n// \n//   1. Redistributions of source code must retain the above copyright notice,\n//      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 name of the author may be used to endorse or promote products\n//      derived from this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\n// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \n// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n// \n///////////////////////////////////////////////////////////////////////////////\n\n#ifndef _MSC_VER // [\n#error \"Use this header only with Microsoft Visual C++ compilers!\"\n#endif // _MSC_VER ]\n\n#ifndef _MSC_STDINT_H_ // [\n#define _MSC_STDINT_H_\n\n#if _MSC_VER > 1000\n#pragma once\n#endif\n\n#include <limits.h>\n\n// For Visual Studio 6 in C++ mode and for many Visual Studio versions when\n// compiling for ARM we should wrap <wchar.h> include with 'extern \"C++\" {}'\n// or compiler give many errors like this:\n//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n#  include <wchar.h>\n#ifdef __cplusplus\n}\n#endif\n\n// Define _W64 macros to mark types changing their size, like intptr_t.\n#ifndef _W64\n#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300\n#     define _W64 __w64\n#  else\n#     define _W64\n#  endif\n#endif\n\n\n// 7.18.1 Integer types\n\n// 7.18.1.1 Exact-width integer types\n\n// Visual Studio 6 and Embedded Visual C++ 4 doesn't\n// realize that, e.g. char has the same size as __int8\n// so we give up on __intX for them.\n#if (_MSC_VER < 1300)\n   typedef signed char       int8_t;\n   typedef signed short      int16_t;\n   typedef signed int        int32_t;\n   typedef unsigned char     uint8_t;\n   typedef unsigned short    uint16_t;\n   typedef unsigned int      uint32_t;\n#else\n   typedef signed __int8     int8_t;\n   typedef signed __int16    int16_t;\n   typedef signed __int32    int32_t;\n   typedef unsigned __int8   uint8_t;\n   typedef unsigned __int16  uint16_t;\n   typedef unsigned __int32  uint32_t;\n#endif\ntypedef signed __int64       int64_t;\ntypedef unsigned __int64     uint64_t;\n\n\n// 7.18.1.2 Minimum-width integer types\ntypedef int8_t    int_least8_t;\ntypedef int16_t   int_least16_t;\ntypedef int32_t   int_least32_t;\ntypedef int64_t   int_least64_t;\ntypedef uint8_t   uint_least8_t;\ntypedef uint16_t  uint_least16_t;\ntypedef uint32_t  uint_least32_t;\ntypedef uint64_t  uint_least64_t;\n\n// 7.18.1.3 Fastest minimum-width integer types\ntypedef int8_t    int_fast8_t;\ntypedef int16_t   int_fast16_t;\ntypedef int32_t   int_fast32_t;\ntypedef int64_t   int_fast64_t;\ntypedef uint8_t   uint_fast8_t;\ntypedef uint16_t  uint_fast16_t;\ntypedef uint32_t  uint_fast32_t;\ntypedef uint64_t  uint_fast64_t;\n\n// 7.18.1.4 Integer types capable of holding object pointers\n#ifdef _WIN64 // [\n   typedef signed __int64    intptr_t;\n   typedef unsigned __int64  uintptr_t;\n#else // _WIN64 ][\n   typedef _W64 signed int   intptr_t;\n   typedef _W64 unsigned int uintptr_t;\n#endif // _WIN64 ]\n\n// 7.18.1.5 Greatest-width integer types\ntypedef int64_t   intmax_t;\ntypedef uint64_t  uintmax_t;\n\n\n// 7.18.2 Limits of specified-width integer types\n\n#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259\n\n// 7.18.2.1 Limits of exact-width integer types\n#define INT8_MIN     ((int8_t)_I8_MIN)\n#define INT8_MAX     _I8_MAX\n#define INT16_MIN    ((int16_t)_I16_MIN)\n#define INT16_MAX    _I16_MAX\n#define INT32_MIN    ((int32_t)_I32_MIN)\n#define INT32_MAX    _I32_MAX\n#define INT64_MIN    ((int64_t)_I64_MIN)\n#define INT64_MAX    _I64_MAX\n#define UINT8_MAX    _UI8_MAX\n#define UINT16_MAX   _UI16_MAX\n#define UINT32_MAX   _UI32_MAX\n#define UINT64_MAX   _UI64_MAX\n\n// 7.18.2.2 Limits of minimum-width integer types\n#define INT_LEAST8_MIN    INT8_MIN\n#define INT_LEAST8_MAX    INT8_MAX\n#define INT_LEAST16_MIN   INT16_MIN\n#define INT_LEAST16_MAX   INT16_MAX\n#define INT_LEAST32_MIN   INT32_MIN\n#define INT_LEAST32_MAX   INT32_MAX\n#define INT_LEAST64_MIN   INT64_MIN\n#define INT_LEAST64_MAX   INT64_MAX\n#define UINT_LEAST8_MAX   UINT8_MAX\n#define UINT_LEAST16_MAX  UINT16_MAX\n#define UINT_LEAST32_MAX  UINT32_MAX\n#define UINT_LEAST64_MAX  UINT64_MAX\n\n// 7.18.2.3 Limits of fastest minimum-width integer types\n#define INT_FAST8_MIN    INT8_MIN\n#define INT_FAST8_MAX    INT8_MAX\n#define INT_FAST16_MIN   INT16_MIN\n#define INT_FAST16_MAX   INT16_MAX\n#define INT_FAST32_MIN   INT32_MIN\n#define INT_FAST32_MAX   INT32_MAX\n#define INT_FAST64_MIN   INT64_MIN\n#define INT_FAST64_MAX   INT64_MAX\n#define UINT_FAST8_MAX   UINT8_MAX\n#define UINT_FAST16_MAX  UINT16_MAX\n#define UINT_FAST32_MAX  UINT32_MAX\n#define UINT_FAST64_MAX  UINT64_MAX\n\n// 7.18.2.4 Limits of integer types capable of holding object pointers\n#ifdef _WIN64 // [\n#  define INTPTR_MIN   INT64_MIN\n#  define INTPTR_MAX   INT64_MAX\n#  define UINTPTR_MAX  UINT64_MAX\n#else // _WIN64 ][\n#  define INTPTR_MIN   INT32_MIN\n#  define INTPTR_MAX   INT32_MAX\n#  define UINTPTR_MAX  UINT32_MAX\n#endif // _WIN64 ]\n\n// 7.18.2.5 Limits of greatest-width integer types\n#define INTMAX_MIN   INT64_MIN\n#define INTMAX_MAX   INT64_MAX\n#define UINTMAX_MAX  UINT64_MAX\n\n// 7.18.3 Limits of other integer types\n\n#ifdef _WIN64 // [\n#  define PTRDIFF_MIN  _I64_MIN\n#  define PTRDIFF_MAX  _I64_MAX\n#else  // _WIN64 ][\n#  define PTRDIFF_MIN  _I32_MIN\n#  define PTRDIFF_MAX  _I32_MAX\n#endif  // _WIN64 ]\n\n#define SIG_ATOMIC_MIN  INT_MIN\n#define SIG_ATOMIC_MAX  INT_MAX\n\n#ifndef SIZE_MAX // [\n#  ifdef _WIN64 // [\n#     define SIZE_MAX  _UI64_MAX\n#  else // _WIN64 ][\n#     define SIZE_MAX  _UI32_MAX\n#  endif // _WIN64 ]\n#endif // SIZE_MAX ]\n\n// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>\n#ifndef WCHAR_MIN // [\n#  define WCHAR_MIN  0\n#endif  // WCHAR_MIN ]\n#ifndef WCHAR_MAX // [\n#  define WCHAR_MAX  _UI16_MAX\n#endif  // WCHAR_MAX ]\n\n#define WINT_MIN  0\n#define WINT_MAX  _UI16_MAX\n\n#endif // __STDC_LIMIT_MACROS ]\n\n\n// 7.18.4 Limits of other integer types\n\n#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260\n\n// 7.18.4.1 Macros for minimum-width integer constants\n\n#define INT8_C(val)  val##i8\n#define INT16_C(val) val##i16\n#define INT32_C(val) val##i32\n#define INT64_C(val) val##i64\n\n#define UINT8_C(val)  val##ui8\n#define UINT16_C(val) val##ui16\n#define UINT32_C(val) val##ui32\n#define UINT64_C(val) val##ui64\n\n// 7.18.4.2 Macros for greatest-width integer constants\n#define INTMAX_C   INT64_C\n#define UINTMAX_C  UINT64_C\n\n#endif // __STDC_CONSTANT_MACROS ]\n\n\n#endif // _MSC_STDINT_H_ ]\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/msvc_compat/strings.h",
    "content": "#ifndef strings_h\n#define strings_h\n\n/* MSVC doesn't define ffs/ffsl. This dummy strings.h header is provided\n * for both */\n#ifdef _MSC_VER\n#  include <intrin.h>\n#  pragma intrinsic(_BitScanForward)\nstatic __forceinline int ffsl(long x)\n{\n\tunsigned long i;\n\n\tif (_BitScanForward(&i, x))\n\t\treturn (i + 1);\n\treturn (0);\n}\n\nstatic __forceinline int ffs(int x)\n{\n\n\treturn (ffsl(x));\n}\n\n#  ifdef  _M_X64\n#    pragma intrinsic(_BitScanForward64)\n#  endif\n\nstatic __forceinline int ffsll(unsigned __int64 x)\n{\n\tunsigned long i;\n#ifdef  _M_X64\n\tif (_BitScanForward64(&i, x))\n\t\treturn (i + 1);\n\treturn (0);\n#else\n// Fallback for 32-bit build where 64-bit version not available\n// assuming little endian\n\tunion {\n\t\tunsigned __int64 ll;\n\t\tunsigned   long l[2];\n\t} s;\n\n\ts.ll = x;\n\n\tif (_BitScanForward(&i, s.l[0]))\n\t\treturn (i + 1);\n\telse if(_BitScanForward(&i, s.l[1]))\n\t\treturn (i + 33);\n\treturn (0);\n#endif\n}\n\n#else\n#  define ffsll(x) __builtin_ffsll(x)\n#  define ffsl(x) __builtin_ffsl(x)\n#  define ffs(x) __builtin_ffs(x)\n#endif\n\n#endif /* strings_h */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/include/msvc_compat/windows_extra.h",
    "content": "#ifndef MSVC_COMPAT_WINDOWS_EXTRA_H\n#define\tMSVC_COMPAT_WINDOWS_EXTRA_H\n\n#ifndef ENOENT\n#  define ENOENT ERROR_PATH_NOT_FOUND\n#endif\n#ifndef EINVAL\n#  define EINVAL ERROR_BAD_ARGUMENTS\n#endif\n#ifndef EAGAIN\n#  define EAGAIN ERROR_OUTOFMEMORY\n#endif\n#ifndef EPERM\n#  define EPERM  ERROR_WRITE_FAULT\n#endif\n#ifndef EFAULT\n#  define EFAULT ERROR_INVALID_ADDRESS\n#endif\n#ifndef ENOMEM\n#  define ENOMEM ERROR_NOT_ENOUGH_MEMORY\n#endif\n#ifndef ERANGE\n#  define ERANGE ERROR_INVALID_DATA\n#endif\n\n#endif /* MSVC_COMPAT_WINDOWS_EXTRA_H */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/jemalloc.pc.in",
    "content": "prefix=@prefix@\nexec_prefix=@exec_prefix@\nlibdir=@libdir@\nincludedir=@includedir@\ninstall_suffix=@install_suffix@\n\nName: jemalloc\nDescription: A general purpose malloc(3) implementation that emphasizes fragmentation avoidance and scalable concurrency support.\nURL: http://www.canonware.com/jemalloc\nVersion: @jemalloc_version@\nCflags: -I${includedir}\nLibs: -L${libdir} -ljemalloc${install_suffix}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/msvc/ReadMe.txt",
    "content": "\nHow to build jemalloc for Windows\n=================================\n\n1. Install Cygwin with at least the following packages:\n   * autoconf\n   * autogen\n   * gawk\n   * grep\n   * sed\n\n2. Install Visual Studio 2015 with Visual C++\n\n3. Add Cygwin\\bin to the PATH environment variable\n\n4. Open \"VS2015 x86 Native Tools Command Prompt\"\n   (note: x86/x64 doesn't matter at this point)\n\n5. Generate header files:\n   sh -c \"./autogen.sh CC=cl --enable-lazy-lock=no\"\n\n6. Now the project can be opened and built in Visual Studio:\n   msvc\\jemalloc_vc2015.sln\n\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/msvc/jemalloc_vc2015.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 14\nVisualStudioVersion = 14.0.24720.0\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Items\", \"Solution Items\", \"{70A99006-6DE9-472B-8F83-4CEE6C616DF3}\"\n\tProjectSection(SolutionItems) = preProject\n\t\tReadMe.txt = ReadMe.txt\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"jemalloc\", \"projects\\vc2015\\jemalloc\\jemalloc.vcxproj\", \"{8D6BB292-9E1C-413D-9F98-4864BDC1514A}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"test_threads\", \"projects\\vc2015\\test_threads\\test_threads.vcxproj\", \"{09028CFD-4EB7-491D-869C-0708DB97ED44}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tDebug-static|x64 = Debug-static|x64\n\t\tDebug-static|x86 = Debug-static|x86\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\t\tRelease-static|x64 = Release-static|x64\n\t\tRelease-static|x86 = Release-static|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug|x64.Build.0 = Debug|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug|x86.Build.0 = Debug|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug-static|x64.ActiveCfg = Debug-static|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug-static|x64.Build.0 = Debug-static|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug-static|x86.ActiveCfg = Debug-static|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug-static|x86.Build.0 = Debug-static|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release|x64.ActiveCfg = Release|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release|x64.Build.0 = Release|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release|x86.ActiveCfg = Release|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release|x86.Build.0 = Release|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release-static|x64.ActiveCfg = Release-static|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release-static|x64.Build.0 = Release-static|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release-static|x86.ActiveCfg = Release-static|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release-static|x86.Build.0 = Release-static|Win32\n\t\t{09028CFD-4EB7-491D-869C-0708DB97ED44}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{09028CFD-4EB7-491D-869C-0708DB97ED44}.Debug|x64.Build.0 = Debug|x64\n\t\t{09028CFD-4EB7-491D-869C-0708DB97ED44}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{09028CFD-4EB7-491D-869C-0708DB97ED44}.Debug|x86.Build.0 = Debug|Win32\n\t\t{09028CFD-4EB7-491D-869C-0708DB97ED44}.Debug-static|x64.ActiveCfg = Debug-static|x64\n\t\t{09028CFD-4EB7-491D-869C-0708DB97ED44}.Debug-static|x64.Build.0 = Debug-static|x64\n\t\t{09028CFD-4EB7-491D-869C-0708DB97ED44}.Debug-static|x86.ActiveCfg = Debug-static|Win32\n\t\t{09028CFD-4EB7-491D-869C-0708DB97ED44}.Debug-static|x86.Build.0 = Debug-static|Win32\n\t\t{09028CFD-4EB7-491D-869C-0708DB97ED44}.Release|x64.ActiveCfg = Release|x64\n\t\t{09028CFD-4EB7-491D-869C-0708DB97ED44}.Release|x64.Build.0 = Release|x64\n\t\t{09028CFD-4EB7-491D-869C-0708DB97ED44}.Release|x86.ActiveCfg = Release|Win32\n\t\t{09028CFD-4EB7-491D-869C-0708DB97ED44}.Release|x86.Build.0 = Release|Win32\n\t\t{09028CFD-4EB7-491D-869C-0708DB97ED44}.Release-static|x64.ActiveCfg = Release-static|x64\n\t\t{09028CFD-4EB7-491D-869C-0708DB97ED44}.Release-static|x64.Build.0 = Release-static|x64\n\t\t{09028CFD-4EB7-491D-869C-0708DB97ED44}.Release-static|x86.ActiveCfg = Release-static|Win32\n\t\t{09028CFD-4EB7-491D-869C-0708DB97ED44}.Release-static|x86.Build.0 = Release-static|Win32\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/msvc/projects/vc2015/jemalloc/jemalloc.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug-static|Win32\">\n      <Configuration>Debug-static</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug-static|x64\">\n      <Configuration>Debug-static</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release-static|Win32\">\n      <Configuration>Release-static</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release-static|x64\">\n      <Configuration>Release-static</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\arena.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\assert.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\atomic.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\base.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\bitmap.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\chunk.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\chunk_dss.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\chunk_mmap.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\ckh.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\ctl.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\extent.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\hash.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\huge.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\jemalloc_internal.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\jemalloc_internal_decls.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\jemalloc_internal_defs.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\jemalloc_internal_macros.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\mb.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\mutex.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\pages.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\private_namespace.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\private_unnamespace.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\prng.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\prof.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\public_namespace.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\public_unnamespace.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\ql.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\qr.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\quarantine.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\rb.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\rtree.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\size_classes.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\stats.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\tcache.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\tsd.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\util.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\valgrind.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\jemalloc.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\jemalloc_defs.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\jemalloc_macros.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\jemalloc_mangle.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\jemalloc_protos.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\jemalloc_protos_jet.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\jemalloc_rename.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\jemalloc_typedefs.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\msvc_compat\\C99\\stdbool.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\msvc_compat\\C99\\stdint.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\msvc_compat\\strings.h\" />\n    <ClInclude Include=\"..\\..\\..\\..\\include\\msvc_compat\\windows_extra.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\arena.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\atomic.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\base.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\bitmap.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\chunk.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\chunk_dss.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\chunk_mmap.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\ckh.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\ctl.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\extent.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\hash.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\huge.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\jemalloc.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\mb.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\mutex.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\nstime.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\pages.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\prof.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\quarantine.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\rtree.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\stats.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\tcache.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\tsd.c\" />\n    <ClCompile Include=\"..\\..\\..\\..\\src\\util.c\" />\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{8D6BB292-9E1C-413D-9F98-4864BDC1514A}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>jemalloc</RootNamespace>\n    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug-static|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release-static|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug-static|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release-static|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"Shared\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug-static|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release-static|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug-static|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release-static|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n    <TargetName>$(ProjectName)d</TargetName>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug-static|Win32'\">\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n    <TargetName>$(ProjectName)-$(PlatformToolset)-$(Configuration)</TargetName>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release-static|Win32'\">\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n    <TargetName>$(ProjectName)-$(PlatformToolset)-$(Configuration)</TargetName>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n    <TargetName>$(ProjectName)d</TargetName>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug-static|x64'\">\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n    <TargetName>$(ProjectName)-$(PlatformToolset)-$(Configuration)</TargetName>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release-static|x64'\">\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n    <TargetName>$(ProjectName)-$(PlatformToolset)-$(Configuration)</TargetName>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>_REENTRANT;_WINDLL;DLLEXPORT;JEMALLOC_DEBUG;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\..\\..\\include;..\\..\\..\\..\\include\\msvc_compat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4090;4146;4244;4267;4334</DisableSpecificWarnings>\n      <ProgramDataBaseFileName>$(OutputPath)$(TargetName).pdb</ProgramDataBaseFileName>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug-static|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>JEMALLOC_DEBUG;_REENTRANT;JEMALLOC_EXPORT=;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\..\\..\\include;..\\..\\..\\..\\include\\msvc_compat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <DisableSpecificWarnings>4090;4146;4244;4267;4334</DisableSpecificWarnings>\n      <ProgramDataBaseFileName>$(OutputPath)$(TargetName).pdb</ProgramDataBaseFileName>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>_REENTRANT;_WINDLL;DLLEXPORT;JEMALLOC_DEBUG;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\..\\..\\include;..\\..\\..\\..\\include\\msvc_compat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4090;4146;4244;4267;4334</DisableSpecificWarnings>\n      <ProgramDataBaseFileName>$(OutputPath)$(TargetName).pdb</ProgramDataBaseFileName>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug-static|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>JEMALLOC_DEBUG;_REENTRANT;JEMALLOC_EXPORT=;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\..\\..\\include;..\\..\\..\\..\\include\\msvc_compat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <DisableSpecificWarnings>4090;4146;4244;4267;4334</DisableSpecificWarnings>\n      <ProgramDataBaseFileName>$(OutputPath)$(TargetName).pdb</ProgramDataBaseFileName>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>_REENTRANT;_WINDLL;DLLEXPORT;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\..\\..\\include;..\\..\\..\\..\\include\\msvc_compat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4090;4146;4244;4267;4334</DisableSpecificWarnings>\n      <ProgramDataBaseFileName>$(OutputPath)$(TargetName).pdb</ProgramDataBaseFileName>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release-static|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>_REENTRANT;JEMALLOC_EXPORT=;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\..\\..\\include;..\\..\\..\\..\\include\\msvc_compat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <DisableSpecificWarnings>4090;4146;4244;4267;4334</DisableSpecificWarnings>\n      <ProgramDataBaseFileName>$(OutputPath)$(TargetName).pdb</ProgramDataBaseFileName>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <AdditionalIncludeDirectories>..\\..\\..\\..\\include;..\\..\\..\\..\\include\\msvc_compat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_REENTRANT;_WINDLL;DLLEXPORT;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <DisableSpecificWarnings>4090;4146;4244;4267;4334</DisableSpecificWarnings>\n      <ProgramDataBaseFileName>$(OutputPath)$(TargetName).pdb</ProgramDataBaseFileName>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release-static|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>_REENTRANT;JEMALLOC_EXPORT=;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\..\\..\\include;..\\..\\..\\..\\include\\msvc_compat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <DisableSpecificWarnings>4090;4146;4244;4267;4334</DisableSpecificWarnings>\n      <ProgramDataBaseFileName>$(OutputPath)$(TargetName).pdb</ProgramDataBaseFileName>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "deps/jemalloc-4.1.0/msvc/projects/vc2015/jemalloc/jemalloc.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\\internal\">\n      <UniqueIdentifier>{5697dfa3-16cf-4932-b428-6e0ec6e9f98e}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Header Files\\msvc_compat\">\n      <UniqueIdentifier>{0cbd2ca6-42a7-4f82-8517-d7e7a14fd986}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Header Files\\msvc_compat\\C99\">\n      <UniqueIdentifier>{0abe6f30-49b5-46dd-8aca-6e33363fa52c}</UniqueIdentifier>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\jemalloc.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\jemalloc_defs.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\jemalloc_macros.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\jemalloc_mangle.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\jemalloc_protos.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\jemalloc_protos_jet.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\jemalloc_rename.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\jemalloc_typedefs.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\arena.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\assert.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\atomic.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\base.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\bitmap.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\chunk.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\chunk_dss.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\chunk_mmap.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\ckh.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\ctl.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\extent.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\hash.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\huge.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\jemalloc_internal.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\jemalloc_internal_decls.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\jemalloc_internal_defs.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\jemalloc_internal_macros.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\mb.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\mutex.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\pages.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\private_namespace.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\private_unnamespace.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\prng.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\prof.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\public_namespace.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\public_unnamespace.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\ql.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\qr.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\quarantine.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\rb.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\rtree.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\size_classes.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\stats.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\tcache.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\tsd.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\util.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\jemalloc\\internal\\valgrind.h\">\n      <Filter>Header Files\\internal</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\msvc_compat\\strings.h\">\n      <Filter>Header Files\\msvc_compat</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\msvc_compat\\windows_extra.h\">\n      <Filter>Header Files\\msvc_compat</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\msvc_compat\\C99\\stdbool.h\">\n      <Filter>Header Files\\msvc_compat\\C99</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\..\\include\\msvc_compat\\C99\\stdint.h\">\n      <Filter>Header Files\\msvc_compat\\C99</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\arena.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\atomic.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\base.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\bitmap.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\chunk.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\chunk_dss.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\chunk_mmap.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\ckh.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\ctl.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\extent.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\hash.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\huge.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\jemalloc.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\mb.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\mutex.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\pages.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\prof.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\quarantine.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\rtree.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\stats.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\tcache.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\tsd.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\util.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\..\\src\\nstime.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "deps/jemalloc-4.1.0/msvc/projects/vc2015/test_threads/test_threads.cpp",
    "content": "// jemalloc C++ threaded test\n// Author: Rustam Abdullaev\n// Public Domain\n\n#include <atomic>\n#include <functional>\n#include <future>\n#include <random>\n#include <thread>\n#include <vector>\n#include <stdio.h>\n#include <jemalloc/jemalloc.h>\n\nusing std::vector;\nusing std::thread;\nusing std::uniform_int_distribution;\nusing std::minstd_rand;\n\nint test_threads()\n{\n  je_malloc_conf = \"narenas:3\";\n  int narenas = 0;\n  size_t sz = sizeof(narenas);\n  je_mallctl(\"opt.narenas\", &narenas, &sz, NULL, 0);\n  if (narenas != 3) {\n    printf(\"Error: unexpected number of arenas: %d\\n\", narenas);\n    return 1;\n  }\n  static const int sizes[] = { 7, 16, 32, 60, 91, 100, 120, 144, 169, 199, 255, 400, 670, 900, 917, 1025, 3333, 5190, 13131, 49192, 99999, 123123, 255265, 2333111 };\n  static const int numSizes = (int)(sizeof(sizes) / sizeof(sizes[0]));\n  vector<thread> workers;\n  static const int numThreads = narenas + 1, numAllocsMax = 25, numIter1 = 50, numIter2 = 50;\n  je_malloc_stats_print(NULL, NULL, NULL);\n  size_t allocated1;\n  size_t sz1 = sizeof(allocated1);\n  je_mallctl(\"stats.active\", &allocated1, &sz1, NULL, 0);\n  printf(\"\\nPress Enter to start threads...\\n\");\n  getchar();\n  printf(\"Starting %d threads x %d x %d iterations...\\n\", numThreads, numIter1, numIter2);\n  for (int i = 0; i < numThreads; i++) {\n    workers.emplace_back([tid=i]() {\n      uniform_int_distribution<int> sizeDist(0, numSizes - 1);\n      minstd_rand rnd(tid * 17);\n      uint8_t* ptrs[numAllocsMax];\n      int ptrsz[numAllocsMax];\n      for (int i = 0; i < numIter1; ++i) {\n        thread t([&]() {\n          for (int i = 0; i < numIter2; ++i) {\n            const int numAllocs = numAllocsMax - sizeDist(rnd);\n            for (int j = 0; j < numAllocs; j += 64) {\n              const int x = sizeDist(rnd);\n              const int sz = sizes[x];\n              ptrsz[j] = sz;\n              ptrs[j] = (uint8_t*)je_malloc(sz);\n              if (!ptrs[j]) {\n                printf(\"Unable to allocate %d bytes in thread %d, iter %d, alloc %d. %d\\n\", sz, tid, i, j, x);\n                exit(1);\n              }\n              for (int k = 0; k < sz; k++)\n                ptrs[j][k] = tid + k;\n            }\n            for (int j = 0; j < numAllocs; j += 64) {\n              for (int k = 0, sz = ptrsz[j]; k < sz; k++)\n                if (ptrs[j][k] != (uint8_t)(tid + k)) {\n                  printf(\"Memory error in thread %d, iter %d, alloc %d @ %d : %02X!=%02X\\n\", tid, i, j, k, ptrs[j][k], (uint8_t)(tid + k));\n                  exit(1);\n                }\n              je_free(ptrs[j]);\n            }\n          }\n        });\n        t.join();\n      }\n    });\n  }\n  for (thread& t : workers) {\n    t.join();\n  }\n  je_malloc_stats_print(NULL, NULL, NULL);\n  size_t allocated2;\n  je_mallctl(\"stats.active\", &allocated2, &sz1, NULL, 0);\n  size_t leaked = allocated2 - allocated1;\n  printf(\"\\nDone. Leaked: %zd bytes\\n\", leaked);\n  bool failed = leaked > 65536; // in case C++ runtime allocated something (e.g. iostream locale or facet)\n  printf(\"\\nTest %s!\\n\", (failed ? \"FAILED\" : \"successful\"));\n  printf(\"\\nPress Enter to continue...\\n\");\n  getchar();\n  return failed ? 1 : 0;\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/msvc/projects/vc2015/test_threads/test_threads.h",
    "content": "#pragma once\n\nint test_threads();\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/msvc/projects/vc2015/test_threads/test_threads.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug-static|Win32\">\n      <Configuration>Debug-static</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug-static|x64\">\n      <Configuration>Debug-static</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release-static|Win32\">\n      <Configuration>Release-static</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release-static|x64\">\n      <Configuration>Release-static</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{09028CFD-4EB7-491D-869C-0708DB97ED44}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>test_threads</RootNamespace>\n    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug-static|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release-static|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug-static|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release-static|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"Shared\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug-static|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release-static|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug-static|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release-static|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n    <LinkIncremental>true</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug-static|Win32'\">\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n    <LinkIncremental>true</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LinkIncremental>true</LinkIncremental>\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug-static|x64'\">\n    <LinkIncremental>true</LinkIncremental>\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n    <LinkIncremental>false</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release-static|Win32'\">\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n    <LinkIncremental>false</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n    <LinkIncremental>false</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release-static|x64'\">\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n    <LinkIncremental>false</LinkIncremental>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\..\\..\\test\\include;..\\..\\..\\..\\include;..\\..\\..\\..\\include\\msvc_compat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\\$(Configuration)</AdditionalLibraryDirectories>\n      <AdditionalDependencies>jemallocd.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug-static|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>JEMALLOC_EXPORT=;JEMALLOC_STATIC;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\..\\..\\test\\include;..\\..\\..\\..\\include;..\\..\\..\\..\\include\\msvc_compat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\\$(Configuration)</AdditionalLibraryDirectories>\n      <AdditionalDependencies>jemalloc-$(PlatformToolset)-$(Configuration).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\..\\..\\test\\include;..\\..\\..\\..\\include;..\\..\\..\\..\\include\\msvc_compat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>jemallocd.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\\$(Configuration)</AdditionalLibraryDirectories>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug-static|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>JEMALLOC_EXPORT=;JEMALLOC_STATIC;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\..\\..\\test\\include;..\\..\\..\\..\\include;..\\..\\..\\..\\include\\msvc_compat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>jemalloc-$(PlatformToolset)-$(Configuration).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\\$(Configuration)</AdditionalLibraryDirectories>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\..\\..\\test\\include;..\\..\\..\\..\\include;..\\..\\..\\..\\include\\msvc_compat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\\$(Configuration)</AdditionalLibraryDirectories>\n      <AdditionalDependencies>jemalloc.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release-static|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>JEMALLOC_EXPORT=;JEMALLOC_STATIC;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\..\\..\\test\\include;..\\..\\..\\..\\include;..\\..\\..\\..\\include\\msvc_compat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\\$(Configuration)</AdditionalLibraryDirectories>\n      <AdditionalDependencies>jemalloc-$(PlatformToolset)-$(Configuration).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\..\\..\\test\\include;..\\..\\..\\..\\include;..\\..\\..\\..\\include\\msvc_compat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\\$(Configuration)</AdditionalLibraryDirectories>\n      <AdditionalDependencies>jemalloc.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release-static|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>JEMALLOC_EXPORT=;JEMALLOC_STATIC;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>..\\..\\..\\..\\test\\include;..\\..\\..\\..\\include;..\\..\\..\\..\\include\\msvc_compat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\\$(Configuration)</AdditionalLibraryDirectories>\n      <AdditionalDependencies>jemalloc-$(PlatformToolset)-$(Configuration).lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"test_threads.cpp\" />\n    <ClCompile Include=\"test_threads_main.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\jemalloc\\jemalloc.vcxproj\">\n      <Project>{8d6bb292-9e1c-413d-9f98-4864bdc1514a}</Project>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"test_threads.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "deps/jemalloc-4.1.0/msvc/projects/vc2015/test_threads/test_threads.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"test_threads.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"test_threads_main.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"test_threads.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "deps/jemalloc-4.1.0/msvc/projects/vc2015/test_threads/test_threads_main.cpp",
    "content": "#include \"test_threads.h\"\n#include <future>\n#include <functional>\n#include <chrono>\n\nusing namespace std::chrono_literals;\n\nint main(int argc, char** argv)\n{\n  int rc = test_threads();\n  return rc;\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/arena.c",
    "content": "#define\tJEMALLOC_ARENA_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n/******************************************************************************/\n/* Data. */\n\npurge_mode_t\topt_purge = PURGE_DEFAULT;\nconst char\t*purge_mode_names[] = {\n\t\"ratio\",\n\t\"decay\",\n\t\"N/A\"\n};\nssize_t\t\topt_lg_dirty_mult = LG_DIRTY_MULT_DEFAULT;\nstatic ssize_t\tlg_dirty_mult_default;\nssize_t\t\topt_decay_time = DECAY_TIME_DEFAULT;\nstatic ssize_t\tdecay_time_default;\n\narena_bin_info_t\tarena_bin_info[NBINS];\n\nsize_t\t\tmap_bias;\nsize_t\t\tmap_misc_offset;\nsize_t\t\tarena_maxrun; /* Max run size for arenas. */\nsize_t\t\tlarge_maxclass; /* Max large size class. */\nsize_t\t\trun_quantize_max; /* Max run_quantize_*() input. */\nstatic size_t\tsmall_maxrun; /* Max run size for small size classes. */\nstatic bool\t*small_run_tab; /* Valid small run page multiples. */\nstatic size_t\t*run_quantize_floor_tab; /* run_quantize_floor() memoization. */\nstatic size_t\t*run_quantize_ceil_tab; /* run_quantize_ceil() memoization. */\nunsigned\tnlclasses; /* Number of large size classes. */\nunsigned\tnhclasses; /* Number of huge size classes. */\nstatic szind_t\truns_avail_bias; /* Size index for first runs_avail tree. */\nstatic szind_t\truns_avail_nclasses; /* Number of runs_avail trees. */\n\n/******************************************************************************/\n/*\n * Function prototypes for static functions that are referenced prior to\n * definition.\n */\n\nstatic void\tarena_purge_to_limit(arena_t *arena, size_t ndirty_limit);\nstatic void\tarena_run_dalloc(arena_t *arena, arena_run_t *run, bool dirty,\n    bool cleaned, bool decommitted);\nstatic void\tarena_dalloc_bin_run(arena_t *arena, arena_chunk_t *chunk,\n    arena_run_t *run, arena_bin_t *bin);\nstatic void\tarena_bin_lower_run(arena_t *arena, arena_chunk_t *chunk,\n    arena_run_t *run, arena_bin_t *bin);\n\n/******************************************************************************/\n\nJEMALLOC_INLINE_C size_t\narena_miscelm_size_get(const arena_chunk_map_misc_t *miscelm)\n{\n\tarena_chunk_t *chunk;\n\tsize_t pageind, mapbits;\n\n\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(miscelm);\n\tpageind = arena_miscelm_to_pageind(miscelm);\n\tmapbits = arena_mapbits_get(chunk, pageind);\n\treturn (arena_mapbits_size_decode(mapbits));\n}\n\nJEMALLOC_INLINE_C int\narena_run_addr_comp(const arena_chunk_map_misc_t *a,\n    const arena_chunk_map_misc_t *b)\n{\n\tuintptr_t a_miscelm = (uintptr_t)a;\n\tuintptr_t b_miscelm = (uintptr_t)b;\n\n\tassert(a != NULL);\n\tassert(b != NULL);\n\n\treturn ((a_miscelm > b_miscelm) - (a_miscelm < b_miscelm));\n}\n\n/* Generate red-black tree functions. */\nrb_gen(static UNUSED, arena_run_tree_, arena_run_tree_t, arena_chunk_map_misc_t,\n    rb_link, arena_run_addr_comp)\n\nstatic size_t\nrun_quantize_floor_compute(size_t size)\n{\n\tsize_t qsize;\n\n\tassert(size != 0);\n\tassert(size == PAGE_CEILING(size));\n\n\t/* Don't change sizes that are valid small run sizes. */\n\tif (size <= small_maxrun && small_run_tab[size >> LG_PAGE])\n\t\treturn (size);\n\n\t/*\n\t * Round down to the nearest run size that can actually be requested\n\t * during normal large allocation.  Add large_pad so that cache index\n\t * randomization can offset the allocation from the page boundary.\n\t */\n\tqsize = index2size(size2index(size - large_pad + 1) - 1) + large_pad;\n\tif (qsize <= SMALL_MAXCLASS + large_pad)\n\t\treturn (run_quantize_floor_compute(size - large_pad));\n\tassert(qsize <= size);\n\treturn (qsize);\n}\n\nstatic size_t\nrun_quantize_ceil_compute_hard(size_t size)\n{\n\tsize_t large_run_size_next;\n\n\tassert(size != 0);\n\tassert(size == PAGE_CEILING(size));\n\n\t/*\n\t * Return the next quantized size greater than the input size.\n\t * Quantized sizes comprise the union of run sizes that back small\n\t * region runs, and run sizes that back large regions with no explicit\n\t * alignment constraints.\n\t */\n\n\tif (size > SMALL_MAXCLASS) {\n\t\tlarge_run_size_next = PAGE_CEILING(index2size(size2index(size -\n\t\t    large_pad) + 1) + large_pad);\n\t} else\n\t\tlarge_run_size_next = SIZE_T_MAX;\n\tif (size >= small_maxrun)\n\t\treturn (large_run_size_next);\n\n\twhile (true) {\n\t\tsize += PAGE;\n\t\tassert(size <= small_maxrun);\n\t\tif (small_run_tab[size >> LG_PAGE]) {\n\t\t\tif (large_run_size_next < size)\n\t\t\t\treturn (large_run_size_next);\n\t\t\treturn (size);\n\t\t}\n\t}\n}\n\nstatic size_t\nrun_quantize_ceil_compute(size_t size)\n{\n\tsize_t qsize = run_quantize_floor_compute(size);\n\n\tif (qsize < size) {\n\t\t/*\n\t\t * Skip a quantization that may have an adequately large run,\n\t\t * because under-sized runs may be mixed in.  This only happens\n\t\t * when an unusual size is requested, i.e. for aligned\n\t\t * allocation, and is just one of several places where linear\n\t\t * search would potentially find sufficiently aligned available\n\t\t * memory somewhere lower.\n\t\t */\n\t\tqsize = run_quantize_ceil_compute_hard(qsize);\n\t}\n\treturn (qsize);\n}\n\n#ifdef JEMALLOC_JET\n#undef run_quantize_floor\n#define\trun_quantize_floor JEMALLOC_N(run_quantize_floor_impl)\n#endif\nstatic size_t\nrun_quantize_floor(size_t size)\n{\n\tsize_t ret;\n\n\tassert(size > 0);\n\tassert(size <= run_quantize_max);\n\tassert((size & PAGE_MASK) == 0);\n\n\tret = run_quantize_floor_tab[(size >> LG_PAGE) - 1];\n\tassert(ret == run_quantize_floor_compute(size));\n\treturn (ret);\n}\n#ifdef JEMALLOC_JET\n#undef run_quantize_floor\n#define\trun_quantize_floor JEMALLOC_N(run_quantize_floor)\nrun_quantize_t *run_quantize_floor = JEMALLOC_N(run_quantize_floor_impl);\n#endif\n\n#ifdef JEMALLOC_JET\n#undef run_quantize_ceil\n#define\trun_quantize_ceil JEMALLOC_N(run_quantize_ceil_impl)\n#endif\nstatic size_t\nrun_quantize_ceil(size_t size)\n{\n\tsize_t ret;\n\n\tassert(size > 0);\n\tassert(size <= run_quantize_max);\n\tassert((size & PAGE_MASK) == 0);\n\n\tret = run_quantize_ceil_tab[(size >> LG_PAGE) - 1];\n\tassert(ret == run_quantize_ceil_compute(size));\n\treturn (ret);\n}\n#ifdef JEMALLOC_JET\n#undef run_quantize_ceil\n#define\trun_quantize_ceil JEMALLOC_N(run_quantize_ceil)\nrun_quantize_t *run_quantize_ceil = JEMALLOC_N(run_quantize_ceil_impl);\n#endif\n\nstatic arena_run_tree_t *\narena_runs_avail_get(arena_t *arena, szind_t ind)\n{\n\n\tassert(ind >= runs_avail_bias);\n\tassert(ind - runs_avail_bias < runs_avail_nclasses);\n\n\treturn (&arena->runs_avail[ind - runs_avail_bias]);\n}\n\nstatic void\narena_avail_insert(arena_t *arena, arena_chunk_t *chunk, size_t pageind,\n    size_t npages)\n{\n\tszind_t ind = size2index(run_quantize_floor(arena_miscelm_size_get(\n\t    arena_miscelm_get(chunk, pageind))));\n\tassert(npages == (arena_mapbits_unallocated_size_get(chunk, pageind) >>\n\t    LG_PAGE));\n\tarena_run_tree_insert(arena_runs_avail_get(arena, ind),\n\t    arena_miscelm_get(chunk, pageind));\n}\n\nstatic void\narena_avail_remove(arena_t *arena, arena_chunk_t *chunk, size_t pageind,\n    size_t npages)\n{\n\tszind_t ind = size2index(run_quantize_floor(arena_miscelm_size_get(\n\t    arena_miscelm_get(chunk, pageind))));\n\tassert(npages == (arena_mapbits_unallocated_size_get(chunk, pageind) >>\n\t    LG_PAGE));\n\tarena_run_tree_remove(arena_runs_avail_get(arena, ind),\n\t    arena_miscelm_get(chunk, pageind));\n}\n\nstatic void\narena_run_dirty_insert(arena_t *arena, arena_chunk_t *chunk, size_t pageind,\n    size_t npages)\n{\n\tarena_chunk_map_misc_t *miscelm = arena_miscelm_get(chunk, pageind);\n\n\tassert(npages == (arena_mapbits_unallocated_size_get(chunk, pageind) >>\n\t    LG_PAGE));\n\tassert(arena_mapbits_dirty_get(chunk, pageind) == CHUNK_MAP_DIRTY);\n\tassert(arena_mapbits_dirty_get(chunk, pageind+npages-1) ==\n\t    CHUNK_MAP_DIRTY);\n\n\tqr_new(&miscelm->rd, rd_link);\n\tqr_meld(&arena->runs_dirty, &miscelm->rd, rd_link);\n\tarena->ndirty += npages;\n}\n\nstatic void\narena_run_dirty_remove(arena_t *arena, arena_chunk_t *chunk, size_t pageind,\n    size_t npages)\n{\n\tarena_chunk_map_misc_t *miscelm = arena_miscelm_get(chunk, pageind);\n\n\tassert(npages == (arena_mapbits_unallocated_size_get(chunk, pageind) >>\n\t    LG_PAGE));\n\tassert(arena_mapbits_dirty_get(chunk, pageind) == CHUNK_MAP_DIRTY);\n\tassert(arena_mapbits_dirty_get(chunk, pageind+npages-1) ==\n\t    CHUNK_MAP_DIRTY);\n\n\tqr_remove(&miscelm->rd, rd_link);\n\tassert(arena->ndirty >= npages);\n\tarena->ndirty -= npages;\n}\n\nstatic size_t\narena_chunk_dirty_npages(const extent_node_t *node)\n{\n\n\treturn (extent_node_size_get(node) >> LG_PAGE);\n}\n\nvoid\narena_chunk_cache_maybe_insert(arena_t *arena, extent_node_t *node, bool cache)\n{\n\n\tif (cache) {\n\t\textent_node_dirty_linkage_init(node);\n\t\textent_node_dirty_insert(node, &arena->runs_dirty,\n\t\t    &arena->chunks_cache);\n\t\tarena->ndirty += arena_chunk_dirty_npages(node);\n\t}\n}\n\nvoid\narena_chunk_cache_maybe_remove(arena_t *arena, extent_node_t *node, bool dirty)\n{\n\n\tif (dirty) {\n\t\textent_node_dirty_remove(node);\n\t\tassert(arena->ndirty >= arena_chunk_dirty_npages(node));\n\t\tarena->ndirty -= arena_chunk_dirty_npages(node);\n\t}\n}\n\nJEMALLOC_INLINE_C void *\narena_run_reg_alloc(arena_run_t *run, arena_bin_info_t *bin_info)\n{\n\tvoid *ret;\n\tsize_t regind;\n\tarena_chunk_map_misc_t *miscelm;\n\tvoid *rpages;\n\n\tassert(run->nfree > 0);\n\tassert(!bitmap_full(run->bitmap, &bin_info->bitmap_info));\n\n\tregind = (unsigned)bitmap_sfu(run->bitmap, &bin_info->bitmap_info);\n\tmiscelm = arena_run_to_miscelm(run);\n\trpages = arena_miscelm_to_rpages(miscelm);\n\tret = (void *)((uintptr_t)rpages + (uintptr_t)bin_info->reg0_offset +\n\t    (uintptr_t)(bin_info->reg_interval * regind));\n\trun->nfree--;\n\treturn (ret);\n}\n\nJEMALLOC_INLINE_C void\narena_run_reg_dalloc(arena_run_t *run, void *ptr)\n{\n\tarena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);\n\tsize_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;\n\tsize_t mapbits = arena_mapbits_get(chunk, pageind);\n\tszind_t binind = arena_ptr_small_binind_get(ptr, mapbits);\n\tarena_bin_info_t *bin_info = &arena_bin_info[binind];\n\tsize_t regind = arena_run_regind(run, bin_info, ptr);\n\n\tassert(run->nfree < bin_info->nregs);\n\t/* Freeing an interior pointer can cause assertion failure. */\n\tassert(((uintptr_t)ptr -\n\t    ((uintptr_t)arena_miscelm_to_rpages(arena_run_to_miscelm(run)) +\n\t    (uintptr_t)bin_info->reg0_offset)) %\n\t    (uintptr_t)bin_info->reg_interval == 0);\n\tassert((uintptr_t)ptr >=\n\t    (uintptr_t)arena_miscelm_to_rpages(arena_run_to_miscelm(run)) +\n\t    (uintptr_t)bin_info->reg0_offset);\n\t/* Freeing an unallocated pointer can cause assertion failure. */\n\tassert(bitmap_get(run->bitmap, &bin_info->bitmap_info, regind));\n\n\tbitmap_unset(run->bitmap, &bin_info->bitmap_info, regind);\n\trun->nfree++;\n}\n\nJEMALLOC_INLINE_C void\narena_run_zero(arena_chunk_t *chunk, size_t run_ind, size_t npages)\n{\n\n\tJEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED((void *)((uintptr_t)chunk +\n\t    (run_ind << LG_PAGE)), (npages << LG_PAGE));\n\tmemset((void *)((uintptr_t)chunk + (run_ind << LG_PAGE)), 0,\n\t    (npages << LG_PAGE));\n}\n\nJEMALLOC_INLINE_C void\narena_run_page_mark_zeroed(arena_chunk_t *chunk, size_t run_ind)\n{\n\n\tJEMALLOC_VALGRIND_MAKE_MEM_DEFINED((void *)((uintptr_t)chunk + (run_ind\n\t    << LG_PAGE)), PAGE);\n}\n\nJEMALLOC_INLINE_C void\narena_run_page_validate_zeroed(arena_chunk_t *chunk, size_t run_ind)\n{\n\tsize_t i;\n\tUNUSED size_t *p = (size_t *)((uintptr_t)chunk + (run_ind << LG_PAGE));\n\n\tarena_run_page_mark_zeroed(chunk, run_ind);\n\tfor (i = 0; i < PAGE / sizeof(size_t); i++)\n\t\tassert(p[i] == 0);\n}\n\nstatic void\narena_nactive_add(arena_t *arena, size_t add_pages)\n{\n\n\tif (config_stats) {\n\t\tsize_t cactive_add = CHUNK_CEILING((arena->nactive +\n\t\t    add_pages) << LG_PAGE) - CHUNK_CEILING(arena->nactive <<\n\t\t    LG_PAGE);\n\t\tif (cactive_add != 0)\n\t\t\tstats_cactive_add(cactive_add);\n\t}\n\tarena->nactive += add_pages;\n}\n\nstatic void\narena_nactive_sub(arena_t *arena, size_t sub_pages)\n{\n\n\tif (config_stats) {\n\t\tsize_t cactive_sub = CHUNK_CEILING(arena->nactive << LG_PAGE) -\n\t\t    CHUNK_CEILING((arena->nactive - sub_pages) << LG_PAGE);\n\t\tif (cactive_sub != 0)\n\t\t\tstats_cactive_sub(cactive_sub);\n\t}\n\tarena->nactive -= sub_pages;\n}\n\nstatic void\narena_run_split_remove(arena_t *arena, arena_chunk_t *chunk, size_t run_ind,\n    size_t flag_dirty, size_t flag_decommitted, size_t need_pages)\n{\n\tsize_t total_pages, rem_pages;\n\n\tassert(flag_dirty == 0 || flag_decommitted == 0);\n\n\ttotal_pages = arena_mapbits_unallocated_size_get(chunk, run_ind) >>\n\t    LG_PAGE;\n\tassert(arena_mapbits_dirty_get(chunk, run_ind+total_pages-1) ==\n\t    flag_dirty);\n\tassert(need_pages <= total_pages);\n\trem_pages = total_pages - need_pages;\n\n\tarena_avail_remove(arena, chunk, run_ind, total_pages);\n\tif (flag_dirty != 0)\n\t\tarena_run_dirty_remove(arena, chunk, run_ind, total_pages);\n\tarena_nactive_add(arena, need_pages);\n\n\t/* Keep track of trailing unused pages for later use. */\n\tif (rem_pages > 0) {\n\t\tsize_t flags = flag_dirty | flag_decommitted;\n\t\tsize_t flag_unzeroed_mask = (flags == 0) ?  CHUNK_MAP_UNZEROED :\n\t\t    0;\n\n\t\tarena_mapbits_unallocated_set(chunk, run_ind+need_pages,\n\t\t    (rem_pages << LG_PAGE), flags |\n\t\t    (arena_mapbits_unzeroed_get(chunk, run_ind+need_pages) &\n\t\t    flag_unzeroed_mask));\n\t\tarena_mapbits_unallocated_set(chunk, run_ind+total_pages-1,\n\t\t    (rem_pages << LG_PAGE), flags |\n\t\t    (arena_mapbits_unzeroed_get(chunk, run_ind+total_pages-1) &\n\t\t    flag_unzeroed_mask));\n\t\tif (flag_dirty != 0) {\n\t\t\tarena_run_dirty_insert(arena, chunk, run_ind+need_pages,\n\t\t\t    rem_pages);\n\t\t}\n\t\tarena_avail_insert(arena, chunk, run_ind+need_pages, rem_pages);\n\t}\n}\n\nstatic bool\narena_run_split_large_helper(arena_t *arena, arena_run_t *run, size_t size,\n    bool remove, bool zero)\n{\n\tarena_chunk_t *chunk;\n\tarena_chunk_map_misc_t *miscelm;\n\tsize_t flag_dirty, flag_decommitted, run_ind, need_pages;\n\tsize_t flag_unzeroed_mask;\n\n\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);\n\tmiscelm = arena_run_to_miscelm(run);\n\trun_ind = arena_miscelm_to_pageind(miscelm);\n\tflag_dirty = arena_mapbits_dirty_get(chunk, run_ind);\n\tflag_decommitted = arena_mapbits_decommitted_get(chunk, run_ind);\n\tneed_pages = (size >> LG_PAGE);\n\tassert(need_pages > 0);\n\n\tif (flag_decommitted != 0 && arena->chunk_hooks.commit(chunk, chunksize,\n\t    run_ind << LG_PAGE, size, arena->ind))\n\t\treturn (true);\n\n\tif (remove) {\n\t\tarena_run_split_remove(arena, chunk, run_ind, flag_dirty,\n\t\t    flag_decommitted, need_pages);\n\t}\n\n\tif (zero) {\n\t\tif (flag_decommitted != 0) {\n\t\t\t/* The run is untouched, and therefore zeroed. */\n\t\t\tJEMALLOC_VALGRIND_MAKE_MEM_DEFINED((void\n\t\t\t    *)((uintptr_t)chunk + (run_ind << LG_PAGE)),\n\t\t\t    (need_pages << LG_PAGE));\n\t\t} else if (flag_dirty != 0) {\n\t\t\t/* The run is dirty, so all pages must be zeroed. */\n\t\t\tarena_run_zero(chunk, run_ind, need_pages);\n\t\t} else {\n\t\t\t/*\n\t\t\t * The run is clean, so some pages may be zeroed (i.e.\n\t\t\t * never before touched).\n\t\t\t */\n\t\t\tsize_t i;\n\t\t\tfor (i = 0; i < need_pages; i++) {\n\t\t\t\tif (arena_mapbits_unzeroed_get(chunk, run_ind+i)\n\t\t\t\t    != 0)\n\t\t\t\t\tarena_run_zero(chunk, run_ind+i, 1);\n\t\t\t\telse if (config_debug) {\n\t\t\t\t\tarena_run_page_validate_zeroed(chunk,\n\t\t\t\t\t    run_ind+i);\n\t\t\t\t} else {\n\t\t\t\t\tarena_run_page_mark_zeroed(chunk,\n\t\t\t\t\t    run_ind+i);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tJEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED((void *)((uintptr_t)chunk +\n\t\t    (run_ind << LG_PAGE)), (need_pages << LG_PAGE));\n\t}\n\n\t/*\n\t * Set the last element first, in case the run only contains one page\n\t * (i.e. both statements set the same element).\n\t */\n\tflag_unzeroed_mask = (flag_dirty | flag_decommitted) == 0 ?\n\t    CHUNK_MAP_UNZEROED : 0;\n\tarena_mapbits_large_set(chunk, run_ind+need_pages-1, 0, flag_dirty |\n\t    (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk,\n\t    run_ind+need_pages-1)));\n\tarena_mapbits_large_set(chunk, run_ind, size, flag_dirty |\n\t    (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, run_ind)));\n\treturn (false);\n}\n\nstatic bool\narena_run_split_large(arena_t *arena, arena_run_t *run, size_t size, bool zero)\n{\n\n\treturn (arena_run_split_large_helper(arena, run, size, true, zero));\n}\n\nstatic bool\narena_run_init_large(arena_t *arena, arena_run_t *run, size_t size, bool zero)\n{\n\n\treturn (arena_run_split_large_helper(arena, run, size, false, zero));\n}\n\nstatic bool\narena_run_split_small(arena_t *arena, arena_run_t *run, size_t size,\n    szind_t binind)\n{\n\tarena_chunk_t *chunk;\n\tarena_chunk_map_misc_t *miscelm;\n\tsize_t flag_dirty, flag_decommitted, run_ind, need_pages, i;\n\n\tassert(binind != BININD_INVALID);\n\n\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);\n\tmiscelm = arena_run_to_miscelm(run);\n\trun_ind = arena_miscelm_to_pageind(miscelm);\n\tflag_dirty = arena_mapbits_dirty_get(chunk, run_ind);\n\tflag_decommitted = arena_mapbits_decommitted_get(chunk, run_ind);\n\tneed_pages = (size >> LG_PAGE);\n\tassert(need_pages > 0);\n\n\tif (flag_decommitted != 0 && arena->chunk_hooks.commit(chunk, chunksize,\n\t    run_ind << LG_PAGE, size, arena->ind))\n\t\treturn (true);\n\n\tarena_run_split_remove(arena, chunk, run_ind, flag_dirty,\n\t    flag_decommitted, need_pages);\n\n\tfor (i = 0; i < need_pages; i++) {\n\t\tsize_t flag_unzeroed = arena_mapbits_unzeroed_get(chunk,\n\t\t    run_ind+i);\n\t\tarena_mapbits_small_set(chunk, run_ind+i, i, binind,\n\t\t    flag_unzeroed);\n\t\tif (config_debug && flag_dirty == 0 && flag_unzeroed == 0)\n\t\t\tarena_run_page_validate_zeroed(chunk, run_ind+i);\n\t}\n\tJEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED((void *)((uintptr_t)chunk +\n\t    (run_ind << LG_PAGE)), (need_pages << LG_PAGE));\n\treturn (false);\n}\n\nstatic arena_chunk_t *\narena_chunk_init_spare(arena_t *arena)\n{\n\tarena_chunk_t *chunk;\n\n\tassert(arena->spare != NULL);\n\n\tchunk = arena->spare;\n\tarena->spare = NULL;\n\n\tassert(arena_mapbits_allocated_get(chunk, map_bias) == 0);\n\tassert(arena_mapbits_allocated_get(chunk, chunk_npages-1) == 0);\n\tassert(arena_mapbits_unallocated_size_get(chunk, map_bias) ==\n\t    arena_maxrun);\n\tassert(arena_mapbits_unallocated_size_get(chunk, chunk_npages-1) ==\n\t    arena_maxrun);\n\tassert(arena_mapbits_dirty_get(chunk, map_bias) ==\n\t    arena_mapbits_dirty_get(chunk, chunk_npages-1));\n\n\treturn (chunk);\n}\n\nstatic bool\narena_chunk_register(arena_t *arena, arena_chunk_t *chunk, bool zero)\n{\n\n\t/*\n\t * The extent node notion of \"committed\" doesn't directly apply to\n\t * arena chunks.  Arbitrarily mark them as committed.  The commit state\n\t * of runs is tracked individually, and upon chunk deallocation the\n\t * entire chunk is in a consistent commit state.\n\t */\n\textent_node_init(&chunk->node, arena, chunk, chunksize, zero, true);\n\textent_node_achunk_set(&chunk->node, true);\n\treturn (chunk_register(chunk, &chunk->node));\n}\n\nstatic arena_chunk_t *\narena_chunk_alloc_internal_hard(arena_t *arena, chunk_hooks_t *chunk_hooks,\n    bool *zero, bool *commit)\n{\n\tarena_chunk_t *chunk;\n\n\tmalloc_mutex_unlock(&arena->lock);\n\n\tchunk = (arena_chunk_t *)chunk_alloc_wrapper(arena, chunk_hooks, NULL,\n\t    chunksize, chunksize, zero, commit);\n\tif (chunk != NULL && !*commit) {\n\t\t/* Commit header. */\n\t\tif (chunk_hooks->commit(chunk, chunksize, 0, map_bias <<\n\t\t    LG_PAGE, arena->ind)) {\n\t\t\tchunk_dalloc_wrapper(arena, chunk_hooks,\n\t\t\t    (void *)chunk, chunksize, *commit);\n\t\t\tchunk = NULL;\n\t\t}\n\t}\n\tif (chunk != NULL && arena_chunk_register(arena, chunk, *zero)) {\n\t\tif (!*commit) {\n\t\t\t/* Undo commit of header. */\n\t\t\tchunk_hooks->decommit(chunk, chunksize, 0, map_bias <<\n\t\t\t    LG_PAGE, arena->ind);\n\t\t}\n\t\tchunk_dalloc_wrapper(arena, chunk_hooks, (void *)chunk,\n\t\t    chunksize, *commit);\n\t\tchunk = NULL;\n\t}\n\n\tmalloc_mutex_lock(&arena->lock);\n\treturn (chunk);\n}\n\nstatic arena_chunk_t *\narena_chunk_alloc_internal(arena_t *arena, bool *zero, bool *commit)\n{\n\tarena_chunk_t *chunk;\n\tchunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER;\n\n\tchunk = chunk_alloc_cache(arena, &chunk_hooks, NULL, chunksize,\n\t    chunksize, zero, true);\n\tif (chunk != NULL) {\n\t\tif (arena_chunk_register(arena, chunk, *zero)) {\n\t\t\tchunk_dalloc_cache(arena, &chunk_hooks, chunk,\n\t\t\t    chunksize, true);\n\t\t\treturn (NULL);\n\t\t}\n\t\t*commit = true;\n\t}\n\tif (chunk == NULL) {\n\t\tchunk = arena_chunk_alloc_internal_hard(arena, &chunk_hooks,\n\t\t    zero, commit);\n\t}\n\n\tif (config_stats && chunk != NULL) {\n\t\tarena->stats.mapped += chunksize;\n\t\tarena->stats.metadata_mapped += (map_bias << LG_PAGE);\n\t}\n\n\treturn (chunk);\n}\n\nstatic arena_chunk_t *\narena_chunk_init_hard(arena_t *arena)\n{\n\tarena_chunk_t *chunk;\n\tbool zero, commit;\n\tsize_t flag_unzeroed, flag_decommitted, i;\n\n\tassert(arena->spare == NULL);\n\n\tzero = false;\n\tcommit = false;\n\tchunk = arena_chunk_alloc_internal(arena, &zero, &commit);\n\tif (chunk == NULL)\n\t\treturn (NULL);\n\n\t/*\n\t * Initialize the map to contain one maximal free untouched run.  Mark\n\t * the pages as zeroed if chunk_alloc() returned a zeroed or decommitted\n\t * chunk.\n\t */\n\tflag_unzeroed = (zero || !commit) ? 0 : CHUNK_MAP_UNZEROED;\n\tflag_decommitted = commit ? 0 : CHUNK_MAP_DECOMMITTED;\n\tarena_mapbits_unallocated_set(chunk, map_bias, arena_maxrun,\n\t    flag_unzeroed | flag_decommitted);\n\t/*\n\t * There is no need to initialize the internal page map entries unless\n\t * the chunk is not zeroed.\n\t */\n\tif (!zero) {\n\t\tJEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(\n\t\t    (void *)arena_bitselm_get(chunk, map_bias+1),\n\t\t    (size_t)((uintptr_t) arena_bitselm_get(chunk,\n\t\t    chunk_npages-1) - (uintptr_t)arena_bitselm_get(chunk,\n\t\t    map_bias+1)));\n\t\tfor (i = map_bias+1; i < chunk_npages-1; i++)\n\t\t\tarena_mapbits_internal_set(chunk, i, flag_unzeroed);\n\t} else {\n\t\tJEMALLOC_VALGRIND_MAKE_MEM_DEFINED((void\n\t\t    *)arena_bitselm_get(chunk, map_bias+1), (size_t)((uintptr_t)\n\t\t    arena_bitselm_get(chunk, chunk_npages-1) -\n\t\t    (uintptr_t)arena_bitselm_get(chunk, map_bias+1)));\n\t\tif (config_debug) {\n\t\t\tfor (i = map_bias+1; i < chunk_npages-1; i++) {\n\t\t\t\tassert(arena_mapbits_unzeroed_get(chunk, i) ==\n\t\t\t\t    flag_unzeroed);\n\t\t\t}\n\t\t}\n\t}\n\tarena_mapbits_unallocated_set(chunk, chunk_npages-1, arena_maxrun,\n\t    flag_unzeroed);\n\n\treturn (chunk);\n}\n\nstatic arena_chunk_t *\narena_chunk_alloc(arena_t *arena)\n{\n\tarena_chunk_t *chunk;\n\n\tif (arena->spare != NULL)\n\t\tchunk = arena_chunk_init_spare(arena);\n\telse {\n\t\tchunk = arena_chunk_init_hard(arena);\n\t\tif (chunk == NULL)\n\t\t\treturn (NULL);\n\t}\n\n\tarena_avail_insert(arena, chunk, map_bias, chunk_npages-map_bias);\n\n\treturn (chunk);\n}\n\nstatic void\narena_chunk_dalloc(arena_t *arena, arena_chunk_t *chunk)\n{\n\n\tassert(arena_mapbits_allocated_get(chunk, map_bias) == 0);\n\tassert(arena_mapbits_allocated_get(chunk, chunk_npages-1) == 0);\n\tassert(arena_mapbits_unallocated_size_get(chunk, map_bias) ==\n\t    arena_maxrun);\n\tassert(arena_mapbits_unallocated_size_get(chunk, chunk_npages-1) ==\n\t    arena_maxrun);\n\tassert(arena_mapbits_dirty_get(chunk, map_bias) ==\n\t    arena_mapbits_dirty_get(chunk, chunk_npages-1));\n\tassert(arena_mapbits_decommitted_get(chunk, map_bias) ==\n\t    arena_mapbits_decommitted_get(chunk, chunk_npages-1));\n\n\t/* Remove run from runs_avail, so that the arena does not use it. */\n\tarena_avail_remove(arena, chunk, map_bias, chunk_npages-map_bias);\n\n\tif (arena->spare != NULL) {\n\t\tarena_chunk_t *spare = arena->spare;\n\t\tchunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER;\n\t\tbool committed;\n\n\t\tarena->spare = chunk;\n\t\tif (arena_mapbits_dirty_get(spare, map_bias) != 0) {\n\t\t\tarena_run_dirty_remove(arena, spare, map_bias,\n\t\t\t    chunk_npages-map_bias);\n\t\t}\n\n\t\tchunk_deregister(spare, &spare->node);\n\n\t\tcommitted = (arena_mapbits_decommitted_get(spare, map_bias) ==\n\t\t    0);\n\t\tif (!committed) {\n\t\t\t/*\n\t\t\t * Decommit the header.  Mark the chunk as decommitted\n\t\t\t * even if header decommit fails, since treating a\n\t\t\t * partially committed chunk as committed has a high\n\t\t\t * potential for causing later access of decommitted\n\t\t\t * memory.\n\t\t\t */\n\t\t\tchunk_hooks = chunk_hooks_get(arena);\n\t\t\tchunk_hooks.decommit(spare, chunksize, 0, map_bias <<\n\t\t\t    LG_PAGE, arena->ind);\n\t\t}\n\n\t\tchunk_dalloc_cache(arena, &chunk_hooks, (void *)spare,\n\t\t    chunksize, committed);\n\n\t\tif (config_stats) {\n\t\t\tarena->stats.mapped -= chunksize;\n\t\t\tarena->stats.metadata_mapped -= (map_bias << LG_PAGE);\n\t\t}\n\t} else\n\t\tarena->spare = chunk;\n}\n\nstatic void\narena_huge_malloc_stats_update(arena_t *arena, size_t usize)\n{\n\tszind_t index = size2index(usize) - nlclasses - NBINS;\n\n\tcassert(config_stats);\n\n\tarena->stats.nmalloc_huge++;\n\tarena->stats.allocated_huge += usize;\n\tarena->stats.hstats[index].nmalloc++;\n\tarena->stats.hstats[index].curhchunks++;\n}\n\nstatic void\narena_huge_malloc_stats_update_undo(arena_t *arena, size_t usize)\n{\n\tszind_t index = size2index(usize) - nlclasses - NBINS;\n\n\tcassert(config_stats);\n\n\tarena->stats.nmalloc_huge--;\n\tarena->stats.allocated_huge -= usize;\n\tarena->stats.hstats[index].nmalloc--;\n\tarena->stats.hstats[index].curhchunks--;\n}\n\nstatic void\narena_huge_dalloc_stats_update(arena_t *arena, size_t usize)\n{\n\tszind_t index = size2index(usize) - nlclasses - NBINS;\n\n\tcassert(config_stats);\n\n\tarena->stats.ndalloc_huge++;\n\tarena->stats.allocated_huge -= usize;\n\tarena->stats.hstats[index].ndalloc++;\n\tarena->stats.hstats[index].curhchunks--;\n}\n\nstatic void\narena_huge_dalloc_stats_update_undo(arena_t *arena, size_t usize)\n{\n\tszind_t index = size2index(usize) - nlclasses - NBINS;\n\n\tcassert(config_stats);\n\n\tarena->stats.ndalloc_huge--;\n\tarena->stats.allocated_huge += usize;\n\tarena->stats.hstats[index].ndalloc--;\n\tarena->stats.hstats[index].curhchunks++;\n}\n\nstatic void\narena_huge_ralloc_stats_update(arena_t *arena, size_t oldsize, size_t usize)\n{\n\n\tarena_huge_dalloc_stats_update(arena, oldsize);\n\tarena_huge_malloc_stats_update(arena, usize);\n}\n\nstatic void\narena_huge_ralloc_stats_update_undo(arena_t *arena, size_t oldsize,\n    size_t usize)\n{\n\n\tarena_huge_dalloc_stats_update_undo(arena, oldsize);\n\tarena_huge_malloc_stats_update_undo(arena, usize);\n}\n\nextent_node_t *\narena_node_alloc(arena_t *arena)\n{\n\textent_node_t *node;\n\n\tmalloc_mutex_lock(&arena->node_cache_mtx);\n\tnode = ql_last(&arena->node_cache, ql_link);\n\tif (node == NULL) {\n\t\tmalloc_mutex_unlock(&arena->node_cache_mtx);\n\t\treturn (base_alloc(sizeof(extent_node_t)));\n\t}\n\tql_tail_remove(&arena->node_cache, extent_node_t, ql_link);\n\tmalloc_mutex_unlock(&arena->node_cache_mtx);\n\treturn (node);\n}\n\nvoid\narena_node_dalloc(arena_t *arena, extent_node_t *node)\n{\n\n\tmalloc_mutex_lock(&arena->node_cache_mtx);\n\tql_elm_new(node, ql_link);\n\tql_tail_insert(&arena->node_cache, node, ql_link);\n\tmalloc_mutex_unlock(&arena->node_cache_mtx);\n}\n\nstatic void *\narena_chunk_alloc_huge_hard(arena_t *arena, chunk_hooks_t *chunk_hooks,\n    size_t usize, size_t alignment, bool *zero, size_t csize)\n{\n\tvoid *ret;\n\tbool commit = true;\n\n\tret = chunk_alloc_wrapper(arena, chunk_hooks, NULL, csize, alignment,\n\t    zero, &commit);\n\tif (ret == NULL) {\n\t\t/* Revert optimistic stats updates. */\n\t\tmalloc_mutex_lock(&arena->lock);\n\t\tif (config_stats) {\n\t\t\tarena_huge_malloc_stats_update_undo(arena, usize);\n\t\t\tarena->stats.mapped -= usize;\n\t\t}\n\t\tarena_nactive_sub(arena, usize >> LG_PAGE);\n\t\tmalloc_mutex_unlock(&arena->lock);\n\t}\n\n\treturn (ret);\n}\n\nvoid *\narena_chunk_alloc_huge(arena_t *arena, size_t usize, size_t alignment,\n    bool *zero)\n{\n\tvoid *ret;\n\tchunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER;\n\tsize_t csize = CHUNK_CEILING(usize);\n\n\tmalloc_mutex_lock(&arena->lock);\n\n\t/* Optimistically update stats. */\n\tif (config_stats) {\n\t\tarena_huge_malloc_stats_update(arena, usize);\n\t\tarena->stats.mapped += usize;\n\t}\n\tarena_nactive_add(arena, usize >> LG_PAGE);\n\n\tret = chunk_alloc_cache(arena, &chunk_hooks, NULL, csize, alignment,\n\t    zero, true);\n\tmalloc_mutex_unlock(&arena->lock);\n\tif (ret == NULL) {\n\t\tret = arena_chunk_alloc_huge_hard(arena, &chunk_hooks, usize,\n\t\t    alignment, zero, csize);\n\t}\n\n\treturn (ret);\n}\n\nvoid\narena_chunk_dalloc_huge(arena_t *arena, void *chunk, size_t usize)\n{\n\tchunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER;\n\tsize_t csize;\n\n\tcsize = CHUNK_CEILING(usize);\n\tmalloc_mutex_lock(&arena->lock);\n\tif (config_stats) {\n\t\tarena_huge_dalloc_stats_update(arena, usize);\n\t\tarena->stats.mapped -= usize;\n\t}\n\tarena_nactive_sub(arena, usize >> LG_PAGE);\n\n\tchunk_dalloc_cache(arena, &chunk_hooks, chunk, csize, true);\n\tmalloc_mutex_unlock(&arena->lock);\n}\n\nvoid\narena_chunk_ralloc_huge_similar(arena_t *arena, void *chunk, size_t oldsize,\n    size_t usize)\n{\n\n\tassert(CHUNK_CEILING(oldsize) == CHUNK_CEILING(usize));\n\tassert(oldsize != usize);\n\n\tmalloc_mutex_lock(&arena->lock);\n\tif (config_stats)\n\t\tarena_huge_ralloc_stats_update(arena, oldsize, usize);\n\tif (oldsize < usize)\n\t\tarena_nactive_add(arena, (usize - oldsize) >> LG_PAGE);\n\telse\n\t\tarena_nactive_sub(arena, (oldsize - usize) >> LG_PAGE);\n\tmalloc_mutex_unlock(&arena->lock);\n}\n\nvoid\narena_chunk_ralloc_huge_shrink(arena_t *arena, void *chunk, size_t oldsize,\n    size_t usize)\n{\n\tsize_t udiff = oldsize - usize;\n\tsize_t cdiff = CHUNK_CEILING(oldsize) - CHUNK_CEILING(usize);\n\n\tmalloc_mutex_lock(&arena->lock);\n\tif (config_stats) {\n\t\tarena_huge_ralloc_stats_update(arena, oldsize, usize);\n\t\tif (cdiff != 0)\n\t\t\tarena->stats.mapped -= cdiff;\n\t}\n\tarena_nactive_sub(arena, udiff >> LG_PAGE);\n\n\tif (cdiff != 0) {\n\t\tchunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER;\n\t\tvoid *nchunk = (void *)((uintptr_t)chunk +\n\t\t    CHUNK_CEILING(usize));\n\n\t\tchunk_dalloc_cache(arena, &chunk_hooks, nchunk, cdiff, true);\n\t}\n\tmalloc_mutex_unlock(&arena->lock);\n}\n\nstatic bool\narena_chunk_ralloc_huge_expand_hard(arena_t *arena, chunk_hooks_t *chunk_hooks,\n    void *chunk, size_t oldsize, size_t usize, bool *zero, void *nchunk,\n    size_t udiff, size_t cdiff)\n{\n\tbool err;\n\tbool commit = true;\n\n\terr = (chunk_alloc_wrapper(arena, chunk_hooks, nchunk, cdiff, chunksize,\n\t    zero, &commit) == NULL);\n\tif (err) {\n\t\t/* Revert optimistic stats updates. */\n\t\tmalloc_mutex_lock(&arena->lock);\n\t\tif (config_stats) {\n\t\t\tarena_huge_ralloc_stats_update_undo(arena, oldsize,\n\t\t\t    usize);\n\t\t\tarena->stats.mapped -= cdiff;\n\t\t}\n\t\tarena_nactive_sub(arena, udiff >> LG_PAGE);\n\t\tmalloc_mutex_unlock(&arena->lock);\n\t} else if (chunk_hooks->merge(chunk, CHUNK_CEILING(oldsize), nchunk,\n\t    cdiff, true, arena->ind)) {\n\t\tchunk_dalloc_arena(arena, chunk_hooks, nchunk, cdiff, *zero,\n\t\t    true);\n\t\terr = true;\n\t}\n\treturn (err);\n}\n\nbool\narena_chunk_ralloc_huge_expand(arena_t *arena, void *chunk, size_t oldsize,\n    size_t usize, bool *zero)\n{\n\tbool err;\n\tchunk_hooks_t chunk_hooks = chunk_hooks_get(arena);\n\tvoid *nchunk = (void *)((uintptr_t)chunk + CHUNK_CEILING(oldsize));\n\tsize_t udiff = usize - oldsize;\n\tsize_t cdiff = CHUNK_CEILING(usize) - CHUNK_CEILING(oldsize);\n\n\tmalloc_mutex_lock(&arena->lock);\n\n\t/* Optimistically update stats. */\n\tif (config_stats) {\n\t\tarena_huge_ralloc_stats_update(arena, oldsize, usize);\n\t\tarena->stats.mapped += cdiff;\n\t}\n\tarena_nactive_add(arena, udiff >> LG_PAGE);\n\n\terr = (chunk_alloc_cache(arena, &arena->chunk_hooks, nchunk, cdiff,\n\t    chunksize, zero, true) == NULL);\n\tmalloc_mutex_unlock(&arena->lock);\n\tif (err) {\n\t\terr = arena_chunk_ralloc_huge_expand_hard(arena, &chunk_hooks,\n\t\t    chunk, oldsize, usize, zero, nchunk, udiff,\n\t\t    cdiff);\n\t} else if (chunk_hooks.merge(chunk, CHUNK_CEILING(oldsize), nchunk,\n\t    cdiff, true, arena->ind)) {\n\t\tchunk_dalloc_arena(arena, &chunk_hooks, nchunk, cdiff, *zero,\n\t\t    true);\n\t\terr = true;\n\t}\n\n\treturn (err);\n}\n\n/*\n * Do first-best-fit run selection, i.e. select the lowest run that best fits.\n * Run sizes are indexed, so not all candidate runs are necessarily exactly the\n * same size.\n */\nstatic arena_run_t *\narena_run_first_best_fit(arena_t *arena, size_t size)\n{\n\tszind_t ind, i;\n\n\tind = size2index(run_quantize_ceil(size));\n\tfor (i = ind; i < runs_avail_nclasses + runs_avail_bias; i++) {\n\t\tarena_chunk_map_misc_t *miscelm = arena_run_tree_first(\n\t\t    arena_runs_avail_get(arena, i));\n\t\tif (miscelm != NULL)\n\t\t\treturn (&miscelm->run);\n\t}\n\n\treturn (NULL);\n}\n\nstatic arena_run_t *\narena_run_alloc_large_helper(arena_t *arena, size_t size, bool zero)\n{\n\tarena_run_t *run = arena_run_first_best_fit(arena, s2u(size));\n\tif (run != NULL) {\n\t\tif (arena_run_split_large(arena, run, size, zero))\n\t\t\trun = NULL;\n\t}\n\treturn (run);\n}\n\nstatic arena_run_t *\narena_run_alloc_large(arena_t *arena, size_t size, bool zero)\n{\n\tarena_chunk_t *chunk;\n\tarena_run_t *run;\n\n\tassert(size <= arena_maxrun);\n\tassert(size == PAGE_CEILING(size));\n\n\t/* Search the arena's chunks for the lowest best fit. */\n\trun = arena_run_alloc_large_helper(arena, size, zero);\n\tif (run != NULL)\n\t\treturn (run);\n\n\t/*\n\t * No usable runs.  Create a new chunk from which to allocate the run.\n\t */\n\tchunk = arena_chunk_alloc(arena);\n\tif (chunk != NULL) {\n\t\trun = &arena_miscelm_get(chunk, map_bias)->run;\n\t\tif (arena_run_split_large(arena, run, size, zero))\n\t\t\trun = NULL;\n\t\treturn (run);\n\t}\n\n\t/*\n\t * arena_chunk_alloc() failed, but another thread may have made\n\t * sufficient memory available while this one dropped arena->lock in\n\t * arena_chunk_alloc(), so search one more time.\n\t */\n\treturn (arena_run_alloc_large_helper(arena, size, zero));\n}\n\nstatic arena_run_t *\narena_run_alloc_small_helper(arena_t *arena, size_t size, szind_t binind)\n{\n\tarena_run_t *run = arena_run_first_best_fit(arena, size);\n\tif (run != NULL) {\n\t\tif (arena_run_split_small(arena, run, size, binind))\n\t\t\trun = NULL;\n\t}\n\treturn (run);\n}\n\nstatic arena_run_t *\narena_run_alloc_small(arena_t *arena, size_t size, szind_t binind)\n{\n\tarena_chunk_t *chunk;\n\tarena_run_t *run;\n\n\tassert(size <= arena_maxrun);\n\tassert(size == PAGE_CEILING(size));\n\tassert(binind != BININD_INVALID);\n\n\t/* Search the arena's chunks for the lowest best fit. */\n\trun = arena_run_alloc_small_helper(arena, size, binind);\n\tif (run != NULL)\n\t\treturn (run);\n\n\t/*\n\t * No usable runs.  Create a new chunk from which to allocate the run.\n\t */\n\tchunk = arena_chunk_alloc(arena);\n\tif (chunk != NULL) {\n\t\trun = &arena_miscelm_get(chunk, map_bias)->run;\n\t\tif (arena_run_split_small(arena, run, size, binind))\n\t\t\trun = NULL;\n\t\treturn (run);\n\t}\n\n\t/*\n\t * arena_chunk_alloc() failed, but another thread may have made\n\t * sufficient memory available while this one dropped arena->lock in\n\t * arena_chunk_alloc(), so search one more time.\n\t */\n\treturn (arena_run_alloc_small_helper(arena, size, binind));\n}\n\nstatic bool\narena_lg_dirty_mult_valid(ssize_t lg_dirty_mult)\n{\n\n\treturn (lg_dirty_mult >= -1 && lg_dirty_mult < (ssize_t)(sizeof(size_t)\n\t    << 3));\n}\n\nssize_t\narena_lg_dirty_mult_get(arena_t *arena)\n{\n\tssize_t lg_dirty_mult;\n\n\tmalloc_mutex_lock(&arena->lock);\n\tlg_dirty_mult = arena->lg_dirty_mult;\n\tmalloc_mutex_unlock(&arena->lock);\n\n\treturn (lg_dirty_mult);\n}\n\nbool\narena_lg_dirty_mult_set(arena_t *arena, ssize_t lg_dirty_mult)\n{\n\n\tif (!arena_lg_dirty_mult_valid(lg_dirty_mult))\n\t\treturn (true);\n\n\tmalloc_mutex_lock(&arena->lock);\n\tarena->lg_dirty_mult = lg_dirty_mult;\n\tarena_maybe_purge(arena);\n\tmalloc_mutex_unlock(&arena->lock);\n\n\treturn (false);\n}\n\nstatic void\narena_decay_deadline_init(arena_t *arena)\n{\n\n\tassert(opt_purge == purge_mode_decay);\n\n\t/*\n\t * Generate a new deadline that is uniformly random within the next\n\t * epoch after the current one.\n\t */\n\tnstime_copy(&arena->decay_deadline, &arena->decay_epoch);\n\tnstime_add(&arena->decay_deadline, &arena->decay_interval);\n\tif (arena->decay_time > 0) {\n\t\tnstime_t jitter;\n\n\t\tnstime_init(&jitter, prng_range(&arena->decay_jitter_state,\n\t\t    nstime_ns(&arena->decay_interval)));\n\t\tnstime_add(&arena->decay_deadline, &jitter);\n\t}\n}\n\nstatic bool\narena_decay_deadline_reached(const arena_t *arena, const nstime_t *time)\n{\n\n\tassert(opt_purge == purge_mode_decay);\n\n\treturn (nstime_compare(&arena->decay_deadline, time) <= 0);\n}\n\nstatic size_t\narena_decay_backlog_npages_limit(const arena_t *arena)\n{\n\tstatic const uint64_t h_steps[] = {\n#define\tSTEP(step, h, x, y) \\\n\t\th,\n\t\tSMOOTHSTEP\n#undef STEP\n\t};\n\tuint64_t sum;\n\tsize_t npages_limit_backlog;\n\tunsigned i;\n\n\tassert(opt_purge == purge_mode_decay);\n\n\t/*\n\t * For each element of decay_backlog, multiply by the corresponding\n\t * fixed-point smoothstep decay factor.  Sum the products, then divide\n\t * to round down to the nearest whole number of pages.\n\t */\n\tsum = 0;\n\tfor (i = 0; i < SMOOTHSTEP_NSTEPS; i++)\n\t\tsum += arena->decay_backlog[i] * h_steps[i];\n\tnpages_limit_backlog = (sum >> SMOOTHSTEP_BFP);\n\n\treturn (npages_limit_backlog);\n}\n\nstatic void\narena_decay_epoch_advance(arena_t *arena, const nstime_t *time)\n{\n\tuint64_t nadvance;\n\tnstime_t delta;\n\tsize_t ndirty_delta;\n\n\tassert(opt_purge == purge_mode_decay);\n\tassert(arena_decay_deadline_reached(arena, time));\n\n\tnstime_copy(&delta, time);\n\tnstime_subtract(&delta, &arena->decay_epoch);\n\tnadvance = nstime_divide(&delta, &arena->decay_interval);\n\tassert(nadvance > 0);\n\n\t/* Add nadvance decay intervals to epoch. */\n\tnstime_copy(&delta, &arena->decay_interval);\n\tnstime_imultiply(&delta, nadvance);\n\tnstime_add(&arena->decay_epoch, &delta);\n\n\t/* Set a new deadline. */\n\tarena_decay_deadline_init(arena);\n\n\t/* Update the backlog. */\n\tif (nadvance >= SMOOTHSTEP_NSTEPS) {\n\t\tmemset(arena->decay_backlog, 0, (SMOOTHSTEP_NSTEPS-1) *\n\t\t    sizeof(size_t));\n\t} else {\n\t\tmemmove(arena->decay_backlog, &arena->decay_backlog[nadvance],\n\t\t    (SMOOTHSTEP_NSTEPS - nadvance) * sizeof(size_t));\n\t\tif (nadvance > 1) {\n\t\t\tmemset(&arena->decay_backlog[SMOOTHSTEP_NSTEPS -\n\t\t\t    nadvance], 0, (nadvance-1) * sizeof(size_t));\n\t\t}\n\t}\n\tndirty_delta = (arena->ndirty > arena->decay_ndirty) ? arena->ndirty -\n\t    arena->decay_ndirty : 0;\n\tarena->decay_ndirty = arena->ndirty;\n\tarena->decay_backlog[SMOOTHSTEP_NSTEPS-1] = ndirty_delta;\n\tarena->decay_backlog_npages_limit =\n\t    arena_decay_backlog_npages_limit(arena);\n}\n\nstatic size_t\narena_decay_npages_limit(arena_t *arena)\n{\n\tsize_t npages_limit;\n\n\tassert(opt_purge == purge_mode_decay);\n\n\tnpages_limit = arena->decay_backlog_npages_limit;\n\n\t/* Add in any dirty pages created during the current epoch. */\n\tif (arena->ndirty > arena->decay_ndirty)\n\t\tnpages_limit += arena->ndirty - arena->decay_ndirty;\n\n\treturn (npages_limit);\n}\n\nstatic void\narena_decay_init(arena_t *arena, ssize_t decay_time)\n{\n\n\tarena->decay_time = decay_time;\n\tif (decay_time > 0) {\n\t\tnstime_init2(&arena->decay_interval, decay_time, 0);\n\t\tnstime_idivide(&arena->decay_interval, SMOOTHSTEP_NSTEPS);\n\t}\n\n\tnstime_init(&arena->decay_epoch, 0);\n\tnstime_update(&arena->decay_epoch);\n\tarena->decay_jitter_state = (uint64_t)(uintptr_t)arena;\n\tarena_decay_deadline_init(arena);\n\tarena->decay_ndirty = arena->ndirty;\n\tarena->decay_backlog_npages_limit = 0;\n\tmemset(arena->decay_backlog, 0, SMOOTHSTEP_NSTEPS * sizeof(size_t));\n}\n\nstatic bool\narena_decay_time_valid(ssize_t decay_time)\n{\n\n\treturn (decay_time >= -1 && decay_time <= NSTIME_SEC_MAX);\n}\n\nssize_t\narena_decay_time_get(arena_t *arena)\n{\n\tssize_t decay_time;\n\n\tmalloc_mutex_lock(&arena->lock);\n\tdecay_time = arena->decay_time;\n\tmalloc_mutex_unlock(&arena->lock);\n\n\treturn (decay_time);\n}\n\nbool\narena_decay_time_set(arena_t *arena, ssize_t decay_time)\n{\n\n\tif (!arena_decay_time_valid(decay_time))\n\t\treturn (true);\n\n\tmalloc_mutex_lock(&arena->lock);\n\t/*\n\t * Restart decay backlog from scratch, which may cause many dirty pages\n\t * to be immediately purged.  It would conceptually be possible to map\n\t * the old backlog onto the new backlog, but there is no justification\n\t * for such complexity since decay_time changes are intended to be\n\t * infrequent, either between the {-1, 0, >0} states, or a one-time\n\t * arbitrary change during initial arena configuration.\n\t */\n\tarena_decay_init(arena, decay_time);\n\tarena_maybe_purge(arena);\n\tmalloc_mutex_unlock(&arena->lock);\n\n\treturn (false);\n}\n\nstatic void\narena_maybe_purge_ratio(arena_t *arena)\n{\n\n\tassert(opt_purge == purge_mode_ratio);\n\n\t/* Don't purge if the option is disabled. */\n\tif (arena->lg_dirty_mult < 0)\n\t\treturn;\n\n\t/*\n\t * Iterate, since preventing recursive purging could otherwise leave too\n\t * many dirty pages.\n\t */\n\twhile (true) {\n\t\tsize_t threshold = (arena->nactive >> arena->lg_dirty_mult);\n\t\tif (threshold < chunk_npages)\n\t\t\tthreshold = chunk_npages;\n\t\t/*\n\t\t * Don't purge unless the number of purgeable pages exceeds the\n\t\t * threshold.\n\t\t */\n\t\tif (arena->ndirty <= threshold)\n\t\t\treturn;\n\t\tarena_purge_to_limit(arena, threshold);\n\t}\n}\n\nstatic void\narena_maybe_purge_decay(arena_t *arena)\n{\n\tnstime_t time;\n\tsize_t ndirty_limit;\n\n\tassert(opt_purge == purge_mode_decay);\n\n\t/* Purge all or nothing if the option is disabled. */\n\tif (arena->decay_time <= 0) {\n\t\tif (arena->decay_time == 0)\n\t\t\tarena_purge_to_limit(arena, 0);\n\t\treturn;\n\t}\n\n\tnstime_copy(&time, &arena->decay_epoch);\n\tif (unlikely(nstime_update(&time))) {\n\t\t/* Time went backwards.  Force an epoch advance. */\n\t\tnstime_copy(&time, &arena->decay_deadline);\n\t}\n\n\tif (arena_decay_deadline_reached(arena, &time))\n\t\tarena_decay_epoch_advance(arena, &time);\n\n\tndirty_limit = arena_decay_npages_limit(arena);\n\n\t/*\n\t * Don't try to purge unless the number of purgeable pages exceeds the\n\t * current limit.\n\t */\n\tif (arena->ndirty <= ndirty_limit)\n\t\treturn;\n\tarena_purge_to_limit(arena, ndirty_limit);\n}\n\nvoid\narena_maybe_purge(arena_t *arena)\n{\n\n\t/* Don't recursively purge. */\n\tif (arena->purging)\n\t\treturn;\n\n\tif (opt_purge == purge_mode_ratio)\n\t\tarena_maybe_purge_ratio(arena);\n\telse\n\t\tarena_maybe_purge_decay(arena);\n}\n\nstatic size_t\narena_dirty_count(arena_t *arena)\n{\n\tsize_t ndirty = 0;\n\tarena_runs_dirty_link_t *rdelm;\n\textent_node_t *chunkselm;\n\n\tfor (rdelm = qr_next(&arena->runs_dirty, rd_link),\n\t    chunkselm = qr_next(&arena->chunks_cache, cc_link);\n\t    rdelm != &arena->runs_dirty; rdelm = qr_next(rdelm, rd_link)) {\n\t\tsize_t npages;\n\n\t\tif (rdelm == &chunkselm->rd) {\n\t\t\tnpages = extent_node_size_get(chunkselm) >> LG_PAGE;\n\t\t\tchunkselm = qr_next(chunkselm, cc_link);\n\t\t} else {\n\t\t\tarena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(\n\t\t\t    rdelm);\n\t\t\tarena_chunk_map_misc_t *miscelm =\n\t\t\t    arena_rd_to_miscelm(rdelm);\n\t\t\tsize_t pageind = arena_miscelm_to_pageind(miscelm);\n\t\t\tassert(arena_mapbits_allocated_get(chunk, pageind) ==\n\t\t\t    0);\n\t\t\tassert(arena_mapbits_large_get(chunk, pageind) == 0);\n\t\t\tassert(arena_mapbits_dirty_get(chunk, pageind) != 0);\n\t\t\tnpages = arena_mapbits_unallocated_size_get(chunk,\n\t\t\t    pageind) >> LG_PAGE;\n\t\t}\n\t\tndirty += npages;\n\t}\n\n\treturn (ndirty);\n}\n\nstatic size_t\narena_stash_dirty(arena_t *arena, chunk_hooks_t *chunk_hooks,\n    size_t ndirty_limit, arena_runs_dirty_link_t *purge_runs_sentinel,\n    extent_node_t *purge_chunks_sentinel)\n{\n\tarena_runs_dirty_link_t *rdelm, *rdelm_next;\n\textent_node_t *chunkselm;\n\tsize_t nstashed = 0;\n\n\t/* Stash runs/chunks according to ndirty_limit. */\n\tfor (rdelm = qr_next(&arena->runs_dirty, rd_link),\n\t    chunkselm = qr_next(&arena->chunks_cache, cc_link);\n\t    rdelm != &arena->runs_dirty; rdelm = rdelm_next) {\n\t\tsize_t npages;\n\t\trdelm_next = qr_next(rdelm, rd_link);\n\n\t\tif (rdelm == &chunkselm->rd) {\n\t\t\textent_node_t *chunkselm_next;\n\t\t\tbool zero;\n\t\t\tUNUSED void *chunk;\n\n\t\t\tnpages = extent_node_size_get(chunkselm) >> LG_PAGE;\n\t\t\tif (opt_purge == purge_mode_decay && arena->ndirty -\n\t\t\t    (nstashed + npages) < ndirty_limit)\n\t\t\t\tbreak;\n\n\t\t\tchunkselm_next = qr_next(chunkselm, cc_link);\n\t\t\t/*\n\t\t\t * Allocate.  chunkselm remains valid due to the\n\t\t\t * dalloc_node=false argument to chunk_alloc_cache().\n\t\t\t */\n\t\t\tzero = false;\n\t\t\tchunk = chunk_alloc_cache(arena, chunk_hooks,\n\t\t\t    extent_node_addr_get(chunkselm),\n\t\t\t    extent_node_size_get(chunkselm), chunksize, &zero,\n\t\t\t    false);\n\t\t\tassert(chunk == extent_node_addr_get(chunkselm));\n\t\t\tassert(zero == extent_node_zeroed_get(chunkselm));\n\t\t\textent_node_dirty_insert(chunkselm, purge_runs_sentinel,\n\t\t\t    purge_chunks_sentinel);\n\t\t\tassert(npages == (extent_node_size_get(chunkselm) >>\n\t\t\t    LG_PAGE));\n\t\t\tchunkselm = chunkselm_next;\n\t\t} else {\n\t\t\tarena_chunk_t *chunk =\n\t\t\t    (arena_chunk_t *)CHUNK_ADDR2BASE(rdelm);\n\t\t\tarena_chunk_map_misc_t *miscelm =\n\t\t\t    arena_rd_to_miscelm(rdelm);\n\t\t\tsize_t pageind = arena_miscelm_to_pageind(miscelm);\n\t\t\tarena_run_t *run = &miscelm->run;\n\t\t\tsize_t run_size =\n\t\t\t    arena_mapbits_unallocated_size_get(chunk, pageind);\n\n\t\t\tnpages = run_size >> LG_PAGE;\n\t\t\tif (opt_purge == purge_mode_decay && arena->ndirty -\n\t\t\t    (nstashed + npages) < ndirty_limit)\n\t\t\t\tbreak;\n\n\t\t\tassert(pageind + npages <= chunk_npages);\n\t\t\tassert(arena_mapbits_dirty_get(chunk, pageind) ==\n\t\t\t    arena_mapbits_dirty_get(chunk, pageind+npages-1));\n\n\t\t\t/*\n\t\t\t * If purging the spare chunk's run, make it available\n\t\t\t * prior to allocation.\n\t\t\t */\n\t\t\tif (chunk == arena->spare)\n\t\t\t\tarena_chunk_alloc(arena);\n\n\t\t\t/* Temporarily allocate the free dirty run. */\n\t\t\tarena_run_split_large(arena, run, run_size, false);\n\t\t\t/* Stash. */\n\t\t\tif (false)\n\t\t\t\tqr_new(rdelm, rd_link); /* Redundant. */\n\t\t\telse {\n\t\t\t\tassert(qr_next(rdelm, rd_link) == rdelm);\n\t\t\t\tassert(qr_prev(rdelm, rd_link) == rdelm);\n\t\t\t}\n\t\t\tqr_meld(purge_runs_sentinel, rdelm, rd_link);\n\t\t}\n\n\t\tnstashed += npages;\n\t\tif (opt_purge == purge_mode_ratio && arena->ndirty - nstashed <=\n\t\t    ndirty_limit)\n\t\t\tbreak;\n\t}\n\n\treturn (nstashed);\n}\n\nstatic size_t\narena_purge_stashed(arena_t *arena, chunk_hooks_t *chunk_hooks,\n    arena_runs_dirty_link_t *purge_runs_sentinel,\n    extent_node_t *purge_chunks_sentinel)\n{\n\tsize_t npurged, nmadvise;\n\tarena_runs_dirty_link_t *rdelm;\n\textent_node_t *chunkselm;\n\n\tif (config_stats)\n\t\tnmadvise = 0;\n\tnpurged = 0;\n\n\tmalloc_mutex_unlock(&arena->lock);\n\tfor (rdelm = qr_next(purge_runs_sentinel, rd_link),\n\t    chunkselm = qr_next(purge_chunks_sentinel, cc_link);\n\t    rdelm != purge_runs_sentinel; rdelm = qr_next(rdelm, rd_link)) {\n\t\tsize_t npages;\n\n\t\tif (rdelm == &chunkselm->rd) {\n\t\t\t/*\n\t\t\t * Don't actually purge the chunk here because 1)\n\t\t\t * chunkselm is embedded in the chunk and must remain\n\t\t\t * valid, and 2) we deallocate the chunk in\n\t\t\t * arena_unstash_purged(), where it is destroyed,\n\t\t\t * decommitted, or purged, depending on chunk\n\t\t\t * deallocation policy.\n\t\t\t */\n\t\t\tsize_t size = extent_node_size_get(chunkselm);\n\t\t\tnpages = size >> LG_PAGE;\n\t\t\tchunkselm = qr_next(chunkselm, cc_link);\n\t\t} else {\n\t\t\tsize_t pageind, run_size, flag_unzeroed, flags, i;\n\t\t\tbool decommitted;\n\t\t\tarena_chunk_t *chunk =\n\t\t\t    (arena_chunk_t *)CHUNK_ADDR2BASE(rdelm);\n\t\t\tarena_chunk_map_misc_t *miscelm =\n\t\t\t    arena_rd_to_miscelm(rdelm);\n\t\t\tpageind = arena_miscelm_to_pageind(miscelm);\n\t\t\trun_size = arena_mapbits_large_size_get(chunk, pageind);\n\t\t\tnpages = run_size >> LG_PAGE;\n\n\t\t\tassert(pageind + npages <= chunk_npages);\n\t\t\tassert(!arena_mapbits_decommitted_get(chunk, pageind));\n\t\t\tassert(!arena_mapbits_decommitted_get(chunk,\n\t\t\t    pageind+npages-1));\n\t\t\tdecommitted = !chunk_hooks->decommit(chunk, chunksize,\n\t\t\t    pageind << LG_PAGE, npages << LG_PAGE, arena->ind);\n\t\t\tif (decommitted) {\n\t\t\t\tflag_unzeroed = 0;\n\t\t\t\tflags = CHUNK_MAP_DECOMMITTED;\n\t\t\t} else {\n\t\t\t\tflag_unzeroed = chunk_purge_wrapper(arena,\n\t\t\t\t    chunk_hooks, chunk, chunksize, pageind <<\n\t\t\t\t    LG_PAGE, run_size) ? CHUNK_MAP_UNZEROED : 0;\n\t\t\t\tflags = flag_unzeroed;\n\t\t\t}\n\t\t\tarena_mapbits_large_set(chunk, pageind+npages-1, 0,\n\t\t\t    flags);\n\t\t\tarena_mapbits_large_set(chunk, pageind, run_size,\n\t\t\t    flags);\n\n\t\t\t/*\n\t\t\t * Set the unzeroed flag for internal pages, now that\n\t\t\t * chunk_purge_wrapper() has returned whether the pages\n\t\t\t * were zeroed as a side effect of purging.  This chunk\n\t\t\t * map modification is safe even though the arena mutex\n\t\t\t * isn't currently owned by this thread, because the run\n\t\t\t * is marked as allocated, thus protecting it from being\n\t\t\t * modified by any other thread.  As long as these\n\t\t\t * writes don't perturb the first and last elements'\n\t\t\t * CHUNK_MAP_ALLOCATED bits, behavior is well defined.\n\t\t\t */\n\t\t\tfor (i = 1; i < npages-1; i++) {\n\t\t\t\tarena_mapbits_internal_set(chunk, pageind+i,\n\t\t\t\t    flag_unzeroed);\n\t\t\t}\n\t\t}\n\n\t\tnpurged += npages;\n\t\tif (config_stats)\n\t\t\tnmadvise++;\n\t}\n\tmalloc_mutex_lock(&arena->lock);\n\n\tif (config_stats) {\n\t\tarena->stats.nmadvise += nmadvise;\n\t\tarena->stats.purged += npurged;\n\t}\n\n\treturn (npurged);\n}\n\nstatic void\narena_unstash_purged(arena_t *arena, chunk_hooks_t *chunk_hooks,\n    arena_runs_dirty_link_t *purge_runs_sentinel,\n    extent_node_t *purge_chunks_sentinel)\n{\n\tarena_runs_dirty_link_t *rdelm, *rdelm_next;\n\textent_node_t *chunkselm;\n\n\t/* Deallocate chunks/runs. */\n\tfor (rdelm = qr_next(purge_runs_sentinel, rd_link),\n\t    chunkselm = qr_next(purge_chunks_sentinel, cc_link);\n\t    rdelm != purge_runs_sentinel; rdelm = rdelm_next) {\n\t\trdelm_next = qr_next(rdelm, rd_link);\n\t\tif (rdelm == &chunkselm->rd) {\n\t\t\textent_node_t *chunkselm_next = qr_next(chunkselm,\n\t\t\t    cc_link);\n\t\t\tvoid *addr = extent_node_addr_get(chunkselm);\n\t\t\tsize_t size = extent_node_size_get(chunkselm);\n\t\t\tbool zeroed = extent_node_zeroed_get(chunkselm);\n\t\t\tbool committed = extent_node_committed_get(chunkselm);\n\t\t\textent_node_dirty_remove(chunkselm);\n\t\t\tarena_node_dalloc(arena, chunkselm);\n\t\t\tchunkselm = chunkselm_next;\n\t\t\tchunk_dalloc_arena(arena, chunk_hooks, addr, size,\n\t\t\t    zeroed, committed);\n\t\t} else {\n\t\t\tarena_chunk_t *chunk =\n\t\t\t    (arena_chunk_t *)CHUNK_ADDR2BASE(rdelm);\n\t\t\tarena_chunk_map_misc_t *miscelm =\n\t\t\t    arena_rd_to_miscelm(rdelm);\n\t\t\tsize_t pageind = arena_miscelm_to_pageind(miscelm);\n\t\t\tbool decommitted = (arena_mapbits_decommitted_get(chunk,\n\t\t\t    pageind) != 0);\n\t\t\tarena_run_t *run = &miscelm->run;\n\t\t\tqr_remove(rdelm, rd_link);\n\t\t\tarena_run_dalloc(arena, run, false, true, decommitted);\n\t\t}\n\t}\n}\n\n/*\n * NB: ndirty_limit is interpreted differently depending on opt_purge:\n *   - purge_mode_ratio: Purge as few dirty run/chunks as possible to reach the\n *                       desired state:\n *                       (arena->ndirty <= ndirty_limit)\n *   - purge_mode_decay: Purge as many dirty runs/chunks as possible without\n *                       violating the invariant:\n *                       (arena->ndirty >= ndirty_limit)\n */\nstatic void\narena_purge_to_limit(arena_t *arena, size_t ndirty_limit)\n{\n\tchunk_hooks_t chunk_hooks = chunk_hooks_get(arena);\n\tsize_t npurge, npurged;\n\tarena_runs_dirty_link_t purge_runs_sentinel;\n\textent_node_t purge_chunks_sentinel;\n\n\tarena->purging = true;\n\n\t/*\n\t * Calls to arena_dirty_count() are disabled even for debug builds\n\t * because overhead grows nonlinearly as memory usage increases.\n\t */\n\tif (false && config_debug) {\n\t\tsize_t ndirty = arena_dirty_count(arena);\n\t\tassert(ndirty == arena->ndirty);\n\t}\n\tassert(opt_purge != purge_mode_ratio || (arena->nactive >>\n\t    arena->lg_dirty_mult) < arena->ndirty || ndirty_limit == 0);\n\n\tqr_new(&purge_runs_sentinel, rd_link);\n\textent_node_dirty_linkage_init(&purge_chunks_sentinel);\n\n\tnpurge = arena_stash_dirty(arena, &chunk_hooks, ndirty_limit,\n\t    &purge_runs_sentinel, &purge_chunks_sentinel);\n\tif (npurge == 0)\n\t\tgoto label_return;\n\tnpurged = arena_purge_stashed(arena, &chunk_hooks, &purge_runs_sentinel,\n\t    &purge_chunks_sentinel);\n\tassert(npurged == npurge);\n\tarena_unstash_purged(arena, &chunk_hooks, &purge_runs_sentinel,\n\t    &purge_chunks_sentinel);\n\n\tif (config_stats)\n\t\tarena->stats.npurge++;\n\nlabel_return:\n\tarena->purging = false;\n}\n\nvoid\narena_purge(arena_t *arena, bool all)\n{\n\n\tmalloc_mutex_lock(&arena->lock);\n\tif (all)\n\t\tarena_purge_to_limit(arena, 0);\n\telse\n\t\tarena_maybe_purge(arena);\n\tmalloc_mutex_unlock(&arena->lock);\n}\n\nstatic void\narena_run_coalesce(arena_t *arena, arena_chunk_t *chunk, size_t *p_size,\n    size_t *p_run_ind, size_t *p_run_pages, size_t flag_dirty,\n    size_t flag_decommitted)\n{\n\tsize_t size = *p_size;\n\tsize_t run_ind = *p_run_ind;\n\tsize_t run_pages = *p_run_pages;\n\n\t/* Try to coalesce forward. */\n\tif (run_ind + run_pages < chunk_npages &&\n\t    arena_mapbits_allocated_get(chunk, run_ind+run_pages) == 0 &&\n\t    arena_mapbits_dirty_get(chunk, run_ind+run_pages) == flag_dirty &&\n\t    arena_mapbits_decommitted_get(chunk, run_ind+run_pages) ==\n\t    flag_decommitted) {\n\t\tsize_t nrun_size = arena_mapbits_unallocated_size_get(chunk,\n\t\t    run_ind+run_pages);\n\t\tsize_t nrun_pages = nrun_size >> LG_PAGE;\n\n\t\t/*\n\t\t * Remove successor from runs_avail; the coalesced run is\n\t\t * inserted later.\n\t\t */\n\t\tassert(arena_mapbits_unallocated_size_get(chunk,\n\t\t    run_ind+run_pages+nrun_pages-1) == nrun_size);\n\t\tassert(arena_mapbits_dirty_get(chunk,\n\t\t    run_ind+run_pages+nrun_pages-1) == flag_dirty);\n\t\tassert(arena_mapbits_decommitted_get(chunk,\n\t\t    run_ind+run_pages+nrun_pages-1) == flag_decommitted);\n\t\tarena_avail_remove(arena, chunk, run_ind+run_pages, nrun_pages);\n\n\t\t/*\n\t\t * If the successor is dirty, remove it from the set of dirty\n\t\t * pages.\n\t\t */\n\t\tif (flag_dirty != 0) {\n\t\t\tarena_run_dirty_remove(arena, chunk, run_ind+run_pages,\n\t\t\t    nrun_pages);\n\t\t}\n\n\t\tsize += nrun_size;\n\t\trun_pages += nrun_pages;\n\n\t\tarena_mapbits_unallocated_size_set(chunk, run_ind, size);\n\t\tarena_mapbits_unallocated_size_set(chunk, run_ind+run_pages-1,\n\t\t    size);\n\t}\n\n\t/* Try to coalesce backward. */\n\tif (run_ind > map_bias && arena_mapbits_allocated_get(chunk,\n\t    run_ind-1) == 0 && arena_mapbits_dirty_get(chunk, run_ind-1) ==\n\t    flag_dirty && arena_mapbits_decommitted_get(chunk, run_ind-1) ==\n\t    flag_decommitted) {\n\t\tsize_t prun_size = arena_mapbits_unallocated_size_get(chunk,\n\t\t    run_ind-1);\n\t\tsize_t prun_pages = prun_size >> LG_PAGE;\n\n\t\trun_ind -= prun_pages;\n\n\t\t/*\n\t\t * Remove predecessor from runs_avail; the coalesced run is\n\t\t * inserted later.\n\t\t */\n\t\tassert(arena_mapbits_unallocated_size_get(chunk, run_ind) ==\n\t\t    prun_size);\n\t\tassert(arena_mapbits_dirty_get(chunk, run_ind) == flag_dirty);\n\t\tassert(arena_mapbits_decommitted_get(chunk, run_ind) ==\n\t\t    flag_decommitted);\n\t\tarena_avail_remove(arena, chunk, run_ind, prun_pages);\n\n\t\t/*\n\t\t * If the predecessor is dirty, remove it from the set of dirty\n\t\t * pages.\n\t\t */\n\t\tif (flag_dirty != 0) {\n\t\t\tarena_run_dirty_remove(arena, chunk, run_ind,\n\t\t\t    prun_pages);\n\t\t}\n\n\t\tsize += prun_size;\n\t\trun_pages += prun_pages;\n\n\t\tarena_mapbits_unallocated_size_set(chunk, run_ind, size);\n\t\tarena_mapbits_unallocated_size_set(chunk, run_ind+run_pages-1,\n\t\t    size);\n\t}\n\n\t*p_size = size;\n\t*p_run_ind = run_ind;\n\t*p_run_pages = run_pages;\n}\n\nstatic size_t\narena_run_size_get(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run,\n    size_t run_ind)\n{\n\tsize_t size;\n\n\tassert(run_ind >= map_bias);\n\tassert(run_ind < chunk_npages);\n\n\tif (arena_mapbits_large_get(chunk, run_ind) != 0) {\n\t\tsize = arena_mapbits_large_size_get(chunk, run_ind);\n\t\tassert(size == PAGE || arena_mapbits_large_size_get(chunk,\n\t\t    run_ind+(size>>LG_PAGE)-1) == 0);\n\t} else {\n\t\tarena_bin_info_t *bin_info = &arena_bin_info[run->binind];\n\t\tsize = bin_info->run_size;\n\t}\n\n\treturn (size);\n}\n\nstatic void\narena_run_dalloc(arena_t *arena, arena_run_t *run, bool dirty, bool cleaned,\n    bool decommitted)\n{\n\tarena_chunk_t *chunk;\n\tarena_chunk_map_misc_t *miscelm;\n\tsize_t size, run_ind, run_pages, flag_dirty, flag_decommitted;\n\n\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);\n\tmiscelm = arena_run_to_miscelm(run);\n\trun_ind = arena_miscelm_to_pageind(miscelm);\n\tassert(run_ind >= map_bias);\n\tassert(run_ind < chunk_npages);\n\tsize = arena_run_size_get(arena, chunk, run, run_ind);\n\trun_pages = (size >> LG_PAGE);\n\tarena_nactive_sub(arena, run_pages);\n\n\t/*\n\t * The run is dirty if the caller claims to have dirtied it, as well as\n\t * if it was already dirty before being allocated and the caller\n\t * doesn't claim to have cleaned it.\n\t */\n\tassert(arena_mapbits_dirty_get(chunk, run_ind) ==\n\t    arena_mapbits_dirty_get(chunk, run_ind+run_pages-1));\n\tif (!cleaned && !decommitted && arena_mapbits_dirty_get(chunk, run_ind)\n\t    != 0)\n\t\tdirty = true;\n\tflag_dirty = dirty ? CHUNK_MAP_DIRTY : 0;\n\tflag_decommitted = decommitted ? CHUNK_MAP_DECOMMITTED : 0;\n\n\t/* Mark pages as unallocated in the chunk map. */\n\tif (dirty || decommitted) {\n\t\tsize_t flags = flag_dirty | flag_decommitted;\n\t\tarena_mapbits_unallocated_set(chunk, run_ind, size, flags);\n\t\tarena_mapbits_unallocated_set(chunk, run_ind+run_pages-1, size,\n\t\t    flags);\n\t} else {\n\t\tarena_mapbits_unallocated_set(chunk, run_ind, size,\n\t\t    arena_mapbits_unzeroed_get(chunk, run_ind));\n\t\tarena_mapbits_unallocated_set(chunk, run_ind+run_pages-1, size,\n\t\t    arena_mapbits_unzeroed_get(chunk, run_ind+run_pages-1));\n\t}\n\n\tarena_run_coalesce(arena, chunk, &size, &run_ind, &run_pages,\n\t    flag_dirty, flag_decommitted);\n\n\t/* Insert into runs_avail, now that coalescing is complete. */\n\tassert(arena_mapbits_unallocated_size_get(chunk, run_ind) ==\n\t    arena_mapbits_unallocated_size_get(chunk, run_ind+run_pages-1));\n\tassert(arena_mapbits_dirty_get(chunk, run_ind) ==\n\t    arena_mapbits_dirty_get(chunk, run_ind+run_pages-1));\n\tassert(arena_mapbits_decommitted_get(chunk, run_ind) ==\n\t    arena_mapbits_decommitted_get(chunk, run_ind+run_pages-1));\n\tarena_avail_insert(arena, chunk, run_ind, run_pages);\n\n\tif (dirty)\n\t\tarena_run_dirty_insert(arena, chunk, run_ind, run_pages);\n\n\t/* Deallocate chunk if it is now completely unused. */\n\tif (size == arena_maxrun) {\n\t\tassert(run_ind == map_bias);\n\t\tassert(run_pages == (arena_maxrun >> LG_PAGE));\n\t\tarena_chunk_dalloc(arena, chunk);\n\t}\n\n\t/*\n\t * It is okay to do dirty page processing here even if the chunk was\n\t * deallocated above, since in that case it is the spare.  Waiting\n\t * until after possible chunk deallocation to do dirty processing\n\t * allows for an old spare to be fully deallocated, thus decreasing the\n\t * chances of spuriously crossing the dirty page purging threshold.\n\t */\n\tif (dirty)\n\t\tarena_maybe_purge(arena);\n}\n\nstatic void\narena_run_trim_head(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run,\n    size_t oldsize, size_t newsize)\n{\n\tarena_chunk_map_misc_t *miscelm = arena_run_to_miscelm(run);\n\tsize_t pageind = arena_miscelm_to_pageind(miscelm);\n\tsize_t head_npages = (oldsize - newsize) >> LG_PAGE;\n\tsize_t flag_dirty = arena_mapbits_dirty_get(chunk, pageind);\n\tsize_t flag_decommitted = arena_mapbits_decommitted_get(chunk, pageind);\n\tsize_t flag_unzeroed_mask = (flag_dirty | flag_decommitted) == 0 ?\n\t    CHUNK_MAP_UNZEROED : 0;\n\n\tassert(oldsize > newsize);\n\n\t/*\n\t * Update the chunk map so that arena_run_dalloc() can treat the\n\t * leading run as separately allocated.  Set the last element of each\n\t * run first, in case of single-page runs.\n\t */\n\tassert(arena_mapbits_large_size_get(chunk, pageind) == oldsize);\n\tarena_mapbits_large_set(chunk, pageind+head_npages-1, 0, flag_dirty |\n\t    (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk,\n\t    pageind+head_npages-1)));\n\tarena_mapbits_large_set(chunk, pageind, oldsize-newsize, flag_dirty |\n\t    (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, pageind)));\n\n\tif (config_debug) {\n\t\tUNUSED size_t tail_npages = newsize >> LG_PAGE;\n\t\tassert(arena_mapbits_large_size_get(chunk,\n\t\t    pageind+head_npages+tail_npages-1) == 0);\n\t\tassert(arena_mapbits_dirty_get(chunk,\n\t\t    pageind+head_npages+tail_npages-1) == flag_dirty);\n\t}\n\tarena_mapbits_large_set(chunk, pageind+head_npages, newsize,\n\t    flag_dirty | (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk,\n\t    pageind+head_npages)));\n\n\tarena_run_dalloc(arena, run, false, false, (flag_decommitted != 0));\n}\n\nstatic void\narena_run_trim_tail(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run,\n    size_t oldsize, size_t newsize, bool dirty)\n{\n\tarena_chunk_map_misc_t *miscelm = arena_run_to_miscelm(run);\n\tsize_t pageind = arena_miscelm_to_pageind(miscelm);\n\tsize_t head_npages = newsize >> LG_PAGE;\n\tsize_t flag_dirty = arena_mapbits_dirty_get(chunk, pageind);\n\tsize_t flag_decommitted = arena_mapbits_decommitted_get(chunk, pageind);\n\tsize_t flag_unzeroed_mask = (flag_dirty | flag_decommitted) == 0 ?\n\t    CHUNK_MAP_UNZEROED : 0;\n\tarena_chunk_map_misc_t *tail_miscelm;\n\tarena_run_t *tail_run;\n\n\tassert(oldsize > newsize);\n\n\t/*\n\t * Update the chunk map so that arena_run_dalloc() can treat the\n\t * trailing run as separately allocated.  Set the last element of each\n\t * run first, in case of single-page runs.\n\t */\n\tassert(arena_mapbits_large_size_get(chunk, pageind) == oldsize);\n\tarena_mapbits_large_set(chunk, pageind+head_npages-1, 0, flag_dirty |\n\t    (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk,\n\t    pageind+head_npages-1)));\n\tarena_mapbits_large_set(chunk, pageind, newsize, flag_dirty |\n\t    (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, pageind)));\n\n\tif (config_debug) {\n\t\tUNUSED size_t tail_npages = (oldsize - newsize) >> LG_PAGE;\n\t\tassert(arena_mapbits_large_size_get(chunk,\n\t\t    pageind+head_npages+tail_npages-1) == 0);\n\t\tassert(arena_mapbits_dirty_get(chunk,\n\t\t    pageind+head_npages+tail_npages-1) == flag_dirty);\n\t}\n\tarena_mapbits_large_set(chunk, pageind+head_npages, oldsize-newsize,\n\t    flag_dirty | (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk,\n\t    pageind+head_npages)));\n\n\ttail_miscelm = arena_miscelm_get(chunk, pageind + head_npages);\n\ttail_run = &tail_miscelm->run;\n\tarena_run_dalloc(arena, tail_run, dirty, false, (flag_decommitted !=\n\t    0));\n}\n\nstatic arena_run_t *\narena_bin_runs_first(arena_bin_t *bin)\n{\n\tarena_chunk_map_misc_t *miscelm = arena_run_tree_first(&bin->runs);\n\tif (miscelm != NULL)\n\t\treturn (&miscelm->run);\n\n\treturn (NULL);\n}\n\nstatic void\narena_bin_runs_insert(arena_bin_t *bin, arena_run_t *run)\n{\n\tarena_chunk_map_misc_t *miscelm = arena_run_to_miscelm(run);\n\n\tassert(arena_run_tree_search(&bin->runs, miscelm) == NULL);\n\n\tarena_run_tree_insert(&bin->runs, miscelm);\n}\n\nstatic void\narena_bin_runs_remove(arena_bin_t *bin, arena_run_t *run)\n{\n\tarena_chunk_map_misc_t *miscelm = arena_run_to_miscelm(run);\n\n\tassert(arena_run_tree_search(&bin->runs, miscelm) != NULL);\n\n\tarena_run_tree_remove(&bin->runs, miscelm);\n}\n\nstatic arena_run_t *\narena_bin_nonfull_run_tryget(arena_bin_t *bin)\n{\n\tarena_run_t *run = arena_bin_runs_first(bin);\n\tif (run != NULL) {\n\t\tarena_bin_runs_remove(bin, run);\n\t\tif (config_stats)\n\t\t\tbin->stats.reruns++;\n\t}\n\treturn (run);\n}\n\nstatic arena_run_t *\narena_bin_nonfull_run_get(arena_t *arena, arena_bin_t *bin)\n{\n\tarena_run_t *run;\n\tszind_t binind;\n\tarena_bin_info_t *bin_info;\n\n\t/* Look for a usable run. */\n\trun = arena_bin_nonfull_run_tryget(bin);\n\tif (run != NULL)\n\t\treturn (run);\n\t/* No existing runs have any space available. */\n\n\tbinind = arena_bin_index(arena, bin);\n\tbin_info = &arena_bin_info[binind];\n\n\t/* Allocate a new run. */\n\tmalloc_mutex_unlock(&bin->lock);\n\t/******************************/\n\tmalloc_mutex_lock(&arena->lock);\n\trun = arena_run_alloc_small(arena, bin_info->run_size, binind);\n\tif (run != NULL) {\n\t\t/* Initialize run internals. */\n\t\trun->binind = binind;\n\t\trun->nfree = bin_info->nregs;\n\t\tbitmap_init(run->bitmap, &bin_info->bitmap_info);\n\t}\n\tmalloc_mutex_unlock(&arena->lock);\n\t/********************************/\n\tmalloc_mutex_lock(&bin->lock);\n\tif (run != NULL) {\n\t\tif (config_stats) {\n\t\t\tbin->stats.nruns++;\n\t\t\tbin->stats.curruns++;\n\t\t}\n\t\treturn (run);\n\t}\n\n\t/*\n\t * arena_run_alloc_small() failed, but another thread may have made\n\t * sufficient memory available while this one dropped bin->lock above,\n\t * so search one more time.\n\t */\n\trun = arena_bin_nonfull_run_tryget(bin);\n\tif (run != NULL)\n\t\treturn (run);\n\n\treturn (NULL);\n}\n\n/* Re-fill bin->runcur, then call arena_run_reg_alloc(). */\nstatic void *\narena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin)\n{\n\tszind_t binind;\n\tarena_bin_info_t *bin_info;\n\tarena_run_t *run;\n\n\tbinind = arena_bin_index(arena, bin);\n\tbin_info = &arena_bin_info[binind];\n\tbin->runcur = NULL;\n\trun = arena_bin_nonfull_run_get(arena, bin);\n\tif (bin->runcur != NULL && bin->runcur->nfree > 0) {\n\t\t/*\n\t\t * Another thread updated runcur while this one ran without the\n\t\t * bin lock in arena_bin_nonfull_run_get().\n\t\t */\n\t\tvoid *ret;\n\t\tassert(bin->runcur->nfree > 0);\n\t\tret = arena_run_reg_alloc(bin->runcur, bin_info);\n\t\tif (run != NULL) {\n\t\t\tarena_chunk_t *chunk;\n\n\t\t\t/*\n\t\t\t * arena_run_alloc_small() may have allocated run, or\n\t\t\t * it may have pulled run from the bin's run tree.\n\t\t\t * Therefore it is unsafe to make any assumptions about\n\t\t\t * how run has previously been used, and\n\t\t\t * arena_bin_lower_run() must be called, as if a region\n\t\t\t * were just deallocated from the run.\n\t\t\t */\n\t\t\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);\n\t\t\tif (run->nfree == bin_info->nregs)\n\t\t\t\tarena_dalloc_bin_run(arena, chunk, run, bin);\n\t\t\telse\n\t\t\t\tarena_bin_lower_run(arena, chunk, run, bin);\n\t\t}\n\t\treturn (ret);\n\t}\n\n\tif (run == NULL)\n\t\treturn (NULL);\n\n\tbin->runcur = run;\n\n\tassert(bin->runcur->nfree > 0);\n\n\treturn (arena_run_reg_alloc(bin->runcur, bin_info));\n}\n\nvoid\narena_tcache_fill_small(tsd_t *tsd, arena_t *arena, tcache_bin_t *tbin,\n    szind_t binind, uint64_t prof_accumbytes)\n{\n\tunsigned i, nfill;\n\tarena_bin_t *bin;\n\n\tassert(tbin->ncached == 0);\n\n\tif (config_prof && arena_prof_accum(arena, prof_accumbytes))\n\t\tprof_idump();\n\tbin = &arena->bins[binind];\n\tmalloc_mutex_lock(&bin->lock);\n\tfor (i = 0, nfill = (tcache_bin_info[binind].ncached_max >>\n\t    tbin->lg_fill_div); i < nfill; i++) {\n\t\tarena_run_t *run;\n\t\tvoid *ptr;\n\t\tif ((run = bin->runcur) != NULL && run->nfree > 0)\n\t\t\tptr = arena_run_reg_alloc(run, &arena_bin_info[binind]);\n\t\telse\n\t\t\tptr = arena_bin_malloc_hard(arena, bin);\n\t\tif (ptr == NULL) {\n\t\t\t/*\n\t\t\t * OOM.  tbin->avail isn't yet filled down to its first\n\t\t\t * element, so the successful allocations (if any) must\n\t\t\t * be moved just before tbin->avail before bailing out.\n\t\t\t */\n\t\t\tif (i > 0) {\n\t\t\t\tmemmove(tbin->avail - i, tbin->avail - nfill,\n\t\t\t\t    i * sizeof(void *));\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tif (config_fill && unlikely(opt_junk_alloc)) {\n\t\t\tarena_alloc_junk_small(ptr, &arena_bin_info[binind],\n\t\t\t    true);\n\t\t}\n\t\t/* Insert such that low regions get used first. */\n\t\t*(tbin->avail - nfill + i) = ptr;\n\t}\n\tif (config_stats) {\n\t\tbin->stats.nmalloc += i;\n\t\tbin->stats.nrequests += tbin->tstats.nrequests;\n\t\tbin->stats.curregs += i;\n\t\tbin->stats.nfills++;\n\t\ttbin->tstats.nrequests = 0;\n\t}\n\tmalloc_mutex_unlock(&bin->lock);\n\ttbin->ncached = i;\n\tarena_decay_tick(tsd, arena);\n}\n\nvoid\narena_alloc_junk_small(void *ptr, arena_bin_info_t *bin_info, bool zero)\n{\n\n\tif (zero) {\n\t\tsize_t redzone_size = bin_info->redzone_size;\n\t\tmemset((void *)((uintptr_t)ptr - redzone_size), 0xa5,\n\t\t    redzone_size);\n\t\tmemset((void *)((uintptr_t)ptr + bin_info->reg_size), 0xa5,\n\t\t    redzone_size);\n\t} else {\n\t\tmemset((void *)((uintptr_t)ptr - bin_info->redzone_size), 0xa5,\n\t\t    bin_info->reg_interval);\n\t}\n}\n\n#ifdef JEMALLOC_JET\n#undef arena_redzone_corruption\n#define\tarena_redzone_corruption JEMALLOC_N(arena_redzone_corruption_impl)\n#endif\nstatic void\narena_redzone_corruption(void *ptr, size_t usize, bool after,\n    size_t offset, uint8_t byte)\n{\n\n\tmalloc_printf(\"<jemalloc>: Corrupt redzone %zu byte%s %s %p \"\n\t    \"(size %zu), byte=%#x\\n\", offset, (offset == 1) ? \"\" : \"s\",\n\t    after ? \"after\" : \"before\", ptr, usize, byte);\n}\n#ifdef JEMALLOC_JET\n#undef arena_redzone_corruption\n#define\tarena_redzone_corruption JEMALLOC_N(arena_redzone_corruption)\narena_redzone_corruption_t *arena_redzone_corruption =\n    JEMALLOC_N(arena_redzone_corruption_impl);\n#endif\n\nstatic void\narena_redzones_validate(void *ptr, arena_bin_info_t *bin_info, bool reset)\n{\n\tbool error = false;\n\n\tif (opt_junk_alloc) {\n\t\tsize_t size = bin_info->reg_size;\n\t\tsize_t redzone_size = bin_info->redzone_size;\n\t\tsize_t i;\n\n\t\tfor (i = 1; i <= redzone_size; i++) {\n\t\t\tuint8_t *byte = (uint8_t *)((uintptr_t)ptr - i);\n\t\t\tif (*byte != 0xa5) {\n\t\t\t\terror = true;\n\t\t\t\tarena_redzone_corruption(ptr, size, false, i,\n\t\t\t\t    *byte);\n\t\t\t\tif (reset)\n\t\t\t\t\t*byte = 0xa5;\n\t\t\t}\n\t\t}\n\t\tfor (i = 0; i < redzone_size; i++) {\n\t\t\tuint8_t *byte = (uint8_t *)((uintptr_t)ptr + size + i);\n\t\t\tif (*byte != 0xa5) {\n\t\t\t\terror = true;\n\t\t\t\tarena_redzone_corruption(ptr, size, true, i,\n\t\t\t\t    *byte);\n\t\t\t\tif (reset)\n\t\t\t\t\t*byte = 0xa5;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (opt_abort && error)\n\t\tabort();\n}\n\n#ifdef JEMALLOC_JET\n#undef arena_dalloc_junk_small\n#define\tarena_dalloc_junk_small JEMALLOC_N(arena_dalloc_junk_small_impl)\n#endif\nvoid\narena_dalloc_junk_small(void *ptr, arena_bin_info_t *bin_info)\n{\n\tsize_t redzone_size = bin_info->redzone_size;\n\n\tarena_redzones_validate(ptr, bin_info, false);\n\tmemset((void *)((uintptr_t)ptr - redzone_size), 0x5a,\n\t    bin_info->reg_interval);\n}\n#ifdef JEMALLOC_JET\n#undef arena_dalloc_junk_small\n#define\tarena_dalloc_junk_small JEMALLOC_N(arena_dalloc_junk_small)\narena_dalloc_junk_small_t *arena_dalloc_junk_small =\n    JEMALLOC_N(arena_dalloc_junk_small_impl);\n#endif\n\nvoid\narena_quarantine_junk_small(void *ptr, size_t usize)\n{\n\tszind_t binind;\n\tarena_bin_info_t *bin_info;\n\tcassert(config_fill);\n\tassert(opt_junk_free);\n\tassert(opt_quarantine);\n\tassert(usize <= SMALL_MAXCLASS);\n\n\tbinind = size2index(usize);\n\tbin_info = &arena_bin_info[binind];\n\tarena_redzones_validate(ptr, bin_info, true);\n}\n\nstatic void *\narena_malloc_small(tsd_t *tsd, arena_t *arena, szind_t binind, bool zero)\n{\n\tvoid *ret;\n\tarena_bin_t *bin;\n\tsize_t usize;\n\tarena_run_t *run;\n\n\tassert(binind < NBINS);\n\tbin = &arena->bins[binind];\n\tusize = index2size(binind);\n\n\tmalloc_mutex_lock(&bin->lock);\n\tif ((run = bin->runcur) != NULL && run->nfree > 0)\n\t\tret = arena_run_reg_alloc(run, &arena_bin_info[binind]);\n\telse\n\t\tret = arena_bin_malloc_hard(arena, bin);\n\n\tif (ret == NULL) {\n\t\tmalloc_mutex_unlock(&bin->lock);\n\t\treturn (NULL);\n\t}\n\n\tif (config_stats) {\n\t\tbin->stats.nmalloc++;\n\t\tbin->stats.nrequests++;\n\t\tbin->stats.curregs++;\n\t}\n\tmalloc_mutex_unlock(&bin->lock);\n\tif (config_prof && !isthreaded && arena_prof_accum(arena, usize))\n\t\tprof_idump();\n\n\tif (!zero) {\n\t\tif (config_fill) {\n\t\t\tif (unlikely(opt_junk_alloc)) {\n\t\t\t\tarena_alloc_junk_small(ret,\n\t\t\t\t    &arena_bin_info[binind], false);\n\t\t\t} else if (unlikely(opt_zero))\n\t\t\t\tmemset(ret, 0, usize);\n\t\t}\n\t\tJEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, usize);\n\t} else {\n\t\tif (config_fill && unlikely(opt_junk_alloc)) {\n\t\t\tarena_alloc_junk_small(ret, &arena_bin_info[binind],\n\t\t\t    true);\n\t\t}\n\t\tJEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, usize);\n\t\tmemset(ret, 0, usize);\n\t}\n\n\tarena_decay_tick(tsd, arena);\n\treturn (ret);\n}\n\nvoid *\narena_malloc_large(tsd_t *tsd, arena_t *arena, szind_t binind, bool zero)\n{\n\tvoid *ret;\n\tsize_t usize;\n\tuintptr_t random_offset;\n\tarena_run_t *run;\n\tarena_chunk_map_misc_t *miscelm;\n\tUNUSED bool idump;\n\n\t/* Large allocation. */\n\tusize = index2size(binind);\n\tmalloc_mutex_lock(&arena->lock);\n\tif (config_cache_oblivious) {\n\t\tuint64_t r;\n\n\t\t/*\n\t\t * Compute a uniformly distributed offset within the first page\n\t\t * that is a multiple of the cacheline size, e.g. [0 .. 63) * 64\n\t\t * for 4 KiB pages and 64-byte cachelines.\n\t\t */\n\t\tr = prng_lg_range(&arena->offset_state, LG_PAGE - LG_CACHELINE);\n\t\trandom_offset = ((uintptr_t)r) << LG_CACHELINE;\n\t} else\n\t\trandom_offset = 0;\n\trun = arena_run_alloc_large(arena, usize + large_pad, zero);\n\tif (run == NULL) {\n\t\tmalloc_mutex_unlock(&arena->lock);\n\t\treturn (NULL);\n\t}\n\tmiscelm = arena_run_to_miscelm(run);\n\tret = (void *)((uintptr_t)arena_miscelm_to_rpages(miscelm) +\n\t    random_offset);\n\tif (config_stats) {\n\t\tszind_t index = binind - NBINS;\n\n\t\tarena->stats.nmalloc_large++;\n\t\tarena->stats.nrequests_large++;\n\t\tarena->stats.allocated_large += usize;\n\t\tarena->stats.lstats[index].nmalloc++;\n\t\tarena->stats.lstats[index].nrequests++;\n\t\tarena->stats.lstats[index].curruns++;\n\t}\n\tif (config_prof)\n\t\tidump = arena_prof_accum_locked(arena, usize);\n\tmalloc_mutex_unlock(&arena->lock);\n\tif (config_prof && idump)\n\t\tprof_idump();\n\n\tif (!zero) {\n\t\tif (config_fill) {\n\t\t\tif (unlikely(opt_junk_alloc))\n\t\t\t\tmemset(ret, 0xa5, usize);\n\t\t\telse if (unlikely(opt_zero))\n\t\t\t\tmemset(ret, 0, usize);\n\t\t}\n\t}\n\n\tarena_decay_tick(tsd, arena);\n\treturn (ret);\n}\n\nvoid *\narena_malloc_hard(tsd_t *tsd, arena_t *arena, size_t size, szind_t ind,\n    bool zero, tcache_t *tcache)\n{\n\n\tarena = arena_choose(tsd, arena);\n\tif (unlikely(arena == NULL))\n\t\treturn (NULL);\n\n\tif (likely(size <= SMALL_MAXCLASS))\n\t\treturn (arena_malloc_small(tsd, arena, ind, zero));\n\tif (likely(size <= large_maxclass))\n\t\treturn (arena_malloc_large(tsd, arena, ind, zero));\n\treturn (huge_malloc(tsd, arena, index2size(ind), zero, tcache));\n}\n\n/* Only handles large allocations that require more than page alignment. */\nstatic void *\narena_palloc_large(tsd_t *tsd, arena_t *arena, size_t usize, size_t alignment,\n    bool zero)\n{\n\tvoid *ret;\n\tsize_t alloc_size, leadsize, trailsize;\n\tarena_run_t *run;\n\tarena_chunk_t *chunk;\n\tarena_chunk_map_misc_t *miscelm;\n\tvoid *rpages;\n\n\tassert(usize == PAGE_CEILING(usize));\n\n\tarena = arena_choose(tsd, arena);\n\tif (unlikely(arena == NULL))\n\t\treturn (NULL);\n\n\talignment = PAGE_CEILING(alignment);\n\talloc_size = usize + large_pad + alignment - PAGE;\n\n\tmalloc_mutex_lock(&arena->lock);\n\trun = arena_run_alloc_large(arena, alloc_size, false);\n\tif (run == NULL) {\n\t\tmalloc_mutex_unlock(&arena->lock);\n\t\treturn (NULL);\n\t}\n\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);\n\tmiscelm = arena_run_to_miscelm(run);\n\trpages = arena_miscelm_to_rpages(miscelm);\n\n\tleadsize = ALIGNMENT_CEILING((uintptr_t)rpages, alignment) -\n\t    (uintptr_t)rpages;\n\tassert(alloc_size >= leadsize + usize);\n\ttrailsize = alloc_size - leadsize - usize - large_pad;\n\tif (leadsize != 0) {\n\t\tarena_chunk_map_misc_t *head_miscelm = miscelm;\n\t\tarena_run_t *head_run = run;\n\n\t\tmiscelm = arena_miscelm_get(chunk,\n\t\t    arena_miscelm_to_pageind(head_miscelm) + (leadsize >>\n\t\t    LG_PAGE));\n\t\trun = &miscelm->run;\n\n\t\tarena_run_trim_head(arena, chunk, head_run, alloc_size,\n\t\t    alloc_size - leadsize);\n\t}\n\tif (trailsize != 0) {\n\t\tarena_run_trim_tail(arena, chunk, run, usize + large_pad +\n\t\t    trailsize, usize + large_pad, false);\n\t}\n\tif (arena_run_init_large(arena, run, usize + large_pad, zero)) {\n\t\tsize_t run_ind =\n\t\t    arena_miscelm_to_pageind(arena_run_to_miscelm(run));\n\t\tbool dirty = (arena_mapbits_dirty_get(chunk, run_ind) != 0);\n\t\tbool decommitted = (arena_mapbits_decommitted_get(chunk,\n\t\t    run_ind) != 0);\n\n\t\tassert(decommitted); /* Cause of OOM. */\n\t\tarena_run_dalloc(arena, run, dirty, false, decommitted);\n\t\tmalloc_mutex_unlock(&arena->lock);\n\t\treturn (NULL);\n\t}\n\tret = arena_miscelm_to_rpages(miscelm);\n\n\tif (config_stats) {\n\t\tszind_t index = size2index(usize) - NBINS;\n\n\t\tarena->stats.nmalloc_large++;\n\t\tarena->stats.nrequests_large++;\n\t\tarena->stats.allocated_large += usize;\n\t\tarena->stats.lstats[index].nmalloc++;\n\t\tarena->stats.lstats[index].nrequests++;\n\t\tarena->stats.lstats[index].curruns++;\n\t}\n\tmalloc_mutex_unlock(&arena->lock);\n\n\tif (config_fill && !zero) {\n\t\tif (unlikely(opt_junk_alloc))\n\t\t\tmemset(ret, 0xa5, usize);\n\t\telse if (unlikely(opt_zero))\n\t\t\tmemset(ret, 0, usize);\n\t}\n\tarena_decay_tick(tsd, arena);\n\treturn (ret);\n}\n\nvoid *\narena_palloc(tsd_t *tsd, arena_t *arena, size_t usize, size_t alignment,\n    bool zero, tcache_t *tcache)\n{\n\tvoid *ret;\n\n\tif (usize <= SMALL_MAXCLASS && (alignment < PAGE || (alignment == PAGE\n\t    && (usize & PAGE_MASK) == 0))) {\n\t\t/* Small; alignment doesn't require special run placement. */\n\t\tret = arena_malloc(tsd, arena, usize, size2index(usize), zero,\n\t\t    tcache, true);\n\t} else if (usize <= large_maxclass && alignment <= PAGE) {\n\t\t/*\n\t\t * Large; alignment doesn't require special run placement.\n\t\t * However, the cached pointer may be at a random offset from\n\t\t * the base of the run, so do some bit manipulation to retrieve\n\t\t * the base.\n\t\t */\n\t\tret = arena_malloc(tsd, arena, usize, size2index(usize), zero,\n\t\t    tcache, true);\n\t\tif (config_cache_oblivious)\n\t\t\tret = (void *)((uintptr_t)ret & ~PAGE_MASK);\n\t} else {\n\t\tif (likely(usize <= large_maxclass)) {\n\t\t\tret = arena_palloc_large(tsd, arena, usize, alignment,\n\t\t\t    zero);\n\t\t} else if (likely(alignment <= chunksize))\n\t\t\tret = huge_malloc(tsd, arena, usize, zero, tcache);\n\t\telse {\n\t\t\tret = huge_palloc(tsd, arena, usize, alignment, zero,\n\t\t\t    tcache);\n\t\t}\n\t}\n\treturn (ret);\n}\n\nvoid\narena_prof_promoted(const void *ptr, size_t size)\n{\n\tarena_chunk_t *chunk;\n\tsize_t pageind;\n\tszind_t binind;\n\n\tcassert(config_prof);\n\tassert(ptr != NULL);\n\tassert(CHUNK_ADDR2BASE(ptr) != ptr);\n\tassert(isalloc(ptr, false) == LARGE_MINCLASS);\n\tassert(isalloc(ptr, true) == LARGE_MINCLASS);\n\tassert(size <= SMALL_MAXCLASS);\n\n\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);\n\tpageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;\n\tbinind = size2index(size);\n\tassert(binind < NBINS);\n\tarena_mapbits_large_binind_set(chunk, pageind, binind);\n\n\tassert(isalloc(ptr, false) == LARGE_MINCLASS);\n\tassert(isalloc(ptr, true) == size);\n}\n\nstatic void\narena_dissociate_bin_run(arena_chunk_t *chunk, arena_run_t *run,\n    arena_bin_t *bin)\n{\n\n\t/* Dissociate run from bin. */\n\tif (run == bin->runcur)\n\t\tbin->runcur = NULL;\n\telse {\n\t\tszind_t binind = arena_bin_index(extent_node_arena_get(\n\t\t    &chunk->node), bin);\n\t\tarena_bin_info_t *bin_info = &arena_bin_info[binind];\n\n\t\tif (bin_info->nregs != 1) {\n\t\t\t/*\n\t\t\t * This block's conditional is necessary because if the\n\t\t\t * run only contains one region, then it never gets\n\t\t\t * inserted into the non-full runs tree.\n\t\t\t */\n\t\t\tarena_bin_runs_remove(bin, run);\n\t\t}\n\t}\n}\n\nstatic void\narena_dalloc_bin_run(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run,\n    arena_bin_t *bin)\n{\n\n\tassert(run != bin->runcur);\n\tassert(arena_run_tree_search(&bin->runs, arena_run_to_miscelm(run)) ==\n\t    NULL);\n\n\tmalloc_mutex_unlock(&bin->lock);\n\t/******************************/\n\tmalloc_mutex_lock(&arena->lock);\n\tarena_run_dalloc(arena, run, true, false, false);\n\tmalloc_mutex_unlock(&arena->lock);\n\t/****************************/\n\tmalloc_mutex_lock(&bin->lock);\n\tif (config_stats)\n\t\tbin->stats.curruns--;\n}\n\nstatic void\narena_bin_lower_run(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run,\n    arena_bin_t *bin)\n{\n\n\t/*\n\t * Make sure that if bin->runcur is non-NULL, it refers to the lowest\n\t * non-full run.  It is okay to NULL runcur out rather than proactively\n\t * keeping it pointing at the lowest non-full run.\n\t */\n\tif ((uintptr_t)run < (uintptr_t)bin->runcur) {\n\t\t/* Switch runcur. */\n\t\tif (bin->runcur->nfree > 0)\n\t\t\tarena_bin_runs_insert(bin, bin->runcur);\n\t\tbin->runcur = run;\n\t\tif (config_stats)\n\t\t\tbin->stats.reruns++;\n\t} else\n\t\tarena_bin_runs_insert(bin, run);\n}\n\nstatic void\narena_dalloc_bin_locked_impl(arena_t *arena, arena_chunk_t *chunk, void *ptr,\n    arena_chunk_map_bits_t *bitselm, bool junked)\n{\n\tsize_t pageind, rpages_ind;\n\tarena_run_t *run;\n\tarena_bin_t *bin;\n\tarena_bin_info_t *bin_info;\n\tszind_t binind;\n\n\tpageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;\n\trpages_ind = pageind - arena_mapbits_small_runind_get(chunk, pageind);\n\trun = &arena_miscelm_get(chunk, rpages_ind)->run;\n\tbinind = run->binind;\n\tbin = &arena->bins[binind];\n\tbin_info = &arena_bin_info[binind];\n\n\tif (!junked && config_fill && unlikely(opt_junk_free))\n\t\tarena_dalloc_junk_small(ptr, bin_info);\n\n\tarena_run_reg_dalloc(run, ptr);\n\tif (run->nfree == bin_info->nregs) {\n\t\tarena_dissociate_bin_run(chunk, run, bin);\n\t\tarena_dalloc_bin_run(arena, chunk, run, bin);\n\t} else if (run->nfree == 1 && run != bin->runcur)\n\t\tarena_bin_lower_run(arena, chunk, run, bin);\n\n\tif (config_stats) {\n\t\tbin->stats.ndalloc++;\n\t\tbin->stats.curregs--;\n\t}\n}\n\nvoid\narena_dalloc_bin_junked_locked(arena_t *arena, arena_chunk_t *chunk, void *ptr,\n    arena_chunk_map_bits_t *bitselm)\n{\n\n\tarena_dalloc_bin_locked_impl(arena, chunk, ptr, bitselm, true);\n}\n\nvoid\narena_dalloc_bin(arena_t *arena, arena_chunk_t *chunk, void *ptr,\n    size_t pageind, arena_chunk_map_bits_t *bitselm)\n{\n\tarena_run_t *run;\n\tarena_bin_t *bin;\n\tsize_t rpages_ind;\n\n\trpages_ind = pageind - arena_mapbits_small_runind_get(chunk, pageind);\n\trun = &arena_miscelm_get(chunk, rpages_ind)->run;\n\tbin = &arena->bins[run->binind];\n\tmalloc_mutex_lock(&bin->lock);\n\tarena_dalloc_bin_locked_impl(arena, chunk, ptr, bitselm, false);\n\tmalloc_mutex_unlock(&bin->lock);\n}\n\nvoid\narena_dalloc_small(tsd_t *tsd, arena_t *arena, arena_chunk_t *chunk, void *ptr,\n    size_t pageind)\n{\n\tarena_chunk_map_bits_t *bitselm;\n\n\tif (config_debug) {\n\t\t/* arena_ptr_small_binind_get() does extra sanity checking. */\n\t\tassert(arena_ptr_small_binind_get(ptr, arena_mapbits_get(chunk,\n\t\t    pageind)) != BININD_INVALID);\n\t}\n\tbitselm = arena_bitselm_get(chunk, pageind);\n\tarena_dalloc_bin(arena, chunk, ptr, pageind, bitselm);\n\tarena_decay_tick(tsd, arena);\n}\n\n#ifdef JEMALLOC_JET\n#undef arena_dalloc_junk_large\n#define\tarena_dalloc_junk_large JEMALLOC_N(arena_dalloc_junk_large_impl)\n#endif\nvoid\narena_dalloc_junk_large(void *ptr, size_t usize)\n{\n\n\tif (config_fill && unlikely(opt_junk_free))\n\t\tmemset(ptr, 0x5a, usize);\n}\n#ifdef JEMALLOC_JET\n#undef arena_dalloc_junk_large\n#define\tarena_dalloc_junk_large JEMALLOC_N(arena_dalloc_junk_large)\narena_dalloc_junk_large_t *arena_dalloc_junk_large =\n    JEMALLOC_N(arena_dalloc_junk_large_impl);\n#endif\n\nstatic void\narena_dalloc_large_locked_impl(arena_t *arena, arena_chunk_t *chunk,\n    void *ptr, bool junked)\n{\n\tsize_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;\n\tarena_chunk_map_misc_t *miscelm = arena_miscelm_get(chunk, pageind);\n\tarena_run_t *run = &miscelm->run;\n\n\tif (config_fill || config_stats) {\n\t\tsize_t usize = arena_mapbits_large_size_get(chunk, pageind) -\n\t\t    large_pad;\n\n\t\tif (!junked)\n\t\t\tarena_dalloc_junk_large(ptr, usize);\n\t\tif (config_stats) {\n\t\t\tszind_t index = size2index(usize) - NBINS;\n\n\t\t\tarena->stats.ndalloc_large++;\n\t\t\tarena->stats.allocated_large -= usize;\n\t\t\tarena->stats.lstats[index].ndalloc++;\n\t\t\tarena->stats.lstats[index].curruns--;\n\t\t}\n\t}\n\n\tarena_run_dalloc(arena, run, true, false, false);\n}\n\nvoid\narena_dalloc_large_junked_locked(arena_t *arena, arena_chunk_t *chunk,\n    void *ptr)\n{\n\n\tarena_dalloc_large_locked_impl(arena, chunk, ptr, true);\n}\n\nvoid\narena_dalloc_large(tsd_t *tsd, arena_t *arena, arena_chunk_t *chunk, void *ptr)\n{\n\n\tmalloc_mutex_lock(&arena->lock);\n\tarena_dalloc_large_locked_impl(arena, chunk, ptr, false);\n\tmalloc_mutex_unlock(&arena->lock);\n\tarena_decay_tick(tsd, arena);\n}\n\nstatic void\narena_ralloc_large_shrink(arena_t *arena, arena_chunk_t *chunk, void *ptr,\n    size_t oldsize, size_t size)\n{\n\tsize_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;\n\tarena_chunk_map_misc_t *miscelm = arena_miscelm_get(chunk, pageind);\n\tarena_run_t *run = &miscelm->run;\n\n\tassert(size < oldsize);\n\n\t/*\n\t * Shrink the run, and make trailing pages available for other\n\t * allocations.\n\t */\n\tmalloc_mutex_lock(&arena->lock);\n\tarena_run_trim_tail(arena, chunk, run, oldsize + large_pad, size +\n\t    large_pad, true);\n\tif (config_stats) {\n\t\tszind_t oldindex = size2index(oldsize) - NBINS;\n\t\tszind_t index = size2index(size) - NBINS;\n\n\t\tarena->stats.ndalloc_large++;\n\t\tarena->stats.allocated_large -= oldsize;\n\t\tarena->stats.lstats[oldindex].ndalloc++;\n\t\tarena->stats.lstats[oldindex].curruns--;\n\n\t\tarena->stats.nmalloc_large++;\n\t\tarena->stats.nrequests_large++;\n\t\tarena->stats.allocated_large += size;\n\t\tarena->stats.lstats[index].nmalloc++;\n\t\tarena->stats.lstats[index].nrequests++;\n\t\tarena->stats.lstats[index].curruns++;\n\t}\n\tmalloc_mutex_unlock(&arena->lock);\n}\n\nstatic bool\narena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk, void *ptr,\n    size_t oldsize, size_t usize_min, size_t usize_max, bool zero)\n{\n\tsize_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;\n\tsize_t npages = (oldsize + large_pad) >> LG_PAGE;\n\tsize_t followsize;\n\n\tassert(oldsize == arena_mapbits_large_size_get(chunk, pageind) -\n\t    large_pad);\n\n\t/* Try to extend the run. */\n\tmalloc_mutex_lock(&arena->lock);\n\tif (pageind+npages >= chunk_npages || arena_mapbits_allocated_get(chunk,\n\t    pageind+npages) != 0)\n\t\tgoto label_fail;\n\tfollowsize = arena_mapbits_unallocated_size_get(chunk, pageind+npages);\n\tif (oldsize + followsize >= usize_min) {\n\t\t/*\n\t\t * The next run is available and sufficiently large.  Split the\n\t\t * following run, then merge the first part with the existing\n\t\t * allocation.\n\t\t */\n\t\tarena_run_t *run;\n\t\tsize_t usize, splitsize, size, flag_dirty, flag_unzeroed_mask;\n\n\t\tusize = usize_max;\n\t\twhile (oldsize + followsize < usize)\n\t\t\tusize = index2size(size2index(usize)-1);\n\t\tassert(usize >= usize_min);\n\t\tassert(usize >= oldsize);\n\t\tsplitsize = usize - oldsize;\n\t\tif (splitsize == 0)\n\t\t\tgoto label_fail;\n\n\t\trun = &arena_miscelm_get(chunk, pageind+npages)->run;\n\t\tif (arena_run_split_large(arena, run, splitsize, zero))\n\t\t\tgoto label_fail;\n\n\t\tif (config_cache_oblivious && zero) {\n\t\t\t/*\n\t\t\t * Zero the trailing bytes of the original allocation's\n\t\t\t * last page, since they are in an indeterminate state.\n\t\t\t * There will always be trailing bytes, because ptr's\n\t\t\t * offset from the beginning of the run is a multiple of\n\t\t\t * CACHELINE in [0 .. PAGE).\n\t\t\t */\n\t\t\tvoid *zbase = (void *)((uintptr_t)ptr + oldsize);\n\t\t\tvoid *zpast = PAGE_ADDR2BASE((void *)((uintptr_t)zbase +\n\t\t\t    PAGE));\n\t\t\tsize_t nzero = (uintptr_t)zpast - (uintptr_t)zbase;\n\t\t\tassert(nzero > 0);\n\t\t\tmemset(zbase, 0, nzero);\n\t\t}\n\n\t\tsize = oldsize + splitsize;\n\t\tnpages = (size + large_pad) >> LG_PAGE;\n\n\t\t/*\n\t\t * Mark the extended run as dirty if either portion of the run\n\t\t * was dirty before allocation.  This is rather pedantic,\n\t\t * because there's not actually any sequence of events that\n\t\t * could cause the resulting run to be passed to\n\t\t * arena_run_dalloc() with the dirty argument set to false\n\t\t * (which is when dirty flag consistency would really matter).\n\t\t */\n\t\tflag_dirty = arena_mapbits_dirty_get(chunk, pageind) |\n\t\t    arena_mapbits_dirty_get(chunk, pageind+npages-1);\n\t\tflag_unzeroed_mask = flag_dirty == 0 ? CHUNK_MAP_UNZEROED : 0;\n\t\tarena_mapbits_large_set(chunk, pageind, size + large_pad,\n\t\t    flag_dirty | (flag_unzeroed_mask &\n\t\t    arena_mapbits_unzeroed_get(chunk, pageind)));\n\t\tarena_mapbits_large_set(chunk, pageind+npages-1, 0, flag_dirty |\n\t\t    (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk,\n\t\t    pageind+npages-1)));\n\n\t\tif (config_stats) {\n\t\t\tszind_t oldindex = size2index(oldsize) - NBINS;\n\t\t\tszind_t index = size2index(size) - NBINS;\n\n\t\t\tarena->stats.ndalloc_large++;\n\t\t\tarena->stats.allocated_large -= oldsize;\n\t\t\tarena->stats.lstats[oldindex].ndalloc++;\n\t\t\tarena->stats.lstats[oldindex].curruns--;\n\n\t\t\tarena->stats.nmalloc_large++;\n\t\t\tarena->stats.nrequests_large++;\n\t\t\tarena->stats.allocated_large += size;\n\t\t\tarena->stats.lstats[index].nmalloc++;\n\t\t\tarena->stats.lstats[index].nrequests++;\n\t\t\tarena->stats.lstats[index].curruns++;\n\t\t}\n\t\tmalloc_mutex_unlock(&arena->lock);\n\t\treturn (false);\n\t}\nlabel_fail:\n\tmalloc_mutex_unlock(&arena->lock);\n\treturn (true);\n}\n\n#ifdef JEMALLOC_JET\n#undef arena_ralloc_junk_large\n#define\tarena_ralloc_junk_large JEMALLOC_N(arena_ralloc_junk_large_impl)\n#endif\nstatic void\narena_ralloc_junk_large(void *ptr, size_t old_usize, size_t usize)\n{\n\n\tif (config_fill && unlikely(opt_junk_free)) {\n\t\tmemset((void *)((uintptr_t)ptr + usize), 0x5a,\n\t\t    old_usize - usize);\n\t}\n}\n#ifdef JEMALLOC_JET\n#undef arena_ralloc_junk_large\n#define\tarena_ralloc_junk_large JEMALLOC_N(arena_ralloc_junk_large)\narena_ralloc_junk_large_t *arena_ralloc_junk_large =\n    JEMALLOC_N(arena_ralloc_junk_large_impl);\n#endif\n\n/*\n * Try to resize a large allocation, in order to avoid copying.  This will\n * always fail if growing an object, and the following run is already in use.\n */\nstatic bool\narena_ralloc_large(void *ptr, size_t oldsize, size_t usize_min,\n    size_t usize_max, bool zero)\n{\n\tarena_chunk_t *chunk;\n\tarena_t *arena;\n\n\tif (oldsize == usize_max) {\n\t\t/* Current size class is compatible and maximal. */\n\t\treturn (false);\n\t}\n\n\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);\n\tarena = extent_node_arena_get(&chunk->node);\n\n\tif (oldsize < usize_max) {\n\t\tbool ret = arena_ralloc_large_grow(arena, chunk, ptr, oldsize,\n\t\t    usize_min, usize_max, zero);\n\t\tif (config_fill && !ret && !zero) {\n\t\t\tif (unlikely(opt_junk_alloc)) {\n\t\t\t\tmemset((void *)((uintptr_t)ptr + oldsize), 0xa5,\n\t\t\t\t    isalloc(ptr, config_prof) - oldsize);\n\t\t\t} else if (unlikely(opt_zero)) {\n\t\t\t\tmemset((void *)((uintptr_t)ptr + oldsize), 0,\n\t\t\t\t    isalloc(ptr, config_prof) - oldsize);\n\t\t\t}\n\t\t}\n\t\treturn (ret);\n\t}\n\n\tassert(oldsize > usize_max);\n\t/* Fill before shrinking in order avoid a race. */\n\tarena_ralloc_junk_large(ptr, oldsize, usize_max);\n\tarena_ralloc_large_shrink(arena, chunk, ptr, oldsize, usize_max);\n\treturn (false);\n}\n\nbool\narena_ralloc_no_move(tsd_t *tsd, void *ptr, size_t oldsize, size_t size,\n    size_t extra, bool zero)\n{\n\tsize_t usize_min, usize_max;\n\n\t/* Calls with non-zero extra had to clamp extra. */\n\tassert(extra == 0 || size + extra <= HUGE_MAXCLASS);\n\n\tif (unlikely(size > HUGE_MAXCLASS))\n\t\treturn (true);\n\n\tusize_min = s2u(size);\n\tusize_max = s2u(size + extra);\n\tif (likely(oldsize <= large_maxclass && usize_min <= large_maxclass)) {\n\t\tarena_chunk_t *chunk;\n\n\t\t/*\n\t\t * Avoid moving the allocation if the size class can be left the\n\t\t * same.\n\t\t */\n\t\tif (oldsize <= SMALL_MAXCLASS) {\n\t\t\tassert(arena_bin_info[size2index(oldsize)].reg_size ==\n\t\t\t    oldsize);\n\t\t\tif ((usize_max > SMALL_MAXCLASS ||\n\t\t\t    size2index(usize_max) != size2index(oldsize)) &&\n\t\t\t    (size > oldsize || usize_max < oldsize))\n\t\t\t\treturn (true);\n\t\t} else {\n\t\t\tif (usize_max <= SMALL_MAXCLASS)\n\t\t\t\treturn (true);\n\t\t\tif (arena_ralloc_large(ptr, oldsize, usize_min,\n\t\t\t    usize_max, zero))\n\t\t\t\treturn (true);\n\t\t}\n\n\t\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);\n\t\tarena_decay_tick(tsd, extent_node_arena_get(&chunk->node));\n\t\treturn (false);\n\t} else {\n\t\treturn (huge_ralloc_no_move(tsd, ptr, oldsize, usize_min,\n\t\t    usize_max, zero));\n\t}\n}\n\nstatic void *\narena_ralloc_move_helper(tsd_t *tsd, arena_t *arena, size_t usize,\n    size_t alignment, bool zero, tcache_t *tcache)\n{\n\n\tif (alignment == 0)\n\t\treturn (arena_malloc(tsd, arena, usize, size2index(usize), zero,\n\t\t    tcache, true));\n\tusize = sa2u(usize, alignment);\n\tif (unlikely(usize == 0 || usize > HUGE_MAXCLASS))\n\t\treturn (NULL);\n\treturn (ipalloct(tsd, usize, alignment, zero, tcache, arena));\n}\n\nvoid *\narena_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, size_t size,\n    size_t alignment, bool zero, tcache_t *tcache)\n{\n\tvoid *ret;\n\tsize_t usize;\n\n\tusize = s2u(size);\n\tif (unlikely(usize == 0 || size > HUGE_MAXCLASS))\n\t\treturn (NULL);\n\n\tif (likely(usize <= large_maxclass)) {\n\t\tsize_t copysize;\n\n\t\t/* Try to avoid moving the allocation. */\n\t\tif (!arena_ralloc_no_move(tsd, ptr, oldsize, usize, 0, zero))\n\t\t\treturn (ptr);\n\n\t\t/*\n\t\t * size and oldsize are different enough that we need to move\n\t\t * the object.  In that case, fall back to allocating new space\n\t\t * and copying.\n\t\t */\n\t\tret = arena_ralloc_move_helper(tsd, arena, usize, alignment,\n\t\t    zero, tcache);\n\t\tif (ret == NULL)\n\t\t\treturn (NULL);\n\n\t\t/*\n\t\t * Junk/zero-filling were already done by\n\t\t * ipalloc()/arena_malloc().\n\t\t */\n\n\t\tcopysize = (usize < oldsize) ? usize : oldsize;\n\t\tJEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, copysize);\n\t\tmemcpy(ret, ptr, copysize);\n\t\tisqalloc(tsd, ptr, oldsize, tcache);\n\t} else {\n\t\tret = huge_ralloc(tsd, arena, ptr, oldsize, usize, alignment,\n\t\t    zero, tcache);\n\t}\n\treturn (ret);\n}\n\ndss_prec_t\narena_dss_prec_get(arena_t *arena)\n{\n\tdss_prec_t ret;\n\n\tmalloc_mutex_lock(&arena->lock);\n\tret = arena->dss_prec;\n\tmalloc_mutex_unlock(&arena->lock);\n\treturn (ret);\n}\n\nbool\narena_dss_prec_set(arena_t *arena, dss_prec_t dss_prec)\n{\n\n\tif (!have_dss)\n\t\treturn (dss_prec != dss_prec_disabled);\n\tmalloc_mutex_lock(&arena->lock);\n\tarena->dss_prec = dss_prec;\n\tmalloc_mutex_unlock(&arena->lock);\n\treturn (false);\n}\n\nssize_t\narena_lg_dirty_mult_default_get(void)\n{\n\n\treturn ((ssize_t)atomic_read_z((size_t *)&lg_dirty_mult_default));\n}\n\nbool\narena_lg_dirty_mult_default_set(ssize_t lg_dirty_mult)\n{\n\n\tif (opt_purge != purge_mode_ratio)\n\t\treturn (true);\n\tif (!arena_lg_dirty_mult_valid(lg_dirty_mult))\n\t\treturn (true);\n\tatomic_write_z((size_t *)&lg_dirty_mult_default, (size_t)lg_dirty_mult);\n\treturn (false);\n}\n\nssize_t\narena_decay_time_default_get(void)\n{\n\n\treturn ((ssize_t)atomic_read_z((size_t *)&decay_time_default));\n}\n\nbool\narena_decay_time_default_set(ssize_t decay_time)\n{\n\n\tif (opt_purge != purge_mode_decay)\n\t\treturn (true);\n\tif (!arena_decay_time_valid(decay_time))\n\t\treturn (true);\n\tatomic_write_z((size_t *)&decay_time_default, (size_t)decay_time);\n\treturn (false);\n}\n\nstatic void\narena_basic_stats_merge_locked(arena_t *arena, unsigned *nthreads,\n    const char **dss, ssize_t *lg_dirty_mult, ssize_t *decay_time,\n    size_t *nactive, size_t *ndirty)\n{\n\n\t*nthreads += arena_nthreads_get(arena);\n\t*dss = dss_prec_names[arena->dss_prec];\n\t*lg_dirty_mult = arena->lg_dirty_mult;\n\t*decay_time = arena->decay_time;\n\t*nactive += arena->nactive;\n\t*ndirty += arena->ndirty;\n}\n\nvoid\narena_basic_stats_merge(arena_t *arena, unsigned *nthreads, const char **dss,\n    ssize_t *lg_dirty_mult, ssize_t *decay_time, size_t *nactive,\n    size_t *ndirty)\n{\n\n\tmalloc_mutex_lock(&arena->lock);\n\tarena_basic_stats_merge_locked(arena, nthreads, dss, lg_dirty_mult,\n\t    decay_time, nactive, ndirty);\n\tmalloc_mutex_unlock(&arena->lock);\n}\n\nvoid\narena_stats_merge(arena_t *arena, unsigned *nthreads, const char **dss,\n    ssize_t *lg_dirty_mult, ssize_t *decay_time, size_t *nactive,\n    size_t *ndirty, arena_stats_t *astats, malloc_bin_stats_t *bstats,\n    malloc_large_stats_t *lstats, malloc_huge_stats_t *hstats)\n{\n\tunsigned i;\n\n\tcassert(config_stats);\n\n\tmalloc_mutex_lock(&arena->lock);\n\tarena_basic_stats_merge_locked(arena, nthreads, dss, lg_dirty_mult,\n\t    decay_time, nactive, ndirty);\n\n\tastats->mapped += arena->stats.mapped;\n\tastats->npurge += arena->stats.npurge;\n\tastats->nmadvise += arena->stats.nmadvise;\n\tastats->purged += arena->stats.purged;\n\tastats->metadata_mapped += arena->stats.metadata_mapped;\n\tastats->metadata_allocated += arena_metadata_allocated_get(arena);\n\tastats->allocated_large += arena->stats.allocated_large;\n\tastats->nmalloc_large += arena->stats.nmalloc_large;\n\tastats->ndalloc_large += arena->stats.ndalloc_large;\n\tastats->nrequests_large += arena->stats.nrequests_large;\n\tastats->allocated_huge += arena->stats.allocated_huge;\n\tastats->nmalloc_huge += arena->stats.nmalloc_huge;\n\tastats->ndalloc_huge += arena->stats.ndalloc_huge;\n\n\tfor (i = 0; i < nlclasses; i++) {\n\t\tlstats[i].nmalloc += arena->stats.lstats[i].nmalloc;\n\t\tlstats[i].ndalloc += arena->stats.lstats[i].ndalloc;\n\t\tlstats[i].nrequests += arena->stats.lstats[i].nrequests;\n\t\tlstats[i].curruns += arena->stats.lstats[i].curruns;\n\t}\n\n\tfor (i = 0; i < nhclasses; i++) {\n\t\thstats[i].nmalloc += arena->stats.hstats[i].nmalloc;\n\t\thstats[i].ndalloc += arena->stats.hstats[i].ndalloc;\n\t\thstats[i].curhchunks += arena->stats.hstats[i].curhchunks;\n\t}\n\tmalloc_mutex_unlock(&arena->lock);\n\n\tfor (i = 0; i < NBINS; i++) {\n\t\tarena_bin_t *bin = &arena->bins[i];\n\n\t\tmalloc_mutex_lock(&bin->lock);\n\t\tbstats[i].nmalloc += bin->stats.nmalloc;\n\t\tbstats[i].ndalloc += bin->stats.ndalloc;\n\t\tbstats[i].nrequests += bin->stats.nrequests;\n\t\tbstats[i].curregs += bin->stats.curregs;\n\t\tif (config_tcache) {\n\t\t\tbstats[i].nfills += bin->stats.nfills;\n\t\t\tbstats[i].nflushes += bin->stats.nflushes;\n\t\t}\n\t\tbstats[i].nruns += bin->stats.nruns;\n\t\tbstats[i].reruns += bin->stats.reruns;\n\t\tbstats[i].curruns += bin->stats.curruns;\n\t\tmalloc_mutex_unlock(&bin->lock);\n\t}\n}\n\nunsigned\narena_nthreads_get(arena_t *arena)\n{\n\n\treturn (atomic_read_u(&arena->nthreads));\n}\n\nvoid\narena_nthreads_inc(arena_t *arena)\n{\n\n\tatomic_add_u(&arena->nthreads, 1);\n}\n\nvoid\narena_nthreads_dec(arena_t *arena)\n{\n\n\tatomic_sub_u(&arena->nthreads, 1);\n}\n\narena_t *\narena_new(unsigned ind)\n{\n\tarena_t *arena;\n\tsize_t arena_size;\n\tunsigned i;\n\tarena_bin_t *bin;\n\n\t/* Compute arena size to incorporate sufficient runs_avail elements. */\n\tarena_size = offsetof(arena_t, runs_avail) + (sizeof(arena_run_tree_t) *\n\t    runs_avail_nclasses);\n\t/*\n\t * Allocate arena, arena->lstats, and arena->hstats contiguously, mainly\n\t * because there is no way to clean up if base_alloc() OOMs.\n\t */\n\tif (config_stats) {\n\t\tarena = (arena_t *)base_alloc(CACHELINE_CEILING(arena_size) +\n\t\t    QUANTUM_CEILING(nlclasses * sizeof(malloc_large_stats_t) +\n\t\t    nhclasses) * sizeof(malloc_huge_stats_t));\n\t} else\n\t\tarena = (arena_t *)base_alloc(arena_size);\n\tif (arena == NULL)\n\t\treturn (NULL);\n\n\tarena->ind = ind;\n\tarena->nthreads = 0;\n\tif (malloc_mutex_init(&arena->lock))\n\t\treturn (NULL);\n\n\tif (config_stats) {\n\t\tmemset(&arena->stats, 0, sizeof(arena_stats_t));\n\t\tarena->stats.lstats = (malloc_large_stats_t *)((uintptr_t)arena\n\t\t    + CACHELINE_CEILING(arena_size));\n\t\tmemset(arena->stats.lstats, 0, nlclasses *\n\t\t    sizeof(malloc_large_stats_t));\n\t\tarena->stats.hstats = (malloc_huge_stats_t *)((uintptr_t)arena\n\t\t    + CACHELINE_CEILING(arena_size) +\n\t\t    QUANTUM_CEILING(nlclasses * sizeof(malloc_large_stats_t)));\n\t\tmemset(arena->stats.hstats, 0, nhclasses *\n\t\t    sizeof(malloc_huge_stats_t));\n\t\tif (config_tcache)\n\t\t\tql_new(&arena->tcache_ql);\n\t}\n\n\tif (config_prof)\n\t\tarena->prof_accumbytes = 0;\n\n\tif (config_cache_oblivious) {\n\t\t/*\n\t\t * A nondeterministic seed based on the address of arena reduces\n\t\t * the likelihood of lockstep non-uniform cache index\n\t\t * utilization among identical concurrent processes, but at the\n\t\t * cost of test repeatability.  For debug builds, instead use a\n\t\t * deterministic seed.\n\t\t */\n\t\tarena->offset_state = config_debug ? ind :\n\t\t    (uint64_t)(uintptr_t)arena;\n\t}\n\n\tarena->dss_prec = chunk_dss_prec_get();\n\n\tarena->spare = NULL;\n\n\tarena->lg_dirty_mult = arena_lg_dirty_mult_default_get();\n\tarena->purging = false;\n\tarena->nactive = 0;\n\tarena->ndirty = 0;\n\n\tfor(i = 0; i < runs_avail_nclasses; i++)\n\t\tarena_run_tree_new(&arena->runs_avail[i]);\n\tqr_new(&arena->runs_dirty, rd_link);\n\tqr_new(&arena->chunks_cache, cc_link);\n\n\tif (opt_purge == purge_mode_decay)\n\t\tarena_decay_init(arena, arena_decay_time_default_get());\n\n\tql_new(&arena->huge);\n\tif (malloc_mutex_init(&arena->huge_mtx))\n\t\treturn (NULL);\n\n\textent_tree_szad_new(&arena->chunks_szad_cached);\n\textent_tree_ad_new(&arena->chunks_ad_cached);\n\textent_tree_szad_new(&arena->chunks_szad_retained);\n\textent_tree_ad_new(&arena->chunks_ad_retained);\n\tif (malloc_mutex_init(&arena->chunks_mtx))\n\t\treturn (NULL);\n\tql_new(&arena->node_cache);\n\tif (malloc_mutex_init(&arena->node_cache_mtx))\n\t\treturn (NULL);\n\n\tarena->chunk_hooks = chunk_hooks_default;\n\n\t/* Initialize bins. */\n\tfor (i = 0; i < NBINS; i++) {\n\t\tbin = &arena->bins[i];\n\t\tif (malloc_mutex_init(&bin->lock))\n\t\t\treturn (NULL);\n\t\tbin->runcur = NULL;\n\t\tarena_run_tree_new(&bin->runs);\n\t\tif (config_stats)\n\t\t\tmemset(&bin->stats, 0, sizeof(malloc_bin_stats_t));\n\t}\n\n\treturn (arena);\n}\n\n/*\n * Calculate bin_info->run_size such that it meets the following constraints:\n *\n *   *) bin_info->run_size <= arena_maxrun\n *   *) bin_info->nregs <= RUN_MAXREGS\n *\n * bin_info->nregs and bin_info->reg0_offset are also calculated here, since\n * these settings are all interdependent.\n */\nstatic void\nbin_info_run_size_calc(arena_bin_info_t *bin_info)\n{\n\tsize_t pad_size;\n\tsize_t try_run_size, perfect_run_size, actual_run_size;\n\tuint32_t try_nregs, perfect_nregs, actual_nregs;\n\n\t/*\n\t * Determine redzone size based on minimum alignment and minimum\n\t * redzone size.  Add padding to the end of the run if it is needed to\n\t * align the regions.  The padding allows each redzone to be half the\n\t * minimum alignment; without the padding, each redzone would have to\n\t * be twice as large in order to maintain alignment.\n\t */\n\tif (config_fill && unlikely(opt_redzone)) {\n\t\tsize_t align_min = ZU(1) << (ffs_zu(bin_info->reg_size) - 1);\n\t\tif (align_min <= REDZONE_MINSIZE) {\n\t\t\tbin_info->redzone_size = REDZONE_MINSIZE;\n\t\t\tpad_size = 0;\n\t\t} else {\n\t\t\tbin_info->redzone_size = align_min >> 1;\n\t\t\tpad_size = bin_info->redzone_size;\n\t\t}\n\t} else {\n\t\tbin_info->redzone_size = 0;\n\t\tpad_size = 0;\n\t}\n\tbin_info->reg_interval = bin_info->reg_size +\n\t    (bin_info->redzone_size << 1);\n\n\t/*\n\t * Compute run size under ideal conditions (no redzones, no limit on run\n\t * size).\n\t */\n\ttry_run_size = PAGE;\n\ttry_nregs = (uint32_t)(try_run_size / bin_info->reg_size);\n\tdo {\n\t\tperfect_run_size = try_run_size;\n\t\tperfect_nregs = try_nregs;\n\n\t\ttry_run_size += PAGE;\n\t\ttry_nregs = (uint32_t)(try_run_size / bin_info->reg_size);\n\t} while (perfect_run_size != perfect_nregs * bin_info->reg_size);\n\tassert(perfect_nregs <= RUN_MAXREGS);\n\n\tactual_run_size = perfect_run_size;\n\tactual_nregs = (uint32_t)((actual_run_size - pad_size) /\n\t    bin_info->reg_interval);\n\n\t/*\n\t * Redzones can require enough padding that not even a single region can\n\t * fit within the number of pages that would normally be dedicated to a\n\t * run for this size class.  Increase the run size until at least one\n\t * region fits.\n\t */\n\twhile (actual_nregs == 0) {\n\t\tassert(config_fill && unlikely(opt_redzone));\n\n\t\tactual_run_size += PAGE;\n\t\tactual_nregs = (uint32_t)((actual_run_size - pad_size) /\n\t\t    bin_info->reg_interval);\n\t}\n\n\t/*\n\t * Make sure that the run will fit within an arena chunk.\n\t */\n\twhile (actual_run_size > arena_maxrun) {\n\t\tactual_run_size -= PAGE;\n\t\tactual_nregs = (uint32_t)((actual_run_size - pad_size) /\n\t\t    bin_info->reg_interval);\n\t}\n\tassert(actual_nregs > 0);\n\tassert(actual_run_size == s2u(actual_run_size));\n\n\t/* Copy final settings. */\n\tbin_info->run_size = actual_run_size;\n\tbin_info->nregs = actual_nregs;\n\tbin_info->reg0_offset = (uint32_t)(actual_run_size - (actual_nregs *\n\t    bin_info->reg_interval) - pad_size + bin_info->redzone_size);\n\n\tif (actual_run_size > small_maxrun)\n\t\tsmall_maxrun = actual_run_size;\n\n\tassert(bin_info->reg0_offset - bin_info->redzone_size + (bin_info->nregs\n\t    * bin_info->reg_interval) + pad_size == bin_info->run_size);\n}\n\nstatic void\nbin_info_init(void)\n{\n\tarena_bin_info_t *bin_info;\n\n#define\tBIN_INFO_INIT_bin_yes(index, size)\t\t\t\t\\\n\tbin_info = &arena_bin_info[index];\t\t\t\t\\\n\tbin_info->reg_size = size;\t\t\t\t\t\\\n\tbin_info_run_size_calc(bin_info);\t\t\t\t\\\n\tbitmap_info_init(&bin_info->bitmap_info, bin_info->nregs);\n#define\tBIN_INFO_INIT_bin_no(index, size)\n#define\tSC(index, lg_grp, lg_delta, ndelta, bin, lg_delta_lookup)\t\\\n\tBIN_INFO_INIT_bin_##bin(index, (ZU(1)<<lg_grp) + (ZU(ndelta)<<lg_delta))\n\tSIZE_CLASSES\n#undef BIN_INFO_INIT_bin_yes\n#undef BIN_INFO_INIT_bin_no\n#undef SC\n}\n\nstatic bool\nsmall_run_size_init(void)\n{\n\n\tassert(small_maxrun != 0);\n\n\tsmall_run_tab = (bool *)base_alloc(sizeof(bool) * (small_maxrun >>\n\t    LG_PAGE));\n\tif (small_run_tab == NULL)\n\t\treturn (true);\n\n#define\tTAB_INIT_bin_yes(index, size) {\t\t\t\t\t\\\n\t\tarena_bin_info_t *bin_info = &arena_bin_info[index];\t\\\n\t\tsmall_run_tab[bin_info->run_size >> LG_PAGE] = true;\t\\\n\t}\n#define\tTAB_INIT_bin_no(index, size)\n#define\tSC(index, lg_grp, lg_delta, ndelta, bin, lg_delta_lookup)\t\\\n\tTAB_INIT_bin_##bin(index, (ZU(1)<<lg_grp) + (ZU(ndelta)<<lg_delta))\n\tSIZE_CLASSES\n#undef TAB_INIT_bin_yes\n#undef TAB_INIT_bin_no\n#undef SC\n\n\treturn (false);\n}\n\nstatic bool\nrun_quantize_init(void)\n{\n\tunsigned i;\n\n\trun_quantize_max = chunksize + large_pad;\n\n\trun_quantize_floor_tab = (size_t *)base_alloc(sizeof(size_t) *\n\t    (run_quantize_max >> LG_PAGE));\n\tif (run_quantize_floor_tab == NULL)\n\t\treturn (true);\n\n\trun_quantize_ceil_tab = (size_t *)base_alloc(sizeof(size_t) *\n\t    (run_quantize_max >> LG_PAGE));\n\tif (run_quantize_ceil_tab == NULL)\n\t\treturn (true);\n\n\tfor (i = 1; i <= run_quantize_max >> LG_PAGE; i++) {\n\t\tsize_t run_size = i << LG_PAGE;\n\n\t\trun_quantize_floor_tab[i-1] =\n\t\t    run_quantize_floor_compute(run_size);\n\t\trun_quantize_ceil_tab[i-1] =\n\t\t    run_quantize_ceil_compute(run_size);\n\t}\n\n\treturn (false);\n}\n\nbool\narena_boot(void)\n{\n\tunsigned i;\n\n\tarena_lg_dirty_mult_default_set(opt_lg_dirty_mult);\n\tarena_decay_time_default_set(opt_decay_time);\n\n\t/*\n\t * Compute the header size such that it is large enough to contain the\n\t * page map.  The page map is biased to omit entries for the header\n\t * itself, so some iteration is necessary to compute the map bias.\n\t *\n\t * 1) Compute safe header_size and map_bias values that include enough\n\t *    space for an unbiased page map.\n\t * 2) Refine map_bias based on (1) to omit the header pages in the page\n\t *    map.  The resulting map_bias may be one too small.\n\t * 3) Refine map_bias based on (2).  The result will be >= the result\n\t *    from (2), and will always be correct.\n\t */\n\tmap_bias = 0;\n\tfor (i = 0; i < 3; i++) {\n\t\tsize_t header_size = offsetof(arena_chunk_t, map_bits) +\n\t\t    ((sizeof(arena_chunk_map_bits_t) +\n\t\t    sizeof(arena_chunk_map_misc_t)) * (chunk_npages-map_bias));\n\t\tmap_bias = (header_size + PAGE_MASK) >> LG_PAGE;\n\t}\n\tassert(map_bias > 0);\n\n\tmap_misc_offset = offsetof(arena_chunk_t, map_bits) +\n\t    sizeof(arena_chunk_map_bits_t) * (chunk_npages-map_bias);\n\n\tarena_maxrun = chunksize - (map_bias << LG_PAGE);\n\tassert(arena_maxrun > 0);\n\tlarge_maxclass = index2size(size2index(chunksize)-1);\n\tif (large_maxclass > arena_maxrun) {\n\t\t/*\n\t\t * For small chunk sizes it's possible for there to be fewer\n\t\t * non-header pages available than are necessary to serve the\n\t\t * size classes just below chunksize.\n\t\t */\n\t\tlarge_maxclass = arena_maxrun;\n\t}\n\tassert(large_maxclass > 0);\n\tnlclasses = size2index(large_maxclass) - size2index(SMALL_MAXCLASS);\n\tnhclasses = NSIZES - nlclasses - NBINS;\n\n\tbin_info_init();\n\tif (small_run_size_init())\n\t\treturn (true);\n\tif (run_quantize_init())\n\t\treturn (true);\n\n\truns_avail_bias = size2index(PAGE);\n\truns_avail_nclasses = size2index(run_quantize_max)+1 - runs_avail_bias;\n\n\treturn (false);\n}\n\nvoid\narena_prefork(arena_t *arena)\n{\n\tunsigned i;\n\n\tmalloc_mutex_prefork(&arena->lock);\n\tmalloc_mutex_prefork(&arena->huge_mtx);\n\tmalloc_mutex_prefork(&arena->chunks_mtx);\n\tmalloc_mutex_prefork(&arena->node_cache_mtx);\n\tfor (i = 0; i < NBINS; i++)\n\t\tmalloc_mutex_prefork(&arena->bins[i].lock);\n}\n\nvoid\narena_postfork_parent(arena_t *arena)\n{\n\tunsigned i;\n\n\tfor (i = 0; i < NBINS; i++)\n\t\tmalloc_mutex_postfork_parent(&arena->bins[i].lock);\n\tmalloc_mutex_postfork_parent(&arena->node_cache_mtx);\n\tmalloc_mutex_postfork_parent(&arena->chunks_mtx);\n\tmalloc_mutex_postfork_parent(&arena->huge_mtx);\n\tmalloc_mutex_postfork_parent(&arena->lock);\n}\n\nvoid\narena_postfork_child(arena_t *arena)\n{\n\tunsigned i;\n\n\tfor (i = 0; i < NBINS; i++)\n\t\tmalloc_mutex_postfork_child(&arena->bins[i].lock);\n\tmalloc_mutex_postfork_child(&arena->node_cache_mtx);\n\tmalloc_mutex_postfork_child(&arena->chunks_mtx);\n\tmalloc_mutex_postfork_child(&arena->huge_mtx);\n\tmalloc_mutex_postfork_child(&arena->lock);\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/atomic.c",
    "content": "#define\tJEMALLOC_ATOMIC_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/base.c",
    "content": "#define\tJEMALLOC_BASE_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n/******************************************************************************/\n/* Data. */\n\nstatic malloc_mutex_t\tbase_mtx;\nstatic extent_tree_t\tbase_avail_szad;\nstatic extent_node_t\t*base_nodes;\nstatic size_t\t\tbase_allocated;\nstatic size_t\t\tbase_resident;\nstatic size_t\t\tbase_mapped;\n\n/******************************************************************************/\n\n/* base_mtx must be held. */\nstatic extent_node_t *\nbase_node_try_alloc(void)\n{\n\textent_node_t *node;\n\n\tif (base_nodes == NULL)\n\t\treturn (NULL);\n\tnode = base_nodes;\n\tbase_nodes = *(extent_node_t **)node;\n\tJEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(node, sizeof(extent_node_t));\n\treturn (node);\n}\n\n/* base_mtx must be held. */\nstatic void\nbase_node_dalloc(extent_node_t *node)\n{\n\n\tJEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(node, sizeof(extent_node_t));\n\t*(extent_node_t **)node = base_nodes;\n\tbase_nodes = node;\n}\n\n/* base_mtx must be held. */\nstatic extent_node_t *\nbase_chunk_alloc(size_t minsize)\n{\n\textent_node_t *node;\n\tsize_t csize, nsize;\n\tvoid *addr;\n\n\tassert(minsize != 0);\n\tnode = base_node_try_alloc();\n\t/* Allocate enough space to also carve a node out if necessary. */\n\tnsize = (node == NULL) ? CACHELINE_CEILING(sizeof(extent_node_t)) : 0;\n\tcsize = CHUNK_CEILING(minsize + nsize);\n\taddr = chunk_alloc_base(csize);\n\tif (addr == NULL) {\n\t\tif (node != NULL)\n\t\t\tbase_node_dalloc(node);\n\t\treturn (NULL);\n\t}\n\tbase_mapped += csize;\n\tif (node == NULL) {\n\t\tnode = (extent_node_t *)addr;\n\t\taddr = (void *)((uintptr_t)addr + nsize);\n\t\tcsize -= nsize;\n\t\tif (config_stats) {\n\t\t\tbase_allocated += nsize;\n\t\t\tbase_resident += PAGE_CEILING(nsize);\n\t\t}\n\t}\n\textent_node_init(node, NULL, addr, csize, true, true);\n\treturn (node);\n}\n\n/*\n * base_alloc() guarantees demand-zeroed memory, in order to make multi-page\n * sparse data structures such as radix tree nodes efficient with respect to\n * physical memory usage.\n */\nvoid *\nbase_alloc(size_t size)\n{\n\tvoid *ret;\n\tsize_t csize, usize;\n\textent_node_t *node;\n\textent_node_t key;\n\n\t/*\n\t * Round size up to nearest multiple of the cacheline size, so that\n\t * there is no chance of false cache line sharing.\n\t */\n\tcsize = CACHELINE_CEILING(size);\n\n\tusize = s2u(csize);\n\textent_node_init(&key, NULL, NULL, usize, false, false);\n\tmalloc_mutex_lock(&base_mtx);\n\tnode = extent_tree_szad_nsearch(&base_avail_szad, &key);\n\tif (node != NULL) {\n\t\t/* Use existing space. */\n\t\textent_tree_szad_remove(&base_avail_szad, node);\n\t} else {\n\t\t/* Try to allocate more space. */\n\t\tnode = base_chunk_alloc(csize);\n\t}\n\tif (node == NULL) {\n\t\tret = NULL;\n\t\tgoto label_return;\n\t}\n\n\tret = extent_node_addr_get(node);\n\tif (extent_node_size_get(node) > csize) {\n\t\textent_node_addr_set(node, (void *)((uintptr_t)ret + csize));\n\t\textent_node_size_set(node, extent_node_size_get(node) - csize);\n\t\textent_tree_szad_insert(&base_avail_szad, node);\n\t} else\n\t\tbase_node_dalloc(node);\n\tif (config_stats) {\n\t\tbase_allocated += csize;\n\t\t/*\n\t\t * Add one PAGE to base_resident for every page boundary that is\n\t\t * crossed by the new allocation.\n\t\t */\n\t\tbase_resident += PAGE_CEILING((uintptr_t)ret + csize) -\n\t\t    PAGE_CEILING((uintptr_t)ret);\n\t}\n\tJEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ret, csize);\nlabel_return:\n\tmalloc_mutex_unlock(&base_mtx);\n\treturn (ret);\n}\n\nvoid\nbase_stats_get(size_t *allocated, size_t *resident, size_t *mapped)\n{\n\n\tmalloc_mutex_lock(&base_mtx);\n\tassert(base_allocated <= base_resident);\n\tassert(base_resident <= base_mapped);\n\t*allocated = base_allocated;\n\t*resident = base_resident;\n\t*mapped = base_mapped;\n\tmalloc_mutex_unlock(&base_mtx);\n}\n\nbool\nbase_boot(void)\n{\n\n\tif (malloc_mutex_init(&base_mtx))\n\t\treturn (true);\n\textent_tree_szad_new(&base_avail_szad);\n\tbase_nodes = NULL;\n\n\treturn (false);\n}\n\nvoid\nbase_prefork(void)\n{\n\n\tmalloc_mutex_prefork(&base_mtx);\n}\n\nvoid\nbase_postfork_parent(void)\n{\n\n\tmalloc_mutex_postfork_parent(&base_mtx);\n}\n\nvoid\nbase_postfork_child(void)\n{\n\n\tmalloc_mutex_postfork_child(&base_mtx);\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/bitmap.c",
    "content": "#define\tJEMALLOC_BITMAP_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n/******************************************************************************/\n\n#ifdef USE_TREE\n\nvoid\nbitmap_info_init(bitmap_info_t *binfo, size_t nbits)\n{\n\tunsigned i;\n\tsize_t group_count;\n\n\tassert(nbits > 0);\n\tassert(nbits <= (ZU(1) << LG_BITMAP_MAXBITS));\n\n\t/*\n\t * Compute the number of groups necessary to store nbits bits, and\n\t * progressively work upward through the levels until reaching a level\n\t * that requires only one group.\n\t */\n\tbinfo->levels[0].group_offset = 0;\n\tgroup_count = BITMAP_BITS2GROUPS(nbits);\n\tfor (i = 1; group_count > 1; i++) {\n\t\tassert(i < BITMAP_MAX_LEVELS);\n\t\tbinfo->levels[i].group_offset = binfo->levels[i-1].group_offset\n\t\t    + group_count;\n\t\tgroup_count = BITMAP_BITS2GROUPS(group_count);\n\t}\n\tbinfo->levels[i].group_offset = binfo->levels[i-1].group_offset\n\t    + group_count;\n\tassert(binfo->levels[i].group_offset <= BITMAP_GROUPS_MAX);\n\tbinfo->nlevels = i;\n\tbinfo->nbits = nbits;\n}\n\nstatic size_t\nbitmap_info_ngroups(const bitmap_info_t *binfo)\n{\n\n\treturn (binfo->levels[binfo->nlevels].group_offset);\n}\n\nvoid\nbitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo)\n{\n\tsize_t extra;\n\tunsigned i;\n\n\t/*\n\t * Bits are actually inverted with regard to the external bitmap\n\t * interface, so the bitmap starts out with all 1 bits, except for\n\t * trailing unused bits (if any).  Note that each group uses bit 0 to\n\t * correspond to the first logical bit in the group, so extra bits\n\t * are the most significant bits of the last group.\n\t */\n\tmemset(bitmap, 0xffU, bitmap_size(binfo));\n\textra = (BITMAP_GROUP_NBITS - (binfo->nbits & BITMAP_GROUP_NBITS_MASK))\n\t    & BITMAP_GROUP_NBITS_MASK;\n\tif (extra != 0)\n\t\tbitmap[binfo->levels[1].group_offset - 1] >>= extra;\n\tfor (i = 1; i < binfo->nlevels; i++) {\n\t\tsize_t group_count = binfo->levels[i].group_offset -\n\t\t    binfo->levels[i-1].group_offset;\n\t\textra = (BITMAP_GROUP_NBITS - (group_count &\n\t\t    BITMAP_GROUP_NBITS_MASK)) & BITMAP_GROUP_NBITS_MASK;\n\t\tif (extra != 0)\n\t\t\tbitmap[binfo->levels[i+1].group_offset - 1] >>= extra;\n\t}\n}\n\n#else /* USE_TREE */\n\nvoid\nbitmap_info_init(bitmap_info_t *binfo, size_t nbits)\n{\n\tsize_t i;\n\n\tassert(nbits > 0);\n\tassert(nbits <= (ZU(1) << LG_BITMAP_MAXBITS));\n\n\ti = nbits >> LG_BITMAP_GROUP_NBITS;\n\tif (nbits % BITMAP_GROUP_NBITS != 0)\n\t\ti++;\n\tbinfo->ngroups = i;\n\tbinfo->nbits = nbits;\n}\n\nstatic size_t\nbitmap_info_ngroups(const bitmap_info_t *binfo)\n{\n\n\treturn (binfo->ngroups);\n}\n\nvoid\nbitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo)\n{\n\tsize_t extra;\n\n\tmemset(bitmap, 0xffU, bitmap_size(binfo));\n\textra = (binfo->nbits % (binfo->ngroups * BITMAP_GROUP_NBITS));\n\tif (extra != 0)\n\t\tbitmap[binfo->ngroups - 1] >>= (BITMAP_GROUP_NBITS - extra);\n}\n\n#endif /* USE_TREE */\n\nsize_t\nbitmap_size(const bitmap_info_t *binfo)\n{\n\n\treturn (bitmap_info_ngroups(binfo) << LG_SIZEOF_BITMAP);\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/chunk.c",
    "content": "#define\tJEMALLOC_CHUNK_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n/******************************************************************************/\n/* Data. */\n\nconst char\t*opt_dss = DSS_DEFAULT;\nsize_t\t\topt_lg_chunk = 0;\n\n/* Used exclusively for gdump triggering. */\nstatic size_t\tcurchunks;\nstatic size_t\thighchunks;\n\nrtree_t\t\tchunks_rtree;\n\n/* Various chunk-related settings. */\nsize_t\t\tchunksize;\nsize_t\t\tchunksize_mask; /* (chunksize - 1). */\nsize_t\t\tchunk_npages;\n\nstatic void\t*chunk_alloc_default(void *new_addr, size_t size,\n    size_t alignment, bool *zero, bool *commit, unsigned arena_ind);\nstatic bool\tchunk_dalloc_default(void *chunk, size_t size, bool committed,\n    unsigned arena_ind);\nstatic bool\tchunk_commit_default(void *chunk, size_t size, size_t offset,\n    size_t length, unsigned arena_ind);\nstatic bool\tchunk_decommit_default(void *chunk, size_t size, size_t offset,\n    size_t length, unsigned arena_ind);\nstatic bool\tchunk_purge_default(void *chunk, size_t size, size_t offset,\n    size_t length, unsigned arena_ind);\nstatic bool\tchunk_split_default(void *chunk, size_t size, size_t size_a,\n    size_t size_b, bool committed, unsigned arena_ind);\nstatic bool\tchunk_merge_default(void *chunk_a, size_t size_a, void *chunk_b,\n    size_t size_b, bool committed, unsigned arena_ind);\n\nconst chunk_hooks_t\tchunk_hooks_default = {\n\tchunk_alloc_default,\n\tchunk_dalloc_default,\n\tchunk_commit_default,\n\tchunk_decommit_default,\n\tchunk_purge_default,\n\tchunk_split_default,\n\tchunk_merge_default\n};\n\n/******************************************************************************/\n/*\n * Function prototypes for static functions that are referenced prior to\n * definition.\n */\n\nstatic void\tchunk_record(arena_t *arena, chunk_hooks_t *chunk_hooks,\n    extent_tree_t *chunks_szad, extent_tree_t *chunks_ad, bool cache,\n    void *chunk, size_t size, bool zeroed, bool committed);\n\n/******************************************************************************/\n\nstatic chunk_hooks_t\nchunk_hooks_get_locked(arena_t *arena)\n{\n\n\treturn (arena->chunk_hooks);\n}\n\nchunk_hooks_t\nchunk_hooks_get(arena_t *arena)\n{\n\tchunk_hooks_t chunk_hooks;\n\n\tmalloc_mutex_lock(&arena->chunks_mtx);\n\tchunk_hooks = chunk_hooks_get_locked(arena);\n\tmalloc_mutex_unlock(&arena->chunks_mtx);\n\n\treturn (chunk_hooks);\n}\n\nchunk_hooks_t\nchunk_hooks_set(arena_t *arena, const chunk_hooks_t *chunk_hooks)\n{\n\tchunk_hooks_t old_chunk_hooks;\n\n\tmalloc_mutex_lock(&arena->chunks_mtx);\n\told_chunk_hooks = arena->chunk_hooks;\n\t/*\n\t * Copy each field atomically so that it is impossible for readers to\n\t * see partially updated pointers.  There are places where readers only\n\t * need one hook function pointer (therefore no need to copy the\n\t * entirety of arena->chunk_hooks), and stale reads do not affect\n\t * correctness, so they perform unlocked reads.\n\t */\n#define\tATOMIC_COPY_HOOK(n) do {\t\t\t\t\t\\\n\tunion {\t\t\t\t\t\t\t\t\\\n\t\tchunk_##n##_t\t**n;\t\t\t\t\t\\\n\t\tvoid\t\t**v;\t\t\t\t\t\\\n\t} u;\t\t\t\t\t\t\t\t\\\n\tu.n = &arena->chunk_hooks.n;\t\t\t\t\t\\\n\tatomic_write_p(u.v, chunk_hooks->n);\t\t\t\t\\\n} while (0)\n\tATOMIC_COPY_HOOK(alloc);\n\tATOMIC_COPY_HOOK(dalloc);\n\tATOMIC_COPY_HOOK(commit);\n\tATOMIC_COPY_HOOK(decommit);\n\tATOMIC_COPY_HOOK(purge);\n\tATOMIC_COPY_HOOK(split);\n\tATOMIC_COPY_HOOK(merge);\n#undef ATOMIC_COPY_HOOK\n\tmalloc_mutex_unlock(&arena->chunks_mtx);\n\n\treturn (old_chunk_hooks);\n}\n\nstatic void\nchunk_hooks_assure_initialized_impl(arena_t *arena, chunk_hooks_t *chunk_hooks,\n    bool locked)\n{\n\tstatic const chunk_hooks_t uninitialized_hooks =\n\t    CHUNK_HOOKS_INITIALIZER;\n\n\tif (memcmp(chunk_hooks, &uninitialized_hooks, sizeof(chunk_hooks_t)) ==\n\t    0) {\n\t\t*chunk_hooks = locked ? chunk_hooks_get_locked(arena) :\n\t\t    chunk_hooks_get(arena);\n\t}\n}\n\nstatic void\nchunk_hooks_assure_initialized_locked(arena_t *arena,\n    chunk_hooks_t *chunk_hooks)\n{\n\n\tchunk_hooks_assure_initialized_impl(arena, chunk_hooks, true);\n}\n\nstatic void\nchunk_hooks_assure_initialized(arena_t *arena, chunk_hooks_t *chunk_hooks)\n{\n\n\tchunk_hooks_assure_initialized_impl(arena, chunk_hooks, false);\n}\n\nbool\nchunk_register(const void *chunk, const extent_node_t *node)\n{\n\n\tassert(extent_node_addr_get(node) == chunk);\n\n\tif (rtree_set(&chunks_rtree, (uintptr_t)chunk, node))\n\t\treturn (true);\n\tif (config_prof && opt_prof) {\n\t\tsize_t size = extent_node_size_get(node);\n\t\tsize_t nadd = (size == 0) ? 1 : size / chunksize;\n\t\tsize_t cur = atomic_add_z(&curchunks, nadd);\n\t\tsize_t high = atomic_read_z(&highchunks);\n\t\twhile (cur > high && atomic_cas_z(&highchunks, high, cur)) {\n\t\t\t/*\n\t\t\t * Don't refresh cur, because it may have decreased\n\t\t\t * since this thread lost the highchunks update race.\n\t\t\t */\n\t\t\thigh = atomic_read_z(&highchunks);\n\t\t}\n\t\tif (cur > high && prof_gdump_get_unlocked())\n\t\t\tprof_gdump();\n\t}\n\n\treturn (false);\n}\n\nvoid\nchunk_deregister(const void *chunk, const extent_node_t *node)\n{\n\tbool err;\n\n\terr = rtree_set(&chunks_rtree, (uintptr_t)chunk, NULL);\n\tassert(!err);\n\tif (config_prof && opt_prof) {\n\t\tsize_t size = extent_node_size_get(node);\n\t\tsize_t nsub = (size == 0) ? 1 : size / chunksize;\n\t\tassert(atomic_read_z(&curchunks) >= nsub);\n\t\tatomic_sub_z(&curchunks, nsub);\n\t}\n}\n\n/*\n * Do first-best-fit chunk selection, i.e. select the lowest chunk that best\n * fits.\n */\nstatic extent_node_t *\nchunk_first_best_fit(arena_t *arena, extent_tree_t *chunks_szad,\n    extent_tree_t *chunks_ad, size_t size)\n{\n\textent_node_t key;\n\n\tassert(size == CHUNK_CEILING(size));\n\n\textent_node_init(&key, arena, NULL, size, false, false);\n\treturn (extent_tree_szad_nsearch(chunks_szad, &key));\n}\n\nstatic void *\nchunk_recycle(arena_t *arena, chunk_hooks_t *chunk_hooks,\n    extent_tree_t *chunks_szad, extent_tree_t *chunks_ad, bool cache,\n    void *new_addr, size_t size, size_t alignment, bool *zero, bool *commit,\n    bool dalloc_node)\n{\n\tvoid *ret;\n\textent_node_t *node;\n\tsize_t alloc_size, leadsize, trailsize;\n\tbool zeroed, committed;\n\n\tassert(new_addr == NULL || alignment == chunksize);\n\t/*\n\t * Cached chunks use the node linkage embedded in their headers, in\n\t * which case dalloc_node is true, and new_addr is non-NULL because\n\t * we're operating on a specific chunk.\n\t */\n\tassert(dalloc_node || new_addr != NULL);\n\n\talloc_size = CHUNK_CEILING(s2u(size + alignment - chunksize));\n\t/* Beware size_t wrap-around. */\n\tif (alloc_size < size)\n\t\treturn (NULL);\n\tmalloc_mutex_lock(&arena->chunks_mtx);\n\tchunk_hooks_assure_initialized_locked(arena, chunk_hooks);\n\tif (new_addr != NULL) {\n\t\textent_node_t key;\n\t\textent_node_init(&key, arena, new_addr, alloc_size, false,\n\t\t    false);\n\t\tnode = extent_tree_ad_search(chunks_ad, &key);\n\t} else {\n\t\tnode = chunk_first_best_fit(arena, chunks_szad, chunks_ad,\n\t\t    alloc_size);\n\t}\n\tif (node == NULL || (new_addr != NULL && extent_node_size_get(node) <\n\t    size)) {\n\t\tmalloc_mutex_unlock(&arena->chunks_mtx);\n\t\treturn (NULL);\n\t}\n\tleadsize = ALIGNMENT_CEILING((uintptr_t)extent_node_addr_get(node),\n\t    alignment) - (uintptr_t)extent_node_addr_get(node);\n\tassert(new_addr == NULL || leadsize == 0);\n\tassert(extent_node_size_get(node) >= leadsize + size);\n\ttrailsize = extent_node_size_get(node) - leadsize - size;\n\tret = (void *)((uintptr_t)extent_node_addr_get(node) + leadsize);\n\tzeroed = extent_node_zeroed_get(node);\n\tif (zeroed)\n\t\t*zero = true;\n\tcommitted = extent_node_committed_get(node);\n\tif (committed)\n\t\t*commit = true;\n\t/* Split the lead. */\n\tif (leadsize != 0 &&\n\t    chunk_hooks->split(extent_node_addr_get(node),\n\t    extent_node_size_get(node), leadsize, size, false, arena->ind)) {\n\t\tmalloc_mutex_unlock(&arena->chunks_mtx);\n\t\treturn (NULL);\n\t}\n\t/* Remove node from the tree. */\n\textent_tree_szad_remove(chunks_szad, node);\n\textent_tree_ad_remove(chunks_ad, node);\n\tarena_chunk_cache_maybe_remove(arena, node, cache);\n\tif (leadsize != 0) {\n\t\t/* Insert the leading space as a smaller chunk. */\n\t\textent_node_size_set(node, leadsize);\n\t\textent_tree_szad_insert(chunks_szad, node);\n\t\textent_tree_ad_insert(chunks_ad, node);\n\t\tarena_chunk_cache_maybe_insert(arena, node, cache);\n\t\tnode = NULL;\n\t}\n\tif (trailsize != 0) {\n\t\t/* Split the trail. */\n\t\tif (chunk_hooks->split(ret, size + trailsize, size,\n\t\t    trailsize, false, arena->ind)) {\n\t\t\tif (dalloc_node && node != NULL)\n\t\t\t\tarena_node_dalloc(arena, node);\n\t\t\tmalloc_mutex_unlock(&arena->chunks_mtx);\n\t\t\tchunk_record(arena, chunk_hooks, chunks_szad, chunks_ad,\n\t\t\t    cache, ret, size + trailsize, zeroed, committed);\n\t\t\treturn (NULL);\n\t\t}\n\t\t/* Insert the trailing space as a smaller chunk. */\n\t\tif (node == NULL) {\n\t\t\tnode = arena_node_alloc(arena);\n\t\t\tif (node == NULL) {\n\t\t\t\tmalloc_mutex_unlock(&arena->chunks_mtx);\n\t\t\t\tchunk_record(arena, chunk_hooks, chunks_szad,\n\t\t\t\t    chunks_ad, cache, ret, size + trailsize,\n\t\t\t\t    zeroed, committed);\n\t\t\t\treturn (NULL);\n\t\t\t}\n\t\t}\n\t\textent_node_init(node, arena, (void *)((uintptr_t)(ret) + size),\n\t\t    trailsize, zeroed, committed);\n\t\textent_tree_szad_insert(chunks_szad, node);\n\t\textent_tree_ad_insert(chunks_ad, node);\n\t\tarena_chunk_cache_maybe_insert(arena, node, cache);\n\t\tnode = NULL;\n\t}\n\tif (!committed && chunk_hooks->commit(ret, size, 0, size, arena->ind)) {\n\t\tmalloc_mutex_unlock(&arena->chunks_mtx);\n\t\tchunk_record(arena, chunk_hooks, chunks_szad, chunks_ad, cache,\n\t\t    ret, size, zeroed, committed);\n\t\treturn (NULL);\n\t}\n\tmalloc_mutex_unlock(&arena->chunks_mtx);\n\n\tassert(dalloc_node || node != NULL);\n\tif (dalloc_node && node != NULL)\n\t\tarena_node_dalloc(arena, node);\n\tif (*zero) {\n\t\tif (!zeroed)\n\t\t\tmemset(ret, 0, size);\n\t\telse if (config_debug) {\n\t\t\tsize_t i;\n\t\t\tsize_t *p = (size_t *)(uintptr_t)ret;\n\n\t\t\tJEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ret, size);\n\t\t\tfor (i = 0; i < size / sizeof(size_t); i++)\n\t\t\t\tassert(p[i] == 0);\n\t\t}\n\t}\n\treturn (ret);\n}\n\n/*\n * If the caller specifies (!*zero), it is still possible to receive zeroed\n * memory, in which case *zero is toggled to true.  arena_chunk_alloc() takes\n * advantage of this to avoid demanding zeroed chunks, but taking advantage of\n * them if they are returned.\n */\nstatic void *\nchunk_alloc_core(arena_t *arena, void *new_addr, size_t size, size_t alignment,\n    bool *zero, bool *commit, dss_prec_t dss_prec)\n{\n\tvoid *ret;\n\n\tassert(size != 0);\n\tassert((size & chunksize_mask) == 0);\n\tassert(alignment != 0);\n\tassert((alignment & chunksize_mask) == 0);\n\n\t/* \"primary\" dss. */\n\tif (have_dss && dss_prec == dss_prec_primary && (ret =\n\t    chunk_alloc_dss(arena, new_addr, size, alignment, zero, commit)) !=\n\t    NULL)\n\t\treturn (ret);\n\t/* mmap. */\n\tif ((ret = chunk_alloc_mmap(new_addr, size, alignment, zero, commit)) !=\n\t    NULL)\n\t\treturn (ret);\n\t/* \"secondary\" dss. */\n\tif (have_dss && dss_prec == dss_prec_secondary && (ret =\n\t    chunk_alloc_dss(arena, new_addr, size, alignment, zero, commit)) !=\n\t    NULL)\n\t\treturn (ret);\n\n\t/* All strategies for allocation failed. */\n\treturn (NULL);\n}\n\nvoid *\nchunk_alloc_base(size_t size)\n{\n\tvoid *ret;\n\tbool zero, commit;\n\n\t/*\n\t * Directly call chunk_alloc_mmap() rather than chunk_alloc_core()\n\t * because it's critical that chunk_alloc_base() return untouched\n\t * demand-zeroed virtual memory.\n\t */\n\tzero = true;\n\tcommit = true;\n\tret = chunk_alloc_mmap(NULL, size, chunksize, &zero, &commit);\n\tif (ret == NULL)\n\t\treturn (NULL);\n\tif (config_valgrind)\n\t\tJEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, size);\n\n\treturn (ret);\n}\n\nvoid *\nchunk_alloc_cache(arena_t *arena, chunk_hooks_t *chunk_hooks, void *new_addr,\n    size_t size, size_t alignment, bool *zero, bool dalloc_node)\n{\n\tvoid *ret;\n\tbool commit;\n\n\tassert(size != 0);\n\tassert((size & chunksize_mask) == 0);\n\tassert(alignment != 0);\n\tassert((alignment & chunksize_mask) == 0);\n\n\tcommit = true;\n\tret = chunk_recycle(arena, chunk_hooks, &arena->chunks_szad_cached,\n\t    &arena->chunks_ad_cached, true, new_addr, size, alignment, zero,\n\t    &commit, dalloc_node);\n\tif (ret == NULL)\n\t\treturn (NULL);\n\tassert(commit);\n\tif (config_valgrind)\n\t\tJEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, size);\n\treturn (ret);\n}\n\nstatic arena_t *\nchunk_arena_get(unsigned arena_ind)\n{\n\tarena_t *arena;\n\n\tarena = arena_get(arena_ind, false);\n\t/*\n\t * The arena we're allocating on behalf of must have been initialized\n\t * already.\n\t */\n\tassert(arena != NULL);\n\treturn (arena);\n}\n\nstatic void *\nchunk_alloc_default(void *new_addr, size_t size, size_t alignment, bool *zero,\n    bool *commit, unsigned arena_ind)\n{\n\tvoid *ret;\n\tarena_t *arena;\n\n\tarena = chunk_arena_get(arena_ind);\n\tret = chunk_alloc_core(arena, new_addr, size, alignment, zero,\n\t    commit, arena->dss_prec);\n\tif (ret == NULL)\n\t\treturn (NULL);\n\tif (config_valgrind)\n\t\tJEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, size);\n\n\treturn (ret);\n}\n\nstatic void *\nchunk_alloc_retained(arena_t *arena, chunk_hooks_t *chunk_hooks, void *new_addr,\n    size_t size, size_t alignment, bool *zero, bool *commit)\n{\n\n\tassert(size != 0);\n\tassert((size & chunksize_mask) == 0);\n\tassert(alignment != 0);\n\tassert((alignment & chunksize_mask) == 0);\n\n\treturn (chunk_recycle(arena, chunk_hooks, &arena->chunks_szad_retained,\n\t    &arena->chunks_ad_retained, false, new_addr, size, alignment, zero,\n\t    commit, true));\n}\n\nvoid *\nchunk_alloc_wrapper(arena_t *arena, chunk_hooks_t *chunk_hooks, void *new_addr,\n    size_t size, size_t alignment, bool *zero, bool *commit)\n{\n\tvoid *ret;\n\n\tchunk_hooks_assure_initialized(arena, chunk_hooks);\n\n\tret = chunk_alloc_retained(arena, chunk_hooks, new_addr, size,\n\t    alignment, zero, commit);\n\tif (ret == NULL) {\n\t\tret = chunk_hooks->alloc(new_addr, size, alignment, zero,\n\t\t    commit, arena->ind);\n\t\tif (ret == NULL)\n\t\t\treturn (NULL);\n\t}\n\n\tif (config_valgrind && chunk_hooks->alloc != chunk_alloc_default)\n\t\tJEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, chunksize);\n\treturn (ret);\n}\n\nstatic void\nchunk_record(arena_t *arena, chunk_hooks_t *chunk_hooks,\n    extent_tree_t *chunks_szad, extent_tree_t *chunks_ad, bool cache,\n    void *chunk, size_t size, bool zeroed, bool committed)\n{\n\tbool unzeroed;\n\textent_node_t *node, *prev;\n\textent_node_t key;\n\n\tassert(!cache || !zeroed);\n\tunzeroed = cache || !zeroed;\n\tJEMALLOC_VALGRIND_MAKE_MEM_NOACCESS(chunk, size);\n\n\tmalloc_mutex_lock(&arena->chunks_mtx);\n\tchunk_hooks_assure_initialized_locked(arena, chunk_hooks);\n\textent_node_init(&key, arena, (void *)((uintptr_t)chunk + size), 0,\n\t    false, false);\n\tnode = extent_tree_ad_nsearch(chunks_ad, &key);\n\t/* Try to coalesce forward. */\n\tif (node != NULL && extent_node_addr_get(node) ==\n\t    extent_node_addr_get(&key) && extent_node_committed_get(node) ==\n\t    committed && !chunk_hooks->merge(chunk, size,\n\t    extent_node_addr_get(node), extent_node_size_get(node), false,\n\t    arena->ind)) {\n\t\t/*\n\t\t * Coalesce chunk with the following address range.  This does\n\t\t * not change the position within chunks_ad, so only\n\t\t * remove/insert from/into chunks_szad.\n\t\t */\n\t\textent_tree_szad_remove(chunks_szad, node);\n\t\tarena_chunk_cache_maybe_remove(arena, node, cache);\n\t\textent_node_addr_set(node, chunk);\n\t\textent_node_size_set(node, size + extent_node_size_get(node));\n\t\textent_node_zeroed_set(node, extent_node_zeroed_get(node) &&\n\t\t    !unzeroed);\n\t\textent_tree_szad_insert(chunks_szad, node);\n\t\tarena_chunk_cache_maybe_insert(arena, node, cache);\n\t} else {\n\t\t/* Coalescing forward failed, so insert a new node. */\n\t\tnode = arena_node_alloc(arena);\n\t\tif (node == NULL) {\n\t\t\t/*\n\t\t\t * Node allocation failed, which is an exceedingly\n\t\t\t * unlikely failure.  Leak chunk after making sure its\n\t\t\t * pages have already been purged, so that this is only\n\t\t\t * a virtual memory leak.\n\t\t\t */\n\t\t\tif (cache) {\n\t\t\t\tchunk_purge_wrapper(arena, chunk_hooks, chunk,\n\t\t\t\t    size, 0, size);\n\t\t\t}\n\t\t\tgoto label_return;\n\t\t}\n\t\textent_node_init(node, arena, chunk, size, !unzeroed,\n\t\t    committed);\n\t\textent_tree_ad_insert(chunks_ad, node);\n\t\textent_tree_szad_insert(chunks_szad, node);\n\t\tarena_chunk_cache_maybe_insert(arena, node, cache);\n\t}\n\n\t/* Try to coalesce backward. */\n\tprev = extent_tree_ad_prev(chunks_ad, node);\n\tif (prev != NULL && (void *)((uintptr_t)extent_node_addr_get(prev) +\n\t    extent_node_size_get(prev)) == chunk &&\n\t    extent_node_committed_get(prev) == committed &&\n\t    !chunk_hooks->merge(extent_node_addr_get(prev),\n\t    extent_node_size_get(prev), chunk, size, false, arena->ind)) {\n\t\t/*\n\t\t * Coalesce chunk with the previous address range.  This does\n\t\t * not change the position within chunks_ad, so only\n\t\t * remove/insert node from/into chunks_szad.\n\t\t */\n\t\textent_tree_szad_remove(chunks_szad, prev);\n\t\textent_tree_ad_remove(chunks_ad, prev);\n\t\tarena_chunk_cache_maybe_remove(arena, prev, cache);\n\t\textent_tree_szad_remove(chunks_szad, node);\n\t\tarena_chunk_cache_maybe_remove(arena, node, cache);\n\t\textent_node_addr_set(node, extent_node_addr_get(prev));\n\t\textent_node_size_set(node, extent_node_size_get(prev) +\n\t\t    extent_node_size_get(node));\n\t\textent_node_zeroed_set(node, extent_node_zeroed_get(prev) &&\n\t\t    extent_node_zeroed_get(node));\n\t\textent_tree_szad_insert(chunks_szad, node);\n\t\tarena_chunk_cache_maybe_insert(arena, node, cache);\n\n\t\tarena_node_dalloc(arena, prev);\n\t}\n\nlabel_return:\n\tmalloc_mutex_unlock(&arena->chunks_mtx);\n}\n\nvoid\nchunk_dalloc_cache(arena_t *arena, chunk_hooks_t *chunk_hooks, void *chunk,\n    size_t size, bool committed)\n{\n\n\tassert(chunk != NULL);\n\tassert(CHUNK_ADDR2BASE(chunk) == chunk);\n\tassert(size != 0);\n\tassert((size & chunksize_mask) == 0);\n\n\tchunk_record(arena, chunk_hooks, &arena->chunks_szad_cached,\n\t    &arena->chunks_ad_cached, true, chunk, size, false, committed);\n\tarena_maybe_purge(arena);\n}\n\nvoid\nchunk_dalloc_arena(arena_t *arena, chunk_hooks_t *chunk_hooks, void *chunk,\n    size_t size, bool zeroed, bool committed)\n{\n\n\tassert(chunk != NULL);\n\tassert(CHUNK_ADDR2BASE(chunk) == chunk);\n\tassert(size != 0);\n\tassert((size & chunksize_mask) == 0);\n\n\tchunk_hooks_assure_initialized(arena, chunk_hooks);\n\t/* Try to deallocate. */\n\tif (!chunk_hooks->dalloc(chunk, size, committed, arena->ind))\n\t\treturn;\n\t/* Try to decommit; purge if that fails. */\n\tif (committed) {\n\t\tcommitted = chunk_hooks->decommit(chunk, size, 0, size,\n\t\t    arena->ind);\n\t}\n\tzeroed = !committed || !chunk_hooks->purge(chunk, size, 0, size,\n\t    arena->ind);\n\tchunk_record(arena, chunk_hooks, &arena->chunks_szad_retained,\n\t    &arena->chunks_ad_retained, false, chunk, size, zeroed, committed);\n}\n\nstatic bool\nchunk_dalloc_default(void *chunk, size_t size, bool committed,\n    unsigned arena_ind)\n{\n\n\tif (!have_dss || !chunk_in_dss(chunk))\n\t\treturn (chunk_dalloc_mmap(chunk, size));\n\treturn (true);\n}\n\nvoid\nchunk_dalloc_wrapper(arena_t *arena, chunk_hooks_t *chunk_hooks, void *chunk,\n    size_t size, bool committed)\n{\n\n\tchunk_hooks_assure_initialized(arena, chunk_hooks);\n\tchunk_hooks->dalloc(chunk, size, committed, arena->ind);\n\tif (config_valgrind && chunk_hooks->dalloc != chunk_dalloc_default)\n\t\tJEMALLOC_VALGRIND_MAKE_MEM_NOACCESS(chunk, size);\n}\n\nstatic bool\nchunk_commit_default(void *chunk, size_t size, size_t offset, size_t length,\n    unsigned arena_ind)\n{\n\n\treturn (pages_commit((void *)((uintptr_t)chunk + (uintptr_t)offset),\n\t    length));\n}\n\nstatic bool\nchunk_decommit_default(void *chunk, size_t size, size_t offset, size_t length,\n    unsigned arena_ind)\n{\n\n\treturn (pages_decommit((void *)((uintptr_t)chunk + (uintptr_t)offset),\n\t    length));\n}\n\nbool\nchunk_purge_arena(arena_t *arena, void *chunk, size_t offset, size_t length)\n{\n\n\tassert(chunk != NULL);\n\tassert(CHUNK_ADDR2BASE(chunk) == chunk);\n\tassert((offset & PAGE_MASK) == 0);\n\tassert(length != 0);\n\tassert((length & PAGE_MASK) == 0);\n\n\treturn (pages_purge((void *)((uintptr_t)chunk + (uintptr_t)offset),\n\t    length));\n}\n\nstatic bool\nchunk_purge_default(void *chunk, size_t size, size_t offset, size_t length,\n    unsigned arena_ind)\n{\n\n\treturn (chunk_purge_arena(chunk_arena_get(arena_ind), chunk, offset,\n\t    length));\n}\n\nbool\nchunk_purge_wrapper(arena_t *arena, chunk_hooks_t *chunk_hooks, void *chunk,\n    size_t size, size_t offset, size_t length)\n{\n\n\tchunk_hooks_assure_initialized(arena, chunk_hooks);\n\treturn (chunk_hooks->purge(chunk, size, offset, length, arena->ind));\n}\n\nstatic bool\nchunk_split_default(void *chunk, size_t size, size_t size_a, size_t size_b,\n    bool committed, unsigned arena_ind)\n{\n\n\tif (!maps_coalesce)\n\t\treturn (true);\n\treturn (false);\n}\n\nstatic bool\nchunk_merge_default(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b,\n    bool committed, unsigned arena_ind)\n{\n\n\tif (!maps_coalesce)\n\t\treturn (true);\n\tif (have_dss && chunk_in_dss(chunk_a) != chunk_in_dss(chunk_b))\n\t\treturn (true);\n\n\treturn (false);\n}\n\nstatic rtree_node_elm_t *\nchunks_rtree_node_alloc(size_t nelms)\n{\n\n\treturn ((rtree_node_elm_t *)base_alloc(nelms *\n\t    sizeof(rtree_node_elm_t)));\n}\n\nbool\nchunk_boot(void)\n{\n#ifdef _WIN32\n\tSYSTEM_INFO info;\n\tGetSystemInfo(&info);\n\n\t/*\n\t * Verify actual page size is equal to or an integral multiple of\n\t * configured page size.\n\t */\n\tif (info.dwPageSize & ((1U << LG_PAGE) - 1))\n\t\treturn (true);\n\n\t/*\n\t * Configure chunksize (if not set) to match granularity (usually 64K),\n\t * so pages_map will always take fast path.\n\t */\n\tif (!opt_lg_chunk) {\n\t\topt_lg_chunk = ffs_u((unsigned)info.dwAllocationGranularity)\n\t\t    - 1;\n\t}\n#else\n\tif (!opt_lg_chunk)\n\t\topt_lg_chunk = LG_CHUNK_DEFAULT;\n#endif\n\n\t/* Set variables according to the value of opt_lg_chunk. */\n\tchunksize = (ZU(1) << opt_lg_chunk);\n\tassert(chunksize >= PAGE);\n\tchunksize_mask = chunksize - 1;\n\tchunk_npages = (chunksize >> LG_PAGE);\n\n\tif (have_dss && chunk_dss_boot())\n\t\treturn (true);\n\tif (rtree_new(&chunks_rtree, (unsigned)((ZU(1) << (LG_SIZEOF_PTR+3)) -\n\t    opt_lg_chunk), chunks_rtree_node_alloc, NULL))\n\t\treturn (true);\n\n\treturn (false);\n}\n\nvoid\nchunk_prefork(void)\n{\n\n\tchunk_dss_prefork();\n}\n\nvoid\nchunk_postfork_parent(void)\n{\n\n\tchunk_dss_postfork_parent();\n}\n\nvoid\nchunk_postfork_child(void)\n{\n\n\tchunk_dss_postfork_child();\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/chunk_dss.c",
    "content": "#define\tJEMALLOC_CHUNK_DSS_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n/******************************************************************************/\n/* Data. */\n\nconst char\t*dss_prec_names[] = {\n\t\"disabled\",\n\t\"primary\",\n\t\"secondary\",\n\t\"N/A\"\n};\n\n/* Current dss precedence default, used when creating new arenas. */\nstatic dss_prec_t\tdss_prec_default = DSS_PREC_DEFAULT;\n\n/*\n * Protects sbrk() calls.  This avoids malloc races among threads, though it\n * does not protect against races with threads that call sbrk() directly.\n */\nstatic malloc_mutex_t\tdss_mtx;\n\n/* Base address of the DSS. */\nstatic void\t\t*dss_base;\n/* Current end of the DSS, or ((void *)-1) if the DSS is exhausted. */\nstatic void\t\t*dss_prev;\n/* Current upper limit on DSS addresses. */\nstatic void\t\t*dss_max;\n\n/******************************************************************************/\n\nstatic void *\nchunk_dss_sbrk(intptr_t increment)\n{\n\n#ifdef JEMALLOC_DSS\n\treturn (sbrk(increment));\n#else\n\tnot_implemented();\n\treturn (NULL);\n#endif\n}\n\ndss_prec_t\nchunk_dss_prec_get(void)\n{\n\tdss_prec_t ret;\n\n\tif (!have_dss)\n\t\treturn (dss_prec_disabled);\n\tmalloc_mutex_lock(&dss_mtx);\n\tret = dss_prec_default;\n\tmalloc_mutex_unlock(&dss_mtx);\n\treturn (ret);\n}\n\nbool\nchunk_dss_prec_set(dss_prec_t dss_prec)\n{\n\n\tif (!have_dss)\n\t\treturn (dss_prec != dss_prec_disabled);\n\tmalloc_mutex_lock(&dss_mtx);\n\tdss_prec_default = dss_prec;\n\tmalloc_mutex_unlock(&dss_mtx);\n\treturn (false);\n}\n\nvoid *\nchunk_alloc_dss(arena_t *arena, void *new_addr, size_t size, size_t alignment,\n    bool *zero, bool *commit)\n{\n\tcassert(have_dss);\n\tassert(size > 0 && (size & chunksize_mask) == 0);\n\tassert(alignment > 0 && (alignment & chunksize_mask) == 0);\n\n\t/*\n\t * sbrk() uses a signed increment argument, so take care not to\n\t * interpret a huge allocation request as a negative increment.\n\t */\n\tif ((intptr_t)size < 0)\n\t\treturn (NULL);\n\n\tmalloc_mutex_lock(&dss_mtx);\n\tif (dss_prev != (void *)-1) {\n\n\t\t/*\n\t\t * The loop is necessary to recover from races with other\n\t\t * threads that are using the DSS for something other than\n\t\t * malloc.\n\t\t */\n\t\tdo {\n\t\t\tvoid *ret, *cpad, *dss_next;\n\t\t\tsize_t gap_size, cpad_size;\n\t\t\tintptr_t incr;\n\t\t\t/* Avoid an unnecessary system call. */\n\t\t\tif (new_addr != NULL && dss_max != new_addr)\n\t\t\t\tbreak;\n\n\t\t\t/* Get the current end of the DSS. */\n\t\t\tdss_max = chunk_dss_sbrk(0);\n\n\t\t\t/* Make sure the earlier condition still holds. */\n\t\t\tif (new_addr != NULL && dss_max != new_addr)\n\t\t\t\tbreak;\n\n\t\t\t/*\n\t\t\t * Calculate how much padding is necessary to\n\t\t\t * chunk-align the end of the DSS.\n\t\t\t */\n\t\t\tgap_size = (chunksize - CHUNK_ADDR2OFFSET(dss_max)) &\n\t\t\t    chunksize_mask;\n\t\t\t/*\n\t\t\t * Compute how much chunk-aligned pad space (if any) is\n\t\t\t * necessary to satisfy alignment.  This space can be\n\t\t\t * recycled for later use.\n\t\t\t */\n\t\t\tcpad = (void *)((uintptr_t)dss_max + gap_size);\n\t\t\tret = (void *)ALIGNMENT_CEILING((uintptr_t)dss_max,\n\t\t\t    alignment);\n\t\t\tcpad_size = (uintptr_t)ret - (uintptr_t)cpad;\n\t\t\tdss_next = (void *)((uintptr_t)ret + size);\n\t\t\tif ((uintptr_t)ret < (uintptr_t)dss_max ||\n\t\t\t    (uintptr_t)dss_next < (uintptr_t)dss_max) {\n\t\t\t\t/* Wrap-around. */\n\t\t\t\tmalloc_mutex_unlock(&dss_mtx);\n\t\t\t\treturn (NULL);\n\t\t\t}\n\t\t\tincr = gap_size + cpad_size + size;\n\t\t\tdss_prev = chunk_dss_sbrk(incr);\n\t\t\tif (dss_prev == dss_max) {\n\t\t\t\t/* Success. */\n\t\t\t\tdss_max = dss_next;\n\t\t\t\tmalloc_mutex_unlock(&dss_mtx);\n\t\t\t\tif (cpad_size != 0) {\n\t\t\t\t\tchunk_hooks_t chunk_hooks =\n\t\t\t\t\t    CHUNK_HOOKS_INITIALIZER;\n\t\t\t\t\tchunk_dalloc_wrapper(arena,\n\t\t\t\t\t    &chunk_hooks, cpad, cpad_size,\n\t\t\t\t\t    true);\n\t\t\t\t}\n\t\t\t\tif (*zero) {\n\t\t\t\t\tJEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(\n\t\t\t\t\t    ret, size);\n\t\t\t\t\tmemset(ret, 0, size);\n\t\t\t\t}\n\t\t\t\tif (!*commit)\n\t\t\t\t\t*commit = pages_decommit(ret, size);\n\t\t\t\treturn (ret);\n\t\t\t}\n\t\t} while (dss_prev != (void *)-1);\n\t}\n\tmalloc_mutex_unlock(&dss_mtx);\n\n\treturn (NULL);\n}\n\nbool\nchunk_in_dss(void *chunk)\n{\n\tbool ret;\n\n\tcassert(have_dss);\n\n\tmalloc_mutex_lock(&dss_mtx);\n\tif ((uintptr_t)chunk >= (uintptr_t)dss_base\n\t    && (uintptr_t)chunk < (uintptr_t)dss_max)\n\t\tret = true;\n\telse\n\t\tret = false;\n\tmalloc_mutex_unlock(&dss_mtx);\n\n\treturn (ret);\n}\n\nbool\nchunk_dss_boot(void)\n{\n\n\tcassert(have_dss);\n\n\tif (malloc_mutex_init(&dss_mtx))\n\t\treturn (true);\n\tdss_base = chunk_dss_sbrk(0);\n\tdss_prev = dss_base;\n\tdss_max = dss_base;\n\n\treturn (false);\n}\n\nvoid\nchunk_dss_prefork(void)\n{\n\n\tif (have_dss)\n\t\tmalloc_mutex_prefork(&dss_mtx);\n}\n\nvoid\nchunk_dss_postfork_parent(void)\n{\n\n\tif (have_dss)\n\t\tmalloc_mutex_postfork_parent(&dss_mtx);\n}\n\nvoid\nchunk_dss_postfork_child(void)\n{\n\n\tif (have_dss)\n\t\tmalloc_mutex_postfork_child(&dss_mtx);\n}\n\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/chunk_mmap.c",
    "content": "#define\tJEMALLOC_CHUNK_MMAP_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n/******************************************************************************/\n\nstatic void *\nchunk_alloc_mmap_slow(size_t size, size_t alignment, bool *zero, bool *commit)\n{\n\tvoid *ret;\n\tsize_t alloc_size;\n\n\talloc_size = size + alignment - PAGE;\n\t/* Beware size_t wrap-around. */\n\tif (alloc_size < size)\n\t\treturn (NULL);\n\tdo {\n\t\tvoid *pages;\n\t\tsize_t leadsize;\n\t\tpages = pages_map(NULL, alloc_size);\n\t\tif (pages == NULL)\n\t\t\treturn (NULL);\n\t\tleadsize = ALIGNMENT_CEILING((uintptr_t)pages, alignment) -\n\t\t    (uintptr_t)pages;\n\t\tret = pages_trim(pages, alloc_size, leadsize, size);\n\t} while (ret == NULL);\n\n\tassert(ret != NULL);\n\t*zero = true;\n\tif (!*commit)\n\t\t*commit = pages_decommit(ret, size);\n\treturn (ret);\n}\n\nvoid *\nchunk_alloc_mmap(void *new_addr, size_t size, size_t alignment, bool *zero,\n    bool *commit)\n{\n\tvoid *ret;\n\tsize_t offset;\n\n\t/*\n\t * Ideally, there would be a way to specify alignment to mmap() (like\n\t * NetBSD has), but in the absence of such a feature, we have to work\n\t * hard to efficiently create aligned mappings.  The reliable, but\n\t * slow method is to create a mapping that is over-sized, then trim the\n\t * excess.  However, that always results in one or two calls to\n\t * pages_unmap().\n\t *\n\t * Optimistically try mapping precisely the right amount before falling\n\t * back to the slow method, with the expectation that the optimistic\n\t * approach works most of the time.\n\t */\n\n\tassert(alignment != 0);\n\tassert((alignment & chunksize_mask) == 0);\n\n\tret = pages_map(new_addr, size);\n\tif (ret == NULL || ret == new_addr)\n\t\treturn (ret);\n\tassert(new_addr == NULL);\n\toffset = ALIGNMENT_ADDR2OFFSET(ret, alignment);\n\tif (offset != 0) {\n\t\tpages_unmap(ret, size);\n\t\treturn (chunk_alloc_mmap_slow(size, alignment, zero, commit));\n\t}\n\n\tassert(ret != NULL);\n\t*zero = true;\n\tif (!*commit)\n\t\t*commit = pages_decommit(ret, size);\n\treturn (ret);\n}\n\nbool\nchunk_dalloc_mmap(void *chunk, size_t size)\n{\n\n\tif (config_munmap)\n\t\tpages_unmap(chunk, size);\n\n\treturn (!config_munmap);\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/ckh.c",
    "content": "/*\n *******************************************************************************\n * Implementation of (2^1+,2) cuckoo hashing, where 2^1+ indicates that each\n * hash bucket contains 2^n cells, for n >= 1, and 2 indicates that two hash\n * functions are employed.  The original cuckoo hashing algorithm was described\n * in:\n *\n *   Pagh, R., F.F. Rodler (2004) Cuckoo Hashing.  Journal of Algorithms\n *     51(2):122-144.\n *\n * Generalization of cuckoo hashing was discussed in:\n *\n *   Erlingsson, U., M. Manasse, F. McSherry (2006) A cool and practical\n *     alternative to traditional hash tables.  In Proceedings of the 7th\n *     Workshop on Distributed Data and Structures (WDAS'06), Santa Clara, CA,\n *     January 2006.\n *\n * This implementation uses precisely two hash functions because that is the\n * fewest that can work, and supporting multiple hashes is an implementation\n * burden.  Here is a reproduction of Figure 1 from Erlingsson et al. (2006)\n * that shows approximate expected maximum load factors for various\n * configurations:\n *\n *           |         #cells/bucket         |\n *   #hashes |   1   |   2   |   4   |   8   |\n *   --------+-------+-------+-------+-------+\n *         1 | 0.006 | 0.006 | 0.03  | 0.12  |\n *         2 | 0.49  | 0.86  |>0.93< |>0.96< |\n *         3 | 0.91  | 0.97  | 0.98  | 0.999 |\n *         4 | 0.97  | 0.99  | 0.999 |       |\n *\n * The number of cells per bucket is chosen such that a bucket fits in one cache\n * line.  So, on 32- and 64-bit systems, we use (8,2) and (4,2) cuckoo hashing,\n * respectively.\n *\n ******************************************************************************/\n#define\tJEMALLOC_CKH_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n/******************************************************************************/\n/* Function prototypes for non-inline static functions. */\n\nstatic bool\tckh_grow(tsd_t *tsd, ckh_t *ckh);\nstatic void\tckh_shrink(tsd_t *tsd, ckh_t *ckh);\n\n/******************************************************************************/\n\n/*\n * Search bucket for key and return the cell number if found; SIZE_T_MAX\n * otherwise.\n */\nJEMALLOC_INLINE_C size_t\nckh_bucket_search(ckh_t *ckh, size_t bucket, const void *key)\n{\n\tckhc_t *cell;\n\tunsigned i;\n\n\tfor (i = 0; i < (ZU(1) << LG_CKH_BUCKET_CELLS); i++) {\n\t\tcell = &ckh->tab[(bucket << LG_CKH_BUCKET_CELLS) + i];\n\t\tif (cell->key != NULL && ckh->keycomp(key, cell->key))\n\t\t\treturn ((bucket << LG_CKH_BUCKET_CELLS) + i);\n\t}\n\n\treturn (SIZE_T_MAX);\n}\n\n/*\n * Search table for key and return cell number if found; SIZE_T_MAX otherwise.\n */\nJEMALLOC_INLINE_C size_t\nckh_isearch(ckh_t *ckh, const void *key)\n{\n\tsize_t hashes[2], bucket, cell;\n\n\tassert(ckh != NULL);\n\n\tckh->hash(key, hashes);\n\n\t/* Search primary bucket. */\n\tbucket = hashes[0] & ((ZU(1) << ckh->lg_curbuckets) - 1);\n\tcell = ckh_bucket_search(ckh, bucket, key);\n\tif (cell != SIZE_T_MAX)\n\t\treturn (cell);\n\n\t/* Search secondary bucket. */\n\tbucket = hashes[1] & ((ZU(1) << ckh->lg_curbuckets) - 1);\n\tcell = ckh_bucket_search(ckh, bucket, key);\n\treturn (cell);\n}\n\nJEMALLOC_INLINE_C bool\nckh_try_bucket_insert(ckh_t *ckh, size_t bucket, const void *key,\n    const void *data)\n{\n\tckhc_t *cell;\n\tunsigned offset, i;\n\n\t/*\n\t * Cycle through the cells in the bucket, starting at a random position.\n\t * The randomness avoids worst-case search overhead as buckets fill up.\n\t */\n\toffset = (unsigned)prng_lg_range(&ckh->prng_state, LG_CKH_BUCKET_CELLS);\n\tfor (i = 0; i < (ZU(1) << LG_CKH_BUCKET_CELLS); i++) {\n\t\tcell = &ckh->tab[(bucket << LG_CKH_BUCKET_CELLS) +\n\t\t    ((i + offset) & ((ZU(1) << LG_CKH_BUCKET_CELLS) - 1))];\n\t\tif (cell->key == NULL) {\n\t\t\tcell->key = key;\n\t\t\tcell->data = data;\n\t\t\tckh->count++;\n\t\t\treturn (false);\n\t\t}\n\t}\n\n\treturn (true);\n}\n\n/*\n * No space is available in bucket.  Randomly evict an item, then try to find an\n * alternate location for that item.  Iteratively repeat this\n * eviction/relocation procedure until either success or detection of an\n * eviction/relocation bucket cycle.\n */\nJEMALLOC_INLINE_C bool\nckh_evict_reloc_insert(ckh_t *ckh, size_t argbucket, void const **argkey,\n    void const **argdata)\n{\n\tconst void *key, *data, *tkey, *tdata;\n\tckhc_t *cell;\n\tsize_t hashes[2], bucket, tbucket;\n\tunsigned i;\n\n\tbucket = argbucket;\n\tkey = *argkey;\n\tdata = *argdata;\n\twhile (true) {\n\t\t/*\n\t\t * Choose a random item within the bucket to evict.  This is\n\t\t * critical to correct function, because without (eventually)\n\t\t * evicting all items within a bucket during iteration, it\n\t\t * would be possible to get stuck in an infinite loop if there\n\t\t * were an item for which both hashes indicated the same\n\t\t * bucket.\n\t\t */\n\t\ti = (unsigned)prng_lg_range(&ckh->prng_state,\n\t\t    LG_CKH_BUCKET_CELLS);\n\t\tcell = &ckh->tab[(bucket << LG_CKH_BUCKET_CELLS) + i];\n\t\tassert(cell->key != NULL);\n\n\t\t/* Swap cell->{key,data} and {key,data} (evict). */\n\t\ttkey = cell->key; tdata = cell->data;\n\t\tcell->key = key; cell->data = data;\n\t\tkey = tkey; data = tdata;\n\n#ifdef CKH_COUNT\n\t\tckh->nrelocs++;\n#endif\n\n\t\t/* Find the alternate bucket for the evicted item. */\n\t\tckh->hash(key, hashes);\n\t\ttbucket = hashes[1] & ((ZU(1) << ckh->lg_curbuckets) - 1);\n\t\tif (tbucket == bucket) {\n\t\t\ttbucket = hashes[0] & ((ZU(1) << ckh->lg_curbuckets)\n\t\t\t    - 1);\n\t\t\t/*\n\t\t\t * It may be that (tbucket == bucket) still, if the\n\t\t\t * item's hashes both indicate this bucket.  However,\n\t\t\t * we are guaranteed to eventually escape this bucket\n\t\t\t * during iteration, assuming pseudo-random item\n\t\t\t * selection (true randomness would make infinite\n\t\t\t * looping a remote possibility).  The reason we can\n\t\t\t * never get trapped forever is that there are two\n\t\t\t * cases:\n\t\t\t *\n\t\t\t * 1) This bucket == argbucket, so we will quickly\n\t\t\t *    detect an eviction cycle and terminate.\n\t\t\t * 2) An item was evicted to this bucket from another,\n\t\t\t *    which means that at least one item in this bucket\n\t\t\t *    has hashes that indicate distinct buckets.\n\t\t\t */\n\t\t}\n\t\t/* Check for a cycle. */\n\t\tif (tbucket == argbucket) {\n\t\t\t*argkey = key;\n\t\t\t*argdata = data;\n\t\t\treturn (true);\n\t\t}\n\n\t\tbucket = tbucket;\n\t\tif (!ckh_try_bucket_insert(ckh, bucket, key, data))\n\t\t\treturn (false);\n\t}\n}\n\nJEMALLOC_INLINE_C bool\nckh_try_insert(ckh_t *ckh, void const**argkey, void const**argdata)\n{\n\tsize_t hashes[2], bucket;\n\tconst void *key = *argkey;\n\tconst void *data = *argdata;\n\n\tckh->hash(key, hashes);\n\n\t/* Try to insert in primary bucket. */\n\tbucket = hashes[0] & ((ZU(1) << ckh->lg_curbuckets) - 1);\n\tif (!ckh_try_bucket_insert(ckh, bucket, key, data))\n\t\treturn (false);\n\n\t/* Try to insert in secondary bucket. */\n\tbucket = hashes[1] & ((ZU(1) << ckh->lg_curbuckets) - 1);\n\tif (!ckh_try_bucket_insert(ckh, bucket, key, data))\n\t\treturn (false);\n\n\t/*\n\t * Try to find a place for this item via iterative eviction/relocation.\n\t */\n\treturn (ckh_evict_reloc_insert(ckh, bucket, argkey, argdata));\n}\n\n/*\n * Try to rebuild the hash table from scratch by inserting all items from the\n * old table into the new.\n */\nJEMALLOC_INLINE_C bool\nckh_rebuild(ckh_t *ckh, ckhc_t *aTab)\n{\n\tsize_t count, i, nins;\n\tconst void *key, *data;\n\n\tcount = ckh->count;\n\tckh->count = 0;\n\tfor (i = nins = 0; nins < count; i++) {\n\t\tif (aTab[i].key != NULL) {\n\t\t\tkey = aTab[i].key;\n\t\t\tdata = aTab[i].data;\n\t\t\tif (ckh_try_insert(ckh, &key, &data)) {\n\t\t\t\tckh->count = count;\n\t\t\t\treturn (true);\n\t\t\t}\n\t\t\tnins++;\n\t\t}\n\t}\n\n\treturn (false);\n}\n\nstatic bool\nckh_grow(tsd_t *tsd, ckh_t *ckh)\n{\n\tbool ret;\n\tckhc_t *tab, *ttab;\n\tunsigned lg_prevbuckets, lg_curcells;\n\n#ifdef CKH_COUNT\n\tckh->ngrows++;\n#endif\n\n\t/*\n\t * It is possible (though unlikely, given well behaved hashes) that the\n\t * table will have to be doubled more than once in order to create a\n\t * usable table.\n\t */\n\tlg_prevbuckets = ckh->lg_curbuckets;\n\tlg_curcells = ckh->lg_curbuckets + LG_CKH_BUCKET_CELLS;\n\twhile (true) {\n\t\tsize_t usize;\n\n\t\tlg_curcells++;\n\t\tusize = sa2u(sizeof(ckhc_t) << lg_curcells, CACHELINE);\n\t\tif (unlikely(usize == 0 || usize > HUGE_MAXCLASS)) {\n\t\t\tret = true;\n\t\t\tgoto label_return;\n\t\t}\n\t\ttab = (ckhc_t *)ipallocztm(tsd, usize, CACHELINE, true, NULL,\n\t\t    true, NULL);\n\t\tif (tab == NULL) {\n\t\t\tret = true;\n\t\t\tgoto label_return;\n\t\t}\n\t\t/* Swap in new table. */\n\t\tttab = ckh->tab;\n\t\tckh->tab = tab;\n\t\ttab = ttab;\n\t\tckh->lg_curbuckets = lg_curcells - LG_CKH_BUCKET_CELLS;\n\n\t\tif (!ckh_rebuild(ckh, tab)) {\n\t\t\tidalloctm(tsd, tab, tcache_get(tsd, false), true, true);\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Rebuilding failed, so back out partially rebuilt table. */\n\t\tidalloctm(tsd, ckh->tab, tcache_get(tsd, false), true, true);\n\t\tckh->tab = tab;\n\t\tckh->lg_curbuckets = lg_prevbuckets;\n\t}\n\n\tret = false;\nlabel_return:\n\treturn (ret);\n}\n\nstatic void\nckh_shrink(tsd_t *tsd, ckh_t *ckh)\n{\n\tckhc_t *tab, *ttab;\n\tsize_t usize;\n\tunsigned lg_prevbuckets, lg_curcells;\n\n\t/*\n\t * It is possible (though unlikely, given well behaved hashes) that the\n\t * table rebuild will fail.\n\t */\n\tlg_prevbuckets = ckh->lg_curbuckets;\n\tlg_curcells = ckh->lg_curbuckets + LG_CKH_BUCKET_CELLS - 1;\n\tusize = sa2u(sizeof(ckhc_t) << lg_curcells, CACHELINE);\n\tif (unlikely(usize == 0 || usize > HUGE_MAXCLASS))\n\t\treturn;\n\ttab = (ckhc_t *)ipallocztm(tsd, usize, CACHELINE, true, NULL, true,\n\t    NULL);\n\tif (tab == NULL) {\n\t\t/*\n\t\t * An OOM error isn't worth propagating, since it doesn't\n\t\t * prevent this or future operations from proceeding.\n\t\t */\n\t\treturn;\n\t}\n\t/* Swap in new table. */\n\tttab = ckh->tab;\n\tckh->tab = tab;\n\ttab = ttab;\n\tckh->lg_curbuckets = lg_curcells - LG_CKH_BUCKET_CELLS;\n\n\tif (!ckh_rebuild(ckh, tab)) {\n\t\tidalloctm(tsd, tab, tcache_get(tsd, false), true, true);\n#ifdef CKH_COUNT\n\t\tckh->nshrinks++;\n#endif\n\t\treturn;\n\t}\n\n\t/* Rebuilding failed, so back out partially rebuilt table. */\n\tidalloctm(tsd, ckh->tab, tcache_get(tsd, false), true, true);\n\tckh->tab = tab;\n\tckh->lg_curbuckets = lg_prevbuckets;\n#ifdef CKH_COUNT\n\tckh->nshrinkfails++;\n#endif\n}\n\nbool\nckh_new(tsd_t *tsd, ckh_t *ckh, size_t minitems, ckh_hash_t *hash,\n    ckh_keycomp_t *keycomp)\n{\n\tbool ret;\n\tsize_t mincells, usize;\n\tunsigned lg_mincells;\n\n\tassert(minitems > 0);\n\tassert(hash != NULL);\n\tassert(keycomp != NULL);\n\n#ifdef CKH_COUNT\n\tckh->ngrows = 0;\n\tckh->nshrinks = 0;\n\tckh->nshrinkfails = 0;\n\tckh->ninserts = 0;\n\tckh->nrelocs = 0;\n#endif\n\tckh->prng_state = 42; /* Value doesn't really matter. */\n\tckh->count = 0;\n\n\t/*\n\t * Find the minimum power of 2 that is large enough to fit minitems\n\t * entries.  We are using (2+,2) cuckoo hashing, which has an expected\n\t * maximum load factor of at least ~0.86, so 0.75 is a conservative load\n\t * factor that will typically allow mincells items to fit without ever\n\t * growing the table.\n\t */\n\tassert(LG_CKH_BUCKET_CELLS > 0);\n\tmincells = ((minitems + (3 - (minitems % 3))) / 3) << 2;\n\tfor (lg_mincells = LG_CKH_BUCKET_CELLS;\n\t    (ZU(1) << lg_mincells) < mincells;\n\t    lg_mincells++)\n\t\t; /* Do nothing. */\n\tckh->lg_minbuckets = lg_mincells - LG_CKH_BUCKET_CELLS;\n\tckh->lg_curbuckets = lg_mincells - LG_CKH_BUCKET_CELLS;\n\tckh->hash = hash;\n\tckh->keycomp = keycomp;\n\n\tusize = sa2u(sizeof(ckhc_t) << lg_mincells, CACHELINE);\n\tif (unlikely(usize == 0 || usize > HUGE_MAXCLASS)) {\n\t\tret = true;\n\t\tgoto label_return;\n\t}\n\tckh->tab = (ckhc_t *)ipallocztm(tsd, usize, CACHELINE, true, NULL, true,\n\t    NULL);\n\tif (ckh->tab == NULL) {\n\t\tret = true;\n\t\tgoto label_return;\n\t}\n\n\tret = false;\nlabel_return:\n\treturn (ret);\n}\n\nvoid\nckh_delete(tsd_t *tsd, ckh_t *ckh)\n{\n\n\tassert(ckh != NULL);\n\n#ifdef CKH_VERBOSE\n\tmalloc_printf(\n\t    \"%s(%p): ngrows: %\"FMTu64\", nshrinks: %\"FMTu64\",\"\n\t    \" nshrinkfails: %\"FMTu64\", ninserts: %\"FMTu64\",\"\n\t    \" nrelocs: %\"FMTu64\"\\n\", __func__, ckh,\n\t    (unsigned long long)ckh->ngrows,\n\t    (unsigned long long)ckh->nshrinks,\n\t    (unsigned long long)ckh->nshrinkfails,\n\t    (unsigned long long)ckh->ninserts,\n\t    (unsigned long long)ckh->nrelocs);\n#endif\n\n\tidalloctm(tsd, ckh->tab, tcache_get(tsd, false), true, true);\n\tif (config_debug)\n\t\tmemset(ckh, 0x5a, sizeof(ckh_t));\n}\n\nsize_t\nckh_count(ckh_t *ckh)\n{\n\n\tassert(ckh != NULL);\n\n\treturn (ckh->count);\n}\n\nbool\nckh_iter(ckh_t *ckh, size_t *tabind, void **key, void **data)\n{\n\tsize_t i, ncells;\n\n\tfor (i = *tabind, ncells = (ZU(1) << (ckh->lg_curbuckets +\n\t    LG_CKH_BUCKET_CELLS)); i < ncells; i++) {\n\t\tif (ckh->tab[i].key != NULL) {\n\t\t\tif (key != NULL)\n\t\t\t\t*key = (void *)ckh->tab[i].key;\n\t\t\tif (data != NULL)\n\t\t\t\t*data = (void *)ckh->tab[i].data;\n\t\t\t*tabind = i + 1;\n\t\t\treturn (false);\n\t\t}\n\t}\n\n\treturn (true);\n}\n\nbool\nckh_insert(tsd_t *tsd, ckh_t *ckh, const void *key, const void *data)\n{\n\tbool ret;\n\n\tassert(ckh != NULL);\n\tassert(ckh_search(ckh, key, NULL, NULL));\n\n#ifdef CKH_COUNT\n\tckh->ninserts++;\n#endif\n\n\twhile (ckh_try_insert(ckh, &key, &data)) {\n\t\tif (ckh_grow(tsd, ckh)) {\n\t\t\tret = true;\n\t\t\tgoto label_return;\n\t\t}\n\t}\n\n\tret = false;\nlabel_return:\n\treturn (ret);\n}\n\nbool\nckh_remove(tsd_t *tsd, ckh_t *ckh, const void *searchkey, void **key,\n    void **data)\n{\n\tsize_t cell;\n\n\tassert(ckh != NULL);\n\n\tcell = ckh_isearch(ckh, searchkey);\n\tif (cell != SIZE_T_MAX) {\n\t\tif (key != NULL)\n\t\t\t*key = (void *)ckh->tab[cell].key;\n\t\tif (data != NULL)\n\t\t\t*data = (void *)ckh->tab[cell].data;\n\t\tckh->tab[cell].key = NULL;\n\t\tckh->tab[cell].data = NULL; /* Not necessary. */\n\n\t\tckh->count--;\n\t\t/* Try to halve the table if it is less than 1/4 full. */\n\t\tif (ckh->count < (ZU(1) << (ckh->lg_curbuckets\n\t\t    + LG_CKH_BUCKET_CELLS - 2)) && ckh->lg_curbuckets\n\t\t    > ckh->lg_minbuckets) {\n\t\t\t/* Ignore error due to OOM. */\n\t\t\tckh_shrink(tsd, ckh);\n\t\t}\n\n\t\treturn (false);\n\t}\n\n\treturn (true);\n}\n\nbool\nckh_search(ckh_t *ckh, const void *searchkey, void **key, void **data)\n{\n\tsize_t cell;\n\n\tassert(ckh != NULL);\n\n\tcell = ckh_isearch(ckh, searchkey);\n\tif (cell != SIZE_T_MAX) {\n\t\tif (key != NULL)\n\t\t\t*key = (void *)ckh->tab[cell].key;\n\t\tif (data != NULL)\n\t\t\t*data = (void *)ckh->tab[cell].data;\n\t\treturn (false);\n\t}\n\n\treturn (true);\n}\n\nvoid\nckh_string_hash(const void *key, size_t r_hash[2])\n{\n\n\thash(key, strlen((const char *)key), 0x94122f33U, r_hash);\n}\n\nbool\nckh_string_keycomp(const void *k1, const void *k2)\n{\n\n    assert(k1 != NULL);\n    assert(k2 != NULL);\n\n    return (strcmp((char *)k1, (char *)k2) ? false : true);\n}\n\nvoid\nckh_pointer_hash(const void *key, size_t r_hash[2])\n{\n\tunion {\n\t\tconst void\t*v;\n\t\tsize_t\t\ti;\n\t} u;\n\n\tassert(sizeof(u.v) == sizeof(u.i));\n\tu.v = key;\n\thash(&u.i, sizeof(u.i), 0xd983396eU, r_hash);\n}\n\nbool\nckh_pointer_keycomp(const void *k1, const void *k2)\n{\n\n\treturn ((k1 == k2) ? true : false);\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/ctl.c",
    "content": "#define\tJEMALLOC_CTL_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n/******************************************************************************/\n/* Data. */\n\n/*\n * ctl_mtx protects the following:\n * - ctl_stats.*\n */\nstatic malloc_mutex_t\tctl_mtx;\nstatic bool\t\tctl_initialized;\nstatic uint64_t\t\tctl_epoch;\nstatic ctl_stats_t\tctl_stats;\n\n/******************************************************************************/\n/* Helpers for named and indexed nodes. */\n\nJEMALLOC_INLINE_C const ctl_named_node_t *\nctl_named_node(const ctl_node_t *node)\n{\n\n\treturn ((node->named) ? (const ctl_named_node_t *)node : NULL);\n}\n\nJEMALLOC_INLINE_C const ctl_named_node_t *\nctl_named_children(const ctl_named_node_t *node, size_t index)\n{\n\tconst ctl_named_node_t *children = ctl_named_node(node->children);\n\n\treturn (children ? &children[index] : NULL);\n}\n\nJEMALLOC_INLINE_C const ctl_indexed_node_t *\nctl_indexed_node(const ctl_node_t *node)\n{\n\n\treturn (!node->named ? (const ctl_indexed_node_t *)node : NULL);\n}\n\n/******************************************************************************/\n/* Function prototypes for non-inline static functions. */\n\n#define\tCTL_PROTO(n)\t\t\t\t\t\t\t\\\nstatic int\tn##_ctl(const size_t *mib, size_t miblen, void *oldp,\t\\\n    size_t *oldlenp, void *newp, size_t newlen);\n\n#define\tINDEX_PROTO(n)\t\t\t\t\t\t\t\\\nstatic const ctl_named_node_t\t*n##_index(const size_t *mib,\t\t\\\n    size_t miblen, size_t i);\n\nstatic bool\tctl_arena_init(ctl_arena_stats_t *astats);\nstatic void\tctl_arena_clear(ctl_arena_stats_t *astats);\nstatic void\tctl_arena_stats_amerge(ctl_arena_stats_t *cstats,\n    arena_t *arena);\nstatic void\tctl_arena_stats_smerge(ctl_arena_stats_t *sstats,\n    ctl_arena_stats_t *astats);\nstatic void\tctl_arena_refresh(arena_t *arena, unsigned i);\nstatic bool\tctl_grow(void);\nstatic void\tctl_refresh(void);\nstatic bool\tctl_init(void);\nstatic int\tctl_lookup(const char *name, ctl_node_t const **nodesp,\n    size_t *mibp, size_t *depthp);\n\nCTL_PROTO(version)\nCTL_PROTO(epoch)\nCTL_PROTO(thread_tcache_enabled)\nCTL_PROTO(thread_tcache_flush)\nCTL_PROTO(thread_prof_name)\nCTL_PROTO(thread_prof_active)\nCTL_PROTO(thread_arena)\nCTL_PROTO(thread_allocated)\nCTL_PROTO(thread_allocatedp)\nCTL_PROTO(thread_deallocated)\nCTL_PROTO(thread_deallocatedp)\nCTL_PROTO(config_cache_oblivious)\nCTL_PROTO(config_debug)\nCTL_PROTO(config_fill)\nCTL_PROTO(config_lazy_lock)\nCTL_PROTO(config_malloc_conf)\nCTL_PROTO(config_munmap)\nCTL_PROTO(config_prof)\nCTL_PROTO(config_prof_libgcc)\nCTL_PROTO(config_prof_libunwind)\nCTL_PROTO(config_stats)\nCTL_PROTO(config_tcache)\nCTL_PROTO(config_tls)\nCTL_PROTO(config_utrace)\nCTL_PROTO(config_valgrind)\nCTL_PROTO(config_xmalloc)\nCTL_PROTO(opt_abort)\nCTL_PROTO(opt_dss)\nCTL_PROTO(opt_lg_chunk)\nCTL_PROTO(opt_narenas)\nCTL_PROTO(opt_purge)\nCTL_PROTO(opt_lg_dirty_mult)\nCTL_PROTO(opt_decay_time)\nCTL_PROTO(opt_stats_print)\nCTL_PROTO(opt_junk)\nCTL_PROTO(opt_zero)\nCTL_PROTO(opt_quarantine)\nCTL_PROTO(opt_redzone)\nCTL_PROTO(opt_utrace)\nCTL_PROTO(opt_xmalloc)\nCTL_PROTO(opt_tcache)\nCTL_PROTO(opt_lg_tcache_max)\nCTL_PROTO(opt_prof)\nCTL_PROTO(opt_prof_prefix)\nCTL_PROTO(opt_prof_active)\nCTL_PROTO(opt_prof_thread_active_init)\nCTL_PROTO(opt_lg_prof_sample)\nCTL_PROTO(opt_lg_prof_interval)\nCTL_PROTO(opt_prof_gdump)\nCTL_PROTO(opt_prof_final)\nCTL_PROTO(opt_prof_leak)\nCTL_PROTO(opt_prof_accum)\nCTL_PROTO(tcache_create)\nCTL_PROTO(tcache_flush)\nCTL_PROTO(tcache_destroy)\nstatic void\tarena_i_purge(unsigned arena_ind, bool all);\nCTL_PROTO(arena_i_purge)\nCTL_PROTO(arena_i_decay)\nCTL_PROTO(arena_i_dss)\nCTL_PROTO(arena_i_lg_dirty_mult)\nCTL_PROTO(arena_i_decay_time)\nCTL_PROTO(arena_i_chunk_hooks)\nINDEX_PROTO(arena_i)\nCTL_PROTO(arenas_bin_i_size)\nCTL_PROTO(arenas_bin_i_nregs)\nCTL_PROTO(arenas_bin_i_run_size)\nINDEX_PROTO(arenas_bin_i)\nCTL_PROTO(arenas_lrun_i_size)\nINDEX_PROTO(arenas_lrun_i)\nCTL_PROTO(arenas_hchunk_i_size)\nINDEX_PROTO(arenas_hchunk_i)\nCTL_PROTO(arenas_narenas)\nCTL_PROTO(arenas_initialized)\nCTL_PROTO(arenas_lg_dirty_mult)\nCTL_PROTO(arenas_decay_time)\nCTL_PROTO(arenas_quantum)\nCTL_PROTO(arenas_page)\nCTL_PROTO(arenas_tcache_max)\nCTL_PROTO(arenas_nbins)\nCTL_PROTO(arenas_nhbins)\nCTL_PROTO(arenas_nlruns)\nCTL_PROTO(arenas_nhchunks)\nCTL_PROTO(arenas_extend)\nCTL_PROTO(prof_thread_active_init)\nCTL_PROTO(prof_active)\nCTL_PROTO(prof_dump)\nCTL_PROTO(prof_gdump)\nCTL_PROTO(prof_reset)\nCTL_PROTO(prof_interval)\nCTL_PROTO(lg_prof_sample)\nCTL_PROTO(stats_arenas_i_small_allocated)\nCTL_PROTO(stats_arenas_i_small_nmalloc)\nCTL_PROTO(stats_arenas_i_small_ndalloc)\nCTL_PROTO(stats_arenas_i_small_nrequests)\nCTL_PROTO(stats_arenas_i_large_allocated)\nCTL_PROTO(stats_arenas_i_large_nmalloc)\nCTL_PROTO(stats_arenas_i_large_ndalloc)\nCTL_PROTO(stats_arenas_i_large_nrequests)\nCTL_PROTO(stats_arenas_i_huge_allocated)\nCTL_PROTO(stats_arenas_i_huge_nmalloc)\nCTL_PROTO(stats_arenas_i_huge_ndalloc)\nCTL_PROTO(stats_arenas_i_huge_nrequests)\nCTL_PROTO(stats_arenas_i_bins_j_nmalloc)\nCTL_PROTO(stats_arenas_i_bins_j_ndalloc)\nCTL_PROTO(stats_arenas_i_bins_j_nrequests)\nCTL_PROTO(stats_arenas_i_bins_j_curregs)\nCTL_PROTO(stats_arenas_i_bins_j_nfills)\nCTL_PROTO(stats_arenas_i_bins_j_nflushes)\nCTL_PROTO(stats_arenas_i_bins_j_nruns)\nCTL_PROTO(stats_arenas_i_bins_j_nreruns)\nCTL_PROTO(stats_arenas_i_bins_j_curruns)\nINDEX_PROTO(stats_arenas_i_bins_j)\nCTL_PROTO(stats_arenas_i_lruns_j_nmalloc)\nCTL_PROTO(stats_arenas_i_lruns_j_ndalloc)\nCTL_PROTO(stats_arenas_i_lruns_j_nrequests)\nCTL_PROTO(stats_arenas_i_lruns_j_curruns)\nINDEX_PROTO(stats_arenas_i_lruns_j)\nCTL_PROTO(stats_arenas_i_hchunks_j_nmalloc)\nCTL_PROTO(stats_arenas_i_hchunks_j_ndalloc)\nCTL_PROTO(stats_arenas_i_hchunks_j_nrequests)\nCTL_PROTO(stats_arenas_i_hchunks_j_curhchunks)\nINDEX_PROTO(stats_arenas_i_hchunks_j)\nCTL_PROTO(stats_arenas_i_nthreads)\nCTL_PROTO(stats_arenas_i_dss)\nCTL_PROTO(stats_arenas_i_lg_dirty_mult)\nCTL_PROTO(stats_arenas_i_decay_time)\nCTL_PROTO(stats_arenas_i_pactive)\nCTL_PROTO(stats_arenas_i_pdirty)\nCTL_PROTO(stats_arenas_i_mapped)\nCTL_PROTO(stats_arenas_i_npurge)\nCTL_PROTO(stats_arenas_i_nmadvise)\nCTL_PROTO(stats_arenas_i_purged)\nCTL_PROTO(stats_arenas_i_metadata_mapped)\nCTL_PROTO(stats_arenas_i_metadata_allocated)\nINDEX_PROTO(stats_arenas_i)\nCTL_PROTO(stats_cactive)\nCTL_PROTO(stats_allocated)\nCTL_PROTO(stats_active)\nCTL_PROTO(stats_metadata)\nCTL_PROTO(stats_resident)\nCTL_PROTO(stats_mapped)\n\n/******************************************************************************/\n/* mallctl tree. */\n\n/* Maximum tree depth. */\n#define\tCTL_MAX_DEPTH\t6\n\n#define\tNAME(n)\t{true},\tn\n#define\tCHILD(t, c)\t\t\t\t\t\t\t\\\n\tsizeof(c##_node) / sizeof(ctl_##t##_node_t),\t\t\t\\\n\t(ctl_node_t *)c##_node,\t\t\t\t\t\t\\\n\tNULL\n#define\tCTL(c)\t0, NULL, c##_ctl\n\n/*\n * Only handles internal indexed nodes, since there are currently no external\n * ones.\n */\n#define\tINDEX(i)\t{false},\ti##_index\n\nstatic const ctl_named_node_t\tthread_tcache_node[] = {\n\t{NAME(\"enabled\"),\tCTL(thread_tcache_enabled)},\n\t{NAME(\"flush\"),\t\tCTL(thread_tcache_flush)}\n};\n\nstatic const ctl_named_node_t\tthread_prof_node[] = {\n\t{NAME(\"name\"),\t\tCTL(thread_prof_name)},\n\t{NAME(\"active\"),\tCTL(thread_prof_active)}\n};\n\nstatic const ctl_named_node_t\tthread_node[] = {\n\t{NAME(\"arena\"),\t\tCTL(thread_arena)},\n\t{NAME(\"allocated\"),\tCTL(thread_allocated)},\n\t{NAME(\"allocatedp\"),\tCTL(thread_allocatedp)},\n\t{NAME(\"deallocated\"),\tCTL(thread_deallocated)},\n\t{NAME(\"deallocatedp\"),\tCTL(thread_deallocatedp)},\n\t{NAME(\"tcache\"),\tCHILD(named, thread_tcache)},\n\t{NAME(\"prof\"),\t\tCHILD(named, thread_prof)}\n};\n\nstatic const ctl_named_node_t\tconfig_node[] = {\n\t{NAME(\"cache_oblivious\"), CTL(config_cache_oblivious)},\n\t{NAME(\"debug\"),\t\tCTL(config_debug)},\n\t{NAME(\"fill\"),\t\tCTL(config_fill)},\n\t{NAME(\"lazy_lock\"),\tCTL(config_lazy_lock)},\n\t{NAME(\"malloc_conf\"),\tCTL(config_malloc_conf)},\n\t{NAME(\"munmap\"),\tCTL(config_munmap)},\n\t{NAME(\"prof\"),\t\tCTL(config_prof)},\n\t{NAME(\"prof_libgcc\"),\tCTL(config_prof_libgcc)},\n\t{NAME(\"prof_libunwind\"), CTL(config_prof_libunwind)},\n\t{NAME(\"stats\"),\t\tCTL(config_stats)},\n\t{NAME(\"tcache\"),\tCTL(config_tcache)},\n\t{NAME(\"tls\"),\t\tCTL(config_tls)},\n\t{NAME(\"utrace\"),\tCTL(config_utrace)},\n\t{NAME(\"valgrind\"),\tCTL(config_valgrind)},\n\t{NAME(\"xmalloc\"),\tCTL(config_xmalloc)}\n};\n\nstatic const ctl_named_node_t opt_node[] = {\n\t{NAME(\"abort\"),\t\tCTL(opt_abort)},\n\t{NAME(\"dss\"),\t\tCTL(opt_dss)},\n\t{NAME(\"lg_chunk\"),\tCTL(opt_lg_chunk)},\n\t{NAME(\"narenas\"),\tCTL(opt_narenas)},\n\t{NAME(\"purge\"),\t\tCTL(opt_purge)},\n\t{NAME(\"lg_dirty_mult\"),\tCTL(opt_lg_dirty_mult)},\n\t{NAME(\"decay_time\"),\tCTL(opt_decay_time)},\n\t{NAME(\"stats_print\"),\tCTL(opt_stats_print)},\n\t{NAME(\"junk\"),\t\tCTL(opt_junk)},\n\t{NAME(\"zero\"),\t\tCTL(opt_zero)},\n\t{NAME(\"quarantine\"),\tCTL(opt_quarantine)},\n\t{NAME(\"redzone\"),\tCTL(opt_redzone)},\n\t{NAME(\"utrace\"),\tCTL(opt_utrace)},\n\t{NAME(\"xmalloc\"),\tCTL(opt_xmalloc)},\n\t{NAME(\"tcache\"),\tCTL(opt_tcache)},\n\t{NAME(\"lg_tcache_max\"),\tCTL(opt_lg_tcache_max)},\n\t{NAME(\"prof\"),\t\tCTL(opt_prof)},\n\t{NAME(\"prof_prefix\"),\tCTL(opt_prof_prefix)},\n\t{NAME(\"prof_active\"),\tCTL(opt_prof_active)},\n\t{NAME(\"prof_thread_active_init\"), CTL(opt_prof_thread_active_init)},\n\t{NAME(\"lg_prof_sample\"), CTL(opt_lg_prof_sample)},\n\t{NAME(\"lg_prof_interval\"), CTL(opt_lg_prof_interval)},\n\t{NAME(\"prof_gdump\"),\tCTL(opt_prof_gdump)},\n\t{NAME(\"prof_final\"),\tCTL(opt_prof_final)},\n\t{NAME(\"prof_leak\"),\tCTL(opt_prof_leak)},\n\t{NAME(\"prof_accum\"),\tCTL(opt_prof_accum)}\n};\n\nstatic const ctl_named_node_t\ttcache_node[] = {\n\t{NAME(\"create\"),\tCTL(tcache_create)},\n\t{NAME(\"flush\"),\t\tCTL(tcache_flush)},\n\t{NAME(\"destroy\"),\tCTL(tcache_destroy)}\n};\n\nstatic const ctl_named_node_t arena_i_node[] = {\n\t{NAME(\"purge\"),\t\tCTL(arena_i_purge)},\n\t{NAME(\"decay\"),\t\tCTL(arena_i_decay)},\n\t{NAME(\"dss\"),\t\tCTL(arena_i_dss)},\n\t{NAME(\"lg_dirty_mult\"),\tCTL(arena_i_lg_dirty_mult)},\n\t{NAME(\"decay_time\"),\tCTL(arena_i_decay_time)},\n\t{NAME(\"chunk_hooks\"),\tCTL(arena_i_chunk_hooks)}\n};\nstatic const ctl_named_node_t super_arena_i_node[] = {\n\t{NAME(\"\"),\t\tCHILD(named, arena_i)}\n};\n\nstatic const ctl_indexed_node_t arena_node[] = {\n\t{INDEX(arena_i)}\n};\n\nstatic const ctl_named_node_t arenas_bin_i_node[] = {\n\t{NAME(\"size\"),\t\tCTL(arenas_bin_i_size)},\n\t{NAME(\"nregs\"),\t\tCTL(arenas_bin_i_nregs)},\n\t{NAME(\"run_size\"),\tCTL(arenas_bin_i_run_size)}\n};\nstatic const ctl_named_node_t super_arenas_bin_i_node[] = {\n\t{NAME(\"\"),\t\tCHILD(named, arenas_bin_i)}\n};\n\nstatic const ctl_indexed_node_t arenas_bin_node[] = {\n\t{INDEX(arenas_bin_i)}\n};\n\nstatic const ctl_named_node_t arenas_lrun_i_node[] = {\n\t{NAME(\"size\"),\t\tCTL(arenas_lrun_i_size)}\n};\nstatic const ctl_named_node_t super_arenas_lrun_i_node[] = {\n\t{NAME(\"\"),\t\tCHILD(named, arenas_lrun_i)}\n};\n\nstatic const ctl_indexed_node_t arenas_lrun_node[] = {\n\t{INDEX(arenas_lrun_i)}\n};\n\nstatic const ctl_named_node_t arenas_hchunk_i_node[] = {\n\t{NAME(\"size\"),\t\tCTL(arenas_hchunk_i_size)}\n};\nstatic const ctl_named_node_t super_arenas_hchunk_i_node[] = {\n\t{NAME(\"\"),\t\tCHILD(named, arenas_hchunk_i)}\n};\n\nstatic const ctl_indexed_node_t arenas_hchunk_node[] = {\n\t{INDEX(arenas_hchunk_i)}\n};\n\nstatic const ctl_named_node_t arenas_node[] = {\n\t{NAME(\"narenas\"),\tCTL(arenas_narenas)},\n\t{NAME(\"initialized\"),\tCTL(arenas_initialized)},\n\t{NAME(\"lg_dirty_mult\"),\tCTL(arenas_lg_dirty_mult)},\n\t{NAME(\"decay_time\"),\tCTL(arenas_decay_time)},\n\t{NAME(\"quantum\"),\tCTL(arenas_quantum)},\n\t{NAME(\"page\"),\t\tCTL(arenas_page)},\n\t{NAME(\"tcache_max\"),\tCTL(arenas_tcache_max)},\n\t{NAME(\"nbins\"),\t\tCTL(arenas_nbins)},\n\t{NAME(\"nhbins\"),\tCTL(arenas_nhbins)},\n\t{NAME(\"bin\"),\t\tCHILD(indexed, arenas_bin)},\n\t{NAME(\"nlruns\"),\tCTL(arenas_nlruns)},\n\t{NAME(\"lrun\"),\t\tCHILD(indexed, arenas_lrun)},\n\t{NAME(\"nhchunks\"),\tCTL(arenas_nhchunks)},\n\t{NAME(\"hchunk\"),\tCHILD(indexed, arenas_hchunk)},\n\t{NAME(\"extend\"),\tCTL(arenas_extend)}\n};\n\nstatic const ctl_named_node_t\tprof_node[] = {\n\t{NAME(\"thread_active_init\"), CTL(prof_thread_active_init)},\n\t{NAME(\"active\"),\tCTL(prof_active)},\n\t{NAME(\"dump\"),\t\tCTL(prof_dump)},\n\t{NAME(\"gdump\"),\t\tCTL(prof_gdump)},\n\t{NAME(\"reset\"),\t\tCTL(prof_reset)},\n\t{NAME(\"interval\"),\tCTL(prof_interval)},\n\t{NAME(\"lg_sample\"),\tCTL(lg_prof_sample)}\n};\n\nstatic const ctl_named_node_t stats_arenas_i_metadata_node[] = {\n\t{NAME(\"mapped\"),\tCTL(stats_arenas_i_metadata_mapped)},\n\t{NAME(\"allocated\"),\tCTL(stats_arenas_i_metadata_allocated)}\n};\n\nstatic const ctl_named_node_t stats_arenas_i_small_node[] = {\n\t{NAME(\"allocated\"),\tCTL(stats_arenas_i_small_allocated)},\n\t{NAME(\"nmalloc\"),\tCTL(stats_arenas_i_small_nmalloc)},\n\t{NAME(\"ndalloc\"),\tCTL(stats_arenas_i_small_ndalloc)},\n\t{NAME(\"nrequests\"),\tCTL(stats_arenas_i_small_nrequests)}\n};\n\nstatic const ctl_named_node_t stats_arenas_i_large_node[] = {\n\t{NAME(\"allocated\"),\tCTL(stats_arenas_i_large_allocated)},\n\t{NAME(\"nmalloc\"),\tCTL(stats_arenas_i_large_nmalloc)},\n\t{NAME(\"ndalloc\"),\tCTL(stats_arenas_i_large_ndalloc)},\n\t{NAME(\"nrequests\"),\tCTL(stats_arenas_i_large_nrequests)}\n};\n\nstatic const ctl_named_node_t stats_arenas_i_huge_node[] = {\n\t{NAME(\"allocated\"),\tCTL(stats_arenas_i_huge_allocated)},\n\t{NAME(\"nmalloc\"),\tCTL(stats_arenas_i_huge_nmalloc)},\n\t{NAME(\"ndalloc\"),\tCTL(stats_arenas_i_huge_ndalloc)},\n\t{NAME(\"nrequests\"),\tCTL(stats_arenas_i_huge_nrequests)}\n};\n\nstatic const ctl_named_node_t stats_arenas_i_bins_j_node[] = {\n\t{NAME(\"nmalloc\"),\tCTL(stats_arenas_i_bins_j_nmalloc)},\n\t{NAME(\"ndalloc\"),\tCTL(stats_arenas_i_bins_j_ndalloc)},\n\t{NAME(\"nrequests\"),\tCTL(stats_arenas_i_bins_j_nrequests)},\n\t{NAME(\"curregs\"),\tCTL(stats_arenas_i_bins_j_curregs)},\n\t{NAME(\"nfills\"),\tCTL(stats_arenas_i_bins_j_nfills)},\n\t{NAME(\"nflushes\"),\tCTL(stats_arenas_i_bins_j_nflushes)},\n\t{NAME(\"nruns\"),\t\tCTL(stats_arenas_i_bins_j_nruns)},\n\t{NAME(\"nreruns\"),\tCTL(stats_arenas_i_bins_j_nreruns)},\n\t{NAME(\"curruns\"),\tCTL(stats_arenas_i_bins_j_curruns)}\n};\nstatic const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = {\n\t{NAME(\"\"),\t\tCHILD(named, stats_arenas_i_bins_j)}\n};\n\nstatic const ctl_indexed_node_t stats_arenas_i_bins_node[] = {\n\t{INDEX(stats_arenas_i_bins_j)}\n};\n\nstatic const ctl_named_node_t stats_arenas_i_lruns_j_node[] = {\n\t{NAME(\"nmalloc\"),\tCTL(stats_arenas_i_lruns_j_nmalloc)},\n\t{NAME(\"ndalloc\"),\tCTL(stats_arenas_i_lruns_j_ndalloc)},\n\t{NAME(\"nrequests\"),\tCTL(stats_arenas_i_lruns_j_nrequests)},\n\t{NAME(\"curruns\"),\tCTL(stats_arenas_i_lruns_j_curruns)}\n};\nstatic const ctl_named_node_t super_stats_arenas_i_lruns_j_node[] = {\n\t{NAME(\"\"),\t\tCHILD(named, stats_arenas_i_lruns_j)}\n};\n\nstatic const ctl_indexed_node_t stats_arenas_i_lruns_node[] = {\n\t{INDEX(stats_arenas_i_lruns_j)}\n};\n\nstatic const ctl_named_node_t stats_arenas_i_hchunks_j_node[] = {\n\t{NAME(\"nmalloc\"),\tCTL(stats_arenas_i_hchunks_j_nmalloc)},\n\t{NAME(\"ndalloc\"),\tCTL(stats_arenas_i_hchunks_j_ndalloc)},\n\t{NAME(\"nrequests\"),\tCTL(stats_arenas_i_hchunks_j_nrequests)},\n\t{NAME(\"curhchunks\"),\tCTL(stats_arenas_i_hchunks_j_curhchunks)}\n};\nstatic const ctl_named_node_t super_stats_arenas_i_hchunks_j_node[] = {\n\t{NAME(\"\"),\t\tCHILD(named, stats_arenas_i_hchunks_j)}\n};\n\nstatic const ctl_indexed_node_t stats_arenas_i_hchunks_node[] = {\n\t{INDEX(stats_arenas_i_hchunks_j)}\n};\n\nstatic const ctl_named_node_t stats_arenas_i_node[] = {\n\t{NAME(\"nthreads\"),\tCTL(stats_arenas_i_nthreads)},\n\t{NAME(\"dss\"),\t\tCTL(stats_arenas_i_dss)},\n\t{NAME(\"lg_dirty_mult\"),\tCTL(stats_arenas_i_lg_dirty_mult)},\n\t{NAME(\"decay_time\"),\tCTL(stats_arenas_i_decay_time)},\n\t{NAME(\"pactive\"),\tCTL(stats_arenas_i_pactive)},\n\t{NAME(\"pdirty\"),\tCTL(stats_arenas_i_pdirty)},\n\t{NAME(\"mapped\"),\tCTL(stats_arenas_i_mapped)},\n\t{NAME(\"npurge\"),\tCTL(stats_arenas_i_npurge)},\n\t{NAME(\"nmadvise\"),\tCTL(stats_arenas_i_nmadvise)},\n\t{NAME(\"purged\"),\tCTL(stats_arenas_i_purged)},\n\t{NAME(\"metadata\"),\tCHILD(named, stats_arenas_i_metadata)},\n\t{NAME(\"small\"),\t\tCHILD(named, stats_arenas_i_small)},\n\t{NAME(\"large\"),\t\tCHILD(named, stats_arenas_i_large)},\n\t{NAME(\"huge\"),\t\tCHILD(named, stats_arenas_i_huge)},\n\t{NAME(\"bins\"),\t\tCHILD(indexed, stats_arenas_i_bins)},\n\t{NAME(\"lruns\"),\t\tCHILD(indexed, stats_arenas_i_lruns)},\n\t{NAME(\"hchunks\"),\tCHILD(indexed, stats_arenas_i_hchunks)}\n};\nstatic const ctl_named_node_t super_stats_arenas_i_node[] = {\n\t{NAME(\"\"),\t\tCHILD(named, stats_arenas_i)}\n};\n\nstatic const ctl_indexed_node_t stats_arenas_node[] = {\n\t{INDEX(stats_arenas_i)}\n};\n\nstatic const ctl_named_node_t stats_node[] = {\n\t{NAME(\"cactive\"),\tCTL(stats_cactive)},\n\t{NAME(\"allocated\"),\tCTL(stats_allocated)},\n\t{NAME(\"active\"),\tCTL(stats_active)},\n\t{NAME(\"metadata\"),\tCTL(stats_metadata)},\n\t{NAME(\"resident\"),\tCTL(stats_resident)},\n\t{NAME(\"mapped\"),\tCTL(stats_mapped)},\n\t{NAME(\"arenas\"),\tCHILD(indexed, stats_arenas)}\n};\n\nstatic const ctl_named_node_t\troot_node[] = {\n\t{NAME(\"version\"),\tCTL(version)},\n\t{NAME(\"epoch\"),\t\tCTL(epoch)},\n\t{NAME(\"thread\"),\tCHILD(named, thread)},\n\t{NAME(\"config\"),\tCHILD(named, config)},\n\t{NAME(\"opt\"),\t\tCHILD(named, opt)},\n\t{NAME(\"tcache\"),\tCHILD(named, tcache)},\n\t{NAME(\"arena\"),\t\tCHILD(indexed, arena)},\n\t{NAME(\"arenas\"),\tCHILD(named, arenas)},\n\t{NAME(\"prof\"),\t\tCHILD(named, prof)},\n\t{NAME(\"stats\"),\t\tCHILD(named, stats)}\n};\nstatic const ctl_named_node_t super_root_node[] = {\n\t{NAME(\"\"),\t\tCHILD(named, root)}\n};\n\n#undef NAME\n#undef CHILD\n#undef CTL\n#undef INDEX\n\n/******************************************************************************/\n\nstatic bool\nctl_arena_init(ctl_arena_stats_t *astats)\n{\n\n\tif (astats->lstats == NULL) {\n\t\tastats->lstats = (malloc_large_stats_t *)a0malloc(nlclasses *\n\t\t    sizeof(malloc_large_stats_t));\n\t\tif (astats->lstats == NULL)\n\t\t\treturn (true);\n\t}\n\n\tif (astats->hstats == NULL) {\n\t\tastats->hstats = (malloc_huge_stats_t *)a0malloc(nhclasses *\n\t\t    sizeof(malloc_huge_stats_t));\n\t\tif (astats->hstats == NULL)\n\t\t\treturn (true);\n\t}\n\n\treturn (false);\n}\n\nstatic void\nctl_arena_clear(ctl_arena_stats_t *astats)\n{\n\n\tastats->nthreads = 0;\n\tastats->dss = dss_prec_names[dss_prec_limit];\n\tastats->lg_dirty_mult = -1;\n\tastats->decay_time = -1;\n\tastats->pactive = 0;\n\tastats->pdirty = 0;\n\tif (config_stats) {\n\t\tmemset(&astats->astats, 0, sizeof(arena_stats_t));\n\t\tastats->allocated_small = 0;\n\t\tastats->nmalloc_small = 0;\n\t\tastats->ndalloc_small = 0;\n\t\tastats->nrequests_small = 0;\n\t\tmemset(astats->bstats, 0, NBINS * sizeof(malloc_bin_stats_t));\n\t\tmemset(astats->lstats, 0, nlclasses *\n\t\t    sizeof(malloc_large_stats_t));\n\t\tmemset(astats->hstats, 0, nhclasses *\n\t\t    sizeof(malloc_huge_stats_t));\n\t}\n}\n\nstatic void\nctl_arena_stats_amerge(ctl_arena_stats_t *cstats, arena_t *arena)\n{\n\tunsigned i;\n\n\tif (config_stats) {\n\t\tarena_stats_merge(arena, &cstats->nthreads, &cstats->dss,\n\t\t    &cstats->lg_dirty_mult, &cstats->decay_time,\n\t\t    &cstats->pactive, &cstats->pdirty, &cstats->astats,\n\t\t    cstats->bstats, cstats->lstats, cstats->hstats);\n\n\t\tfor (i = 0; i < NBINS; i++) {\n\t\t\tcstats->allocated_small += cstats->bstats[i].curregs *\n\t\t\t    index2size(i);\n\t\t\tcstats->nmalloc_small += cstats->bstats[i].nmalloc;\n\t\t\tcstats->ndalloc_small += cstats->bstats[i].ndalloc;\n\t\t\tcstats->nrequests_small += cstats->bstats[i].nrequests;\n\t\t}\n\t} else {\n\t\tarena_basic_stats_merge(arena, &cstats->nthreads, &cstats->dss,\n\t\t    &cstats->lg_dirty_mult, &cstats->decay_time,\n\t\t    &cstats->pactive, &cstats->pdirty);\n\t}\n}\n\nstatic void\nctl_arena_stats_smerge(ctl_arena_stats_t *sstats, ctl_arena_stats_t *astats)\n{\n\tunsigned i;\n\n\tsstats->nthreads += astats->nthreads;\n\tsstats->pactive += astats->pactive;\n\tsstats->pdirty += astats->pdirty;\n\n\tif (config_stats) {\n\t\tsstats->astats.mapped += astats->astats.mapped;\n\t\tsstats->astats.npurge += astats->astats.npurge;\n\t\tsstats->astats.nmadvise += astats->astats.nmadvise;\n\t\tsstats->astats.purged += astats->astats.purged;\n\n\t\tsstats->astats.metadata_mapped +=\n\t\t    astats->astats.metadata_mapped;\n\t\tsstats->astats.metadata_allocated +=\n\t\t    astats->astats.metadata_allocated;\n\n\t\tsstats->allocated_small += astats->allocated_small;\n\t\tsstats->nmalloc_small += astats->nmalloc_small;\n\t\tsstats->ndalloc_small += astats->ndalloc_small;\n\t\tsstats->nrequests_small += astats->nrequests_small;\n\n\t\tsstats->astats.allocated_large +=\n\t\t    astats->astats.allocated_large;\n\t\tsstats->astats.nmalloc_large += astats->astats.nmalloc_large;\n\t\tsstats->astats.ndalloc_large += astats->astats.ndalloc_large;\n\t\tsstats->astats.nrequests_large +=\n\t\t    astats->astats.nrequests_large;\n\n\t\tsstats->astats.allocated_huge += astats->astats.allocated_huge;\n\t\tsstats->astats.nmalloc_huge += astats->astats.nmalloc_huge;\n\t\tsstats->astats.ndalloc_huge += astats->astats.ndalloc_huge;\n\n\t\tfor (i = 0; i < NBINS; i++) {\n\t\t\tsstats->bstats[i].nmalloc += astats->bstats[i].nmalloc;\n\t\t\tsstats->bstats[i].ndalloc += astats->bstats[i].ndalloc;\n\t\t\tsstats->bstats[i].nrequests +=\n\t\t\t    astats->bstats[i].nrequests;\n\t\t\tsstats->bstats[i].curregs += astats->bstats[i].curregs;\n\t\t\tif (config_tcache) {\n\t\t\t\tsstats->bstats[i].nfills +=\n\t\t\t\t    astats->bstats[i].nfills;\n\t\t\t\tsstats->bstats[i].nflushes +=\n\t\t\t\t    astats->bstats[i].nflushes;\n\t\t\t}\n\t\t\tsstats->bstats[i].nruns += astats->bstats[i].nruns;\n\t\t\tsstats->bstats[i].reruns += astats->bstats[i].reruns;\n\t\t\tsstats->bstats[i].curruns += astats->bstats[i].curruns;\n\t\t}\n\n\t\tfor (i = 0; i < nlclasses; i++) {\n\t\t\tsstats->lstats[i].nmalloc += astats->lstats[i].nmalloc;\n\t\t\tsstats->lstats[i].ndalloc += astats->lstats[i].ndalloc;\n\t\t\tsstats->lstats[i].nrequests +=\n\t\t\t    astats->lstats[i].nrequests;\n\t\t\tsstats->lstats[i].curruns += astats->lstats[i].curruns;\n\t\t}\n\n\t\tfor (i = 0; i < nhclasses; i++) {\n\t\t\tsstats->hstats[i].nmalloc += astats->hstats[i].nmalloc;\n\t\t\tsstats->hstats[i].ndalloc += astats->hstats[i].ndalloc;\n\t\t\tsstats->hstats[i].curhchunks +=\n\t\t\t    astats->hstats[i].curhchunks;\n\t\t}\n\t}\n}\n\nstatic void\nctl_arena_refresh(arena_t *arena, unsigned i)\n{\n\tctl_arena_stats_t *astats = &ctl_stats.arenas[i];\n\tctl_arena_stats_t *sstats = &ctl_stats.arenas[ctl_stats.narenas];\n\n\tctl_arena_clear(astats);\n\tctl_arena_stats_amerge(astats, arena);\n\t/* Merge into sum stats as well. */\n\tctl_arena_stats_smerge(sstats, astats);\n}\n\nstatic bool\nctl_grow(void)\n{\n\tctl_arena_stats_t *astats;\n\n\t/* Initialize new arena. */\n\tif (arena_init(ctl_stats.narenas) == NULL)\n\t\treturn (true);\n\n\t/* Allocate extended arena stats. */\n\tastats = (ctl_arena_stats_t *)a0malloc((ctl_stats.narenas + 2) *\n\t    sizeof(ctl_arena_stats_t));\n\tif (astats == NULL)\n\t\treturn (true);\n\n\t/* Initialize the new astats element. */\n\tmemcpy(astats, ctl_stats.arenas, (ctl_stats.narenas + 1) *\n\t    sizeof(ctl_arena_stats_t));\n\tmemset(&astats[ctl_stats.narenas + 1], 0, sizeof(ctl_arena_stats_t));\n\tif (ctl_arena_init(&astats[ctl_stats.narenas + 1])) {\n\t\ta0dalloc(astats);\n\t\treturn (true);\n\t}\n\t/* Swap merged stats to their new location. */\n\t{\n\t\tctl_arena_stats_t tstats;\n\t\tmemcpy(&tstats, &astats[ctl_stats.narenas],\n\t\t    sizeof(ctl_arena_stats_t));\n\t\tmemcpy(&astats[ctl_stats.narenas],\n\t\t    &astats[ctl_stats.narenas + 1], sizeof(ctl_arena_stats_t));\n\t\tmemcpy(&astats[ctl_stats.narenas + 1], &tstats,\n\t\t    sizeof(ctl_arena_stats_t));\n\t}\n\ta0dalloc(ctl_stats.arenas);\n\tctl_stats.arenas = astats;\n\tctl_stats.narenas++;\n\n\treturn (false);\n}\n\nstatic void\nctl_refresh(void)\n{\n\tunsigned i;\n\tVARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas);\n\n\t/*\n\t * Clear sum stats, since they will be merged into by\n\t * ctl_arena_refresh().\n\t */\n\tctl_arena_clear(&ctl_stats.arenas[ctl_stats.narenas]);\n\n\tfor (i = 0; i < ctl_stats.narenas; i++)\n\t\ttarenas[i] = arena_get(i, false);\n\n\tfor (i = 0; i < ctl_stats.narenas; i++) {\n\t\tbool initialized = (tarenas[i] != NULL);\n\n\t\tctl_stats.arenas[i].initialized = initialized;\n\t\tif (initialized)\n\t\t\tctl_arena_refresh(tarenas[i], i);\n\t}\n\n\tif (config_stats) {\n\t\tsize_t base_allocated, base_resident, base_mapped;\n\t\tbase_stats_get(&base_allocated, &base_resident, &base_mapped);\n\t\tctl_stats.allocated =\n\t\t    ctl_stats.arenas[ctl_stats.narenas].allocated_small +\n\t\t    ctl_stats.arenas[ctl_stats.narenas].astats.allocated_large +\n\t\t    ctl_stats.arenas[ctl_stats.narenas].astats.allocated_huge;\n\t\tctl_stats.active =\n\t\t    (ctl_stats.arenas[ctl_stats.narenas].pactive << LG_PAGE);\n\t\tctl_stats.metadata = base_allocated +\n\t\t    ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped +\n\t\t    ctl_stats.arenas[ctl_stats.narenas].astats\n\t\t    .metadata_allocated;\n\t\tctl_stats.resident = base_resident +\n\t\t    ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped +\n\t\t    ((ctl_stats.arenas[ctl_stats.narenas].pactive +\n\t\t    ctl_stats.arenas[ctl_stats.narenas].pdirty) << LG_PAGE);\n\t\tctl_stats.mapped = base_mapped +\n\t\t    ctl_stats.arenas[ctl_stats.narenas].astats.mapped;\n\t}\n\n\tctl_epoch++;\n}\n\nstatic bool\nctl_init(void)\n{\n\tbool ret;\n\n\tmalloc_mutex_lock(&ctl_mtx);\n\tif (!ctl_initialized) {\n\t\t/*\n\t\t * Allocate space for one extra arena stats element, which\n\t\t * contains summed stats across all arenas.\n\t\t */\n\t\tctl_stats.narenas = narenas_total_get();\n\t\tctl_stats.arenas = (ctl_arena_stats_t *)a0malloc(\n\t\t    (ctl_stats.narenas + 1) * sizeof(ctl_arena_stats_t));\n\t\tif (ctl_stats.arenas == NULL) {\n\t\t\tret = true;\n\t\t\tgoto label_return;\n\t\t}\n\t\tmemset(ctl_stats.arenas, 0, (ctl_stats.narenas + 1) *\n\t\t    sizeof(ctl_arena_stats_t));\n\n\t\t/*\n\t\t * Initialize all stats structures, regardless of whether they\n\t\t * ever get used.  Lazy initialization would allow errors to\n\t\t * cause inconsistent state to be viewable by the application.\n\t\t */\n\t\tif (config_stats) {\n\t\t\tunsigned i;\n\t\t\tfor (i = 0; i <= ctl_stats.narenas; i++) {\n\t\t\t\tif (ctl_arena_init(&ctl_stats.arenas[i])) {\n\t\t\t\t\tunsigned j;\n\t\t\t\t\tfor (j = 0; j < i; j++) {\n\t\t\t\t\t\ta0dalloc(\n\t\t\t\t\t\t    ctl_stats.arenas[j].lstats);\n\t\t\t\t\t\ta0dalloc(\n\t\t\t\t\t\t    ctl_stats.arenas[j].hstats);\n\t\t\t\t\t}\n\t\t\t\t\ta0dalloc(ctl_stats.arenas);\n\t\t\t\t\tctl_stats.arenas = NULL;\n\t\t\t\t\tret = true;\n\t\t\t\t\tgoto label_return;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tctl_stats.arenas[ctl_stats.narenas].initialized = true;\n\n\t\tctl_epoch = 0;\n\t\tctl_refresh();\n\t\tctl_initialized = true;\n\t}\n\n\tret = false;\nlabel_return:\n\tmalloc_mutex_unlock(&ctl_mtx);\n\treturn (ret);\n}\n\nstatic int\nctl_lookup(const char *name, ctl_node_t const **nodesp, size_t *mibp,\n    size_t *depthp)\n{\n\tint ret;\n\tconst char *elm, *tdot, *dot;\n\tsize_t elen, i, j;\n\tconst ctl_named_node_t *node;\n\n\telm = name;\n\t/* Equivalent to strchrnul(). */\n\tdot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\\0');\n\telen = (size_t)((uintptr_t)dot - (uintptr_t)elm);\n\tif (elen == 0) {\n\t\tret = ENOENT;\n\t\tgoto label_return;\n\t}\n\tnode = super_root_node;\n\tfor (i = 0; i < *depthp; i++) {\n\t\tassert(node);\n\t\tassert(node->nchildren > 0);\n\t\tif (ctl_named_node(node->children) != NULL) {\n\t\t\tconst ctl_named_node_t *pnode = node;\n\n\t\t\t/* Children are named. */\n\t\t\tfor (j = 0; j < node->nchildren; j++) {\n\t\t\t\tconst ctl_named_node_t *child =\n\t\t\t\t    ctl_named_children(node, j);\n\t\t\t\tif (strlen(child->name) == elen &&\n\t\t\t\t    strncmp(elm, child->name, elen) == 0) {\n\t\t\t\t\tnode = child;\n\t\t\t\t\tif (nodesp != NULL)\n\t\t\t\t\t\tnodesp[i] =\n\t\t\t\t\t\t    (const ctl_node_t *)node;\n\t\t\t\t\tmibp[i] = j;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (node == pnode) {\n\t\t\t\tret = ENOENT;\n\t\t\t\tgoto label_return;\n\t\t\t}\n\t\t} else {\n\t\t\tuintmax_t index;\n\t\t\tconst ctl_indexed_node_t *inode;\n\n\t\t\t/* Children are indexed. */\n\t\t\tindex = malloc_strtoumax(elm, NULL, 10);\n\t\t\tif (index == UINTMAX_MAX || index > SIZE_T_MAX) {\n\t\t\t\tret = ENOENT;\n\t\t\t\tgoto label_return;\n\t\t\t}\n\n\t\t\tinode = ctl_indexed_node(node->children);\n\t\t\tnode = inode->index(mibp, *depthp, (size_t)index);\n\t\t\tif (node == NULL) {\n\t\t\t\tret = ENOENT;\n\t\t\t\tgoto label_return;\n\t\t\t}\n\n\t\t\tif (nodesp != NULL)\n\t\t\t\tnodesp[i] = (const ctl_node_t *)node;\n\t\t\tmibp[i] = (size_t)index;\n\t\t}\n\n\t\tif (node->ctl != NULL) {\n\t\t\t/* Terminal node. */\n\t\t\tif (*dot != '\\0') {\n\t\t\t\t/*\n\t\t\t\t * The name contains more elements than are\n\t\t\t\t * in this path through the tree.\n\t\t\t\t */\n\t\t\t\tret = ENOENT;\n\t\t\t\tgoto label_return;\n\t\t\t}\n\t\t\t/* Complete lookup successful. */\n\t\t\t*depthp = i + 1;\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Update elm. */\n\t\tif (*dot == '\\0') {\n\t\t\t/* No more elements. */\n\t\t\tret = ENOENT;\n\t\t\tgoto label_return;\n\t\t}\n\t\telm = &dot[1];\n\t\tdot = ((tdot = strchr(elm, '.')) != NULL) ? tdot :\n\t\t    strchr(elm, '\\0');\n\t\telen = (size_t)((uintptr_t)dot - (uintptr_t)elm);\n\t}\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\nint\nctl_byname(const char *name, void *oldp, size_t *oldlenp, void *newp,\n    size_t newlen)\n{\n\tint ret;\n\tsize_t depth;\n\tctl_node_t const *nodes[CTL_MAX_DEPTH];\n\tsize_t mib[CTL_MAX_DEPTH];\n\tconst ctl_named_node_t *node;\n\n\tif (!ctl_initialized && ctl_init()) {\n\t\tret = EAGAIN;\n\t\tgoto label_return;\n\t}\n\n\tdepth = CTL_MAX_DEPTH;\n\tret = ctl_lookup(name, nodes, mib, &depth);\n\tif (ret != 0)\n\t\tgoto label_return;\n\n\tnode = ctl_named_node(nodes[depth-1]);\n\tif (node != NULL && node->ctl)\n\t\tret = node->ctl(mib, depth, oldp, oldlenp, newp, newlen);\n\telse {\n\t\t/* The name refers to a partial path through the ctl tree. */\n\t\tret = ENOENT;\n\t}\n\nlabel_return:\n\treturn(ret);\n}\n\nint\nctl_nametomib(const char *name, size_t *mibp, size_t *miblenp)\n{\n\tint ret;\n\n\tif (!ctl_initialized && ctl_init()) {\n\t\tret = EAGAIN;\n\t\tgoto label_return;\n\t}\n\n\tret = ctl_lookup(name, NULL, mibp, miblenp);\nlabel_return:\n\treturn(ret);\n}\n\nint\nctl_bymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\n    void *newp, size_t newlen)\n{\n\tint ret;\n\tconst ctl_named_node_t *node;\n\tsize_t i;\n\n\tif (!ctl_initialized && ctl_init()) {\n\t\tret = EAGAIN;\n\t\tgoto label_return;\n\t}\n\n\t/* Iterate down the tree. */\n\tnode = super_root_node;\n\tfor (i = 0; i < miblen; i++) {\n\t\tassert(node);\n\t\tassert(node->nchildren > 0);\n\t\tif (ctl_named_node(node->children) != NULL) {\n\t\t\t/* Children are named. */\n\t\t\tif (node->nchildren <= (unsigned)mib[i]) {\n\t\t\t\tret = ENOENT;\n\t\t\t\tgoto label_return;\n\t\t\t}\n\t\t\tnode = ctl_named_children(node, mib[i]);\n\t\t} else {\n\t\t\tconst ctl_indexed_node_t *inode;\n\n\t\t\t/* Indexed element. */\n\t\t\tinode = ctl_indexed_node(node->children);\n\t\t\tnode = inode->index(mib, miblen, mib[i]);\n\t\t\tif (node == NULL) {\n\t\t\t\tret = ENOENT;\n\t\t\t\tgoto label_return;\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Call the ctl function. */\n\tif (node && node->ctl)\n\t\tret = node->ctl(mib, miblen, oldp, oldlenp, newp, newlen);\n\telse {\n\t\t/* Partial MIB. */\n\t\tret = ENOENT;\n\t}\n\nlabel_return:\n\treturn(ret);\n}\n\nbool\nctl_boot(void)\n{\n\n\tif (malloc_mutex_init(&ctl_mtx))\n\t\treturn (true);\n\n\tctl_initialized = false;\n\n\treturn (false);\n}\n\nvoid\nctl_prefork(void)\n{\n\n\tmalloc_mutex_prefork(&ctl_mtx);\n}\n\nvoid\nctl_postfork_parent(void)\n{\n\n\tmalloc_mutex_postfork_parent(&ctl_mtx);\n}\n\nvoid\nctl_postfork_child(void)\n{\n\n\tmalloc_mutex_postfork_child(&ctl_mtx);\n}\n\n/******************************************************************************/\n/* *_ctl() functions. */\n\n#define\tREADONLY()\tdo {\t\t\t\t\t\t\\\n\tif (newp != NULL || newlen != 0) {\t\t\t\t\\\n\t\tret = EPERM;\t\t\t\t\t\t\\\n\t\tgoto label_return;\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tWRITEONLY()\tdo {\t\t\t\t\t\t\\\n\tif (oldp != NULL || oldlenp != NULL) {\t\t\t\t\\\n\t\tret = EPERM;\t\t\t\t\t\t\\\n\t\tgoto label_return;\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tREAD_XOR_WRITE()\tdo {\t\t\t\t\t\\\n\tif ((oldp != NULL && oldlenp != NULL) && (newp != NULL ||\t\\\n\t    newlen != 0)) {\t\t\t\t\t\t\\\n\t\tret = EPERM;\t\t\t\t\t\t\\\n\t\tgoto label_return;\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tREAD(v, t)\tdo {\t\t\t\t\t\t\\\n\tif (oldp != NULL && oldlenp != NULL) {\t\t\t\t\\\n\t\tif (*oldlenp != sizeof(t)) {\t\t\t\t\\\n\t\t\tsize_t\tcopylen = (sizeof(t) <= *oldlenp)\t\\\n\t\t\t    ? sizeof(t) : *oldlenp;\t\t\t\\\n\t\t\tmemcpy(oldp, (void *)&(v), copylen);\t\t\\\n\t\t\tret = EINVAL;\t\t\t\t\t\\\n\t\t\tgoto label_return;\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t\t*(t *)oldp = (v);\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tWRITE(v, t)\tdo {\t\t\t\t\t\t\\\n\tif (newp != NULL) {\t\t\t\t\t\t\\\n\t\tif (newlen != sizeof(t)) {\t\t\t\t\\\n\t\t\tret = EINVAL;\t\t\t\t\t\\\n\t\t\tgoto label_return;\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t\t(v) = *(t *)newp;\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n/*\n * There's a lot of code duplication in the following macros due to limitations\n * in how nested cpp macros are expanded.\n */\n#define\tCTL_RO_CLGEN(c, l, n, v, t)\t\t\t\t\t\\\nstatic int\t\t\t\t\t\t\t\t\\\nn##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\t\\\n    void *newp, size_t newlen)\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tint ret;\t\t\t\t\t\t\t\\\n\tt oldval;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tif (!(c))\t\t\t\t\t\t\t\\\n\t\treturn (ENOENT);\t\t\t\t\t\\\n\tif (l)\t\t\t\t\t\t\t\t\\\n\t\tmalloc_mutex_lock(&ctl_mtx);\t\t\t\t\\\n\tREADONLY();\t\t\t\t\t\t\t\\\n\toldval = (v);\t\t\t\t\t\t\t\\\n\tREAD(oldval, t);\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tret = 0;\t\t\t\t\t\t\t\\\nlabel_return:\t\t\t\t\t\t\t\t\\\n\tif (l)\t\t\t\t\t\t\t\t\\\n\t\tmalloc_mutex_unlock(&ctl_mtx);\t\t\t\t\\\n\treturn (ret);\t\t\t\t\t\t\t\\\n}\n\n#define\tCTL_RO_CGEN(c, n, v, t)\t\t\t\t\t\t\\\nstatic int\t\t\t\t\t\t\t\t\\\nn##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\t\\\n    void *newp, size_t newlen)\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tint ret;\t\t\t\t\t\t\t\\\n\tt oldval;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tif (!(c))\t\t\t\t\t\t\t\\\n\t\treturn (ENOENT);\t\t\t\t\t\\\n\tmalloc_mutex_lock(&ctl_mtx);\t\t\t\t\t\\\n\tREADONLY();\t\t\t\t\t\t\t\\\n\toldval = (v);\t\t\t\t\t\t\t\\\n\tREAD(oldval, t);\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tret = 0;\t\t\t\t\t\t\t\\\nlabel_return:\t\t\t\t\t\t\t\t\\\n\tmalloc_mutex_unlock(&ctl_mtx);\t\t\t\t\t\\\n\treturn (ret);\t\t\t\t\t\t\t\\\n}\n\n#define\tCTL_RO_GEN(n, v, t)\t\t\t\t\t\t\\\nstatic int\t\t\t\t\t\t\t\t\\\nn##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\t\\\n    void *newp, size_t newlen)\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tint ret;\t\t\t\t\t\t\t\\\n\tt oldval;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tmalloc_mutex_lock(&ctl_mtx);\t\t\t\t\t\\\n\tREADONLY();\t\t\t\t\t\t\t\\\n\toldval = (v);\t\t\t\t\t\t\t\\\n\tREAD(oldval, t);\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tret = 0;\t\t\t\t\t\t\t\\\nlabel_return:\t\t\t\t\t\t\t\t\\\n\tmalloc_mutex_unlock(&ctl_mtx);\t\t\t\t\t\\\n\treturn (ret);\t\t\t\t\t\t\t\\\n}\n\n/*\n * ctl_mtx is not acquired, under the assumption that no pertinent data will\n * mutate during the call.\n */\n#define\tCTL_RO_NL_CGEN(c, n, v, t)\t\t\t\t\t\\\nstatic int\t\t\t\t\t\t\t\t\\\nn##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\t\\\n    void *newp, size_t newlen)\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tint ret;\t\t\t\t\t\t\t\\\n\tt oldval;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tif (!(c))\t\t\t\t\t\t\t\\\n\t\treturn (ENOENT);\t\t\t\t\t\\\n\tREADONLY();\t\t\t\t\t\t\t\\\n\toldval = (v);\t\t\t\t\t\t\t\\\n\tREAD(oldval, t);\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tret = 0;\t\t\t\t\t\t\t\\\nlabel_return:\t\t\t\t\t\t\t\t\\\n\treturn (ret);\t\t\t\t\t\t\t\\\n}\n\n#define\tCTL_RO_NL_GEN(n, v, t)\t\t\t\t\t\t\\\nstatic int\t\t\t\t\t\t\t\t\\\nn##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\t\\\n    void *newp, size_t newlen)\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tint ret;\t\t\t\t\t\t\t\\\n\tt oldval;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tREADONLY();\t\t\t\t\t\t\t\\\n\toldval = (v);\t\t\t\t\t\t\t\\\n\tREAD(oldval, t);\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tret = 0;\t\t\t\t\t\t\t\\\nlabel_return:\t\t\t\t\t\t\t\t\\\n\treturn (ret);\t\t\t\t\t\t\t\\\n}\n\n#define\tCTL_TSD_RO_NL_CGEN(c, n, m, t)\t\t\t\t\t\\\nstatic int\t\t\t\t\t\t\t\t\\\nn##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\t\\\n    void *newp, size_t newlen)\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tint ret;\t\t\t\t\t\t\t\\\n\tt oldval;\t\t\t\t\t\t\t\\\n\ttsd_t *tsd;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tif (!(c))\t\t\t\t\t\t\t\\\n\t\treturn (ENOENT);\t\t\t\t\t\\\n\tREADONLY();\t\t\t\t\t\t\t\\\n\ttsd = tsd_fetch();\t\t\t\t\t\t\\\n\toldval = (m(tsd));\t\t\t\t\t\t\\\n\tREAD(oldval, t);\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tret = 0;\t\t\t\t\t\t\t\\\nlabel_return:\t\t\t\t\t\t\t\t\\\n\treturn (ret);\t\t\t\t\t\t\t\\\n}\n\n#define\tCTL_RO_CONFIG_GEN(n, t)\t\t\t\t\t\t\\\nstatic int\t\t\t\t\t\t\t\t\\\nn##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\t\\\n    void *newp, size_t newlen)\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tint ret;\t\t\t\t\t\t\t\\\n\tt oldval;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tREADONLY();\t\t\t\t\t\t\t\\\n\toldval = n;\t\t\t\t\t\t\t\\\n\tREAD(oldval, t);\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tret = 0;\t\t\t\t\t\t\t\\\nlabel_return:\t\t\t\t\t\t\t\t\\\n\treturn (ret);\t\t\t\t\t\t\t\\\n}\n\n/******************************************************************************/\n\nCTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *)\n\nstatic int\nepoch_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\n    void *newp, size_t newlen)\n{\n\tint ret;\n\tUNUSED uint64_t newval;\n\n\tmalloc_mutex_lock(&ctl_mtx);\n\tWRITE(newval, uint64_t);\n\tif (newp != NULL)\n\t\tctl_refresh();\n\tREAD(ctl_epoch, uint64_t);\n\n\tret = 0;\nlabel_return:\n\tmalloc_mutex_unlock(&ctl_mtx);\n\treturn (ret);\n}\n\n/******************************************************************************/\n\nCTL_RO_CONFIG_GEN(config_cache_oblivious, bool)\nCTL_RO_CONFIG_GEN(config_debug, bool)\nCTL_RO_CONFIG_GEN(config_fill, bool)\nCTL_RO_CONFIG_GEN(config_lazy_lock, bool)\nCTL_RO_CONFIG_GEN(config_malloc_conf, const char *)\nCTL_RO_CONFIG_GEN(config_munmap, bool)\nCTL_RO_CONFIG_GEN(config_prof, bool)\nCTL_RO_CONFIG_GEN(config_prof_libgcc, bool)\nCTL_RO_CONFIG_GEN(config_prof_libunwind, bool)\nCTL_RO_CONFIG_GEN(config_stats, bool)\nCTL_RO_CONFIG_GEN(config_tcache, bool)\nCTL_RO_CONFIG_GEN(config_tls, bool)\nCTL_RO_CONFIG_GEN(config_utrace, bool)\nCTL_RO_CONFIG_GEN(config_valgrind, bool)\nCTL_RO_CONFIG_GEN(config_xmalloc, bool)\n\n/******************************************************************************/\n\nCTL_RO_NL_GEN(opt_abort, opt_abort, bool)\nCTL_RO_NL_GEN(opt_dss, opt_dss, const char *)\nCTL_RO_NL_GEN(opt_lg_chunk, opt_lg_chunk, size_t)\nCTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned)\nCTL_RO_NL_GEN(opt_purge, purge_mode_names[opt_purge], const char *)\nCTL_RO_NL_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t)\nCTL_RO_NL_GEN(opt_decay_time, opt_decay_time, ssize_t)\nCTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)\nCTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *)\nCTL_RO_NL_CGEN(config_fill, opt_quarantine, opt_quarantine, size_t)\nCTL_RO_NL_CGEN(config_fill, opt_redzone, opt_redzone, bool)\nCTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool)\nCTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)\nCTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool)\nCTL_RO_NL_CGEN(config_tcache, opt_tcache, opt_tcache, bool)\nCTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t)\nCTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool)\nCTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *)\nCTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool)\nCTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init,\n    opt_prof_thread_active_init, bool)\nCTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t)\nCTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool)\nCTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)\nCTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool)\nCTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool)\nCTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool)\n\n/******************************************************************************/\n\nstatic int\nthread_arena_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\n    void *newp, size_t newlen)\n{\n\tint ret;\n\ttsd_t *tsd;\n\tarena_t *oldarena;\n\tunsigned newind, oldind;\n\n\ttsd = tsd_fetch();\n\toldarena = arena_choose(tsd, NULL);\n\tif (oldarena == NULL)\n\t\treturn (EAGAIN);\n\n\tmalloc_mutex_lock(&ctl_mtx);\n\tnewind = oldind = oldarena->ind;\n\tWRITE(newind, unsigned);\n\tREAD(oldind, unsigned);\n\tif (newind != oldind) {\n\t\tarena_t *newarena;\n\n\t\tif (newind >= ctl_stats.narenas) {\n\t\t\t/* New arena index is out of range. */\n\t\t\tret = EFAULT;\n\t\t\tgoto label_return;\n\t\t}\n\n\t\t/* Initialize arena if necessary. */\n\t\tnewarena = arena_get(newind, true);\n\t\tif (newarena == NULL) {\n\t\t\tret = EAGAIN;\n\t\t\tgoto label_return;\n\t\t}\n\t\t/* Set new arena/tcache associations. */\n\t\tarena_migrate(tsd, oldind, newind);\n\t\tif (config_tcache) {\n\t\t\ttcache_t *tcache = tsd_tcache_get(tsd);\n\t\t\tif (tcache != NULL) {\n\t\t\t\ttcache_arena_reassociate(tcache, oldarena,\n\t\t\t\t    newarena);\n\t\t\t}\n\t\t}\n\t}\n\n\tret = 0;\nlabel_return:\n\tmalloc_mutex_unlock(&ctl_mtx);\n\treturn (ret);\n}\n\nCTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get,\n    uint64_t)\nCTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get,\n    uint64_t *)\nCTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get,\n    uint64_t)\nCTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp,\n    tsd_thread_deallocatedp_get, uint64_t *)\n\nstatic int\nthread_tcache_enabled_ctl(const size_t *mib, size_t miblen, void *oldp,\n    size_t *oldlenp, void *newp, size_t newlen)\n{\n\tint ret;\n\tbool oldval;\n\n\tif (!config_tcache)\n\t\treturn (ENOENT);\n\n\toldval = tcache_enabled_get();\n\tif (newp != NULL) {\n\t\tif (newlen != sizeof(bool)) {\n\t\t\tret = EINVAL;\n\t\t\tgoto label_return;\n\t\t}\n\t\ttcache_enabled_set(*(bool *)newp);\n\t}\n\tREAD(oldval, bool);\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\nstatic int\nthread_tcache_flush_ctl(const size_t *mib, size_t miblen, void *oldp,\n    size_t *oldlenp, void *newp, size_t newlen)\n{\n\tint ret;\n\n\tif (!config_tcache)\n\t\treturn (ENOENT);\n\n\tREADONLY();\n\tWRITEONLY();\n\n\ttcache_flush();\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\nstatic int\nthread_prof_name_ctl(const size_t *mib, size_t miblen, void *oldp,\n    size_t *oldlenp, void *newp, size_t newlen)\n{\n\tint ret;\n\n\tif (!config_prof)\n\t\treturn (ENOENT);\n\n\tREAD_XOR_WRITE();\n\n\tif (newp != NULL) {\n\t\ttsd_t *tsd;\n\n\t\tif (newlen != sizeof(const char *)) {\n\t\t\tret = EINVAL;\n\t\t\tgoto label_return;\n\t\t}\n\n\t\ttsd = tsd_fetch();\n\n\t\tif ((ret = prof_thread_name_set(tsd, *(const char **)newp)) !=\n\t\t    0)\n\t\t\tgoto label_return;\n\t} else {\n\t\tconst char *oldname = prof_thread_name_get();\n\t\tREAD(oldname, const char *);\n\t}\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\nstatic int\nthread_prof_active_ctl(const size_t *mib, size_t miblen, void *oldp,\n    size_t *oldlenp, void *newp, size_t newlen)\n{\n\tint ret;\n\tbool oldval;\n\n\tif (!config_prof)\n\t\treturn (ENOENT);\n\n\toldval = prof_thread_active_get();\n\tif (newp != NULL) {\n\t\tif (newlen != sizeof(bool)) {\n\t\t\tret = EINVAL;\n\t\t\tgoto label_return;\n\t\t}\n\t\tif (prof_thread_active_set(*(bool *)newp)) {\n\t\t\tret = EAGAIN;\n\t\t\tgoto label_return;\n\t\t}\n\t}\n\tREAD(oldval, bool);\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\n/******************************************************************************/\n\nstatic int\ntcache_create_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\n    void *newp, size_t newlen)\n{\n\tint ret;\n\ttsd_t *tsd;\n\tunsigned tcache_ind;\n\n\tif (!config_tcache)\n\t\treturn (ENOENT);\n\n\ttsd = tsd_fetch();\n\n\tmalloc_mutex_lock(&ctl_mtx);\n\tREADONLY();\n\tif (tcaches_create(tsd, &tcache_ind)) {\n\t\tret = EFAULT;\n\t\tgoto label_return;\n\t}\n\tREAD(tcache_ind, unsigned);\n\n\tret = 0;\nlabel_return:\n\tmalloc_mutex_unlock(&ctl_mtx);\n\treturn (ret);\n}\n\nstatic int\ntcache_flush_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\n    void *newp, size_t newlen)\n{\n\tint ret;\n\ttsd_t *tsd;\n\tunsigned tcache_ind;\n\n\tif (!config_tcache)\n\t\treturn (ENOENT);\n\n\ttsd = tsd_fetch();\n\n\tWRITEONLY();\n\ttcache_ind = UINT_MAX;\n\tWRITE(tcache_ind, unsigned);\n\tif (tcache_ind == UINT_MAX) {\n\t\tret = EFAULT;\n\t\tgoto label_return;\n\t}\n\ttcaches_flush(tsd, tcache_ind);\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\nstatic int\ntcache_destroy_ctl(const size_t *mib, size_t miblen, void *oldp,\n    size_t *oldlenp, void *newp, size_t newlen)\n{\n\tint ret;\n\ttsd_t *tsd;\n\tunsigned tcache_ind;\n\n\tif (!config_tcache)\n\t\treturn (ENOENT);\n\n\ttsd = tsd_fetch();\n\n\tWRITEONLY();\n\ttcache_ind = UINT_MAX;\n\tWRITE(tcache_ind, unsigned);\n\tif (tcache_ind == UINT_MAX) {\n\t\tret = EFAULT;\n\t\tgoto label_return;\n\t}\n\ttcaches_destroy(tsd, tcache_ind);\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\n/******************************************************************************/\n\nstatic void\narena_i_purge(unsigned arena_ind, bool all)\n{\n\n\tmalloc_mutex_lock(&ctl_mtx);\n\t{\n\t\tunsigned narenas = ctl_stats.narenas;\n\n\t\tif (arena_ind == narenas) {\n\t\t\tunsigned i;\n\t\t\tVARIABLE_ARRAY(arena_t *, tarenas, narenas);\n\n\t\t\tfor (i = 0; i < narenas; i++)\n\t\t\t\ttarenas[i] = arena_get(i, false);\n\n\t\t\t/*\n\t\t\t * No further need to hold ctl_mtx, since narenas and\n\t\t\t * tarenas contain everything needed below.\n\t\t\t */\n\t\t\tmalloc_mutex_unlock(&ctl_mtx);\n\n\t\t\tfor (i = 0; i < narenas; i++) {\n\t\t\t\tif (tarenas[i] != NULL)\n\t\t\t\t\tarena_purge(tarenas[i], all);\n\t\t\t}\n\t\t} else {\n\t\t\tarena_t *tarena;\n\n\t\t\tassert(arena_ind < narenas);\n\n\t\t\ttarena = arena_get(arena_ind, false);\n\n\t\t\t/* No further need to hold ctl_mtx. */\n\t\t\tmalloc_mutex_unlock(&ctl_mtx);\n\n\t\t\tif (tarena != NULL)\n\t\t\t\tarena_purge(tarena, all);\n\t\t}\n\t}\n}\n\nstatic int\narena_i_purge_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\n    void *newp, size_t newlen)\n{\n\tint ret;\n\n\tREADONLY();\n\tWRITEONLY();\n\tarena_i_purge((unsigned)mib[1], true);\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\nstatic int\narena_i_decay_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\n    void *newp, size_t newlen)\n{\n\tint ret;\n\n\tREADONLY();\n\tWRITEONLY();\n\tarena_i_purge((unsigned)mib[1], false);\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\nstatic int\narena_i_dss_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\n    void *newp, size_t newlen)\n{\n\tint ret;\n\tconst char *dss = NULL;\n\tunsigned arena_ind = (unsigned)mib[1];\n\tdss_prec_t dss_prec_old = dss_prec_limit;\n\tdss_prec_t dss_prec = dss_prec_limit;\n\n\tmalloc_mutex_lock(&ctl_mtx);\n\tWRITE(dss, const char *);\n\tif (dss != NULL) {\n\t\tint i;\n\t\tbool match = false;\n\n\t\tfor (i = 0; i < dss_prec_limit; i++) {\n\t\t\tif (strcmp(dss_prec_names[i], dss) == 0) {\n\t\t\t\tdss_prec = i;\n\t\t\t\tmatch = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!match) {\n\t\t\tret = EINVAL;\n\t\t\tgoto label_return;\n\t\t}\n\t}\n\n\tif (arena_ind < ctl_stats.narenas) {\n\t\tarena_t *arena = arena_get(arena_ind, false);\n\t\tif (arena == NULL || (dss_prec != dss_prec_limit &&\n\t\t    arena_dss_prec_set(arena, dss_prec))) {\n\t\t\tret = EFAULT;\n\t\t\tgoto label_return;\n\t\t}\n\t\tdss_prec_old = arena_dss_prec_get(arena);\n\t} else {\n\t\tif (dss_prec != dss_prec_limit &&\n\t\t    chunk_dss_prec_set(dss_prec)) {\n\t\t\tret = EFAULT;\n\t\t\tgoto label_return;\n\t\t}\n\t\tdss_prec_old = chunk_dss_prec_get();\n\t}\n\n\tdss = dss_prec_names[dss_prec_old];\n\tREAD(dss, const char *);\n\n\tret = 0;\nlabel_return:\n\tmalloc_mutex_unlock(&ctl_mtx);\n\treturn (ret);\n}\n\nstatic int\narena_i_lg_dirty_mult_ctl(const size_t *mib, size_t miblen, void *oldp,\n    size_t *oldlenp, void *newp, size_t newlen)\n{\n\tint ret;\n\tunsigned arena_ind = (unsigned)mib[1];\n\tarena_t *arena;\n\n\tarena = arena_get(arena_ind, false);\n\tif (arena == NULL) {\n\t\tret = EFAULT;\n\t\tgoto label_return;\n\t}\n\n\tif (oldp != NULL && oldlenp != NULL) {\n\t\tsize_t oldval = arena_lg_dirty_mult_get(arena);\n\t\tREAD(oldval, ssize_t);\n\t}\n\tif (newp != NULL) {\n\t\tif (newlen != sizeof(ssize_t)) {\n\t\t\tret = EINVAL;\n\t\t\tgoto label_return;\n\t\t}\n\t\tif (arena_lg_dirty_mult_set(arena, *(ssize_t *)newp)) {\n\t\t\tret = EFAULT;\n\t\t\tgoto label_return;\n\t\t}\n\t}\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\nstatic int\narena_i_decay_time_ctl(const size_t *mib, size_t miblen, void *oldp,\n    size_t *oldlenp, void *newp, size_t newlen)\n{\n\tint ret;\n\tunsigned arena_ind = (unsigned)mib[1];\n\tarena_t *arena;\n\n\tarena = arena_get(arena_ind, false);\n\tif (arena == NULL) {\n\t\tret = EFAULT;\n\t\tgoto label_return;\n\t}\n\n\tif (oldp != NULL && oldlenp != NULL) {\n\t\tsize_t oldval = arena_decay_time_get(arena);\n\t\tREAD(oldval, ssize_t);\n\t}\n\tif (newp != NULL) {\n\t\tif (newlen != sizeof(ssize_t)) {\n\t\t\tret = EINVAL;\n\t\t\tgoto label_return;\n\t\t}\n\t\tif (arena_decay_time_set(arena, *(ssize_t *)newp)) {\n\t\t\tret = EFAULT;\n\t\t\tgoto label_return;\n\t\t}\n\t}\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\nstatic int\narena_i_chunk_hooks_ctl(const size_t *mib, size_t miblen, void *oldp,\n    size_t *oldlenp, void *newp, size_t newlen)\n{\n\tint ret;\n\tunsigned arena_ind = (unsigned)mib[1];\n\tarena_t *arena;\n\n\tmalloc_mutex_lock(&ctl_mtx);\n\tif (arena_ind < narenas_total_get() && (arena =\n\t    arena_get(arena_ind, false)) != NULL) {\n\t\tif (newp != NULL) {\n\t\t\tchunk_hooks_t old_chunk_hooks, new_chunk_hooks;\n\t\t\tWRITE(new_chunk_hooks, chunk_hooks_t);\n\t\t\told_chunk_hooks = chunk_hooks_set(arena,\n\t\t\t    &new_chunk_hooks);\n\t\t\tREAD(old_chunk_hooks, chunk_hooks_t);\n\t\t} else {\n\t\t\tchunk_hooks_t old_chunk_hooks = chunk_hooks_get(arena);\n\t\t\tREAD(old_chunk_hooks, chunk_hooks_t);\n\t\t}\n\t} else {\n\t\tret = EFAULT;\n\t\tgoto label_return;\n\t}\n\tret = 0;\nlabel_return:\n\tmalloc_mutex_unlock(&ctl_mtx);\n\treturn (ret);\n}\n\nstatic const ctl_named_node_t *\narena_i_index(const size_t *mib, size_t miblen, size_t i)\n{\n\tconst ctl_named_node_t * ret;\n\n\tmalloc_mutex_lock(&ctl_mtx);\n\tif (i > ctl_stats.narenas) {\n\t\tret = NULL;\n\t\tgoto label_return;\n\t}\n\n\tret = super_arena_i_node;\nlabel_return:\n\tmalloc_mutex_unlock(&ctl_mtx);\n\treturn (ret);\n}\n\n/******************************************************************************/\n\nstatic int\narenas_narenas_ctl(const size_t *mib, size_t miblen, void *oldp,\n    size_t *oldlenp, void *newp, size_t newlen)\n{\n\tint ret;\n\tunsigned narenas;\n\n\tmalloc_mutex_lock(&ctl_mtx);\n\tREADONLY();\n\tif (*oldlenp != sizeof(unsigned)) {\n\t\tret = EINVAL;\n\t\tgoto label_return;\n\t}\n\tnarenas = ctl_stats.narenas;\n\tREAD(narenas, unsigned);\n\n\tret = 0;\nlabel_return:\n\tmalloc_mutex_unlock(&ctl_mtx);\n\treturn (ret);\n}\n\nstatic int\narenas_initialized_ctl(const size_t *mib, size_t miblen, void *oldp,\n    size_t *oldlenp, void *newp, size_t newlen)\n{\n\tint ret;\n\tunsigned nread, i;\n\n\tmalloc_mutex_lock(&ctl_mtx);\n\tREADONLY();\n\tif (*oldlenp != ctl_stats.narenas * sizeof(bool)) {\n\t\tret = EINVAL;\n\t\tnread = (*oldlenp < ctl_stats.narenas * sizeof(bool))\n\t\t    ? (unsigned)(*oldlenp / sizeof(bool)) : ctl_stats.narenas;\n\t} else {\n\t\tret = 0;\n\t\tnread = ctl_stats.narenas;\n\t}\n\n\tfor (i = 0; i < nread; i++)\n\t\t((bool *)oldp)[i] = ctl_stats.arenas[i].initialized;\n\nlabel_return:\n\tmalloc_mutex_unlock(&ctl_mtx);\n\treturn (ret);\n}\n\nstatic int\narenas_lg_dirty_mult_ctl(const size_t *mib, size_t miblen, void *oldp,\n    size_t *oldlenp, void *newp, size_t newlen)\n{\n\tint ret;\n\n\tif (oldp != NULL && oldlenp != NULL) {\n\t\tsize_t oldval = arena_lg_dirty_mult_default_get();\n\t\tREAD(oldval, ssize_t);\n\t}\n\tif (newp != NULL) {\n\t\tif (newlen != sizeof(ssize_t)) {\n\t\t\tret = EINVAL;\n\t\t\tgoto label_return;\n\t\t}\n\t\tif (arena_lg_dirty_mult_default_set(*(ssize_t *)newp)) {\n\t\t\tret = EFAULT;\n\t\t\tgoto label_return;\n\t\t}\n\t}\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\nstatic int\narenas_decay_time_ctl(const size_t *mib, size_t miblen, void *oldp,\n    size_t *oldlenp, void *newp, size_t newlen)\n{\n\tint ret;\n\n\tif (oldp != NULL && oldlenp != NULL) {\n\t\tsize_t oldval = arena_decay_time_default_get();\n\t\tREAD(oldval, ssize_t);\n\t}\n\tif (newp != NULL) {\n\t\tif (newlen != sizeof(ssize_t)) {\n\t\t\tret = EINVAL;\n\t\t\tgoto label_return;\n\t\t}\n\t\tif (arena_decay_time_default_set(*(ssize_t *)newp)) {\n\t\t\tret = EFAULT;\n\t\t\tgoto label_return;\n\t\t}\n\t}\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\nCTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t)\nCTL_RO_NL_GEN(arenas_page, PAGE, size_t)\nCTL_RO_NL_CGEN(config_tcache, arenas_tcache_max, tcache_maxclass, size_t)\nCTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned)\nCTL_RO_NL_CGEN(config_tcache, arenas_nhbins, nhbins, unsigned)\nCTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t)\nCTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t)\nCTL_RO_NL_GEN(arenas_bin_i_run_size, arena_bin_info[mib[2]].run_size, size_t)\nstatic const ctl_named_node_t *\narenas_bin_i_index(const size_t *mib, size_t miblen, size_t i)\n{\n\n\tif (i > NBINS)\n\t\treturn (NULL);\n\treturn (super_arenas_bin_i_node);\n}\n\nCTL_RO_NL_GEN(arenas_nlruns, nlclasses, unsigned)\nCTL_RO_NL_GEN(arenas_lrun_i_size, index2size(NBINS+(szind_t)mib[2]), size_t)\nstatic const ctl_named_node_t *\narenas_lrun_i_index(const size_t *mib, size_t miblen, size_t i)\n{\n\n\tif (i > nlclasses)\n\t\treturn (NULL);\n\treturn (super_arenas_lrun_i_node);\n}\n\nCTL_RO_NL_GEN(arenas_nhchunks, nhclasses, unsigned)\nCTL_RO_NL_GEN(arenas_hchunk_i_size, index2size(NBINS+nlclasses+(szind_t)mib[2]),\n    size_t)\nstatic const ctl_named_node_t *\narenas_hchunk_i_index(const size_t *mib, size_t miblen, size_t i)\n{\n\n\tif (i > nhclasses)\n\t\treturn (NULL);\n\treturn (super_arenas_hchunk_i_node);\n}\n\nstatic int\narenas_extend_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\n    void *newp, size_t newlen)\n{\n\tint ret;\n\tunsigned narenas;\n\n\tmalloc_mutex_lock(&ctl_mtx);\n\tREADONLY();\n\tif (ctl_grow()) {\n\t\tret = EAGAIN;\n\t\tgoto label_return;\n\t}\n\tnarenas = ctl_stats.narenas - 1;\n\tREAD(narenas, unsigned);\n\n\tret = 0;\nlabel_return:\n\tmalloc_mutex_unlock(&ctl_mtx);\n\treturn (ret);\n}\n\n/******************************************************************************/\n\nstatic int\nprof_thread_active_init_ctl(const size_t *mib, size_t miblen, void *oldp,\n    size_t *oldlenp, void *newp, size_t newlen)\n{\n\tint ret;\n\tbool oldval;\n\n\tif (!config_prof)\n\t\treturn (ENOENT);\n\n\tif (newp != NULL) {\n\t\tif (newlen != sizeof(bool)) {\n\t\t\tret = EINVAL;\n\t\t\tgoto label_return;\n\t\t}\n\t\toldval = prof_thread_active_init_set(*(bool *)newp);\n\t} else\n\t\toldval = prof_thread_active_init_get();\n\tREAD(oldval, bool);\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\nstatic int\nprof_active_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\n    void *newp, size_t newlen)\n{\n\tint ret;\n\tbool oldval;\n\n\tif (!config_prof)\n\t\treturn (ENOENT);\n\n\tif (newp != NULL) {\n\t\tif (newlen != sizeof(bool)) {\n\t\t\tret = EINVAL;\n\t\t\tgoto label_return;\n\t\t}\n\t\toldval = prof_active_set(*(bool *)newp);\n\t} else\n\t\toldval = prof_active_get();\n\tREAD(oldval, bool);\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\nstatic int\nprof_dump_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\n    void *newp, size_t newlen)\n{\n\tint ret;\n\tconst char *filename = NULL;\n\n\tif (!config_prof)\n\t\treturn (ENOENT);\n\n\tWRITEONLY();\n\tWRITE(filename, const char *);\n\n\tif (prof_mdump(filename)) {\n\t\tret = EFAULT;\n\t\tgoto label_return;\n\t}\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\nstatic int\nprof_gdump_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\n    void *newp, size_t newlen)\n{\n\tint ret;\n\tbool oldval;\n\n\tif (!config_prof)\n\t\treturn (ENOENT);\n\n\tif (newp != NULL) {\n\t\tif (newlen != sizeof(bool)) {\n\t\t\tret = EINVAL;\n\t\t\tgoto label_return;\n\t\t}\n\t\toldval = prof_gdump_set(*(bool *)newp);\n\t} else\n\t\toldval = prof_gdump_get();\n\tREAD(oldval, bool);\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\nstatic int\nprof_reset_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\n    void *newp, size_t newlen)\n{\n\tint ret;\n\tsize_t lg_sample = lg_prof_sample;\n\ttsd_t *tsd;\n\n\tif (!config_prof)\n\t\treturn (ENOENT);\n\n\tWRITEONLY();\n\tWRITE(lg_sample, size_t);\n\tif (lg_sample >= (sizeof(uint64_t) << 3))\n\t\tlg_sample = (sizeof(uint64_t) << 3) - 1;\n\n\ttsd = tsd_fetch();\n\n\tprof_reset(tsd, lg_sample);\n\n\tret = 0;\nlabel_return:\n\treturn (ret);\n}\n\nCTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t)\nCTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t)\n\n/******************************************************************************/\n\nCTL_RO_CGEN(config_stats, stats_cactive, &stats_cactive, size_t *)\nCTL_RO_CGEN(config_stats, stats_allocated, ctl_stats.allocated, size_t)\nCTL_RO_CGEN(config_stats, stats_active, ctl_stats.active, size_t)\nCTL_RO_CGEN(config_stats, stats_metadata, ctl_stats.metadata, size_t)\nCTL_RO_CGEN(config_stats, stats_resident, ctl_stats.resident, size_t)\nCTL_RO_CGEN(config_stats, stats_mapped, ctl_stats.mapped, size_t)\n\nCTL_RO_GEN(stats_arenas_i_dss, ctl_stats.arenas[mib[2]].dss, const char *)\nCTL_RO_GEN(stats_arenas_i_lg_dirty_mult, ctl_stats.arenas[mib[2]].lg_dirty_mult,\n    ssize_t)\nCTL_RO_GEN(stats_arenas_i_decay_time, ctl_stats.arenas[mib[2]].decay_time,\n    ssize_t)\nCTL_RO_GEN(stats_arenas_i_nthreads, ctl_stats.arenas[mib[2]].nthreads, unsigned)\nCTL_RO_GEN(stats_arenas_i_pactive, ctl_stats.arenas[mib[2]].pactive, size_t)\nCTL_RO_GEN(stats_arenas_i_pdirty, ctl_stats.arenas[mib[2]].pdirty, size_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_mapped,\n    ctl_stats.arenas[mib[2]].astats.mapped, size_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_npurge,\n    ctl_stats.arenas[mib[2]].astats.npurge, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_nmadvise,\n    ctl_stats.arenas[mib[2]].astats.nmadvise, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_purged,\n    ctl_stats.arenas[mib[2]].astats.purged, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_metadata_mapped,\n    ctl_stats.arenas[mib[2]].astats.metadata_mapped, size_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_metadata_allocated,\n    ctl_stats.arenas[mib[2]].astats.metadata_allocated, size_t)\n\nCTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated,\n    ctl_stats.arenas[mib[2]].allocated_small, size_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc,\n    ctl_stats.arenas[mib[2]].nmalloc_small, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc,\n    ctl_stats.arenas[mib[2]].ndalloc_small, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests,\n    ctl_stats.arenas[mib[2]].nrequests_small, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated,\n    ctl_stats.arenas[mib[2]].astats.allocated_large, size_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc,\n    ctl_stats.arenas[mib[2]].astats.nmalloc_large, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc,\n    ctl_stats.arenas[mib[2]].astats.ndalloc_large, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests,\n    ctl_stats.arenas[mib[2]].astats.nrequests_large, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_huge_allocated,\n    ctl_stats.arenas[mib[2]].astats.allocated_huge, size_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_huge_nmalloc,\n    ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_huge_ndalloc,\n    ctl_stats.arenas[mib[2]].astats.ndalloc_huge, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_huge_nrequests,\n    ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t) /* Intentional. */\n\nCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc,\n    ctl_stats.arenas[mib[2]].bstats[mib[4]].nmalloc, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc,\n    ctl_stats.arenas[mib[2]].bstats[mib[4]].ndalloc, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests,\n    ctl_stats.arenas[mib[2]].bstats[mib[4]].nrequests, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs,\n    ctl_stats.arenas[mib[2]].bstats[mib[4]].curregs, size_t)\nCTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nfills,\n    ctl_stats.arenas[mib[2]].bstats[mib[4]].nfills, uint64_t)\nCTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nflushes,\n    ctl_stats.arenas[mib[2]].bstats[mib[4]].nflushes, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nruns,\n    ctl_stats.arenas[mib[2]].bstats[mib[4]].nruns, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreruns,\n    ctl_stats.arenas[mib[2]].bstats[mib[4]].reruns, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curruns,\n    ctl_stats.arenas[mib[2]].bstats[mib[4]].curruns, size_t)\n\nstatic const ctl_named_node_t *\nstats_arenas_i_bins_j_index(const size_t *mib, size_t miblen, size_t j)\n{\n\n\tif (j > NBINS)\n\t\treturn (NULL);\n\treturn (super_stats_arenas_i_bins_j_node);\n}\n\nCTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nmalloc,\n    ctl_stats.arenas[mib[2]].lstats[mib[4]].nmalloc, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_ndalloc,\n    ctl_stats.arenas[mib[2]].lstats[mib[4]].ndalloc, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nrequests,\n    ctl_stats.arenas[mib[2]].lstats[mib[4]].nrequests, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_curruns,\n    ctl_stats.arenas[mib[2]].lstats[mib[4]].curruns, size_t)\n\nstatic const ctl_named_node_t *\nstats_arenas_i_lruns_j_index(const size_t *mib, size_t miblen, size_t j)\n{\n\n\tif (j > nlclasses)\n\t\treturn (NULL);\n\treturn (super_stats_arenas_i_lruns_j_node);\n}\n\nCTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nmalloc,\n    ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_ndalloc,\n    ctl_stats.arenas[mib[2]].hstats[mib[4]].ndalloc, uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nrequests,\n    ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, /* Intentional. */\n    uint64_t)\nCTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_curhchunks,\n    ctl_stats.arenas[mib[2]].hstats[mib[4]].curhchunks, size_t)\n\nstatic const ctl_named_node_t *\nstats_arenas_i_hchunks_j_index(const size_t *mib, size_t miblen, size_t j)\n{\n\n\tif (j > nhclasses)\n\t\treturn (NULL);\n\treturn (super_stats_arenas_i_hchunks_j_node);\n}\n\nstatic const ctl_named_node_t *\nstats_arenas_i_index(const size_t *mib, size_t miblen, size_t i)\n{\n\tconst ctl_named_node_t * ret;\n\n\tmalloc_mutex_lock(&ctl_mtx);\n\tif (i > ctl_stats.narenas || !ctl_stats.arenas[i].initialized) {\n\t\tret = NULL;\n\t\tgoto label_return;\n\t}\n\n\tret = super_stats_arenas_i_node;\nlabel_return:\n\tmalloc_mutex_unlock(&ctl_mtx);\n\treturn (ret);\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/extent.c",
    "content": "#define\tJEMALLOC_EXTENT_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n/******************************************************************************/\n\nJEMALLOC_INLINE_C size_t\nextent_quantize(size_t size)\n{\n\n\t/*\n\t * Round down to the nearest chunk size that can actually be requested\n\t * during normal huge allocation.\n\t */\n\treturn (index2size(size2index(size + 1) - 1));\n}\n\nJEMALLOC_INLINE_C int\nextent_szad_comp(const extent_node_t *a, const extent_node_t *b)\n{\n\tint ret;\n\tsize_t a_qsize = extent_quantize(extent_node_size_get(a));\n\tsize_t b_qsize = extent_quantize(extent_node_size_get(b));\n\n\t/*\n\t * Compare based on quantized size rather than size, in order to sort\n\t * equally useful extents only by address.\n\t */\n\tret = (a_qsize > b_qsize) - (a_qsize < b_qsize);\n\tif (ret == 0) {\n\t\tuintptr_t a_addr = (uintptr_t)extent_node_addr_get(a);\n\t\tuintptr_t b_addr = (uintptr_t)extent_node_addr_get(b);\n\n\t\tret = (a_addr > b_addr) - (a_addr < b_addr);\n\t}\n\n\treturn (ret);\n}\n\n/* Generate red-black tree functions. */\nrb_gen(, extent_tree_szad_, extent_tree_t, extent_node_t, szad_link,\n    extent_szad_comp)\n\nJEMALLOC_INLINE_C int\nextent_ad_comp(const extent_node_t *a, const extent_node_t *b)\n{\n\tuintptr_t a_addr = (uintptr_t)extent_node_addr_get(a);\n\tuintptr_t b_addr = (uintptr_t)extent_node_addr_get(b);\n\n\treturn ((a_addr > b_addr) - (a_addr < b_addr));\n}\n\n/* Generate red-black tree functions. */\nrb_gen(, extent_tree_ad_, extent_tree_t, extent_node_t, ad_link, extent_ad_comp)\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/hash.c",
    "content": "#define\tJEMALLOC_HASH_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/huge.c",
    "content": "#define\tJEMALLOC_HUGE_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n/******************************************************************************/\n\nstatic extent_node_t *\nhuge_node_get(const void *ptr)\n{\n\textent_node_t *node;\n\n\tnode = chunk_lookup(ptr, true);\n\tassert(!extent_node_achunk_get(node));\n\n\treturn (node);\n}\n\nstatic bool\nhuge_node_set(const void *ptr, extent_node_t *node)\n{\n\n\tassert(extent_node_addr_get(node) == ptr);\n\tassert(!extent_node_achunk_get(node));\n\treturn (chunk_register(ptr, node));\n}\n\nstatic void\nhuge_node_unset(const void *ptr, const extent_node_t *node)\n{\n\n\tchunk_deregister(ptr, node);\n}\n\nvoid *\nhuge_malloc(tsd_t *tsd, arena_t *arena, size_t usize, bool zero,\n    tcache_t *tcache)\n{\n\n\tassert(usize == s2u(usize));\n\n\treturn (huge_palloc(tsd, arena, usize, chunksize, zero, tcache));\n}\n\nvoid *\nhuge_palloc(tsd_t *tsd, arena_t *arena, size_t usize, size_t alignment,\n    bool zero, tcache_t *tcache)\n{\n\tvoid *ret;\n\tsize_t ausize;\n\textent_node_t *node;\n\tbool is_zeroed;\n\n\t/* Allocate one or more contiguous chunks for this request. */\n\n\tausize = sa2u(usize, alignment);\n\tif (unlikely(ausize == 0 || ausize > HUGE_MAXCLASS))\n\t\treturn (NULL);\n\tassert(ausize >= chunksize);\n\n\t/* Allocate an extent node with which to track the chunk. */\n\tnode = ipallocztm(tsd, CACHELINE_CEILING(sizeof(extent_node_t)),\n\t    CACHELINE, false, tcache, true, arena);\n\tif (node == NULL)\n\t\treturn (NULL);\n\n\t/*\n\t * Copy zero into is_zeroed and pass the copy to chunk_alloc(), so that\n\t * it is possible to make correct junk/zero fill decisions below.\n\t */\n\tis_zeroed = zero;\n\tarena = arena_choose(tsd, arena);\n\tif (unlikely(arena == NULL) || (ret = arena_chunk_alloc_huge(arena,\n\t    usize, alignment, &is_zeroed)) == NULL) {\n\t\tidalloctm(tsd, node, tcache, true, true);\n\t\treturn (NULL);\n\t}\n\n\textent_node_init(node, arena, ret, usize, is_zeroed, true);\n\n\tif (huge_node_set(ret, node)) {\n\t\tarena_chunk_dalloc_huge(arena, ret, usize);\n\t\tidalloctm(tsd, node, tcache, true, true);\n\t\treturn (NULL);\n\t}\n\n\t/* Insert node into huge. */\n\tmalloc_mutex_lock(&arena->huge_mtx);\n\tql_elm_new(node, ql_link);\n\tql_tail_insert(&arena->huge, node, ql_link);\n\tmalloc_mutex_unlock(&arena->huge_mtx);\n\n\tif (zero || (config_fill && unlikely(opt_zero))) {\n\t\tif (!is_zeroed)\n\t\t\tmemset(ret, 0, usize);\n\t} else if (config_fill && unlikely(opt_junk_alloc))\n\t\tmemset(ret, 0xa5, usize);\n\n\tarena_decay_tick(tsd, arena);\n\treturn (ret);\n}\n\n#ifdef JEMALLOC_JET\n#undef huge_dalloc_junk\n#define\thuge_dalloc_junk JEMALLOC_N(huge_dalloc_junk_impl)\n#endif\nstatic void\nhuge_dalloc_junk(void *ptr, size_t usize)\n{\n\n\tif (config_fill && have_dss && unlikely(opt_junk_free)) {\n\t\t/*\n\t\t * Only bother junk filling if the chunk isn't about to be\n\t\t * unmapped.\n\t\t */\n\t\tif (!config_munmap || (have_dss && chunk_in_dss(ptr)))\n\t\t\tmemset(ptr, 0x5a, usize);\n\t}\n}\n#ifdef JEMALLOC_JET\n#undef huge_dalloc_junk\n#define\thuge_dalloc_junk JEMALLOC_N(huge_dalloc_junk)\nhuge_dalloc_junk_t *huge_dalloc_junk = JEMALLOC_N(huge_dalloc_junk_impl);\n#endif\n\nstatic void\nhuge_ralloc_no_move_similar(void *ptr, size_t oldsize, size_t usize_min,\n    size_t usize_max, bool zero)\n{\n\tsize_t usize, usize_next;\n\textent_node_t *node;\n\tarena_t *arena;\n\tchunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER;\n\tbool pre_zeroed, post_zeroed;\n\n\t/* Increase usize to incorporate extra. */\n\tfor (usize = usize_min; usize < usize_max && (usize_next = s2u(usize+1))\n\t    <= oldsize; usize = usize_next)\n\t\t; /* Do nothing. */\n\n\tif (oldsize == usize)\n\t\treturn;\n\n\tnode = huge_node_get(ptr);\n\tarena = extent_node_arena_get(node);\n\tpre_zeroed = extent_node_zeroed_get(node);\n\n\t/* Fill if necessary (shrinking). */\n\tif (oldsize > usize) {\n\t\tsize_t sdiff = oldsize - usize;\n\t\tif (config_fill && unlikely(opt_junk_free)) {\n\t\t\tmemset((void *)((uintptr_t)ptr + usize), 0x5a, sdiff);\n\t\t\tpost_zeroed = false;\n\t\t} else {\n\t\t\tpost_zeroed = !chunk_purge_wrapper(arena, &chunk_hooks,\n\t\t\t    ptr, CHUNK_CEILING(oldsize), usize, sdiff);\n\t\t}\n\t} else\n\t\tpost_zeroed = pre_zeroed;\n\n\tmalloc_mutex_lock(&arena->huge_mtx);\n\t/* Update the size of the huge allocation. */\n\tassert(extent_node_size_get(node) != usize);\n\textent_node_size_set(node, usize);\n\t/* Update zeroed. */\n\textent_node_zeroed_set(node, post_zeroed);\n\tmalloc_mutex_unlock(&arena->huge_mtx);\n\n\tarena_chunk_ralloc_huge_similar(arena, ptr, oldsize, usize);\n\n\t/* Fill if necessary (growing). */\n\tif (oldsize < usize) {\n\t\tif (zero || (config_fill && unlikely(opt_zero))) {\n\t\t\tif (!pre_zeroed) {\n\t\t\t\tmemset((void *)((uintptr_t)ptr + oldsize), 0,\n\t\t\t\t    usize - oldsize);\n\t\t\t}\n\t\t} else if (config_fill && unlikely(opt_junk_alloc)) {\n\t\t\tmemset((void *)((uintptr_t)ptr + oldsize), 0xa5, usize -\n\t\t\t    oldsize);\n\t\t}\n\t}\n}\n\nstatic bool\nhuge_ralloc_no_move_shrink(void *ptr, size_t oldsize, size_t usize)\n{\n\textent_node_t *node;\n\tarena_t *arena;\n\tchunk_hooks_t chunk_hooks;\n\tsize_t cdiff;\n\tbool pre_zeroed, post_zeroed;\n\n\tnode = huge_node_get(ptr);\n\tarena = extent_node_arena_get(node);\n\tpre_zeroed = extent_node_zeroed_get(node);\n\tchunk_hooks = chunk_hooks_get(arena);\n\n\tassert(oldsize > usize);\n\n\t/* Split excess chunks. */\n\tcdiff = CHUNK_CEILING(oldsize) - CHUNK_CEILING(usize);\n\tif (cdiff != 0 && chunk_hooks.split(ptr, CHUNK_CEILING(oldsize),\n\t    CHUNK_CEILING(usize), cdiff, true, arena->ind))\n\t\treturn (true);\n\n\tif (oldsize > usize) {\n\t\tsize_t sdiff = oldsize - usize;\n\t\tif (config_fill && unlikely(opt_junk_free)) {\n\t\t\thuge_dalloc_junk((void *)((uintptr_t)ptr + usize),\n\t\t\t    sdiff);\n\t\t\tpost_zeroed = false;\n\t\t} else {\n\t\t\tpost_zeroed = !chunk_purge_wrapper(arena, &chunk_hooks,\n\t\t\t    CHUNK_ADDR2BASE((uintptr_t)ptr + usize),\n\t\t\t    CHUNK_CEILING(oldsize),\n\t\t\t    CHUNK_ADDR2OFFSET((uintptr_t)ptr + usize), sdiff);\n\t\t}\n\t} else\n\t\tpost_zeroed = pre_zeroed;\n\n\tmalloc_mutex_lock(&arena->huge_mtx);\n\t/* Update the size of the huge allocation. */\n\textent_node_size_set(node, usize);\n\t/* Update zeroed. */\n\textent_node_zeroed_set(node, post_zeroed);\n\tmalloc_mutex_unlock(&arena->huge_mtx);\n\n\t/* Zap the excess chunks. */\n\tarena_chunk_ralloc_huge_shrink(arena, ptr, oldsize, usize);\n\n\treturn (false);\n}\n\nstatic bool\nhuge_ralloc_no_move_expand(void *ptr, size_t oldsize, size_t usize, bool zero) {\n\textent_node_t *node;\n\tarena_t *arena;\n\tbool is_zeroed_subchunk, is_zeroed_chunk;\n\n\tnode = huge_node_get(ptr);\n\tarena = extent_node_arena_get(node);\n\tmalloc_mutex_lock(&arena->huge_mtx);\n\tis_zeroed_subchunk = extent_node_zeroed_get(node);\n\tmalloc_mutex_unlock(&arena->huge_mtx);\n\n\t/*\n\t * Copy zero into is_zeroed_chunk and pass the copy to chunk_alloc(), so\n\t * that it is possible to make correct junk/zero fill decisions below.\n\t */\n\tis_zeroed_chunk = zero;\n\n\tif (arena_chunk_ralloc_huge_expand(arena, ptr, oldsize, usize,\n\t     &is_zeroed_chunk))\n\t\treturn (true);\n\n\tmalloc_mutex_lock(&arena->huge_mtx);\n\t/* Update the size of the huge allocation. */\n\textent_node_size_set(node, usize);\n\tmalloc_mutex_unlock(&arena->huge_mtx);\n\n\tif (zero || (config_fill && unlikely(opt_zero))) {\n\t\tif (!is_zeroed_subchunk) {\n\t\t\tmemset((void *)((uintptr_t)ptr + oldsize), 0,\n\t\t\t    CHUNK_CEILING(oldsize) - oldsize);\n\t\t}\n\t\tif (!is_zeroed_chunk) {\n\t\t\tmemset((void *)((uintptr_t)ptr +\n\t\t\t    CHUNK_CEILING(oldsize)), 0, usize -\n\t\t\t    CHUNK_CEILING(oldsize));\n\t\t}\n\t} else if (config_fill && unlikely(opt_junk_alloc)) {\n\t\tmemset((void *)((uintptr_t)ptr + oldsize), 0xa5, usize -\n\t\t    oldsize);\n\t}\n\n\treturn (false);\n}\n\nbool\nhuge_ralloc_no_move(tsd_t *tsd, void *ptr, size_t oldsize, size_t usize_min,\n    size_t usize_max, bool zero)\n{\n\n\tassert(s2u(oldsize) == oldsize);\n\t/* The following should have been caught by callers. */\n\tassert(usize_min > 0 && usize_max <= HUGE_MAXCLASS);\n\n\t/* Both allocations must be huge to avoid a move. */\n\tif (oldsize < chunksize || usize_max < chunksize)\n\t\treturn (true);\n\n\tif (CHUNK_CEILING(usize_max) > CHUNK_CEILING(oldsize)) {\n\t\t/* Attempt to expand the allocation in-place. */\n\t\tif (!huge_ralloc_no_move_expand(ptr, oldsize, usize_max,\n\t\t    zero)) {\n\t\t\tarena_decay_tick(tsd, huge_aalloc(ptr));\n\t\t\treturn (false);\n\t\t}\n\t\t/* Try again, this time with usize_min. */\n\t\tif (usize_min < usize_max && CHUNK_CEILING(usize_min) >\n\t\t    CHUNK_CEILING(oldsize) && huge_ralloc_no_move_expand(ptr,\n\t\t    oldsize, usize_min, zero)) {\n\t\t\tarena_decay_tick(tsd, huge_aalloc(ptr));\n\t\t\treturn (false);\n\t\t}\n\t}\n\n\t/*\n\t * Avoid moving the allocation if the existing chunk size accommodates\n\t * the new size.\n\t */\n\tif (CHUNK_CEILING(oldsize) >= CHUNK_CEILING(usize_min)\n\t    && CHUNK_CEILING(oldsize) <= CHUNK_CEILING(usize_max)) {\n\t\thuge_ralloc_no_move_similar(ptr, oldsize, usize_min, usize_max,\n\t\t    zero);\n\t\tarena_decay_tick(tsd, huge_aalloc(ptr));\n\t\treturn (false);\n\t}\n\n\t/* Attempt to shrink the allocation in-place. */\n\tif (CHUNK_CEILING(oldsize) > CHUNK_CEILING(usize_max)) {\n\t\tif (!huge_ralloc_no_move_shrink(ptr, oldsize, usize_max)) {\n\t\t\tarena_decay_tick(tsd, huge_aalloc(ptr));\n\t\t\treturn (false);\n\t\t}\n\t}\n\treturn (true);\n}\n\nstatic void *\nhuge_ralloc_move_helper(tsd_t *tsd, arena_t *arena, size_t usize,\n    size_t alignment, bool zero, tcache_t *tcache)\n{\n\n\tif (alignment <= chunksize)\n\t\treturn (huge_malloc(tsd, arena, usize, zero, tcache));\n\treturn (huge_palloc(tsd, arena, usize, alignment, zero, tcache));\n}\n\nvoid *\nhuge_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, size_t usize,\n    size_t alignment, bool zero, tcache_t *tcache)\n{\n\tvoid *ret;\n\tsize_t copysize;\n\n\t/* The following should have been caught by callers. */\n\tassert(usize > 0 && usize <= HUGE_MAXCLASS);\n\n\t/* Try to avoid moving the allocation. */\n\tif (!huge_ralloc_no_move(tsd, ptr, oldsize, usize, usize, zero))\n\t\treturn (ptr);\n\n\t/*\n\t * usize and oldsize are different enough that we need to use a\n\t * different size class.  In that case, fall back to allocating new\n\t * space and copying.\n\t */\n\tret = huge_ralloc_move_helper(tsd, arena, usize, alignment, zero,\n\t    tcache);\n\tif (ret == NULL)\n\t\treturn (NULL);\n\n\tcopysize = (usize < oldsize) ? usize : oldsize;\n\tmemcpy(ret, ptr, copysize);\n\tisqalloc(tsd, ptr, oldsize, tcache);\n\treturn (ret);\n}\n\nvoid\nhuge_dalloc(tsd_t *tsd, void *ptr, tcache_t *tcache)\n{\n\textent_node_t *node;\n\tarena_t *arena;\n\n\tnode = huge_node_get(ptr);\n\tarena = extent_node_arena_get(node);\n\thuge_node_unset(ptr, node);\n\tmalloc_mutex_lock(&arena->huge_mtx);\n\tql_remove(&arena->huge, node, ql_link);\n\tmalloc_mutex_unlock(&arena->huge_mtx);\n\n\thuge_dalloc_junk(extent_node_addr_get(node),\n\t    extent_node_size_get(node));\n\tarena_chunk_dalloc_huge(extent_node_arena_get(node),\n\t    extent_node_addr_get(node), extent_node_size_get(node));\n\tidalloctm(tsd, node, tcache, true, true);\n\n\tarena_decay_tick(tsd, arena);\n}\n\narena_t *\nhuge_aalloc(const void *ptr)\n{\n\n\treturn (extent_node_arena_get(huge_node_get(ptr)));\n}\n\nsize_t\nhuge_salloc(const void *ptr)\n{\n\tsize_t size;\n\textent_node_t *node;\n\tarena_t *arena;\n\n\tnode = huge_node_get(ptr);\n\tarena = extent_node_arena_get(node);\n\tmalloc_mutex_lock(&arena->huge_mtx);\n\tsize = extent_node_size_get(node);\n\tmalloc_mutex_unlock(&arena->huge_mtx);\n\n\treturn (size);\n}\n\nprof_tctx_t *\nhuge_prof_tctx_get(const void *ptr)\n{\n\tprof_tctx_t *tctx;\n\textent_node_t *node;\n\tarena_t *arena;\n\n\tnode = huge_node_get(ptr);\n\tarena = extent_node_arena_get(node);\n\tmalloc_mutex_lock(&arena->huge_mtx);\n\ttctx = extent_node_prof_tctx_get(node);\n\tmalloc_mutex_unlock(&arena->huge_mtx);\n\n\treturn (tctx);\n}\n\nvoid\nhuge_prof_tctx_set(const void *ptr, prof_tctx_t *tctx)\n{\n\textent_node_t *node;\n\tarena_t *arena;\n\n\tnode = huge_node_get(ptr);\n\tarena = extent_node_arena_get(node);\n\tmalloc_mutex_lock(&arena->huge_mtx);\n\textent_node_prof_tctx_set(node, tctx);\n\tmalloc_mutex_unlock(&arena->huge_mtx);\n}\n\nvoid\nhuge_prof_tctx_reset(const void *ptr)\n{\n\n\thuge_prof_tctx_set(ptr, (prof_tctx_t *)(uintptr_t)1U);\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/jemalloc.c",
    "content": "#define\tJEMALLOC_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n/******************************************************************************/\n/* Data. */\n\n/* Runtime configuration options. */\nconst char\t*je_malloc_conf JEMALLOC_ATTR(weak);\nbool\topt_abort =\n#ifdef JEMALLOC_DEBUG\n    true\n#else\n    false\n#endif\n    ;\nconst char\t*opt_junk =\n#if (defined(JEMALLOC_DEBUG) && defined(JEMALLOC_FILL))\n    \"true\"\n#else\n    \"false\"\n#endif\n    ;\nbool\topt_junk_alloc =\n#if (defined(JEMALLOC_DEBUG) && defined(JEMALLOC_FILL))\n    true\n#else\n    false\n#endif\n    ;\nbool\topt_junk_free =\n#if (defined(JEMALLOC_DEBUG) && defined(JEMALLOC_FILL))\n    true\n#else\n    false\n#endif\n    ;\n\nsize_t\topt_quarantine = ZU(0);\nbool\topt_redzone = false;\nbool\topt_utrace = false;\nbool\topt_xmalloc = false;\nbool\topt_zero = false;\nunsigned\topt_narenas = 0;\n\n/* Initialized to true if the process is running inside Valgrind. */\nbool\tin_valgrind;\n\nunsigned\tncpus;\n\n/* Protects arenas initialization. */\nstatic malloc_mutex_t\tarenas_lock;\n/*\n * Arenas that are used to service external requests.  Not all elements of the\n * arenas array are necessarily used; arenas are created lazily as needed.\n *\n * arenas[0..narenas_auto) are used for automatic multiplexing of threads and\n * arenas.  arenas[narenas_auto..narenas_total) are only used if the application\n * takes some action to create them and allocate from them.\n */\narena_t\t\t\t**arenas;\nstatic unsigned\t\tnarenas_total; /* Use narenas_total_*(). */\nstatic arena_t\t\t*a0; /* arenas[0]; read-only after initialization. */\nstatic unsigned\t\tnarenas_auto; /* Read-only after initialization. */\n\ntypedef enum {\n\tmalloc_init_uninitialized\t= 3,\n\tmalloc_init_a0_initialized\t= 2,\n\tmalloc_init_recursible\t\t= 1,\n\tmalloc_init_initialized\t\t= 0 /* Common case --> jnz. */\n} malloc_init_t;\nstatic malloc_init_t\tmalloc_init_state = malloc_init_uninitialized;\n\n/* 0 should be the common case.  Set to true to trigger initialization. */\nstatic bool\tmalloc_slow = true;\n\n/* When malloc_slow != 0, set the corresponding bits for sanity check. */\nenum {\n\tflag_opt_junk_alloc\t= (1U),\n\tflag_opt_junk_free\t= (1U << 1),\n\tflag_opt_quarantine\t= (1U << 2),\n\tflag_opt_zero\t\t= (1U << 3),\n\tflag_opt_utrace\t\t= (1U << 4),\n\tflag_in_valgrind\t= (1U << 5),\n\tflag_opt_xmalloc\t= (1U << 6)\n};\nstatic uint8_t\tmalloc_slow_flags;\n\n/* Last entry for overflow detection only.  */\nJEMALLOC_ALIGNED(CACHELINE)\nconst size_t\tindex2size_tab[NSIZES+1] = {\n#define\tSC(index, lg_grp, lg_delta, ndelta, bin, lg_delta_lookup) \\\n\t((ZU(1)<<lg_grp) + (ZU(ndelta)<<lg_delta)),\n\tSIZE_CLASSES\n#undef SC\n\tZU(0)\n};\n\nJEMALLOC_ALIGNED(CACHELINE)\nconst uint8_t\tsize2index_tab[] = {\n#if LG_TINY_MIN == 0\n#warning \"Dangerous LG_TINY_MIN\"\n#define\tS2B_0(i)\ti,\n#elif LG_TINY_MIN == 1\n#warning \"Dangerous LG_TINY_MIN\"\n#define\tS2B_1(i)\ti,\n#elif LG_TINY_MIN == 2\n#warning \"Dangerous LG_TINY_MIN\"\n#define\tS2B_2(i)\ti,\n#elif LG_TINY_MIN == 3\n#define\tS2B_3(i)\ti,\n#elif LG_TINY_MIN == 4\n#define\tS2B_4(i)\ti,\n#elif LG_TINY_MIN == 5\n#define\tS2B_5(i)\ti,\n#elif LG_TINY_MIN == 6\n#define\tS2B_6(i)\ti,\n#elif LG_TINY_MIN == 7\n#define\tS2B_7(i)\ti,\n#elif LG_TINY_MIN == 8\n#define\tS2B_8(i)\ti,\n#elif LG_TINY_MIN == 9\n#define\tS2B_9(i)\ti,\n#elif LG_TINY_MIN == 10\n#define\tS2B_10(i)\ti,\n#elif LG_TINY_MIN == 11\n#define\tS2B_11(i)\ti,\n#else\n#error \"Unsupported LG_TINY_MIN\"\n#endif\n#if LG_TINY_MIN < 1\n#define\tS2B_1(i)\tS2B_0(i) S2B_0(i)\n#endif\n#if LG_TINY_MIN < 2\n#define\tS2B_2(i)\tS2B_1(i) S2B_1(i)\n#endif\n#if LG_TINY_MIN < 3\n#define\tS2B_3(i)\tS2B_2(i) S2B_2(i)\n#endif\n#if LG_TINY_MIN < 4\n#define\tS2B_4(i)\tS2B_3(i) S2B_3(i)\n#endif\n#if LG_TINY_MIN < 5\n#define\tS2B_5(i)\tS2B_4(i) S2B_4(i)\n#endif\n#if LG_TINY_MIN < 6\n#define\tS2B_6(i)\tS2B_5(i) S2B_5(i)\n#endif\n#if LG_TINY_MIN < 7\n#define\tS2B_7(i)\tS2B_6(i) S2B_6(i)\n#endif\n#if LG_TINY_MIN < 8\n#define\tS2B_8(i)\tS2B_7(i) S2B_7(i)\n#endif\n#if LG_TINY_MIN < 9\n#define\tS2B_9(i)\tS2B_8(i) S2B_8(i)\n#endif\n#if LG_TINY_MIN < 10\n#define\tS2B_10(i)\tS2B_9(i) S2B_9(i)\n#endif\n#if LG_TINY_MIN < 11\n#define\tS2B_11(i)\tS2B_10(i) S2B_10(i)\n#endif\n#define\tS2B_no(i)\n#define\tSC(index, lg_grp, lg_delta, ndelta, bin, lg_delta_lookup) \\\n\tS2B_##lg_delta_lookup(index)\n\tSIZE_CLASSES\n#undef S2B_3\n#undef S2B_4\n#undef S2B_5\n#undef S2B_6\n#undef S2B_7\n#undef S2B_8\n#undef S2B_9\n#undef S2B_10\n#undef S2B_11\n#undef S2B_no\n#undef SC\n};\n\n#ifdef JEMALLOC_THREADED_INIT\n/* Used to let the initializing thread recursively allocate. */\n#  define NO_INITIALIZER\t((unsigned long)0)\n#  define INITIALIZER\t\tpthread_self()\n#  define IS_INITIALIZER\t(malloc_initializer == pthread_self())\nstatic pthread_t\t\tmalloc_initializer = NO_INITIALIZER;\n#else\n#  define NO_INITIALIZER\tfalse\n#  define INITIALIZER\t\ttrue\n#  define IS_INITIALIZER\tmalloc_initializer\nstatic bool\t\t\tmalloc_initializer = NO_INITIALIZER;\n#endif\n\n/* Used to avoid initialization races. */\n#ifdef _WIN32\n#if _WIN32_WINNT >= 0x0600\nstatic malloc_mutex_t\tinit_lock = SRWLOCK_INIT;\n#else\nstatic malloc_mutex_t\tinit_lock;\nstatic bool init_lock_initialized = false;\n\nJEMALLOC_ATTR(constructor)\nstatic void WINAPI\n_init_init_lock(void)\n{\n\n\t/* If another constructor in the same binary is using mallctl to\n\t * e.g. setup chunk hooks, it may end up running before this one,\n\t * and malloc_init_hard will crash trying to lock the uninitialized\n\t * lock. So we force an initialization of the lock in\n\t * malloc_init_hard as well. We don't try to care about atomicity\n\t * of the accessed to the init_lock_initialized boolean, since it\n\t * really only matters early in the process creation, before any\n\t * separate thread normally starts doing anything. */\n\tif (!init_lock_initialized)\n\t\tmalloc_mutex_init(&init_lock);\n\tinit_lock_initialized = true;\n}\n\n#ifdef _MSC_VER\n#  pragma section(\".CRT$XCU\", read)\nJEMALLOC_SECTION(\".CRT$XCU\") JEMALLOC_ATTR(used)\nstatic const void (WINAPI *init_init_lock)(void) = _init_init_lock;\n#endif\n#endif\n#else\nstatic malloc_mutex_t\tinit_lock = MALLOC_MUTEX_INITIALIZER;\n#endif\n\ntypedef struct {\n\tvoid\t*p;\t/* Input pointer (as in realloc(p, s)). */\n\tsize_t\ts;\t/* Request size. */\n\tvoid\t*r;\t/* Result pointer. */\n} malloc_utrace_t;\n\n#ifdef JEMALLOC_UTRACE\n#  define UTRACE(a, b, c) do {\t\t\t\t\t\t\\\n\tif (unlikely(opt_utrace)) {\t\t\t\t\t\\\n\t\tint utrace_serrno = errno;\t\t\t\t\\\n\t\tmalloc_utrace_t ut;\t\t\t\t\t\\\n\t\tut.p = (a);\t\t\t\t\t\t\\\n\t\tut.s = (b);\t\t\t\t\t\t\\\n\t\tut.r = (c);\t\t\t\t\t\t\\\n\t\tutrace(&ut, sizeof(ut));\t\t\t\t\\\n\t\terrno = utrace_serrno;\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n#else\n#  define UTRACE(a, b, c)\n#endif\n\n/******************************************************************************/\n/*\n * Function prototypes for static functions that are referenced prior to\n * definition.\n */\n\nstatic bool\tmalloc_init_hard_a0(void);\nstatic bool\tmalloc_init_hard(void);\n\n/******************************************************************************/\n/*\n * Begin miscellaneous support functions.\n */\n\nJEMALLOC_ALWAYS_INLINE_C bool\nmalloc_initialized(void)\n{\n\n\treturn (malloc_init_state == malloc_init_initialized);\n}\n\nJEMALLOC_ALWAYS_INLINE_C void\nmalloc_thread_init(void)\n{\n\n\t/*\n\t * TSD initialization can't be safely done as a side effect of\n\t * deallocation, because it is possible for a thread to do nothing but\n\t * deallocate its TLS data via free(), in which case writing to TLS\n\t * would cause write-after-free memory corruption.  The quarantine\n\t * facility *only* gets used as a side effect of deallocation, so make\n\t * a best effort attempt at initializing its TSD by hooking all\n\t * allocation events.\n\t */\n\tif (config_fill && unlikely(opt_quarantine))\n\t\tquarantine_alloc_hook();\n}\n\nJEMALLOC_ALWAYS_INLINE_C bool\nmalloc_init_a0(void)\n{\n\n\tif (unlikely(malloc_init_state == malloc_init_uninitialized))\n\t\treturn (malloc_init_hard_a0());\n\treturn (false);\n}\n\nJEMALLOC_ALWAYS_INLINE_C bool\nmalloc_init(void)\n{\n\n\tif (unlikely(!malloc_initialized()) && malloc_init_hard())\n\t\treturn (true);\n\tmalloc_thread_init();\n\n\treturn (false);\n}\n\n/*\n * The a0*() functions are used instead of i[mcd]alloc() in situations that\n * cannot tolerate TLS variable access.\n */\n\nstatic void *\na0ialloc(size_t size, bool zero, bool is_metadata)\n{\n\n\tif (unlikely(malloc_init_a0()))\n\t\treturn (NULL);\n\n\treturn (iallocztm(NULL, size, size2index(size), zero, false,\n\t    is_metadata, arena_get(0, false), true));\n}\n\nstatic void\na0idalloc(void *ptr, bool is_metadata)\n{\n\n\tidalloctm(NULL, ptr, false, is_metadata, true);\n}\n\nvoid *\na0malloc(size_t size)\n{\n\n\treturn (a0ialloc(size, false, true));\n}\n\nvoid\na0dalloc(void *ptr)\n{\n\n\ta0idalloc(ptr, true);\n}\n\n/*\n * FreeBSD's libc uses the bootstrap_*() functions in bootstrap-senstive\n * situations that cannot tolerate TLS variable access (TLS allocation and very\n * early internal data structure initialization).\n */\n\nvoid *\nbootstrap_malloc(size_t size)\n{\n\n\tif (unlikely(size == 0))\n\t\tsize = 1;\n\n\treturn (a0ialloc(size, false, false));\n}\n\nvoid *\nbootstrap_calloc(size_t num, size_t size)\n{\n\tsize_t num_size;\n\n\tnum_size = num * size;\n\tif (unlikely(num_size == 0)) {\n\t\tassert(num == 0 || size == 0);\n\t\tnum_size = 1;\n\t}\n\n\treturn (a0ialloc(num_size, true, false));\n}\n\nvoid\nbootstrap_free(void *ptr)\n{\n\n\tif (unlikely(ptr == NULL))\n\t\treturn;\n\n\ta0idalloc(ptr, false);\n}\n\nstatic void\narena_set(unsigned ind, arena_t *arena)\n{\n\n\tatomic_write_p((void **)&arenas[ind], arena);\n}\n\nstatic void\nnarenas_total_set(unsigned narenas)\n{\n\n\tatomic_write_u(&narenas_total, narenas);\n}\n\nstatic void\nnarenas_total_inc(void)\n{\n\n\tatomic_add_u(&narenas_total, 1);\n}\n\nunsigned\nnarenas_total_get(void)\n{\n\n\treturn (atomic_read_u(&narenas_total));\n}\n\n/* Create a new arena and insert it into the arenas array at index ind. */\nstatic arena_t *\narena_init_locked(unsigned ind)\n{\n\tarena_t *arena;\n\n\tassert(ind <= narenas_total_get());\n\tif (ind > MALLOCX_ARENA_MAX)\n\t\treturn (NULL);\n\tif (ind == narenas_total_get())\n\t\tnarenas_total_inc();\n\n\t/*\n\t * Another thread may have already initialized arenas[ind] if it's an\n\t * auto arena.\n\t */\n\tarena = arena_get(ind, false);\n\tif (arena != NULL) {\n\t\tassert(ind < narenas_auto);\n\t\treturn (arena);\n\t}\n\n\t/* Actually initialize the arena. */\n\tarena = arena_new(ind);\n\tarena_set(ind, arena);\n\treturn (arena);\n}\n\narena_t *\narena_init(unsigned ind)\n{\n\tarena_t *arena;\n\n\tmalloc_mutex_lock(&arenas_lock);\n\tarena = arena_init_locked(ind);\n\tmalloc_mutex_unlock(&arenas_lock);\n\treturn (arena);\n}\n\nstatic void\narena_bind(tsd_t *tsd, unsigned ind)\n{\n\tarena_t *arena;\n\n\tarena = arena_get(ind, false);\n\tarena_nthreads_inc(arena);\n\n\tif (tsd_nominal(tsd))\n\t\ttsd_arena_set(tsd, arena);\n}\n\nvoid\narena_migrate(tsd_t *tsd, unsigned oldind, unsigned newind)\n{\n\tarena_t *oldarena, *newarena;\n\n\toldarena = arena_get(oldind, false);\n\tnewarena = arena_get(newind, false);\n\tarena_nthreads_dec(oldarena);\n\tarena_nthreads_inc(newarena);\n\ttsd_arena_set(tsd, newarena);\n}\n\nstatic void\narena_unbind(tsd_t *tsd, unsigned ind)\n{\n\tarena_t *arena;\n\n\tarena = arena_get(ind, false);\n\tarena_nthreads_dec(arena);\n\ttsd_arena_set(tsd, NULL);\n}\n\narena_tdata_t *\narena_tdata_get_hard(tsd_t *tsd, unsigned ind)\n{\n\tarena_tdata_t *tdata, *arenas_tdata_old;\n\tarena_tdata_t *arenas_tdata = tsd_arenas_tdata_get(tsd);\n\tunsigned narenas_tdata_old, i;\n\tunsigned narenas_tdata = tsd_narenas_tdata_get(tsd);\n\tunsigned narenas_actual = narenas_total_get();\n\n\t/*\n\t * Dissociate old tdata array (and set up for deallocation upon return)\n\t * if it's too small.\n\t */\n\tif (arenas_tdata != NULL && narenas_tdata < narenas_actual) {\n\t\tarenas_tdata_old = arenas_tdata;\n\t\tnarenas_tdata_old = narenas_tdata;\n\t\tarenas_tdata = NULL;\n\t\tnarenas_tdata = 0;\n\t\ttsd_arenas_tdata_set(tsd, arenas_tdata);\n\t\ttsd_narenas_tdata_set(tsd, narenas_tdata);\n\t} else {\n\t\tarenas_tdata_old = NULL;\n\t\tnarenas_tdata_old = 0;\n\t}\n\n\t/* Allocate tdata array if it's missing. */\n\tif (arenas_tdata == NULL) {\n\t\tbool *arenas_tdata_bypassp = tsd_arenas_tdata_bypassp_get(tsd);\n\t\tnarenas_tdata = (ind < narenas_actual) ? narenas_actual : ind+1;\n\n\t\tif (tsd_nominal(tsd) && !*arenas_tdata_bypassp) {\n\t\t\t*arenas_tdata_bypassp = true;\n\t\t\tarenas_tdata = (arena_tdata_t *)a0malloc(\n\t\t\t    sizeof(arena_tdata_t) * narenas_tdata);\n\t\t\t*arenas_tdata_bypassp = false;\n\t\t}\n\t\tif (arenas_tdata == NULL) {\n\t\t\ttdata = NULL;\n\t\t\tgoto label_return;\n\t\t}\n\t\tassert(tsd_nominal(tsd) && !*arenas_tdata_bypassp);\n\t\ttsd_arenas_tdata_set(tsd, arenas_tdata);\n\t\ttsd_narenas_tdata_set(tsd, narenas_tdata);\n\t}\n\n\t/*\n\t * Copy to tdata array.  It's possible that the actual number of arenas\n\t * has increased since narenas_total_get() was called above, but that\n\t * causes no correctness issues unless two threads concurrently execute\n\t * the arenas.extend mallctl, which we trust mallctl synchronization to\n\t * prevent.\n\t */\n\n\t/* Copy/initialize tickers. */\n\tfor (i = 0; i < narenas_actual; i++) {\n\t\tif (i < narenas_tdata_old) {\n\t\t\tticker_copy(&arenas_tdata[i].decay_ticker,\n\t\t\t    &arenas_tdata_old[i].decay_ticker);\n\t\t} else {\n\t\t\tticker_init(&arenas_tdata[i].decay_ticker,\n\t\t\t    DECAY_NTICKS_PER_UPDATE);\n\t\t}\n\t}\n\tif (narenas_tdata > narenas_actual) {\n\t\tmemset(&arenas_tdata[narenas_actual], 0, sizeof(arena_tdata_t)\n\t\t    * (narenas_tdata - narenas_actual));\n\t}\n\n\t/* Read the refreshed tdata array. */\n\ttdata = &arenas_tdata[ind];\nlabel_return:\n\tif (arenas_tdata_old != NULL)\n\t\ta0dalloc(arenas_tdata_old);\n\treturn (tdata);\n}\n\n/* Slow path, called only by arena_choose(). */\narena_t *\narena_choose_hard(tsd_t *tsd)\n{\n\tarena_t *ret;\n\n\tif (narenas_auto > 1) {\n\t\tunsigned i, choose, first_null;\n\n\t\tchoose = 0;\n\t\tfirst_null = narenas_auto;\n\t\tmalloc_mutex_lock(&arenas_lock);\n\t\tassert(arena_get(0, false) != NULL);\n\t\tfor (i = 1; i < narenas_auto; i++) {\n\t\t\tif (arena_get(i, false) != NULL) {\n\t\t\t\t/*\n\t\t\t\t * Choose the first arena that has the lowest\n\t\t\t\t * number of threads assigned to it.\n\t\t\t\t */\n\t\t\t\tif (arena_nthreads_get(arena_get(i, false)) <\n\t\t\t\t    arena_nthreads_get(arena_get(choose,\n\t\t\t\t    false)))\n\t\t\t\t\tchoose = i;\n\t\t\t} else if (first_null == narenas_auto) {\n\t\t\t\t/*\n\t\t\t\t * Record the index of the first uninitialized\n\t\t\t\t * arena, in case all extant arenas are in use.\n\t\t\t\t *\n\t\t\t\t * NB: It is possible for there to be\n\t\t\t\t * discontinuities in terms of initialized\n\t\t\t\t * versus uninitialized arenas, due to the\n\t\t\t\t * \"thread.arena\" mallctl.\n\t\t\t\t */\n\t\t\t\tfirst_null = i;\n\t\t\t}\n\t\t}\n\n\t\tif (arena_nthreads_get(arena_get(choose, false)) == 0\n\t\t    || first_null == narenas_auto) {\n\t\t\t/*\n\t\t\t * Use an unloaded arena, or the least loaded arena if\n\t\t\t * all arenas are already initialized.\n\t\t\t */\n\t\t\tret = arena_get(choose, false);\n\t\t} else {\n\t\t\t/* Initialize a new arena. */\n\t\t\tchoose = first_null;\n\t\t\tret = arena_init_locked(choose);\n\t\t\tif (ret == NULL) {\n\t\t\t\tmalloc_mutex_unlock(&arenas_lock);\n\t\t\t\treturn (NULL);\n\t\t\t}\n\t\t}\n\t\tarena_bind(tsd, choose);\n\t\tmalloc_mutex_unlock(&arenas_lock);\n\t} else {\n\t\tret = arena_get(0, false);\n\t\tarena_bind(tsd, 0);\n\t}\n\n\treturn (ret);\n}\n\nvoid\nthread_allocated_cleanup(tsd_t *tsd)\n{\n\n\t/* Do nothing. */\n}\n\nvoid\nthread_deallocated_cleanup(tsd_t *tsd)\n{\n\n\t/* Do nothing. */\n}\n\nvoid\narena_cleanup(tsd_t *tsd)\n{\n\tarena_t *arena;\n\n\tarena = tsd_arena_get(tsd);\n\tif (arena != NULL)\n\t\tarena_unbind(tsd, arena->ind);\n}\n\nvoid\narenas_tdata_cleanup(tsd_t *tsd)\n{\n\tarena_tdata_t *arenas_tdata;\n\n\t/* Prevent tsd->arenas_tdata from being (re)created. */\n\t*tsd_arenas_tdata_bypassp_get(tsd) = true;\n\n\tarenas_tdata = tsd_arenas_tdata_get(tsd);\n\tif (arenas_tdata != NULL) {\n\t\ttsd_arenas_tdata_set(tsd, NULL);\n\t\ta0dalloc(arenas_tdata);\n\t}\n}\n\nvoid\nnarenas_tdata_cleanup(tsd_t *tsd)\n{\n\n\t/* Do nothing. */\n}\n\nvoid\narenas_tdata_bypass_cleanup(tsd_t *tsd)\n{\n\n\t/* Do nothing. */\n}\n\nstatic void\nstats_print_atexit(void)\n{\n\n\tif (config_tcache && config_stats) {\n\t\tunsigned narenas, i;\n\n\t\t/*\n\t\t * Merge stats from extant threads.  This is racy, since\n\t\t * individual threads do not lock when recording tcache stats\n\t\t * events.  As a consequence, the final stats may be slightly\n\t\t * out of date by the time they are reported, if other threads\n\t\t * continue to allocate.\n\t\t */\n\t\tfor (i = 0, narenas = narenas_total_get(); i < narenas; i++) {\n\t\t\tarena_t *arena = arena_get(i, false);\n\t\t\tif (arena != NULL) {\n\t\t\t\ttcache_t *tcache;\n\n\t\t\t\t/*\n\t\t\t\t * tcache_stats_merge() locks bins, so if any\n\t\t\t\t * code is introduced that acquires both arena\n\t\t\t\t * and bin locks in the opposite order,\n\t\t\t\t * deadlocks may result.\n\t\t\t\t */\n\t\t\t\tmalloc_mutex_lock(&arena->lock);\n\t\t\t\tql_foreach(tcache, &arena->tcache_ql, link) {\n\t\t\t\t\ttcache_stats_merge(tcache, arena);\n\t\t\t\t}\n\t\t\t\tmalloc_mutex_unlock(&arena->lock);\n\t\t\t}\n\t\t}\n\t}\n\tje_malloc_stats_print(NULL, NULL, NULL);\n}\n\n/*\n * End miscellaneous support functions.\n */\n/******************************************************************************/\n/*\n * Begin initialization functions.\n */\n\n#ifndef JEMALLOC_HAVE_SECURE_GETENV\nstatic char *\nsecure_getenv(const char *name)\n{\n\n#  ifdef JEMALLOC_HAVE_ISSETUGID\n\tif (issetugid() != 0)\n\t\treturn (NULL);\n#  endif\n\treturn (getenv(name));\n}\n#endif\n\nstatic unsigned\nmalloc_ncpus(void)\n{\n\tlong result;\n\n#ifdef _WIN32\n\tSYSTEM_INFO si;\n\tGetSystemInfo(&si);\n\tresult = si.dwNumberOfProcessors;\n#else\n\tresult = sysconf(_SC_NPROCESSORS_ONLN);\n#endif\n\treturn ((result == -1) ? 1 : (unsigned)result);\n}\n\nstatic bool\nmalloc_conf_next(char const **opts_p, char const **k_p, size_t *klen_p,\n    char const **v_p, size_t *vlen_p)\n{\n\tbool accept;\n\tconst char *opts = *opts_p;\n\n\t*k_p = opts;\n\n\tfor (accept = false; !accept;) {\n\t\tswitch (*opts) {\n\t\tcase 'A': case 'B': case 'C': case 'D': case 'E': case 'F':\n\t\tcase 'G': case 'H': case 'I': case 'J': case 'K': case 'L':\n\t\tcase 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':\n\t\tcase 'S': case 'T': case 'U': case 'V': case 'W': case 'X':\n\t\tcase 'Y': case 'Z':\n\t\tcase 'a': case 'b': case 'c': case 'd': case 'e': case 'f':\n\t\tcase 'g': case 'h': case 'i': case 'j': case 'k': case 'l':\n\t\tcase 'm': case 'n': case 'o': case 'p': case 'q': case 'r':\n\t\tcase 's': case 't': case 'u': case 'v': case 'w': case 'x':\n\t\tcase 'y': case 'z':\n\t\tcase '0': case '1': case '2': case '3': case '4': case '5':\n\t\tcase '6': case '7': case '8': case '9':\n\t\tcase '_':\n\t\t\topts++;\n\t\t\tbreak;\n\t\tcase ':':\n\t\t\topts++;\n\t\t\t*klen_p = (uintptr_t)opts - 1 - (uintptr_t)*k_p;\n\t\t\t*v_p = opts;\n\t\t\taccept = true;\n\t\t\tbreak;\n\t\tcase '\\0':\n\t\t\tif (opts != *opts_p) {\n\t\t\t\tmalloc_write(\"<jemalloc>: Conf string ends \"\n\t\t\t\t    \"with key\\n\");\n\t\t\t}\n\t\t\treturn (true);\n\t\tdefault:\n\t\t\tmalloc_write(\"<jemalloc>: Malformed conf string\\n\");\n\t\t\treturn (true);\n\t\t}\n\t}\n\n\tfor (accept = false; !accept;) {\n\t\tswitch (*opts) {\n\t\tcase ',':\n\t\t\topts++;\n\t\t\t/*\n\t\t\t * Look ahead one character here, because the next time\n\t\t\t * this function is called, it will assume that end of\n\t\t\t * input has been cleanly reached if no input remains,\n\t\t\t * but we have optimistically already consumed the\n\t\t\t * comma if one exists.\n\t\t\t */\n\t\t\tif (*opts == '\\0') {\n\t\t\t\tmalloc_write(\"<jemalloc>: Conf string ends \"\n\t\t\t\t    \"with comma\\n\");\n\t\t\t}\n\t\t\t*vlen_p = (uintptr_t)opts - 1 - (uintptr_t)*v_p;\n\t\t\taccept = true;\n\t\t\tbreak;\n\t\tcase '\\0':\n\t\t\t*vlen_p = (uintptr_t)opts - (uintptr_t)*v_p;\n\t\t\taccept = true;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\topts++;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t*opts_p = opts;\n\treturn (false);\n}\n\nstatic void\nmalloc_conf_error(const char *msg, const char *k, size_t klen, const char *v,\n    size_t vlen)\n{\n\n\tmalloc_printf(\"<jemalloc>: %s: %.*s:%.*s\\n\", msg, (int)klen, k,\n\t    (int)vlen, v);\n}\n\nstatic void\nmalloc_slow_flag_init(void)\n{\n\t/*\n\t * Combine the runtime options into malloc_slow for fast path.  Called\n\t * after processing all the options.\n\t */\n\tmalloc_slow_flags |= (opt_junk_alloc ? flag_opt_junk_alloc : 0)\n\t    | (opt_junk_free ? flag_opt_junk_free : 0)\n\t    | (opt_quarantine ? flag_opt_quarantine : 0)\n\t    | (opt_zero ? flag_opt_zero : 0)\n\t    | (opt_utrace ? flag_opt_utrace : 0)\n\t    | (opt_xmalloc ? flag_opt_xmalloc : 0);\n\n\tif (config_valgrind)\n\t\tmalloc_slow_flags |= (in_valgrind ? flag_in_valgrind : 0);\n\n\tmalloc_slow = (malloc_slow_flags != 0);\n}\n\nstatic void\nmalloc_conf_init(void)\n{\n\tunsigned i;\n\tchar buf[PATH_MAX + 1];\n\tconst char *opts, *k, *v;\n\tsize_t klen, vlen;\n\n\t/*\n\t * Automatically configure valgrind before processing options.  The\n\t * valgrind option remains in jemalloc 3.x for compatibility reasons.\n\t */\n\tif (config_valgrind) {\n\t\tin_valgrind = (RUNNING_ON_VALGRIND != 0) ? true : false;\n\t\tif (config_fill && unlikely(in_valgrind)) {\n\t\t\topt_junk = \"false\";\n\t\t\topt_junk_alloc = false;\n\t\t\topt_junk_free = false;\n\t\t\tassert(!opt_zero);\n\t\t\topt_quarantine = JEMALLOC_VALGRIND_QUARANTINE_DEFAULT;\n\t\t\topt_redzone = true;\n\t\t}\n\t\tif (config_tcache && unlikely(in_valgrind))\n\t\t\topt_tcache = false;\n\t}\n\n\tfor (i = 0; i < 4; i++) {\n\t\t/* Get runtime configuration. */\n\t\tswitch (i) {\n\t\tcase 0:\n\t\t\topts = config_malloc_conf;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tif (je_malloc_conf != NULL) {\n\t\t\t\t/*\n\t\t\t\t * Use options that were compiled into the\n\t\t\t\t * program.\n\t\t\t\t */\n\t\t\t\topts = je_malloc_conf;\n\t\t\t} else {\n\t\t\t\t/* No configuration specified. */\n\t\t\t\tbuf[0] = '\\0';\n\t\t\t\topts = buf;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 2: {\n\t\t\tssize_t linklen = 0;\n#ifndef _WIN32\n\t\t\tint saved_errno = errno;\n\t\t\tconst char *linkname =\n#  ifdef JEMALLOC_PREFIX\n\t\t\t    \"/etc/\"JEMALLOC_PREFIX\"malloc.conf\"\n#  else\n\t\t\t    \"/etc/malloc.conf\"\n#  endif\n\t\t\t    ;\n\n\t\t\t/*\n\t\t\t * Try to use the contents of the \"/etc/malloc.conf\"\n\t\t\t * symbolic link's name.\n\t\t\t */\n\t\t\tlinklen = readlink(linkname, buf, sizeof(buf) - 1);\n\t\t\tif (linklen == -1) {\n\t\t\t\t/* No configuration specified. */\n\t\t\t\tlinklen = 0;\n\t\t\t\t/* Restore errno. */\n\t\t\t\tset_errno(saved_errno);\n\t\t\t}\n#endif\n\t\t\tbuf[linklen] = '\\0';\n\t\t\topts = buf;\n\t\t\tbreak;\n\t\t} case 3: {\n\t\t\tconst char *envname =\n#ifdef JEMALLOC_PREFIX\n\t\t\t    JEMALLOC_CPREFIX\"MALLOC_CONF\"\n#else\n\t\t\t    \"MALLOC_CONF\"\n#endif\n\t\t\t    ;\n\n\t\t\tif ((opts = secure_getenv(envname)) != NULL) {\n\t\t\t\t/*\n\t\t\t\t * Do nothing; opts is already initialized to\n\t\t\t\t * the value of the MALLOC_CONF environment\n\t\t\t\t * variable.\n\t\t\t\t */\n\t\t\t} else {\n\t\t\t\t/* No configuration specified. */\n\t\t\t\tbuf[0] = '\\0';\n\t\t\t\topts = buf;\n\t\t\t}\n\t\t\tbreak;\n\t\t} default:\n\t\t\tnot_reached();\n\t\t\tbuf[0] = '\\0';\n\t\t\topts = buf;\n\t\t}\n\n\t\twhile (*opts != '\\0' && !malloc_conf_next(&opts, &k, &klen, &v,\n\t\t    &vlen)) {\n#define\tCONF_MATCH(n)\t\t\t\t\t\t\t\\\n\t(sizeof(n)-1 == klen && strncmp(n, k, klen) == 0)\n#define\tCONF_MATCH_VALUE(n)\t\t\t\t\t\t\\\n\t(sizeof(n)-1 == vlen && strncmp(n, v, vlen) == 0)\n#define\tCONF_HANDLE_BOOL(o, n, cont)\t\t\t\t\t\\\n\t\t\tif (CONF_MATCH(n)) {\t\t\t\t\\\n\t\t\t\tif (CONF_MATCH_VALUE(\"true\"))\t\t\\\n\t\t\t\t\to = true;\t\t\t\\\n\t\t\t\telse if (CONF_MATCH_VALUE(\"false\"))\t\\\n\t\t\t\t\to = false;\t\t\t\\\n\t\t\t\telse {\t\t\t\t\t\\\n\t\t\t\t\tmalloc_conf_error(\t\t\\\n\t\t\t\t\t    \"Invalid conf value\",\t\\\n\t\t\t\t\t    k, klen, v, vlen);\t\t\\\n\t\t\t\t}\t\t\t\t\t\\\n\t\t\t\tif (cont)\t\t\t\t\\\n\t\t\t\t\tcontinue;\t\t\t\\\n\t\t\t}\n#define\tCONF_HANDLE_T_U(t, o, n, min, max, clip)\t\t\t\\\n\t\t\tif (CONF_MATCH(n)) {\t\t\t\t\\\n\t\t\t\tuintmax_t um;\t\t\t\t\\\n\t\t\t\tchar *end;\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\t\t\tset_errno(0);\t\t\t\t\\\n\t\t\t\tum = malloc_strtoumax(v, &end, 0);\t\\\n\t\t\t\tif (get_errno() != 0 || (uintptr_t)end -\\\n\t\t\t\t    (uintptr_t)v != vlen) {\t\t\\\n\t\t\t\t\tmalloc_conf_error(\t\t\\\n\t\t\t\t\t    \"Invalid conf value\",\t\\\n\t\t\t\t\t    k, klen, v, vlen);\t\t\\\n\t\t\t\t} else if (clip) {\t\t\t\\\n\t\t\t\t\tif ((min) != 0 && um < (min))\t\\\n\t\t\t\t\t\to = (t)(min);\t\t\\\n\t\t\t\t\telse if (um > (max))\t\t\\\n\t\t\t\t\t\to = (t)(max);\t\t\\\n\t\t\t\t\telse\t\t\t\t\\\n\t\t\t\t\t\to = (t)um;\t\t\\\n\t\t\t\t} else {\t\t\t\t\\\n\t\t\t\t\tif (((min) != 0 && um < (min))\t\\\n\t\t\t\t\t    || um > (max)) {\t\t\\\n\t\t\t\t\t\tmalloc_conf_error(\t\\\n\t\t\t\t\t\t    \"Out-of-range \"\t\\\n\t\t\t\t\t\t    \"conf value\",\t\\\n\t\t\t\t\t\t    k, klen, v, vlen);\t\\\n\t\t\t\t\t} else\t\t\t\t\\\n\t\t\t\t\t\to = (t)um;\t\t\\\n\t\t\t\t}\t\t\t\t\t\\\n\t\t\t\tcontinue;\t\t\t\t\\\n\t\t\t}\n#define\tCONF_HANDLE_UNSIGNED(o, n, min, max, clip)\t\t\t\\\n\t\t\tCONF_HANDLE_T_U(unsigned, o, n, min, max, clip)\n#define\tCONF_HANDLE_SIZE_T(o, n, min, max, clip)\t\t\t\\\n\t\t\tCONF_HANDLE_T_U(size_t, o, n, min, max, clip)\n#define\tCONF_HANDLE_SSIZE_T(o, n, min, max)\t\t\t\t\\\n\t\t\tif (CONF_MATCH(n)) {\t\t\t\t\\\n\t\t\t\tlong l;\t\t\t\t\t\\\n\t\t\t\tchar *end;\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\t\t\tset_errno(0);\t\t\t\t\\\n\t\t\t\tl = strtol(v, &end, 0);\t\t\t\\\n\t\t\t\tif (get_errno() != 0 || (uintptr_t)end -\\\n\t\t\t\t    (uintptr_t)v != vlen) {\t\t\\\n\t\t\t\t\tmalloc_conf_error(\t\t\\\n\t\t\t\t\t    \"Invalid conf value\",\t\\\n\t\t\t\t\t    k, klen, v, vlen);\t\t\\\n\t\t\t\t} else if (l < (ssize_t)(min) || l >\t\\\n\t\t\t\t    (ssize_t)(max)) {\t\t\t\\\n\t\t\t\t\tmalloc_conf_error(\t\t\\\n\t\t\t\t\t    \"Out-of-range conf value\",\t\\\n\t\t\t\t\t    k, klen, v, vlen);\t\t\\\n\t\t\t\t} else\t\t\t\t\t\\\n\t\t\t\t\to = l;\t\t\t\t\\\n\t\t\t\tcontinue;\t\t\t\t\\\n\t\t\t}\n#define\tCONF_HANDLE_CHAR_P(o, n, d)\t\t\t\t\t\\\n\t\t\tif (CONF_MATCH(n)) {\t\t\t\t\\\n\t\t\t\tsize_t cpylen = (vlen <=\t\t\\\n\t\t\t\t    sizeof(o)-1) ? vlen :\t\t\\\n\t\t\t\t    sizeof(o)-1;\t\t\t\\\n\t\t\t\tstrncpy(o, v, cpylen);\t\t\t\\\n\t\t\t\to[cpylen] = '\\0';\t\t\t\\\n\t\t\t\tcontinue;\t\t\t\t\\\n\t\t\t}\n\n\t\t\tCONF_HANDLE_BOOL(opt_abort, \"abort\", true)\n\t\t\t/*\n\t\t\t * Chunks always require at least one header page,\n\t\t\t * as many as 2^(LG_SIZE_CLASS_GROUP+1) data pages, and\n\t\t\t * possibly an additional page in the presence of\n\t\t\t * redzones.  In order to simplify options processing,\n\t\t\t * use a conservative bound that accommodates all these\n\t\t\t * constraints.\n\t\t\t */\n\t\t\tCONF_HANDLE_SIZE_T(opt_lg_chunk, \"lg_chunk\", LG_PAGE +\n\t\t\t    LG_SIZE_CLASS_GROUP + (config_fill ? 2 : 1),\n\t\t\t    (sizeof(size_t) << 3) - 1, true)\n\t\t\tif (strncmp(\"dss\", k, klen) == 0) {\n\t\t\t\tint i;\n\t\t\t\tbool match = false;\n\t\t\t\tfor (i = 0; i < dss_prec_limit; i++) {\n\t\t\t\t\tif (strncmp(dss_prec_names[i], v, vlen)\n\t\t\t\t\t    == 0) {\n\t\t\t\t\t\tif (chunk_dss_prec_set(i)) {\n\t\t\t\t\t\t\tmalloc_conf_error(\n\t\t\t\t\t\t\t    \"Error setting dss\",\n\t\t\t\t\t\t\t    k, klen, v, vlen);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\topt_dss =\n\t\t\t\t\t\t\t    dss_prec_names[i];\n\t\t\t\t\t\t\tmatch = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!match) {\n\t\t\t\t\tmalloc_conf_error(\"Invalid conf value\",\n\t\t\t\t\t    k, klen, v, vlen);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tCONF_HANDLE_UNSIGNED(opt_narenas, \"narenas\", 1,\n\t\t\t    UINT_MAX, false)\n\t\t\tif (strncmp(\"purge\", k, klen) == 0) {\n\t\t\t\tint i;\n\t\t\t\tbool match = false;\n\t\t\t\tfor (i = 0; i < purge_mode_limit; i++) {\n\t\t\t\t\tif (strncmp(purge_mode_names[i], v,\n\t\t\t\t\t    vlen) == 0) {\n\t\t\t\t\t\topt_purge = (purge_mode_t)i;\n\t\t\t\t\t\tmatch = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!match) {\n\t\t\t\t\tmalloc_conf_error(\"Invalid conf value\",\n\t\t\t\t\t    k, klen, v, vlen);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tCONF_HANDLE_SSIZE_T(opt_lg_dirty_mult, \"lg_dirty_mult\",\n\t\t\t    -1, (sizeof(size_t) << 3) - 1)\n\t\t\tCONF_HANDLE_SSIZE_T(opt_decay_time, \"decay_time\", -1,\n\t\t\t    NSTIME_SEC_MAX);\n\t\t\tCONF_HANDLE_BOOL(opt_stats_print, \"stats_print\", true)\n\t\t\tif (config_fill) {\n\t\t\t\tif (CONF_MATCH(\"junk\")) {\n\t\t\t\t\tif (CONF_MATCH_VALUE(\"true\")) {\n\t\t\t\t\t\topt_junk = \"true\";\n\t\t\t\t\t\topt_junk_alloc = opt_junk_free =\n\t\t\t\t\t\t    true;\n\t\t\t\t\t} else if (CONF_MATCH_VALUE(\"false\")) {\n\t\t\t\t\t\topt_junk = \"false\";\n\t\t\t\t\t\topt_junk_alloc = opt_junk_free =\n\t\t\t\t\t\t    false;\n\t\t\t\t\t} else if (CONF_MATCH_VALUE(\"alloc\")) {\n\t\t\t\t\t\topt_junk = \"alloc\";\n\t\t\t\t\t\topt_junk_alloc = true;\n\t\t\t\t\t\topt_junk_free = false;\n\t\t\t\t\t} else if (CONF_MATCH_VALUE(\"free\")) {\n\t\t\t\t\t\topt_junk = \"free\";\n\t\t\t\t\t\topt_junk_alloc = false;\n\t\t\t\t\t\topt_junk_free = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmalloc_conf_error(\n\t\t\t\t\t\t    \"Invalid conf value\", k,\n\t\t\t\t\t\t    klen, v, vlen);\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tCONF_HANDLE_SIZE_T(opt_quarantine, \"quarantine\",\n\t\t\t\t    0, SIZE_T_MAX, false)\n\t\t\t\tCONF_HANDLE_BOOL(opt_redzone, \"redzone\", true)\n\t\t\t\tCONF_HANDLE_BOOL(opt_zero, \"zero\", true)\n\t\t\t}\n\t\t\tif (config_utrace) {\n\t\t\t\tCONF_HANDLE_BOOL(opt_utrace, \"utrace\", true)\n\t\t\t}\n\t\t\tif (config_xmalloc) {\n\t\t\t\tCONF_HANDLE_BOOL(opt_xmalloc, \"xmalloc\", true)\n\t\t\t}\n\t\t\tif (config_tcache) {\n\t\t\t\tCONF_HANDLE_BOOL(opt_tcache, \"tcache\",\n\t\t\t\t    !config_valgrind || !in_valgrind)\n\t\t\t\tif (CONF_MATCH(\"tcache\")) {\n\t\t\t\t\tassert(config_valgrind && in_valgrind);\n\t\t\t\t\tif (opt_tcache) {\n\t\t\t\t\t\topt_tcache = false;\n\t\t\t\t\t\tmalloc_conf_error(\n\t\t\t\t\t\t\"tcache cannot be enabled \"\n\t\t\t\t\t\t\"while running inside Valgrind\",\n\t\t\t\t\t\tk, klen, v, vlen);\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tCONF_HANDLE_SSIZE_T(opt_lg_tcache_max,\n\t\t\t\t    \"lg_tcache_max\", -1,\n\t\t\t\t    (sizeof(size_t) << 3) - 1)\n\t\t\t}\n\t\t\tif (config_prof) {\n\t\t\t\tCONF_HANDLE_BOOL(opt_prof, \"prof\", true)\n\t\t\t\tCONF_HANDLE_CHAR_P(opt_prof_prefix,\n\t\t\t\t    \"prof_prefix\", \"jeprof\")\n\t\t\t\tCONF_HANDLE_BOOL(opt_prof_active, \"prof_active\",\n\t\t\t\t    true)\n\t\t\t\tCONF_HANDLE_BOOL(opt_prof_thread_active_init,\n\t\t\t\t    \"prof_thread_active_init\", true)\n\t\t\t\tCONF_HANDLE_SIZE_T(opt_lg_prof_sample,\n\t\t\t\t    \"lg_prof_sample\", 0,\n\t\t\t\t    (sizeof(uint64_t) << 3) - 1, true)\n\t\t\t\tCONF_HANDLE_BOOL(opt_prof_accum, \"prof_accum\",\n\t\t\t\t    true)\n\t\t\t\tCONF_HANDLE_SSIZE_T(opt_lg_prof_interval,\n\t\t\t\t    \"lg_prof_interval\", -1,\n\t\t\t\t    (sizeof(uint64_t) << 3) - 1)\n\t\t\t\tCONF_HANDLE_BOOL(opt_prof_gdump, \"prof_gdump\",\n\t\t\t\t    true)\n\t\t\t\tCONF_HANDLE_BOOL(opt_prof_final, \"prof_final\",\n\t\t\t\t    true)\n\t\t\t\tCONF_HANDLE_BOOL(opt_prof_leak, \"prof_leak\",\n\t\t\t\t    true)\n\t\t\t}\n\t\t\tmalloc_conf_error(\"Invalid conf pair\", k, klen, v,\n\t\t\t    vlen);\n#undef CONF_MATCH\n#undef CONF_HANDLE_BOOL\n#undef CONF_HANDLE_SIZE_T\n#undef CONF_HANDLE_SSIZE_T\n#undef CONF_HANDLE_CHAR_P\n\t\t}\n\t}\n}\n\n/* init_lock must be held. */\nstatic bool\nmalloc_init_hard_needed(void)\n{\n\n\tif (malloc_initialized() || (IS_INITIALIZER && malloc_init_state ==\n\t    malloc_init_recursible)) {\n\t\t/*\n\t\t * Another thread initialized the allocator before this one\n\t\t * acquired init_lock, or this thread is the initializing\n\t\t * thread, and it is recursively allocating.\n\t\t */\n\t\treturn (false);\n\t}\n#ifdef JEMALLOC_THREADED_INIT\n\tif (malloc_initializer != NO_INITIALIZER && !IS_INITIALIZER) {\n\t\t/* Busy-wait until the initializing thread completes. */\n\t\tdo {\n\t\t\tmalloc_mutex_unlock(&init_lock);\n\t\t\tCPU_SPINWAIT;\n\t\t\tmalloc_mutex_lock(&init_lock);\n\t\t} while (!malloc_initialized());\n\t\treturn (false);\n\t}\n#endif\n\treturn (true);\n}\n\n/* init_lock must be held. */\nstatic bool\nmalloc_init_hard_a0_locked(void)\n{\n\n\tmalloc_initializer = INITIALIZER;\n\n\tif (config_prof)\n\t\tprof_boot0();\n\tmalloc_conf_init();\n\tif (opt_stats_print) {\n\t\t/* Print statistics at exit. */\n\t\tif (atexit(stats_print_atexit) != 0) {\n\t\t\tmalloc_write(\"<jemalloc>: Error in atexit()\\n\");\n\t\t\tif (opt_abort)\n\t\t\t\tabort();\n\t\t}\n\t}\n\tif (base_boot())\n\t\treturn (true);\n\tif (chunk_boot())\n\t\treturn (true);\n\tif (ctl_boot())\n\t\treturn (true);\n\tif (config_prof)\n\t\tprof_boot1();\n\tif (arena_boot())\n\t\treturn (true);\n\tif (config_tcache && tcache_boot())\n\t\treturn (true);\n\tif (malloc_mutex_init(&arenas_lock))\n\t\treturn (true);\n\t/*\n\t * Create enough scaffolding to allow recursive allocation in\n\t * malloc_ncpus().\n\t */\n\tnarenas_auto = 1;\n\tnarenas_total_set(narenas_auto);\n\tarenas = &a0;\n\tmemset(arenas, 0, sizeof(arena_t *) * narenas_auto);\n\t/*\n\t * Initialize one arena here.  The rest are lazily created in\n\t * arena_choose_hard().\n\t */\n\tif (arena_init(0) == NULL)\n\t\treturn (true);\n\tmalloc_init_state = malloc_init_a0_initialized;\n\treturn (false);\n}\n\nstatic bool\nmalloc_init_hard_a0(void)\n{\n\tbool ret;\n\n\tmalloc_mutex_lock(&init_lock);\n\tret = malloc_init_hard_a0_locked();\n\tmalloc_mutex_unlock(&init_lock);\n\treturn (ret);\n}\n\n/*\n * Initialize data structures which may trigger recursive allocation.\n *\n * init_lock must be held.\n */\nstatic bool\nmalloc_init_hard_recursible(void)\n{\n\tbool ret = false;\n\n\tmalloc_init_state = malloc_init_recursible;\n\tmalloc_mutex_unlock(&init_lock);\n\n\t/* LinuxThreads' pthread_setspecific() allocates. */\n\tif (malloc_tsd_boot0()) {\n\t\tret = true;\n\t\tgoto label_return;\n\t}\n\n\tncpus = malloc_ncpus();\n\n#if (!defined(JEMALLOC_MUTEX_INIT_CB) && !defined(JEMALLOC_ZONE) \\\n    && !defined(_WIN32) && !defined(__native_client__))\n\t/* LinuxThreads' pthread_atfork() allocates. */\n\tif (pthread_atfork(jemalloc_prefork, jemalloc_postfork_parent,\n\t    jemalloc_postfork_child) != 0) {\n\t\tret = true;\n\t\tmalloc_write(\"<jemalloc>: Error in pthread_atfork()\\n\");\n\t\tif (opt_abort)\n\t\t\tabort();\n\t}\n#endif\n\nlabel_return:\n\tmalloc_mutex_lock(&init_lock);\n\treturn (ret);\n}\n\n/* init_lock must be held. */\nstatic bool\nmalloc_init_hard_finish(void)\n{\n\n\tif (mutex_boot())\n\t\treturn (true);\n\n\tif (opt_narenas == 0) {\n\t\t/*\n\t\t * For SMP systems, create more than one arena per CPU by\n\t\t * default.\n\t\t */\n\t\tif (ncpus > 1)\n\t\t\topt_narenas = ncpus << 2;\n\t\telse\n\t\t\topt_narenas = 1;\n\t}\n\tnarenas_auto = opt_narenas;\n\t/*\n\t * Limit the number of arenas to the indexing range of MALLOCX_ARENA().\n\t */\n\tif (narenas_auto > MALLOCX_ARENA_MAX) {\n\t\tnarenas_auto = MALLOCX_ARENA_MAX;\n\t\tmalloc_printf(\"<jemalloc>: Reducing narenas to limit (%d)\\n\",\n\t\t    narenas_auto);\n\t}\n\tnarenas_total_set(narenas_auto);\n\n\t/* Allocate and initialize arenas. */\n\tarenas = (arena_t **)base_alloc(sizeof(arena_t *) *\n\t    (MALLOCX_ARENA_MAX+1));\n\tif (arenas == NULL)\n\t\treturn (true);\n\t/* Copy the pointer to the one arena that was already initialized. */\n\tarena_set(0, a0);\n\n\tmalloc_init_state = malloc_init_initialized;\n\tmalloc_slow_flag_init();\n\n\treturn (false);\n}\n\nstatic bool\nmalloc_init_hard(void)\n{\n\n#if defined(_WIN32) && _WIN32_WINNT < 0x0600\n\t_init_init_lock();\n#endif\n\tmalloc_mutex_lock(&init_lock);\n\tif (!malloc_init_hard_needed()) {\n\t\tmalloc_mutex_unlock(&init_lock);\n\t\treturn (false);\n\t}\n\n\tif (malloc_init_state != malloc_init_a0_initialized &&\n\t    malloc_init_hard_a0_locked()) {\n\t\tmalloc_mutex_unlock(&init_lock);\n\t\treturn (true);\n\t}\n\n\tif (malloc_init_hard_recursible()) {\n\t\tmalloc_mutex_unlock(&init_lock);\n\t\treturn (true);\n\t}\n\n\tif (config_prof && prof_boot2()) {\n\t\tmalloc_mutex_unlock(&init_lock);\n\t\treturn (true);\n\t}\n\n\tif (malloc_init_hard_finish()) {\n\t\tmalloc_mutex_unlock(&init_lock);\n\t\treturn (true);\n\t}\n\n\tmalloc_mutex_unlock(&init_lock);\n\tmalloc_tsd_boot1();\n\treturn (false);\n}\n\n/*\n * End initialization functions.\n */\n/******************************************************************************/\n/*\n * Begin malloc(3)-compatible functions.\n */\n\nstatic void *\nimalloc_prof_sample(tsd_t *tsd, size_t usize, szind_t ind,\n    prof_tctx_t *tctx, bool slow_path)\n{\n\tvoid *p;\n\n\tif (tctx == NULL)\n\t\treturn (NULL);\n\tif (usize <= SMALL_MAXCLASS) {\n\t\tszind_t ind_large = size2index(LARGE_MINCLASS);\n\t\tp = imalloc(tsd, LARGE_MINCLASS, ind_large, slow_path);\n\t\tif (p == NULL)\n\t\t\treturn (NULL);\n\t\tarena_prof_promoted(p, usize);\n\t} else\n\t\tp = imalloc(tsd, usize, ind, slow_path);\n\n\treturn (p);\n}\n\nJEMALLOC_ALWAYS_INLINE_C void *\nimalloc_prof(tsd_t *tsd, size_t usize, szind_t ind, bool slow_path)\n{\n\tvoid *p;\n\tprof_tctx_t *tctx;\n\n\ttctx = prof_alloc_prep(tsd, usize, prof_active_get_unlocked(), true);\n\tif (unlikely((uintptr_t)tctx != (uintptr_t)1U))\n\t\tp = imalloc_prof_sample(tsd, usize, ind, tctx, slow_path);\n\telse\n\t\tp = imalloc(tsd, usize, ind, slow_path);\n\tif (unlikely(p == NULL)) {\n\t\tprof_alloc_rollback(tsd, tctx, true);\n\t\treturn (NULL);\n\t}\n\tprof_malloc(p, usize, tctx);\n\n\treturn (p);\n}\n\nJEMALLOC_ALWAYS_INLINE_C void *\nimalloc_body(size_t size, tsd_t **tsd, size_t *usize, bool slow_path)\n{\n\tszind_t ind;\n\n\tif (slow_path && unlikely(malloc_init()))\n\t\treturn (NULL);\n\t*tsd = tsd_fetch();\n\tind = size2index(size);\n\tif (unlikely(ind >= NSIZES))\n\t\treturn (NULL);\n\n\tif (config_stats || (config_prof && opt_prof) || (slow_path &&\n\t    config_valgrind && unlikely(in_valgrind))) {\n\t\t*usize = index2size(ind);\n\t\tassert(*usize > 0 && *usize <= HUGE_MAXCLASS);\n\t}\n\n\tif (config_prof && opt_prof)\n\t\treturn (imalloc_prof(*tsd, *usize, ind, slow_path));\n\n\treturn (imalloc(*tsd, size, ind, slow_path));\n}\n\nJEMALLOC_ALWAYS_INLINE_C void\nimalloc_post_check(void *ret, tsd_t *tsd, size_t usize, bool slow_path)\n{\n\tif (unlikely(ret == NULL)) {\n\t\tif (slow_path && config_xmalloc && unlikely(opt_xmalloc)) {\n\t\t\tmalloc_write(\"<jemalloc>: Error in malloc(): \"\n\t\t\t    \"out of memory\\n\");\n\t\t\tabort();\n\t\t}\n\t\tset_errno(ENOMEM);\n\t}\n\tif (config_stats && likely(ret != NULL)) {\n\t\tassert(usize == isalloc(ret, config_prof));\n\t\t*tsd_thread_allocatedp_get(tsd) += usize;\n\t}\n}\n\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\nvoid JEMALLOC_NOTHROW *\nJEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1)\nje_malloc(size_t size)\n{\n\tvoid *ret;\n\ttsd_t *tsd;\n\tsize_t usize JEMALLOC_CC_SILENCE_INIT(0);\n\n\tif (size == 0)\n\t\tsize = 1;\n\n\tif (likely(!malloc_slow)) {\n\t\t/*\n\t\t * imalloc_body() is inlined so that fast and slow paths are\n\t\t * generated separately with statically known slow_path.\n\t\t */\n\t\tret = imalloc_body(size, &tsd, &usize, false);\n\t\timalloc_post_check(ret, tsd, usize, false);\n\t} else {\n\t\tret = imalloc_body(size, &tsd, &usize, true);\n\t\timalloc_post_check(ret, tsd, usize, true);\n\t\tUTRACE(0, size, ret);\n\t\tJEMALLOC_VALGRIND_MALLOC(ret != NULL, ret, usize, false);\n\t}\n\n\treturn (ret);\n}\n\nstatic void *\nimemalign_prof_sample(tsd_t *tsd, size_t alignment, size_t usize,\n    prof_tctx_t *tctx)\n{\n\tvoid *p;\n\n\tif (tctx == NULL)\n\t\treturn (NULL);\n\tif (usize <= SMALL_MAXCLASS) {\n\t\tassert(sa2u(LARGE_MINCLASS, alignment) == LARGE_MINCLASS);\n\t\tp = ipalloc(tsd, LARGE_MINCLASS, alignment, false);\n\t\tif (p == NULL)\n\t\t\treturn (NULL);\n\t\tarena_prof_promoted(p, usize);\n\t} else\n\t\tp = ipalloc(tsd, usize, alignment, false);\n\n\treturn (p);\n}\n\nJEMALLOC_ALWAYS_INLINE_C void *\nimemalign_prof(tsd_t *tsd, size_t alignment, size_t usize)\n{\n\tvoid *p;\n\tprof_tctx_t *tctx;\n\n\ttctx = prof_alloc_prep(tsd, usize, prof_active_get_unlocked(), true);\n\tif (unlikely((uintptr_t)tctx != (uintptr_t)1U))\n\t\tp = imemalign_prof_sample(tsd, alignment, usize, tctx);\n\telse\n\t\tp = ipalloc(tsd, usize, alignment, false);\n\tif (unlikely(p == NULL)) {\n\t\tprof_alloc_rollback(tsd, tctx, true);\n\t\treturn (NULL);\n\t}\n\tprof_malloc(p, usize, tctx);\n\n\treturn (p);\n}\n\nJEMALLOC_ATTR(nonnull(1))\nstatic int\nimemalign(void **memptr, size_t alignment, size_t size, size_t min_alignment)\n{\n\tint ret;\n\ttsd_t *tsd;\n\tsize_t usize;\n\tvoid *result;\n\n\tassert(min_alignment != 0);\n\n\tif (unlikely(malloc_init())) {\n\t\tresult = NULL;\n\t\tgoto label_oom;\n\t}\n\ttsd = tsd_fetch();\n\tif (size == 0)\n\t\tsize = 1;\n\n\t/* Make sure that alignment is a large enough power of 2. */\n\tif (unlikely(((alignment - 1) & alignment) != 0\n\t    || (alignment < min_alignment))) {\n\t\tif (config_xmalloc && unlikely(opt_xmalloc)) {\n\t\t\tmalloc_write(\"<jemalloc>: Error allocating \"\n\t\t\t    \"aligned memory: invalid alignment\\n\");\n\t\t\tabort();\n\t\t}\n\t\tresult = NULL;\n\t\tret = EINVAL;\n\t\tgoto label_return;\n\t}\n\n\tusize = sa2u(size, alignment);\n\tif (unlikely(usize == 0 || usize > HUGE_MAXCLASS)) {\n\t\tresult = NULL;\n\t\tgoto label_oom;\n\t}\n\n\tif (config_prof && opt_prof)\n\t\tresult = imemalign_prof(tsd, alignment, usize);\n\telse\n\t\tresult = ipalloc(tsd, usize, alignment, false);\n\tif (unlikely(result == NULL))\n\t\tgoto label_oom;\n\tassert(((uintptr_t)result & (alignment - 1)) == ZU(0));\n\n\t*memptr = result;\n\tret = 0;\nlabel_return:\n\tif (config_stats && likely(result != NULL)) {\n\t\tassert(usize == isalloc(result, config_prof));\n\t\t*tsd_thread_allocatedp_get(tsd) += usize;\n\t}\n\tUTRACE(0, size, result);\n\treturn (ret);\nlabel_oom:\n\tassert(result == NULL);\n\tif (config_xmalloc && unlikely(opt_xmalloc)) {\n\t\tmalloc_write(\"<jemalloc>: Error allocating aligned memory: \"\n\t\t    \"out of memory\\n\");\n\t\tabort();\n\t}\n\tret = ENOMEM;\n\tgoto label_return;\n}\n\nJEMALLOC_EXPORT int JEMALLOC_NOTHROW\nJEMALLOC_ATTR(nonnull(1))\nje_posix_memalign(void **memptr, size_t alignment, size_t size)\n{\n\tint ret = imemalign(memptr, alignment, size, sizeof(void *));\n\tJEMALLOC_VALGRIND_MALLOC(ret == 0, *memptr, isalloc(*memptr,\n\t    config_prof), false);\n\treturn (ret);\n}\n\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\nvoid JEMALLOC_NOTHROW *\nJEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(2)\nje_aligned_alloc(size_t alignment, size_t size)\n{\n\tvoid *ret;\n\tint err;\n\n\tif (unlikely((err = imemalign(&ret, alignment, size, 1)) != 0)) {\n\t\tret = NULL;\n\t\tset_errno(err);\n\t}\n\tJEMALLOC_VALGRIND_MALLOC(err == 0, ret, isalloc(ret, config_prof),\n\t    false);\n\treturn (ret);\n}\n\nstatic void *\nicalloc_prof_sample(tsd_t *tsd, size_t usize, szind_t ind, prof_tctx_t *tctx)\n{\n\tvoid *p;\n\n\tif (tctx == NULL)\n\t\treturn (NULL);\n\tif (usize <= SMALL_MAXCLASS) {\n\t\tszind_t ind_large = size2index(LARGE_MINCLASS);\n\t\tp = icalloc(tsd, LARGE_MINCLASS, ind_large);\n\t\tif (p == NULL)\n\t\t\treturn (NULL);\n\t\tarena_prof_promoted(p, usize);\n\t} else\n\t\tp = icalloc(tsd, usize, ind);\n\n\treturn (p);\n}\n\nJEMALLOC_ALWAYS_INLINE_C void *\nicalloc_prof(tsd_t *tsd, size_t usize, szind_t ind)\n{\n\tvoid *p;\n\tprof_tctx_t *tctx;\n\n\ttctx = prof_alloc_prep(tsd, usize, prof_active_get_unlocked(), true);\n\tif (unlikely((uintptr_t)tctx != (uintptr_t)1U))\n\t\tp = icalloc_prof_sample(tsd, usize, ind, tctx);\n\telse\n\t\tp = icalloc(tsd, usize, ind);\n\tif (unlikely(p == NULL)) {\n\t\tprof_alloc_rollback(tsd, tctx, true);\n\t\treturn (NULL);\n\t}\n\tprof_malloc(p, usize, tctx);\n\n\treturn (p);\n}\n\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\nvoid JEMALLOC_NOTHROW *\nJEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE2(1, 2)\nje_calloc(size_t num, size_t size)\n{\n\tvoid *ret;\n\ttsd_t *tsd;\n\tsize_t num_size;\n\tszind_t ind;\n\tsize_t usize JEMALLOC_CC_SILENCE_INIT(0);\n\n\tif (unlikely(malloc_init())) {\n\t\tnum_size = 0;\n\t\tret = NULL;\n\t\tgoto label_return;\n\t}\n\ttsd = tsd_fetch();\n\n\tnum_size = num * size;\n\tif (unlikely(num_size == 0)) {\n\t\tif (num == 0 || size == 0)\n\t\t\tnum_size = 1;\n\t\telse {\n\t\t\tret = NULL;\n\t\t\tgoto label_return;\n\t\t}\n\t/*\n\t * Try to avoid division here.  We know that it isn't possible to\n\t * overflow during multiplication if neither operand uses any of the\n\t * most significant half of the bits in a size_t.\n\t */\n\t} else if (unlikely(((num | size) & (SIZE_T_MAX << (sizeof(size_t) <<\n\t    2))) && (num_size / size != num))) {\n\t\t/* size_t overflow. */\n\t\tret = NULL;\n\t\tgoto label_return;\n\t}\n\n\tind = size2index(num_size);\n\tif (unlikely(ind >= NSIZES)) {\n\t\tret = NULL;\n\t\tgoto label_return;\n\t}\n\tif (config_prof && opt_prof) {\n\t\tusize = index2size(ind);\n\t\tret = icalloc_prof(tsd, usize, ind);\n\t} else {\n\t\tif (config_stats || (config_valgrind && unlikely(in_valgrind)))\n\t\t\tusize = index2size(ind);\n\t\tret = icalloc(tsd, num_size, ind);\n\t}\n\nlabel_return:\n\tif (unlikely(ret == NULL)) {\n\t\tif (config_xmalloc && unlikely(opt_xmalloc)) {\n\t\t\tmalloc_write(\"<jemalloc>: Error in calloc(): out of \"\n\t\t\t    \"memory\\n\");\n\t\t\tabort();\n\t\t}\n\t\tset_errno(ENOMEM);\n\t}\n\tif (config_stats && likely(ret != NULL)) {\n\t\tassert(usize == isalloc(ret, config_prof));\n\t\t*tsd_thread_allocatedp_get(tsd) += usize;\n\t}\n\tUTRACE(0, num_size, ret);\n\tJEMALLOC_VALGRIND_MALLOC(ret != NULL, ret, usize, true);\n\treturn (ret);\n}\n\nstatic void *\nirealloc_prof_sample(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t usize,\n    prof_tctx_t *tctx)\n{\n\tvoid *p;\n\n\tif (tctx == NULL)\n\t\treturn (NULL);\n\tif (usize <= SMALL_MAXCLASS) {\n\t\tp = iralloc(tsd, old_ptr, old_usize, LARGE_MINCLASS, 0, false);\n\t\tif (p == NULL)\n\t\t\treturn (NULL);\n\t\tarena_prof_promoted(p, usize);\n\t} else\n\t\tp = iralloc(tsd, old_ptr, old_usize, usize, 0, false);\n\n\treturn (p);\n}\n\nJEMALLOC_ALWAYS_INLINE_C void *\nirealloc_prof(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t usize)\n{\n\tvoid *p;\n\tbool prof_active;\n\tprof_tctx_t *old_tctx, *tctx;\n\n\tprof_active = prof_active_get_unlocked();\n\told_tctx = prof_tctx_get(old_ptr);\n\ttctx = prof_alloc_prep(tsd, usize, prof_active, true);\n\tif (unlikely((uintptr_t)tctx != (uintptr_t)1U))\n\t\tp = irealloc_prof_sample(tsd, old_ptr, old_usize, usize, tctx);\n\telse\n\t\tp = iralloc(tsd, old_ptr, old_usize, usize, 0, false);\n\tif (unlikely(p == NULL)) {\n\t\tprof_alloc_rollback(tsd, tctx, true);\n\t\treturn (NULL);\n\t}\n\tprof_realloc(tsd, p, usize, tctx, prof_active, true, old_ptr, old_usize,\n\t    old_tctx);\n\n\treturn (p);\n}\n\nJEMALLOC_INLINE_C void\nifree(tsd_t *tsd, void *ptr, tcache_t *tcache, bool slow_path)\n{\n\tsize_t usize;\n\tUNUSED size_t rzsize JEMALLOC_CC_SILENCE_INIT(0);\n\n\tassert(ptr != NULL);\n\tassert(malloc_initialized() || IS_INITIALIZER);\n\n\tif (config_prof && opt_prof) {\n\t\tusize = isalloc(ptr, config_prof);\n\t\tprof_free(tsd, ptr, usize);\n\t} else if (config_stats || config_valgrind)\n\t\tusize = isalloc(ptr, config_prof);\n\tif (config_stats)\n\t\t*tsd_thread_deallocatedp_get(tsd) += usize;\n\n\tif (likely(!slow_path))\n\t\tiqalloc(tsd, ptr, tcache, false);\n\telse {\n\t\tif (config_valgrind && unlikely(in_valgrind))\n\t\t\trzsize = p2rz(ptr);\n\t\tiqalloc(tsd, ptr, tcache, true);\n\t\tJEMALLOC_VALGRIND_FREE(ptr, rzsize);\n\t}\n}\n\nJEMALLOC_INLINE_C void\nisfree(tsd_t *tsd, void *ptr, size_t usize, tcache_t *tcache)\n{\n\tUNUSED size_t rzsize JEMALLOC_CC_SILENCE_INIT(0);\n\n\tassert(ptr != NULL);\n\tassert(malloc_initialized() || IS_INITIALIZER);\n\n\tif (config_prof && opt_prof)\n\t\tprof_free(tsd, ptr, usize);\n\tif (config_stats)\n\t\t*tsd_thread_deallocatedp_get(tsd) += usize;\n\tif (config_valgrind && unlikely(in_valgrind))\n\t\trzsize = p2rz(ptr);\n\tisqalloc(tsd, ptr, usize, tcache);\n\tJEMALLOC_VALGRIND_FREE(ptr, rzsize);\n}\n\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\nvoid JEMALLOC_NOTHROW *\nJEMALLOC_ALLOC_SIZE(2)\nje_realloc(void *ptr, size_t size)\n{\n\tvoid *ret;\n\ttsd_t *tsd JEMALLOC_CC_SILENCE_INIT(NULL);\n\tsize_t usize JEMALLOC_CC_SILENCE_INIT(0);\n\tsize_t old_usize = 0;\n\tUNUSED size_t old_rzsize JEMALLOC_CC_SILENCE_INIT(0);\n\n\tif (unlikely(size == 0)) {\n\t\tif (ptr != NULL) {\n\t\t\t/* realloc(ptr, 0) is equivalent to free(ptr). */\n\t\t\tUTRACE(ptr, 0, 0);\n\t\t\ttsd = tsd_fetch();\n\t\t\tifree(tsd, ptr, tcache_get(tsd, false), true);\n\t\t\treturn (NULL);\n\t\t}\n\t\tsize = 1;\n\t}\n\n\tif (likely(ptr != NULL)) {\n\t\tassert(malloc_initialized() || IS_INITIALIZER);\n\t\tmalloc_thread_init();\n\t\ttsd = tsd_fetch();\n\n\t\told_usize = isalloc(ptr, config_prof);\n\t\tif (config_valgrind && unlikely(in_valgrind))\n\t\t\told_rzsize = config_prof ? p2rz(ptr) : u2rz(old_usize);\n\n\t\tif (config_prof && opt_prof) {\n\t\t\tusize = s2u(size);\n\t\t\tret = unlikely(usize == 0 || usize > HUGE_MAXCLASS) ?\n\t\t\t    NULL : irealloc_prof(tsd, ptr, old_usize, usize);\n\t\t} else {\n\t\t\tif (config_stats || (config_valgrind &&\n\t\t\t    unlikely(in_valgrind)))\n\t\t\t\tusize = s2u(size);\n\t\t\tret = iralloc(tsd, ptr, old_usize, size, 0, false);\n\t\t}\n\t} else {\n\t\t/* realloc(NULL, size) is equivalent to malloc(size). */\n\t\tif (likely(!malloc_slow))\n\t\t\tret = imalloc_body(size, &tsd, &usize, false);\n\t\telse\n\t\t\tret = imalloc_body(size, &tsd, &usize, true);\n\t}\n\n\tif (unlikely(ret == NULL)) {\n\t\tif (config_xmalloc && unlikely(opt_xmalloc)) {\n\t\t\tmalloc_write(\"<jemalloc>: Error in realloc(): \"\n\t\t\t    \"out of memory\\n\");\n\t\t\tabort();\n\t\t}\n\t\tset_errno(ENOMEM);\n\t}\n\tif (config_stats && likely(ret != NULL)) {\n\t\tassert(usize == isalloc(ret, config_prof));\n\t\t*tsd_thread_allocatedp_get(tsd) += usize;\n\t\t*tsd_thread_deallocatedp_get(tsd) += old_usize;\n\t}\n\tUTRACE(ptr, size, ret);\n\tJEMALLOC_VALGRIND_REALLOC(true, ret, usize, true, ptr, old_usize,\n\t    old_rzsize, true, false);\n\treturn (ret);\n}\n\nJEMALLOC_EXPORT void JEMALLOC_NOTHROW\nje_free(void *ptr)\n{\n\n\tUTRACE(ptr, 0, 0);\n\tif (likely(ptr != NULL)) {\n\t\ttsd_t *tsd = tsd_fetch();\n\t\tif (likely(!malloc_slow))\n\t\t\tifree(tsd, ptr, tcache_get(tsd, false), false);\n\t\telse\n\t\t\tifree(tsd, ptr, tcache_get(tsd, false), true);\n\t}\n}\n\n/*\n * End malloc(3)-compatible functions.\n */\n/******************************************************************************/\n/*\n * Begin non-standard override functions.\n */\n\n#ifdef JEMALLOC_OVERRIDE_MEMALIGN\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\nvoid JEMALLOC_NOTHROW *\nJEMALLOC_ATTR(malloc)\nje_memalign(size_t alignment, size_t size)\n{\n\tvoid *ret JEMALLOC_CC_SILENCE_INIT(NULL);\n\tif (unlikely(imemalign(&ret, alignment, size, 1) != 0))\n\t\tret = NULL;\n\tJEMALLOC_VALGRIND_MALLOC(ret != NULL, ret, size, false);\n\treturn (ret);\n}\n#endif\n\n#ifdef JEMALLOC_OVERRIDE_VALLOC\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\nvoid JEMALLOC_NOTHROW *\nJEMALLOC_ATTR(malloc)\nje_valloc(size_t size)\n{\n\tvoid *ret JEMALLOC_CC_SILENCE_INIT(NULL);\n\tif (unlikely(imemalign(&ret, PAGE, size, 1) != 0))\n\t\tret = NULL;\n\tJEMALLOC_VALGRIND_MALLOC(ret != NULL, ret, size, false);\n\treturn (ret);\n}\n#endif\n\n/*\n * is_malloc(je_malloc) is some macro magic to detect if jemalloc_defs.h has\n * #define je_malloc malloc\n */\n#define\tmalloc_is_malloc 1\n#define\tis_malloc_(a) malloc_is_ ## a\n#define\tis_malloc(a) is_malloc_(a)\n\n#if ((is_malloc(je_malloc) == 1) && defined(JEMALLOC_GLIBC_MALLOC_HOOK))\n/*\n * glibc provides the RTLD_DEEPBIND flag for dlopen which can make it possible\n * to inconsistently reference libc's malloc(3)-compatible functions\n * (https://bugzilla.mozilla.org/show_bug.cgi?id=493541).\n *\n * These definitions interpose hooks in glibc.  The functions are actually\n * passed an extra argument for the caller return address, which will be\n * ignored.\n */\nJEMALLOC_EXPORT void (*__free_hook)(void *ptr) = je_free;\nJEMALLOC_EXPORT void *(*__malloc_hook)(size_t size) = je_malloc;\nJEMALLOC_EXPORT void *(*__realloc_hook)(void *ptr, size_t size) = je_realloc;\n# ifdef JEMALLOC_GLIBC_MEMALIGN_HOOK\nJEMALLOC_EXPORT void *(*__memalign_hook)(size_t alignment, size_t size) =\n    je_memalign;\n# endif\n#endif\n\n/*\n * End non-standard override functions.\n */\n/******************************************************************************/\n/*\n * Begin non-standard functions.\n */\n\nJEMALLOC_ALWAYS_INLINE_C bool\nimallocx_flags_decode_hard(tsd_t *tsd, size_t size, int flags, size_t *usize,\n    size_t *alignment, bool *zero, tcache_t **tcache, arena_t **arena)\n{\n\n\tif ((flags & MALLOCX_LG_ALIGN_MASK) == 0) {\n\t\t*alignment = 0;\n\t\t*usize = s2u(size);\n\t} else {\n\t\t*alignment = MALLOCX_ALIGN_GET_SPECIFIED(flags);\n\t\t*usize = sa2u(size, *alignment);\n\t}\n\tif (unlikely(*usize == 0 || *usize > HUGE_MAXCLASS))\n\t\treturn (true);\n\t*zero = MALLOCX_ZERO_GET(flags);\n\tif ((flags & MALLOCX_TCACHE_MASK) != 0) {\n\t\tif ((flags & MALLOCX_TCACHE_MASK) == MALLOCX_TCACHE_NONE)\n\t\t\t*tcache = NULL;\n\t\telse\n\t\t\t*tcache = tcaches_get(tsd, MALLOCX_TCACHE_GET(flags));\n\t} else\n\t\t*tcache = tcache_get(tsd, true);\n\tif ((flags & MALLOCX_ARENA_MASK) != 0) {\n\t\tunsigned arena_ind = MALLOCX_ARENA_GET(flags);\n\t\t*arena = arena_get(arena_ind, true);\n\t\tif (unlikely(*arena == NULL))\n\t\t\treturn (true);\n\t} else\n\t\t*arena = NULL;\n\treturn (false);\n}\n\nJEMALLOC_ALWAYS_INLINE_C bool\nimallocx_flags_decode(tsd_t *tsd, size_t size, int flags, size_t *usize,\n    size_t *alignment, bool *zero, tcache_t **tcache, arena_t **arena)\n{\n\n\tif (likely(flags == 0)) {\n\t\t*usize = s2u(size);\n\t\tif (unlikely(*usize == 0 || *usize > HUGE_MAXCLASS))\n\t\t\treturn (true);\n\t\t*alignment = 0;\n\t\t*zero = false;\n\t\t*tcache = tcache_get(tsd, true);\n\t\t*arena = NULL;\n\t\treturn (false);\n\t} else {\n\t\treturn (imallocx_flags_decode_hard(tsd, size, flags, usize,\n\t\t    alignment, zero, tcache, arena));\n\t}\n}\n\nJEMALLOC_ALWAYS_INLINE_C void *\nimallocx_flags(tsd_t *tsd, size_t usize, size_t alignment, bool zero,\n    tcache_t *tcache, arena_t *arena)\n{\n\tszind_t ind;\n\n\tif (unlikely(alignment != 0))\n\t\treturn (ipalloct(tsd, usize, alignment, zero, tcache, arena));\n\tind = size2index(usize);\n\tassert(ind < NSIZES);\n\tif (unlikely(zero))\n\t\treturn (icalloct(tsd, usize, ind, tcache, arena));\n\treturn (imalloct(tsd, usize, ind, tcache, arena));\n}\n\nstatic void *\nimallocx_prof_sample(tsd_t *tsd, size_t usize, size_t alignment, bool zero,\n    tcache_t *tcache, arena_t *arena)\n{\n\tvoid *p;\n\n\tif (usize <= SMALL_MAXCLASS) {\n\t\tassert(((alignment == 0) ? s2u(LARGE_MINCLASS) :\n\t\t    sa2u(LARGE_MINCLASS, alignment)) == LARGE_MINCLASS);\n\t\tp = imallocx_flags(tsd, LARGE_MINCLASS, alignment, zero, tcache,\n\t\t    arena);\n\t\tif (p == NULL)\n\t\t\treturn (NULL);\n\t\tarena_prof_promoted(p, usize);\n\t} else\n\t\tp = imallocx_flags(tsd, usize, alignment, zero, tcache, arena);\n\n\treturn (p);\n}\n\nJEMALLOC_ALWAYS_INLINE_C void *\nimallocx_prof(tsd_t *tsd, size_t size, int flags, size_t *usize)\n{\n\tvoid *p;\n\tsize_t alignment;\n\tbool zero;\n\ttcache_t *tcache;\n\tarena_t *arena;\n\tprof_tctx_t *tctx;\n\n\tif (unlikely(imallocx_flags_decode(tsd, size, flags, usize, &alignment,\n\t    &zero, &tcache, &arena)))\n\t\treturn (NULL);\n\ttctx = prof_alloc_prep(tsd, *usize, prof_active_get_unlocked(), true);\n\tif (likely((uintptr_t)tctx == (uintptr_t)1U))\n\t\tp = imallocx_flags(tsd, *usize, alignment, zero, tcache, arena);\n\telse if ((uintptr_t)tctx > (uintptr_t)1U) {\n\t\tp = imallocx_prof_sample(tsd, *usize, alignment, zero, tcache,\n\t\t    arena);\n\t} else\n\t\tp = NULL;\n\tif (unlikely(p == NULL)) {\n\t\tprof_alloc_rollback(tsd, tctx, true);\n\t\treturn (NULL);\n\t}\n\tprof_malloc(p, *usize, tctx);\n\n\tassert(alignment == 0 || ((uintptr_t)p & (alignment - 1)) == ZU(0));\n\treturn (p);\n}\n\nJEMALLOC_ALWAYS_INLINE_C void *\nimallocx_no_prof(tsd_t *tsd, size_t size, int flags, size_t *usize)\n{\n\tvoid *p;\n\tsize_t alignment;\n\tbool zero;\n\ttcache_t *tcache;\n\tarena_t *arena;\n\n\tif (likely(flags == 0)) {\n\t\tszind_t ind = size2index(size);\n\t\tif (unlikely(ind >= NSIZES))\n\t\t\treturn (NULL);\n\t\tif (config_stats || (config_valgrind &&\n\t\t    unlikely(in_valgrind))) {\n\t\t\t*usize = index2size(ind);\n\t\t\tassert(*usize > 0 && *usize <= HUGE_MAXCLASS);\n\t\t}\n\t\treturn (imalloc(tsd, size, ind, true));\n\t}\n\n\tif (unlikely(imallocx_flags_decode_hard(tsd, size, flags, usize,\n\t    &alignment, &zero, &tcache, &arena)))\n\t\treturn (NULL);\n\tp = imallocx_flags(tsd, *usize, alignment, zero, tcache, arena);\n\tassert(alignment == 0 || ((uintptr_t)p & (alignment - 1)) == ZU(0));\n\treturn (p);\n}\n\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\nvoid JEMALLOC_NOTHROW *\nJEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1)\nje_mallocx(size_t size, int flags)\n{\n\ttsd_t *tsd;\n\tvoid *p;\n\tsize_t usize;\n\n\tassert(size != 0);\n\n\tif (unlikely(malloc_init()))\n\t\tgoto label_oom;\n\ttsd = tsd_fetch();\n\n\tif (config_prof && opt_prof)\n\t\tp = imallocx_prof(tsd, size, flags, &usize);\n\telse\n\t\tp = imallocx_no_prof(tsd, size, flags, &usize);\n\tif (unlikely(p == NULL))\n\t\tgoto label_oom;\n\n\tif (config_stats) {\n\t\tassert(usize == isalloc(p, config_prof));\n\t\t*tsd_thread_allocatedp_get(tsd) += usize;\n\t}\n\tUTRACE(0, size, p);\n\tJEMALLOC_VALGRIND_MALLOC(true, p, usize, MALLOCX_ZERO_GET(flags));\n\treturn (p);\nlabel_oom:\n\tif (config_xmalloc && unlikely(opt_xmalloc)) {\n\t\tmalloc_write(\"<jemalloc>: Error in mallocx(): out of memory\\n\");\n\t\tabort();\n\t}\n\tUTRACE(0, size, 0);\n\treturn (NULL);\n}\n\nstatic void *\nirallocx_prof_sample(tsd_t *tsd, void *old_ptr, size_t old_usize,\n    size_t usize, size_t alignment, bool zero, tcache_t *tcache, arena_t *arena,\n    prof_tctx_t *tctx)\n{\n\tvoid *p;\n\n\tif (tctx == NULL)\n\t\treturn (NULL);\n\tif (usize <= SMALL_MAXCLASS) {\n\t\tp = iralloct(tsd, old_ptr, old_usize, LARGE_MINCLASS, alignment,\n\t\t    zero, tcache, arena);\n\t\tif (p == NULL)\n\t\t\treturn (NULL);\n\t\tarena_prof_promoted(p, usize);\n\t} else {\n\t\tp = iralloct(tsd, old_ptr, old_usize, usize, alignment, zero,\n\t\t    tcache, arena);\n\t}\n\n\treturn (p);\n}\n\nJEMALLOC_ALWAYS_INLINE_C void *\nirallocx_prof(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t size,\n    size_t alignment, size_t *usize, bool zero, tcache_t *tcache,\n    arena_t *arena)\n{\n\tvoid *p;\n\tbool prof_active;\n\tprof_tctx_t *old_tctx, *tctx;\n\n\tprof_active = prof_active_get_unlocked();\n\told_tctx = prof_tctx_get(old_ptr);\n\ttctx = prof_alloc_prep(tsd, *usize, prof_active, true);\n\tif (unlikely((uintptr_t)tctx != (uintptr_t)1U)) {\n\t\tp = irallocx_prof_sample(tsd, old_ptr, old_usize, *usize,\n\t\t    alignment, zero, tcache, arena, tctx);\n\t} else {\n\t\tp = iralloct(tsd, old_ptr, old_usize, size, alignment, zero,\n\t\t    tcache, arena);\n\t}\n\tif (unlikely(p == NULL)) {\n\t\tprof_alloc_rollback(tsd, tctx, true);\n\t\treturn (NULL);\n\t}\n\n\tif (p == old_ptr && alignment != 0) {\n\t\t/*\n\t\t * The allocation did not move, so it is possible that the size\n\t\t * class is smaller than would guarantee the requested\n\t\t * alignment, and that the alignment constraint was\n\t\t * serendipitously satisfied.  Additionally, old_usize may not\n\t\t * be the same as the current usize because of in-place large\n\t\t * reallocation.  Therefore, query the actual value of usize.\n\t\t */\n\t\t*usize = isalloc(p, config_prof);\n\t}\n\tprof_realloc(tsd, p, *usize, tctx, prof_active, true, old_ptr,\n\t    old_usize, old_tctx);\n\n\treturn (p);\n}\n\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\nvoid JEMALLOC_NOTHROW *\nJEMALLOC_ALLOC_SIZE(2)\nje_rallocx(void *ptr, size_t size, int flags)\n{\n\tvoid *p;\n\ttsd_t *tsd;\n\tsize_t usize;\n\tsize_t old_usize;\n\tUNUSED size_t old_rzsize JEMALLOC_CC_SILENCE_INIT(0);\n\tsize_t alignment = MALLOCX_ALIGN_GET(flags);\n\tbool zero = flags & MALLOCX_ZERO;\n\tarena_t *arena;\n\ttcache_t *tcache;\n\n\tassert(ptr != NULL);\n\tassert(size != 0);\n\tassert(malloc_initialized() || IS_INITIALIZER);\n\tmalloc_thread_init();\n\ttsd = tsd_fetch();\n\n\tif (unlikely((flags & MALLOCX_ARENA_MASK) != 0)) {\n\t\tunsigned arena_ind = MALLOCX_ARENA_GET(flags);\n\t\tarena = arena_get(arena_ind, true);\n\t\tif (unlikely(arena == NULL))\n\t\t\tgoto label_oom;\n\t} else\n\t\tarena = NULL;\n\n\tif (unlikely((flags & MALLOCX_TCACHE_MASK) != 0)) {\n\t\tif ((flags & MALLOCX_TCACHE_MASK) == MALLOCX_TCACHE_NONE)\n\t\t\ttcache = NULL;\n\t\telse\n\t\t\ttcache = tcaches_get(tsd, MALLOCX_TCACHE_GET(flags));\n\t} else\n\t\ttcache = tcache_get(tsd, true);\n\n\told_usize = isalloc(ptr, config_prof);\n\tif (config_valgrind && unlikely(in_valgrind))\n\t\told_rzsize = u2rz(old_usize);\n\n\tif (config_prof && opt_prof) {\n\t\tusize = (alignment == 0) ? s2u(size) : sa2u(size, alignment);\n\t\tif (unlikely(usize == 0 || usize > HUGE_MAXCLASS))\n\t\t\tgoto label_oom;\n\t\tp = irallocx_prof(tsd, ptr, old_usize, size, alignment, &usize,\n\t\t    zero, tcache, arena);\n\t\tif (unlikely(p == NULL))\n\t\t\tgoto label_oom;\n\t} else {\n\t\tp = iralloct(tsd, ptr, old_usize, size, alignment, zero,\n\t\t     tcache, arena);\n\t\tif (unlikely(p == NULL))\n\t\t\tgoto label_oom;\n\t\tif (config_stats || (config_valgrind && unlikely(in_valgrind)))\n\t\t\tusize = isalloc(p, config_prof);\n\t}\n\tassert(alignment == 0 || ((uintptr_t)p & (alignment - 1)) == ZU(0));\n\n\tif (config_stats) {\n\t\t*tsd_thread_allocatedp_get(tsd) += usize;\n\t\t*tsd_thread_deallocatedp_get(tsd) += old_usize;\n\t}\n\tUTRACE(ptr, size, p);\n\tJEMALLOC_VALGRIND_REALLOC(true, p, usize, false, ptr, old_usize,\n\t    old_rzsize, false, zero);\n\treturn (p);\nlabel_oom:\n\tif (config_xmalloc && unlikely(opt_xmalloc)) {\n\t\tmalloc_write(\"<jemalloc>: Error in rallocx(): out of memory\\n\");\n\t\tabort();\n\t}\n\tUTRACE(ptr, size, 0);\n\treturn (NULL);\n}\n\nJEMALLOC_ALWAYS_INLINE_C size_t\nixallocx_helper(tsd_t *tsd, void *ptr, size_t old_usize, size_t size,\n    size_t extra, size_t alignment, bool zero)\n{\n\tsize_t usize;\n\n\tif (ixalloc(tsd, ptr, old_usize, size, extra, alignment, zero))\n\t\treturn (old_usize);\n\tusize = isalloc(ptr, config_prof);\n\n\treturn (usize);\n}\n\nstatic size_t\nixallocx_prof_sample(tsd_t *tsd, void *ptr, size_t old_usize, size_t size,\n    size_t extra, size_t alignment, bool zero, prof_tctx_t *tctx)\n{\n\tsize_t usize;\n\n\tif (tctx == NULL)\n\t\treturn (old_usize);\n\tusize = ixallocx_helper(tsd, ptr, old_usize, size, extra, alignment,\n\t    zero);\n\n\treturn (usize);\n}\n\nJEMALLOC_ALWAYS_INLINE_C size_t\nixallocx_prof(tsd_t *tsd, void *ptr, size_t old_usize, size_t size,\n    size_t extra, size_t alignment, bool zero)\n{\n\tsize_t usize_max, usize;\n\tbool prof_active;\n\tprof_tctx_t *old_tctx, *tctx;\n\n\tprof_active = prof_active_get_unlocked();\n\told_tctx = prof_tctx_get(ptr);\n\t/*\n\t * usize isn't knowable before ixalloc() returns when extra is non-zero.\n\t * Therefore, compute its maximum possible value and use that in\n\t * prof_alloc_prep() to decide whether to capture a backtrace.\n\t * prof_realloc() will use the actual usize to decide whether to sample.\n\t */\n\tif (alignment == 0) {\n\t\tusize_max = s2u(size+extra);\n\t\tassert(usize_max > 0 && usize_max <= HUGE_MAXCLASS);\n\t} else {\n\t\tusize_max = sa2u(size+extra, alignment);\n\t\tif (unlikely(usize_max == 0 || usize_max > HUGE_MAXCLASS)) {\n\t\t\t/*\n\t\t\t * usize_max is out of range, and chances are that\n\t\t\t * allocation will fail, but use the maximum possible\n\t\t\t * value and carry on with prof_alloc_prep(), just in\n\t\t\t * case allocation succeeds.\n\t\t\t */\n\t\t\tusize_max = HUGE_MAXCLASS;\n\t\t}\n\t}\n\ttctx = prof_alloc_prep(tsd, usize_max, prof_active, false);\n\n\tif (unlikely((uintptr_t)tctx != (uintptr_t)1U)) {\n\t\tusize = ixallocx_prof_sample(tsd, ptr, old_usize, size, extra,\n\t\t    alignment, zero, tctx);\n\t} else {\n\t\tusize = ixallocx_helper(tsd, ptr, old_usize, size, extra,\n\t\t    alignment, zero);\n\t}\n\tif (usize == old_usize) {\n\t\tprof_alloc_rollback(tsd, tctx, false);\n\t\treturn (usize);\n\t}\n\tprof_realloc(tsd, ptr, usize, tctx, prof_active, false, ptr, old_usize,\n\t    old_tctx);\n\n\treturn (usize);\n}\n\nJEMALLOC_EXPORT size_t JEMALLOC_NOTHROW\nje_xallocx(void *ptr, size_t size, size_t extra, int flags)\n{\n\ttsd_t *tsd;\n\tsize_t usize, old_usize;\n\tUNUSED size_t old_rzsize JEMALLOC_CC_SILENCE_INIT(0);\n\tsize_t alignment = MALLOCX_ALIGN_GET(flags);\n\tbool zero = flags & MALLOCX_ZERO;\n\n\tassert(ptr != NULL);\n\tassert(size != 0);\n\tassert(SIZE_T_MAX - size >= extra);\n\tassert(malloc_initialized() || IS_INITIALIZER);\n\tmalloc_thread_init();\n\ttsd = tsd_fetch();\n\n\told_usize = isalloc(ptr, config_prof);\n\n\t/*\n\t * The API explicitly absolves itself of protecting against (size +\n\t * extra) numerical overflow, but we may need to clamp extra to avoid\n\t * exceeding HUGE_MAXCLASS.\n\t *\n\t * Ordinarily, size limit checking is handled deeper down, but here we\n\t * have to check as part of (size + extra) clamping, since we need the\n\t * clamped value in the above helper functions.\n\t */\n\tif (unlikely(size > HUGE_MAXCLASS)) {\n\t\tusize = old_usize;\n\t\tgoto label_not_resized;\n\t}\n\tif (unlikely(HUGE_MAXCLASS - size < extra))\n\t\textra = HUGE_MAXCLASS - size;\n\n\tif (config_valgrind && unlikely(in_valgrind))\n\t\told_rzsize = u2rz(old_usize);\n\n\tif (config_prof && opt_prof) {\n\t\tusize = ixallocx_prof(tsd, ptr, old_usize, size, extra,\n\t\t    alignment, zero);\n\t} else {\n\t\tusize = ixallocx_helper(tsd, ptr, old_usize, size, extra,\n\t\t    alignment, zero);\n\t}\n\tif (unlikely(usize == old_usize))\n\t\tgoto label_not_resized;\n\n\tif (config_stats) {\n\t\t*tsd_thread_allocatedp_get(tsd) += usize;\n\t\t*tsd_thread_deallocatedp_get(tsd) += old_usize;\n\t}\n\tJEMALLOC_VALGRIND_REALLOC(false, ptr, usize, false, ptr, old_usize,\n\t    old_rzsize, false, zero);\nlabel_not_resized:\n\tUTRACE(ptr, size, ptr);\n\treturn (usize);\n}\n\nJEMALLOC_EXPORT size_t JEMALLOC_NOTHROW\nJEMALLOC_ATTR(pure)\nje_sallocx(const void *ptr, int flags)\n{\n\tsize_t usize;\n\n\tassert(malloc_initialized() || IS_INITIALIZER);\n\tmalloc_thread_init();\n\n\tif (config_ivsalloc)\n\t\tusize = ivsalloc(ptr, config_prof);\n\telse\n\t\tusize = isalloc(ptr, config_prof);\n\n\treturn (usize);\n}\n\nJEMALLOC_EXPORT void JEMALLOC_NOTHROW\nje_dallocx(void *ptr, int flags)\n{\n\ttsd_t *tsd;\n\ttcache_t *tcache;\n\n\tassert(ptr != NULL);\n\tassert(malloc_initialized() || IS_INITIALIZER);\n\n\ttsd = tsd_fetch();\n\tif (unlikely((flags & MALLOCX_TCACHE_MASK) != 0)) {\n\t\tif ((flags & MALLOCX_TCACHE_MASK) == MALLOCX_TCACHE_NONE)\n\t\t\ttcache = NULL;\n\t\telse\n\t\t\ttcache = tcaches_get(tsd, MALLOCX_TCACHE_GET(flags));\n\t} else\n\t\ttcache = tcache_get(tsd, false);\n\n\tUTRACE(ptr, 0, 0);\n\tifree(tsd_fetch(), ptr, tcache, true);\n}\n\nJEMALLOC_ALWAYS_INLINE_C size_t\ninallocx(size_t size, int flags)\n{\n\tsize_t usize;\n\n\tif (likely((flags & MALLOCX_LG_ALIGN_MASK) == 0))\n\t\tusize = s2u(size);\n\telse\n\t\tusize = sa2u(size, MALLOCX_ALIGN_GET_SPECIFIED(flags));\n\treturn (usize);\n}\n\nJEMALLOC_EXPORT void JEMALLOC_NOTHROW\nje_sdallocx(void *ptr, size_t size, int flags)\n{\n\ttsd_t *tsd;\n\ttcache_t *tcache;\n\tsize_t usize;\n\n\tassert(ptr != NULL);\n\tassert(malloc_initialized() || IS_INITIALIZER);\n\tusize = inallocx(size, flags);\n\tassert(usize == isalloc(ptr, config_prof));\n\n\ttsd = tsd_fetch();\n\tif (unlikely((flags & MALLOCX_TCACHE_MASK) != 0)) {\n\t\tif ((flags & MALLOCX_TCACHE_MASK) == MALLOCX_TCACHE_NONE)\n\t\t\ttcache = NULL;\n\t\telse\n\t\t\ttcache = tcaches_get(tsd, MALLOCX_TCACHE_GET(flags));\n\t} else\n\t\ttcache = tcache_get(tsd, false);\n\n\tUTRACE(ptr, 0, 0);\n\tisfree(tsd, ptr, usize, tcache);\n}\n\nJEMALLOC_EXPORT size_t JEMALLOC_NOTHROW\nJEMALLOC_ATTR(pure)\nje_nallocx(size_t size, int flags)\n{\n\tsize_t usize;\n\n\tassert(size != 0);\n\n\tif (unlikely(malloc_init()))\n\t\treturn (0);\n\n\tusize = inallocx(size, flags);\n\tif (unlikely(usize > HUGE_MAXCLASS))\n\t\treturn (0);\n\n\treturn (usize);\n}\n\nJEMALLOC_EXPORT int JEMALLOC_NOTHROW\nje_mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp,\n    size_t newlen)\n{\n\n\tif (unlikely(malloc_init()))\n\t\treturn (EAGAIN);\n\n\treturn (ctl_byname(name, oldp, oldlenp, newp, newlen));\n}\n\nJEMALLOC_EXPORT int JEMALLOC_NOTHROW\nje_mallctlnametomib(const char *name, size_t *mibp, size_t *miblenp)\n{\n\n\tif (unlikely(malloc_init()))\n\t\treturn (EAGAIN);\n\n\treturn (ctl_nametomib(name, mibp, miblenp));\n}\n\nJEMALLOC_EXPORT int JEMALLOC_NOTHROW\nje_mallctlbymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,\n  void *newp, size_t newlen)\n{\n\n\tif (unlikely(malloc_init()))\n\t\treturn (EAGAIN);\n\n\treturn (ctl_bymib(mib, miblen, oldp, oldlenp, newp, newlen));\n}\n\nJEMALLOC_EXPORT void JEMALLOC_NOTHROW\nje_malloc_stats_print(void (*write_cb)(void *, const char *), void *cbopaque,\n    const char *opts)\n{\n\n\tstats_print(write_cb, cbopaque, opts);\n}\n\nJEMALLOC_EXPORT size_t JEMALLOC_NOTHROW\nje_malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *ptr)\n{\n\tsize_t ret;\n\n\tassert(malloc_initialized() || IS_INITIALIZER);\n\tmalloc_thread_init();\n\n\tif (config_ivsalloc)\n\t\tret = ivsalloc(ptr, config_prof);\n\telse\n\t\tret = (ptr == NULL) ? 0 : isalloc(ptr, config_prof);\n\n\treturn (ret);\n}\n\n/*\n * End non-standard functions.\n */\n/******************************************************************************/\n/*\n * The following functions are used by threading libraries for protection of\n * malloc during fork().\n */\n\n/*\n * If an application creates a thread before doing any allocation in the main\n * thread, then calls fork(2) in the main thread followed by memory allocation\n * in the child process, a race can occur that results in deadlock within the\n * child: the main thread may have forked while the created thread had\n * partially initialized the allocator.  Ordinarily jemalloc prevents\n * fork/malloc races via the following functions it registers during\n * initialization using pthread_atfork(), but of course that does no good if\n * the allocator isn't fully initialized at fork time.  The following library\n * constructor is a partial solution to this problem.  It may still be possible\n * to trigger the deadlock described above, but doing so would involve forking\n * via a library constructor that runs before jemalloc's runs.\n */\nJEMALLOC_ATTR(constructor)\nstatic void\njemalloc_constructor(void)\n{\n\n\tmalloc_init();\n}\n\n#ifndef JEMALLOC_MUTEX_INIT_CB\nvoid\njemalloc_prefork(void)\n#else\nJEMALLOC_EXPORT void\n_malloc_prefork(void)\n#endif\n{\n\tunsigned i, narenas;\n\n#ifdef JEMALLOC_MUTEX_INIT_CB\n\tif (!malloc_initialized())\n\t\treturn;\n#endif\n\tassert(malloc_initialized());\n\n\t/* Acquire all mutexes in a safe order. */\n\tctl_prefork();\n\tprof_prefork();\n\tmalloc_mutex_prefork(&arenas_lock);\n\tfor (i = 0, narenas = narenas_total_get(); i < narenas; i++) {\n\t\tarena_t *arena;\n\n\t\tif ((arena = arena_get(i, false)) != NULL)\n\t\t\tarena_prefork(arena);\n\t}\n\tchunk_prefork();\n\tbase_prefork();\n}\n\n#ifndef JEMALLOC_MUTEX_INIT_CB\nvoid\njemalloc_postfork_parent(void)\n#else\nJEMALLOC_EXPORT void\n_malloc_postfork(void)\n#endif\n{\n\tunsigned i, narenas;\n\n#ifdef JEMALLOC_MUTEX_INIT_CB\n\tif (!malloc_initialized())\n\t\treturn;\n#endif\n\tassert(malloc_initialized());\n\n\t/* Release all mutexes, now that fork() has completed. */\n\tbase_postfork_parent();\n\tchunk_postfork_parent();\n\tfor (i = 0, narenas = narenas_total_get(); i < narenas; i++) {\n\t\tarena_t *arena;\n\n\t\tif ((arena = arena_get(i, false)) != NULL)\n\t\t\tarena_postfork_parent(arena);\n\t}\n\tmalloc_mutex_postfork_parent(&arenas_lock);\n\tprof_postfork_parent();\n\tctl_postfork_parent();\n}\n\nvoid\njemalloc_postfork_child(void)\n{\n\tunsigned i, narenas;\n\n\tassert(malloc_initialized());\n\n\t/* Release all mutexes, now that fork() has completed. */\n\tbase_postfork_child();\n\tchunk_postfork_child();\n\tfor (i = 0, narenas = narenas_total_get(); i < narenas; i++) {\n\t\tarena_t *arena;\n\n\t\tif ((arena = arena_get(i, false)) != NULL)\n\t\t\tarena_postfork_child(arena);\n\t}\n\tmalloc_mutex_postfork_child(&arenas_lock);\n\tprof_postfork_child();\n\tctl_postfork_child();\n}\n\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/mb.c",
    "content": "#define\tJEMALLOC_MB_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/mutex.c",
    "content": "#define\tJEMALLOC_MUTEX_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n#if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32)\n#include <dlfcn.h>\n#endif\n\n#ifndef _CRT_SPINCOUNT\n#define\t_CRT_SPINCOUNT 4000\n#endif\n\n/******************************************************************************/\n/* Data. */\n\n#ifdef JEMALLOC_LAZY_LOCK\nbool isthreaded = false;\n#endif\n#ifdef JEMALLOC_MUTEX_INIT_CB\nstatic bool\t\tpostpone_init = true;\nstatic malloc_mutex_t\t*postponed_mutexes = NULL;\n#endif\n\n#if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32)\nstatic void\tpthread_create_once(void);\n#endif\n\n/******************************************************************************/\n/*\n * We intercept pthread_create() calls in order to toggle isthreaded if the\n * process goes multi-threaded.\n */\n\n#if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32)\nstatic int (*pthread_create_fptr)(pthread_t *__restrict, const pthread_attr_t *,\n    void *(*)(void *), void *__restrict);\n\nstatic void\npthread_create_once(void)\n{\n\n\tpthread_create_fptr = dlsym(RTLD_NEXT, \"pthread_create\");\n\tif (pthread_create_fptr == NULL) {\n\t\tmalloc_write(\"<jemalloc>: Error in dlsym(RTLD_NEXT, \"\n\t\t    \"\\\"pthread_create\\\")\\n\");\n\t\tabort();\n\t}\n\n\tisthreaded = true;\n}\n\nJEMALLOC_EXPORT int\npthread_create(pthread_t *__restrict thread,\n    const pthread_attr_t *__restrict attr, void *(*start_routine)(void *),\n    void *__restrict arg)\n{\n\tstatic pthread_once_t once_control = PTHREAD_ONCE_INIT;\n\n\tpthread_once(&once_control, pthread_create_once);\n\n\treturn (pthread_create_fptr(thread, attr, start_routine, arg));\n}\n#endif\n\n/******************************************************************************/\n\n#ifdef JEMALLOC_MUTEX_INIT_CB\nJEMALLOC_EXPORT int\t_pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex,\n    void *(calloc_cb)(size_t, size_t));\n#endif\n\nbool\nmalloc_mutex_init(malloc_mutex_t *mutex)\n{\n\n#ifdef _WIN32\n#  if _WIN32_WINNT >= 0x0600\n\tInitializeSRWLock(&mutex->lock);\n#  else\n\tif (!InitializeCriticalSectionAndSpinCount(&mutex->lock,\n\t    _CRT_SPINCOUNT))\n\t\treturn (true);\n#  endif\n#elif (defined(JEMALLOC_OSSPIN))\n\tmutex->lock = 0;\n#elif (defined(JEMALLOC_MUTEX_INIT_CB))\n\tif (postpone_init) {\n\t\tmutex->postponed_next = postponed_mutexes;\n\t\tpostponed_mutexes = mutex;\n\t} else {\n\t\tif (_pthread_mutex_init_calloc_cb(&mutex->lock,\n\t\t    bootstrap_calloc) != 0)\n\t\t\treturn (true);\n\t}\n#else\n\tpthread_mutexattr_t attr;\n\n\tif (pthread_mutexattr_init(&attr) != 0)\n\t\treturn (true);\n\tpthread_mutexattr_settype(&attr, MALLOC_MUTEX_TYPE);\n\tif (pthread_mutex_init(&mutex->lock, &attr) != 0) {\n\t\tpthread_mutexattr_destroy(&attr);\n\t\treturn (true);\n\t}\n\tpthread_mutexattr_destroy(&attr);\n#endif\n\treturn (false);\n}\n\nvoid\nmalloc_mutex_prefork(malloc_mutex_t *mutex)\n{\n\n\tmalloc_mutex_lock(mutex);\n}\n\nvoid\nmalloc_mutex_postfork_parent(malloc_mutex_t *mutex)\n{\n\n\tmalloc_mutex_unlock(mutex);\n}\n\nvoid\nmalloc_mutex_postfork_child(malloc_mutex_t *mutex)\n{\n\n#ifdef JEMALLOC_MUTEX_INIT_CB\n\tmalloc_mutex_unlock(mutex);\n#else\n\tif (malloc_mutex_init(mutex)) {\n\t\tmalloc_printf(\"<jemalloc>: Error re-initializing mutex in \"\n\t\t    \"child\\n\");\n\t\tif (opt_abort)\n\t\t\tabort();\n\t}\n#endif\n}\n\nbool\nmutex_boot(void)\n{\n\n#ifdef JEMALLOC_MUTEX_INIT_CB\n\tpostpone_init = false;\n\twhile (postponed_mutexes != NULL) {\n\t\tif (_pthread_mutex_init_calloc_cb(&postponed_mutexes->lock,\n\t\t    bootstrap_calloc) != 0)\n\t\t\treturn (true);\n\t\tpostponed_mutexes = postponed_mutexes->postponed_next;\n\t}\n#endif\n\treturn (false);\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/nstime.c",
    "content": "#include \"jemalloc/internal/jemalloc_internal.h\"\n\n#define\tBILLION\tUINT64_C(1000000000)\n\nvoid\nnstime_init(nstime_t *time, uint64_t ns)\n{\n\n\ttime->ns = ns;\n}\n\nvoid\nnstime_init2(nstime_t *time, uint64_t sec, uint64_t nsec)\n{\n\n\ttime->ns = sec * BILLION + nsec;\n}\n\nuint64_t\nnstime_ns(const nstime_t *time)\n{\n\n\treturn (time->ns);\n}\n\nuint64_t\nnstime_sec(const nstime_t *time)\n{\n\n\treturn (time->ns / BILLION);\n}\n\nuint64_t\nnstime_nsec(const nstime_t *time)\n{\n\n\treturn (time->ns % BILLION);\n}\n\nvoid\nnstime_copy(nstime_t *time, const nstime_t *source)\n{\n\n\t*time = *source;\n}\n\nint\nnstime_compare(const nstime_t *a, const nstime_t *b)\n{\n\n\treturn ((a->ns > b->ns) - (a->ns < b->ns));\n}\n\nvoid\nnstime_add(nstime_t *time, const nstime_t *addend)\n{\n\n\tassert(UINT64_MAX - time->ns >= addend->ns);\n\n\ttime->ns += addend->ns;\n}\n\nvoid\nnstime_subtract(nstime_t *time, const nstime_t *subtrahend)\n{\n\n\tassert(nstime_compare(time, subtrahend) >= 0);\n\n\ttime->ns -= subtrahend->ns;\n}\n\nvoid\nnstime_imultiply(nstime_t *time, uint64_t multiplier)\n{\n\n\tassert((((time->ns | multiplier) & (UINT64_MAX << (sizeof(uint64_t) <<\n\t    2))) == 0) || ((time->ns * multiplier) / multiplier == time->ns));\n\n\ttime->ns *= multiplier;\n}\n\nvoid\nnstime_idivide(nstime_t *time, uint64_t divisor)\n{\n\n\tassert(divisor != 0);\n\n\ttime->ns /= divisor;\n}\n\nuint64_t\nnstime_divide(const nstime_t *time, const nstime_t *divisor)\n{\n\n\tassert(divisor->ns != 0);\n\n\treturn (time->ns / divisor->ns);\n}\n\n#ifdef JEMALLOC_JET\n#undef nstime_update\n#define\tnstime_update JEMALLOC_N(nstime_update_impl)\n#endif\nbool\nnstime_update(nstime_t *time)\n{\n\tnstime_t old_time;\n\n\tnstime_copy(&old_time, time);\n\n#ifdef _WIN32\n\t{\n\t\tFILETIME ft;\n\t\tuint64_t ticks;\n\t\tGetSystemTimeAsFileTime(&ft);\n\t\tticks = (((uint64_t)ft.dwHighDateTime) << 32) |\n\t\t    ft.dwLowDateTime;\n\t\ttime->ns = ticks * 100;\n\t}\n#elif JEMALLOC_CLOCK_GETTIME\n\t{\n\t\tstruct timespec ts;\n\n\t\tif (sysconf(_SC_MONOTONIC_CLOCK) > 0)\n\t\t\tclock_gettime(CLOCK_MONOTONIC, &ts);\n\t\telse\n\t\t\tclock_gettime(CLOCK_REALTIME, &ts);\n\t\ttime->ns = ts.tv_sec * BILLION + ts.tv_nsec;\n\t}\n#else\n\tstruct timeval tv;\n\tgettimeofday(&tv, NULL);\n\ttime->ns = tv.tv_sec * BILLION + tv.tv_usec * 1000;\n#endif\n\n\t/* Handle non-monotonic clocks. */\n\tif (unlikely(nstime_compare(&old_time, time) > 0)) {\n\t\tnstime_copy(time, &old_time);\n\t\treturn (true);\n\t}\n\n\treturn (false);\n}\n#ifdef JEMALLOC_JET\n#undef nstime_update\n#define\tnstime_update JEMALLOC_N(nstime_update)\nnstime_update_t *nstime_update = JEMALLOC_N(nstime_update_impl);\n#endif\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/pages.c",
    "content": "#define\tJEMALLOC_PAGES_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n/******************************************************************************/\n\nvoid *\npages_map(void *addr, size_t size)\n{\n\tvoid *ret;\n\n\tassert(size != 0);\n\n#ifdef _WIN32\n\t/*\n\t * If VirtualAlloc can't allocate at the given address when one is\n\t * given, it fails and returns NULL.\n\t */\n\tret = VirtualAlloc(addr, size, MEM_COMMIT | MEM_RESERVE,\n\t    PAGE_READWRITE);\n#else\n\t/*\n\t * We don't use MAP_FIXED here, because it can cause the *replacement*\n\t * of existing mappings, and we only want to create new mappings.\n\t */\n\tret = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON,\n\t    -1, 0);\n\tassert(ret != NULL);\n\n\tif (ret == MAP_FAILED)\n\t\tret = NULL;\n\telse if (addr != NULL && ret != addr) {\n\t\t/*\n\t\t * We succeeded in mapping memory, but not in the right place.\n\t\t */\n\t\tpages_unmap(ret, size);\n\t\tret = NULL;\n\t}\n#endif\n\tassert(ret == NULL || (addr == NULL && ret != addr)\n\t    || (addr != NULL && ret == addr));\n\treturn (ret);\n}\n\nvoid\npages_unmap(void *addr, size_t size)\n{\n\n#ifdef _WIN32\n\tif (VirtualFree(addr, 0, MEM_RELEASE) == 0)\n#else\n\tif (munmap(addr, size) == -1)\n#endif\n\t{\n\t\tchar buf[BUFERROR_BUF];\n\n\t\tbuferror(get_errno(), buf, sizeof(buf));\n\t\tmalloc_printf(\"<jemalloc>: Error in \"\n#ifdef _WIN32\n\t\t              \"VirtualFree\"\n#else\n\t\t              \"munmap\"\n#endif\n\t\t              \"(): %s\\n\", buf);\n\t\tif (opt_abort)\n\t\t\tabort();\n\t}\n}\n\nvoid *\npages_trim(void *addr, size_t alloc_size, size_t leadsize, size_t size)\n{\n\tvoid *ret = (void *)((uintptr_t)addr + leadsize);\n\n\tassert(alloc_size >= leadsize + size);\n#ifdef _WIN32\n\t{\n\t\tvoid *new_addr;\n\n\t\tpages_unmap(addr, alloc_size);\n\t\tnew_addr = pages_map(ret, size);\n\t\tif (new_addr == ret)\n\t\t\treturn (ret);\n\t\tif (new_addr)\n\t\t\tpages_unmap(new_addr, size);\n\t\treturn (NULL);\n\t}\n#else\n\t{\n\t\tsize_t trailsize = alloc_size - leadsize - size;\n\n\t\tif (leadsize != 0)\n\t\t\tpages_unmap(addr, leadsize);\n\t\tif (trailsize != 0)\n\t\t\tpages_unmap((void *)((uintptr_t)ret + size), trailsize);\n\t\treturn (ret);\n\t}\n#endif\n}\n\nstatic bool\npages_commit_impl(void *addr, size_t size, bool commit)\n{\n\n#ifndef _WIN32\n\t/*\n\t * The following decommit/commit implementation is functional, but\n\t * always disabled because it doesn't add value beyong improved\n\t * debugging (at the cost of extra system calls) on systems that\n\t * overcommit.\n\t */\n\tif (false) {\n\t\tint prot = commit ? (PROT_READ | PROT_WRITE) : PROT_NONE;\n\t\tvoid *result = mmap(addr, size, prot, MAP_PRIVATE | MAP_ANON |\n\t\t    MAP_FIXED, -1, 0);\n\t\tif (result == MAP_FAILED)\n\t\t\treturn (true);\n\t\tif (result != addr) {\n\t\t\t/*\n\t\t\t * We succeeded in mapping memory, but not in the right\n\t\t\t * place.\n\t\t\t */\n\t\t\tpages_unmap(result, size);\n\t\t\treturn (true);\n\t\t}\n\t\treturn (false);\n\t}\n#endif\n\treturn (true);\n}\n\nbool\npages_commit(void *addr, size_t size)\n{\n\n\treturn (pages_commit_impl(addr, size, true));\n}\n\nbool\npages_decommit(void *addr, size_t size)\n{\n\n\treturn (pages_commit_impl(addr, size, false));\n}\n\nbool\npages_purge(void *addr, size_t size)\n{\n\tbool unzeroed;\n\n#ifdef _WIN32\n\tVirtualAlloc(addr, size, MEM_RESET, PAGE_READWRITE);\n\tunzeroed = true;\n#elif defined(JEMALLOC_HAVE_MADVISE)\n#  ifdef JEMALLOC_PURGE_MADVISE_DONTNEED\n#    define JEMALLOC_MADV_PURGE MADV_DONTNEED\n#    define JEMALLOC_MADV_ZEROS true\n#  elif defined(JEMALLOC_PURGE_MADVISE_FREE)\n#    define JEMALLOC_MADV_PURGE MADV_FREE\n#    define JEMALLOC_MADV_ZEROS false\n#  else\n#    error \"No madvise(2) flag defined for purging unused dirty pages.\"\n#  endif\n\tint err = madvise(addr, size, JEMALLOC_MADV_PURGE);\n\tunzeroed = (!JEMALLOC_MADV_ZEROS || err != 0);\n#  undef JEMALLOC_MADV_PURGE\n#  undef JEMALLOC_MADV_ZEROS\n#else\n\t/* Last resort no-op. */\n\tunzeroed = true;\n#endif\n\treturn (unzeroed);\n}\n\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/prng.c",
    "content": "#define\tJEMALLOC_PRNG_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/prof.c",
    "content": "#define\tJEMALLOC_PROF_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n/******************************************************************************/\n\n#ifdef JEMALLOC_PROF_LIBUNWIND\n#define\tUNW_LOCAL_ONLY\n#include <libunwind.h>\n#endif\n\n#ifdef JEMALLOC_PROF_LIBGCC\n#include <unwind.h>\n#endif\n\n/******************************************************************************/\n/* Data. */\n\nbool\t\topt_prof = false;\nbool\t\topt_prof_active = true;\nbool\t\topt_prof_thread_active_init = true;\nsize_t\t\topt_lg_prof_sample = LG_PROF_SAMPLE_DEFAULT;\nssize_t\t\topt_lg_prof_interval = LG_PROF_INTERVAL_DEFAULT;\nbool\t\topt_prof_gdump = false;\nbool\t\topt_prof_final = false;\nbool\t\topt_prof_leak = false;\nbool\t\topt_prof_accum = false;\nchar\t\topt_prof_prefix[\n    /* Minimize memory bloat for non-prof builds. */\n#ifdef JEMALLOC_PROF\n    PATH_MAX +\n#endif\n    1];\n\n/*\n * Initialized as opt_prof_active, and accessed via\n * prof_active_[gs]et{_unlocked,}().\n */\nbool\t\t\tprof_active;\nstatic malloc_mutex_t\tprof_active_mtx;\n\n/*\n * Initialized as opt_prof_thread_active_init, and accessed via\n * prof_thread_active_init_[gs]et().\n */\nstatic bool\t\tprof_thread_active_init;\nstatic malloc_mutex_t\tprof_thread_active_init_mtx;\n\n/*\n * Initialized as opt_prof_gdump, and accessed via\n * prof_gdump_[gs]et{_unlocked,}().\n */\nbool\t\t\tprof_gdump_val;\nstatic malloc_mutex_t\tprof_gdump_mtx;\n\nuint64_t\tprof_interval = 0;\n\nsize_t\t\tlg_prof_sample;\n\n/*\n * Table of mutexes that are shared among gctx's.  These are leaf locks, so\n * there is no problem with using them for more than one gctx at the same time.\n * The primary motivation for this sharing though is that gctx's are ephemeral,\n * and destroying mutexes causes complications for systems that allocate when\n * creating/destroying mutexes.\n */\nstatic malloc_mutex_t\t*gctx_locks;\nstatic unsigned\t\tcum_gctxs; /* Atomic counter. */\n\n/*\n * Table of mutexes that are shared among tdata's.  No operations require\n * holding multiple tdata locks, so there is no problem with using them for more\n * than one tdata at the same time, even though a gctx lock may be acquired\n * while holding a tdata lock.\n */\nstatic malloc_mutex_t\t*tdata_locks;\n\n/*\n * Global hash of (prof_bt_t *)-->(prof_gctx_t *).  This is the master data\n * structure that knows about all backtraces currently captured.\n */\nstatic ckh_t\t\tbt2gctx;\nstatic malloc_mutex_t\tbt2gctx_mtx;\n\n/*\n * Tree of all extant prof_tdata_t structures, regardless of state,\n * {attached,detached,expired}.\n */\nstatic prof_tdata_tree_t\ttdatas;\nstatic malloc_mutex_t\ttdatas_mtx;\n\nstatic uint64_t\t\tnext_thr_uid;\nstatic malloc_mutex_t\tnext_thr_uid_mtx;\n\nstatic malloc_mutex_t\tprof_dump_seq_mtx;\nstatic uint64_t\t\tprof_dump_seq;\nstatic uint64_t\t\tprof_dump_iseq;\nstatic uint64_t\t\tprof_dump_mseq;\nstatic uint64_t\t\tprof_dump_useq;\n\n/*\n * This buffer is rather large for stack allocation, so use a single buffer for\n * all profile dumps.\n */\nstatic malloc_mutex_t\tprof_dump_mtx;\nstatic char\t\tprof_dump_buf[\n    /* Minimize memory bloat for non-prof builds. */\n#ifdef JEMALLOC_PROF\n    PROF_DUMP_BUFSIZE\n#else\n    1\n#endif\n];\nstatic size_t\t\tprof_dump_buf_end;\nstatic int\t\tprof_dump_fd;\n\n/* Do not dump any profiles until bootstrapping is complete. */\nstatic bool\t\tprof_booted = false;\n\n/******************************************************************************/\n/*\n * Function prototypes for static functions that are referenced prior to\n * definition.\n */\n\nstatic bool\tprof_tctx_should_destroy(prof_tctx_t *tctx);\nstatic void\tprof_tctx_destroy(tsd_t *tsd, prof_tctx_t *tctx);\nstatic bool\tprof_tdata_should_destroy(prof_tdata_t *tdata,\n    bool even_if_attached);\nstatic void\tprof_tdata_destroy(tsd_t *tsd, prof_tdata_t *tdata,\n    bool even_if_attached);\nstatic char\t*prof_thread_name_alloc(tsd_t *tsd, const char *thread_name);\n\n/******************************************************************************/\n/* Red-black trees. */\n\nJEMALLOC_INLINE_C int\nprof_tctx_comp(const prof_tctx_t *a, const prof_tctx_t *b)\n{\n\tuint64_t a_thr_uid = a->thr_uid;\n\tuint64_t b_thr_uid = b->thr_uid;\n\tint ret = (a_thr_uid > b_thr_uid) - (a_thr_uid < b_thr_uid);\n\tif (ret == 0) {\n\t\tuint64_t a_thr_discrim = a->thr_discrim;\n\t\tuint64_t b_thr_discrim = b->thr_discrim;\n\t\tret = (a_thr_discrim > b_thr_discrim) - (a_thr_discrim <\n\t\t    b_thr_discrim);\n\t\tif (ret == 0) {\n\t\t\tuint64_t a_tctx_uid = a->tctx_uid;\n\t\t\tuint64_t b_tctx_uid = b->tctx_uid;\n\t\t\tret = (a_tctx_uid > b_tctx_uid) - (a_tctx_uid <\n\t\t\t    b_tctx_uid);\n\t\t}\n\t}\n\treturn (ret);\n}\n\nrb_gen(static UNUSED, tctx_tree_, prof_tctx_tree_t, prof_tctx_t,\n    tctx_link, prof_tctx_comp)\n\nJEMALLOC_INLINE_C int\nprof_gctx_comp(const prof_gctx_t *a, const prof_gctx_t *b)\n{\n\tunsigned a_len = a->bt.len;\n\tunsigned b_len = b->bt.len;\n\tunsigned comp_len = (a_len < b_len) ? a_len : b_len;\n\tint ret = memcmp(a->bt.vec, b->bt.vec, comp_len * sizeof(void *));\n\tif (ret == 0)\n\t\tret = (a_len > b_len) - (a_len < b_len);\n\treturn (ret);\n}\n\nrb_gen(static UNUSED, gctx_tree_, prof_gctx_tree_t, prof_gctx_t, dump_link,\n    prof_gctx_comp)\n\nJEMALLOC_INLINE_C int\nprof_tdata_comp(const prof_tdata_t *a, const prof_tdata_t *b)\n{\n\tint ret;\n\tuint64_t a_uid = a->thr_uid;\n\tuint64_t b_uid = b->thr_uid;\n\n\tret = ((a_uid > b_uid) - (a_uid < b_uid));\n\tif (ret == 0) {\n\t\tuint64_t a_discrim = a->thr_discrim;\n\t\tuint64_t b_discrim = b->thr_discrim;\n\n\t\tret = ((a_discrim > b_discrim) - (a_discrim < b_discrim));\n\t}\n\treturn (ret);\n}\n\nrb_gen(static UNUSED, tdata_tree_, prof_tdata_tree_t, prof_tdata_t, tdata_link,\n    prof_tdata_comp)\n\n/******************************************************************************/\n\nvoid\nprof_alloc_rollback(tsd_t *tsd, prof_tctx_t *tctx, bool updated)\n{\n\tprof_tdata_t *tdata;\n\n\tcassert(config_prof);\n\n\tif (updated) {\n\t\t/*\n\t\t * Compute a new sample threshold.  This isn't very important in\n\t\t * practice, because this function is rarely executed, so the\n\t\t * potential for sample bias is minimal except in contrived\n\t\t * programs.\n\t\t */\n\t\ttdata = prof_tdata_get(tsd, true);\n\t\tif (tdata != NULL)\n\t\t\tprof_sample_threshold_update(tdata);\n\t}\n\n\tif ((uintptr_t)tctx > (uintptr_t)1U) {\n\t\tmalloc_mutex_lock(tctx->tdata->lock);\n\t\ttctx->prepared = false;\n\t\tif (prof_tctx_should_destroy(tctx))\n\t\t\tprof_tctx_destroy(tsd, tctx);\n\t\telse\n\t\t\tmalloc_mutex_unlock(tctx->tdata->lock);\n\t}\n}\n\nvoid\nprof_malloc_sample_object(const void *ptr, size_t usize, prof_tctx_t *tctx)\n{\n\n\tprof_tctx_set(ptr, usize, tctx);\n\n\tmalloc_mutex_lock(tctx->tdata->lock);\n\ttctx->cnts.curobjs++;\n\ttctx->cnts.curbytes += usize;\n\tif (opt_prof_accum) {\n\t\ttctx->cnts.accumobjs++;\n\t\ttctx->cnts.accumbytes += usize;\n\t}\n\ttctx->prepared = false;\n\tmalloc_mutex_unlock(tctx->tdata->lock);\n}\n\nvoid\nprof_free_sampled_object(tsd_t *tsd, size_t usize, prof_tctx_t *tctx)\n{\n\n\tmalloc_mutex_lock(tctx->tdata->lock);\n\tassert(tctx->cnts.curobjs > 0);\n\tassert(tctx->cnts.curbytes >= usize);\n\ttctx->cnts.curobjs--;\n\ttctx->cnts.curbytes -= usize;\n\n\tif (prof_tctx_should_destroy(tctx))\n\t\tprof_tctx_destroy(tsd, tctx);\n\telse\n\t\tmalloc_mutex_unlock(tctx->tdata->lock);\n}\n\nvoid\nbt_init(prof_bt_t *bt, void **vec)\n{\n\n\tcassert(config_prof);\n\n\tbt->vec = vec;\n\tbt->len = 0;\n}\n\nJEMALLOC_INLINE_C void\nprof_enter(tsd_t *tsd, prof_tdata_t *tdata)\n{\n\n\tcassert(config_prof);\n\tassert(tdata == prof_tdata_get(tsd, false));\n\n\tif (tdata != NULL) {\n\t\tassert(!tdata->enq);\n\t\ttdata->enq = true;\n\t}\n\n\tmalloc_mutex_lock(&bt2gctx_mtx);\n}\n\nJEMALLOC_INLINE_C void\nprof_leave(tsd_t *tsd, prof_tdata_t *tdata)\n{\n\n\tcassert(config_prof);\n\tassert(tdata == prof_tdata_get(tsd, false));\n\n\tmalloc_mutex_unlock(&bt2gctx_mtx);\n\n\tif (tdata != NULL) {\n\t\tbool idump, gdump;\n\n\t\tassert(tdata->enq);\n\t\ttdata->enq = false;\n\t\tidump = tdata->enq_idump;\n\t\ttdata->enq_idump = false;\n\t\tgdump = tdata->enq_gdump;\n\t\ttdata->enq_gdump = false;\n\n\t\tif (idump)\n\t\t\tprof_idump();\n\t\tif (gdump)\n\t\t\tprof_gdump();\n\t}\n}\n\n#ifdef JEMALLOC_PROF_LIBUNWIND\nvoid\nprof_backtrace(prof_bt_t *bt)\n{\n\tint nframes;\n\n\tcassert(config_prof);\n\tassert(bt->len == 0);\n\tassert(bt->vec != NULL);\n\n\tnframes = unw_backtrace(bt->vec, PROF_BT_MAX);\n\tif (nframes <= 0)\n\t\treturn;\n\tbt->len = nframes;\n}\n#elif (defined(JEMALLOC_PROF_LIBGCC))\nstatic _Unwind_Reason_Code\nprof_unwind_init_callback(struct _Unwind_Context *context, void *arg)\n{\n\n\tcassert(config_prof);\n\n\treturn (_URC_NO_REASON);\n}\n\nstatic _Unwind_Reason_Code\nprof_unwind_callback(struct _Unwind_Context *context, void *arg)\n{\n\tprof_unwind_data_t *data = (prof_unwind_data_t *)arg;\n\tvoid *ip;\n\n\tcassert(config_prof);\n\n\tip = (void *)_Unwind_GetIP(context);\n\tif (ip == NULL)\n\t\treturn (_URC_END_OF_STACK);\n\tdata->bt->vec[data->bt->len] = ip;\n\tdata->bt->len++;\n\tif (data->bt->len == data->max)\n\t\treturn (_URC_END_OF_STACK);\n\n\treturn (_URC_NO_REASON);\n}\n\nvoid\nprof_backtrace(prof_bt_t *bt)\n{\n\tprof_unwind_data_t data = {bt, PROF_BT_MAX};\n\n\tcassert(config_prof);\n\n\t_Unwind_Backtrace(prof_unwind_callback, &data);\n}\n#elif (defined(JEMALLOC_PROF_GCC))\nvoid\nprof_backtrace(prof_bt_t *bt)\n{\n#define\tBT_FRAME(i)\t\t\t\t\t\t\t\\\n\tif ((i) < PROF_BT_MAX) {\t\t\t\t\t\\\n\t\tvoid *p;\t\t\t\t\t\t\\\n\t\tif (__builtin_frame_address(i) == 0)\t\t\t\\\n\t\t\treturn;\t\t\t\t\t\t\\\n\t\tp = __builtin_return_address(i);\t\t\t\\\n\t\tif (p == NULL)\t\t\t\t\t\t\\\n\t\t\treturn;\t\t\t\t\t\t\\\n\t\tbt->vec[(i)] = p;\t\t\t\t\t\\\n\t\tbt->len = (i) + 1;\t\t\t\t\t\\\n\t} else\t\t\t\t\t\t\t\t\\\n\t\treturn;\n\n\tcassert(config_prof);\n\n\tBT_FRAME(0)\n\tBT_FRAME(1)\n\tBT_FRAME(2)\n\tBT_FRAME(3)\n\tBT_FRAME(4)\n\tBT_FRAME(5)\n\tBT_FRAME(6)\n\tBT_FRAME(7)\n\tBT_FRAME(8)\n\tBT_FRAME(9)\n\n\tBT_FRAME(10)\n\tBT_FRAME(11)\n\tBT_FRAME(12)\n\tBT_FRAME(13)\n\tBT_FRAME(14)\n\tBT_FRAME(15)\n\tBT_FRAME(16)\n\tBT_FRAME(17)\n\tBT_FRAME(18)\n\tBT_FRAME(19)\n\n\tBT_FRAME(20)\n\tBT_FRAME(21)\n\tBT_FRAME(22)\n\tBT_FRAME(23)\n\tBT_FRAME(24)\n\tBT_FRAME(25)\n\tBT_FRAME(26)\n\tBT_FRAME(27)\n\tBT_FRAME(28)\n\tBT_FRAME(29)\n\n\tBT_FRAME(30)\n\tBT_FRAME(31)\n\tBT_FRAME(32)\n\tBT_FRAME(33)\n\tBT_FRAME(34)\n\tBT_FRAME(35)\n\tBT_FRAME(36)\n\tBT_FRAME(37)\n\tBT_FRAME(38)\n\tBT_FRAME(39)\n\n\tBT_FRAME(40)\n\tBT_FRAME(41)\n\tBT_FRAME(42)\n\tBT_FRAME(43)\n\tBT_FRAME(44)\n\tBT_FRAME(45)\n\tBT_FRAME(46)\n\tBT_FRAME(47)\n\tBT_FRAME(48)\n\tBT_FRAME(49)\n\n\tBT_FRAME(50)\n\tBT_FRAME(51)\n\tBT_FRAME(52)\n\tBT_FRAME(53)\n\tBT_FRAME(54)\n\tBT_FRAME(55)\n\tBT_FRAME(56)\n\tBT_FRAME(57)\n\tBT_FRAME(58)\n\tBT_FRAME(59)\n\n\tBT_FRAME(60)\n\tBT_FRAME(61)\n\tBT_FRAME(62)\n\tBT_FRAME(63)\n\tBT_FRAME(64)\n\tBT_FRAME(65)\n\tBT_FRAME(66)\n\tBT_FRAME(67)\n\tBT_FRAME(68)\n\tBT_FRAME(69)\n\n\tBT_FRAME(70)\n\tBT_FRAME(71)\n\tBT_FRAME(72)\n\tBT_FRAME(73)\n\tBT_FRAME(74)\n\tBT_FRAME(75)\n\tBT_FRAME(76)\n\tBT_FRAME(77)\n\tBT_FRAME(78)\n\tBT_FRAME(79)\n\n\tBT_FRAME(80)\n\tBT_FRAME(81)\n\tBT_FRAME(82)\n\tBT_FRAME(83)\n\tBT_FRAME(84)\n\tBT_FRAME(85)\n\tBT_FRAME(86)\n\tBT_FRAME(87)\n\tBT_FRAME(88)\n\tBT_FRAME(89)\n\n\tBT_FRAME(90)\n\tBT_FRAME(91)\n\tBT_FRAME(92)\n\tBT_FRAME(93)\n\tBT_FRAME(94)\n\tBT_FRAME(95)\n\tBT_FRAME(96)\n\tBT_FRAME(97)\n\tBT_FRAME(98)\n\tBT_FRAME(99)\n\n\tBT_FRAME(100)\n\tBT_FRAME(101)\n\tBT_FRAME(102)\n\tBT_FRAME(103)\n\tBT_FRAME(104)\n\tBT_FRAME(105)\n\tBT_FRAME(106)\n\tBT_FRAME(107)\n\tBT_FRAME(108)\n\tBT_FRAME(109)\n\n\tBT_FRAME(110)\n\tBT_FRAME(111)\n\tBT_FRAME(112)\n\tBT_FRAME(113)\n\tBT_FRAME(114)\n\tBT_FRAME(115)\n\tBT_FRAME(116)\n\tBT_FRAME(117)\n\tBT_FRAME(118)\n\tBT_FRAME(119)\n\n\tBT_FRAME(120)\n\tBT_FRAME(121)\n\tBT_FRAME(122)\n\tBT_FRAME(123)\n\tBT_FRAME(124)\n\tBT_FRAME(125)\n\tBT_FRAME(126)\n\tBT_FRAME(127)\n#undef BT_FRAME\n}\n#else\nvoid\nprof_backtrace(prof_bt_t *bt)\n{\n\n\tcassert(config_prof);\n\tnot_reached();\n}\n#endif\n\nstatic malloc_mutex_t *\nprof_gctx_mutex_choose(void)\n{\n\tunsigned ngctxs = atomic_add_u(&cum_gctxs, 1);\n\n\treturn (&gctx_locks[(ngctxs - 1) % PROF_NCTX_LOCKS]);\n}\n\nstatic malloc_mutex_t *\nprof_tdata_mutex_choose(uint64_t thr_uid)\n{\n\n\treturn (&tdata_locks[thr_uid % PROF_NTDATA_LOCKS]);\n}\n\nstatic prof_gctx_t *\nprof_gctx_create(tsd_t *tsd, prof_bt_t *bt)\n{\n\t/*\n\t * Create a single allocation that has space for vec of length bt->len.\n\t */\n\tsize_t size = offsetof(prof_gctx_t, vec) + (bt->len * sizeof(void *));\n\tprof_gctx_t *gctx = (prof_gctx_t *)iallocztm(tsd, size,\n\t    size2index(size), false, tcache_get(tsd, true), true, NULL, true);\n\tif (gctx == NULL)\n\t\treturn (NULL);\n\tgctx->lock = prof_gctx_mutex_choose();\n\t/*\n\t * Set nlimbo to 1, in order to avoid a race condition with\n\t * prof_tctx_destroy()/prof_gctx_try_destroy().\n\t */\n\tgctx->nlimbo = 1;\n\ttctx_tree_new(&gctx->tctxs);\n\t/* Duplicate bt. */\n\tmemcpy(gctx->vec, bt->vec, bt->len * sizeof(void *));\n\tgctx->bt.vec = gctx->vec;\n\tgctx->bt.len = bt->len;\n\treturn (gctx);\n}\n\nstatic void\nprof_gctx_try_destroy(tsd_t *tsd, prof_tdata_t *tdata_self, prof_gctx_t *gctx,\n    prof_tdata_t *tdata)\n{\n\n\tcassert(config_prof);\n\n\t/*\n\t * Check that gctx is still unused by any thread cache before destroying\n\t * it.  prof_lookup() increments gctx->nlimbo in order to avoid a race\n\t * condition with this function, as does prof_tctx_destroy() in order to\n\t * avoid a race between the main body of prof_tctx_destroy() and entry\n\t * into this function.\n\t */\n\tprof_enter(tsd, tdata_self);\n\tmalloc_mutex_lock(gctx->lock);\n\tassert(gctx->nlimbo != 0);\n\tif (tctx_tree_empty(&gctx->tctxs) && gctx->nlimbo == 1) {\n\t\t/* Remove gctx from bt2gctx. */\n\t\tif (ckh_remove(tsd, &bt2gctx, &gctx->bt, NULL, NULL))\n\t\t\tnot_reached();\n\t\tprof_leave(tsd, tdata_self);\n\t\t/* Destroy gctx. */\n\t\tmalloc_mutex_unlock(gctx->lock);\n\t\tidalloctm(tsd, gctx, tcache_get(tsd, false), true, true);\n\t} else {\n\t\t/*\n\t\t * Compensate for increment in prof_tctx_destroy() or\n\t\t * prof_lookup().\n\t\t */\n\t\tgctx->nlimbo--;\n\t\tmalloc_mutex_unlock(gctx->lock);\n\t\tprof_leave(tsd, tdata_self);\n\t}\n}\n\n/* tctx->tdata->lock must be held. */\nstatic bool\nprof_tctx_should_destroy(prof_tctx_t *tctx)\n{\n\n\tif (opt_prof_accum)\n\t\treturn (false);\n\tif (tctx->cnts.curobjs != 0)\n\t\treturn (false);\n\tif (tctx->prepared)\n\t\treturn (false);\n\treturn (true);\n}\n\nstatic bool\nprof_gctx_should_destroy(prof_gctx_t *gctx)\n{\n\n\tif (opt_prof_accum)\n\t\treturn (false);\n\tif (!tctx_tree_empty(&gctx->tctxs))\n\t\treturn (false);\n\tif (gctx->nlimbo != 0)\n\t\treturn (false);\n\treturn (true);\n}\n\n/* tctx->tdata->lock is held upon entry, and released before return. */\nstatic void\nprof_tctx_destroy(tsd_t *tsd, prof_tctx_t *tctx)\n{\n\tprof_tdata_t *tdata = tctx->tdata;\n\tprof_gctx_t *gctx = tctx->gctx;\n\tbool destroy_tdata, destroy_tctx, destroy_gctx;\n\n\tassert(tctx->cnts.curobjs == 0);\n\tassert(tctx->cnts.curbytes == 0);\n\tassert(!opt_prof_accum);\n\tassert(tctx->cnts.accumobjs == 0);\n\tassert(tctx->cnts.accumbytes == 0);\n\n\tckh_remove(tsd, &tdata->bt2tctx, &gctx->bt, NULL, NULL);\n\tdestroy_tdata = prof_tdata_should_destroy(tdata, false);\n\tmalloc_mutex_unlock(tdata->lock);\n\n\tmalloc_mutex_lock(gctx->lock);\n\tswitch (tctx->state) {\n\tcase prof_tctx_state_nominal:\n\t\ttctx_tree_remove(&gctx->tctxs, tctx);\n\t\tdestroy_tctx = true;\n\t\tif (prof_gctx_should_destroy(gctx)) {\n\t\t\t/*\n\t\t\t * Increment gctx->nlimbo in order to keep another\n\t\t\t * thread from winning the race to destroy gctx while\n\t\t\t * this one has gctx->lock dropped.  Without this, it\n\t\t\t * would be possible for another thread to:\n\t\t\t *\n\t\t\t * 1) Sample an allocation associated with gctx.\n\t\t\t * 2) Deallocate the sampled object.\n\t\t\t * 3) Successfully prof_gctx_try_destroy(gctx).\n\t\t\t *\n\t\t\t * The result would be that gctx no longer exists by the\n\t\t\t * time this thread accesses it in\n\t\t\t * prof_gctx_try_destroy().\n\t\t\t */\n\t\t\tgctx->nlimbo++;\n\t\t\tdestroy_gctx = true;\n\t\t} else\n\t\t\tdestroy_gctx = false;\n\t\tbreak;\n\tcase prof_tctx_state_dumping:\n\t\t/*\n\t\t * A dumping thread needs tctx to remain valid until dumping\n\t\t * has finished.  Change state such that the dumping thread will\n\t\t * complete destruction during a late dump iteration phase.\n\t\t */\n\t\ttctx->state = prof_tctx_state_purgatory;\n\t\tdestroy_tctx = false;\n\t\tdestroy_gctx = false;\n\t\tbreak;\n\tdefault:\n\t\tnot_reached();\n\t\tdestroy_tctx = false;\n\t\tdestroy_gctx = false;\n\t}\n\tmalloc_mutex_unlock(gctx->lock);\n\tif (destroy_gctx) {\n\t\tprof_gctx_try_destroy(tsd, prof_tdata_get(tsd, false), gctx,\n\t\t    tdata);\n\t}\n\n\tif (destroy_tdata)\n\t\tprof_tdata_destroy(tsd, tdata, false);\n\n\tif (destroy_tctx)\n\t\tidalloctm(tsd, tctx, tcache_get(tsd, false), true, true);\n}\n\nstatic bool\nprof_lookup_global(tsd_t *tsd, prof_bt_t *bt, prof_tdata_t *tdata,\n    void **p_btkey, prof_gctx_t **p_gctx, bool *p_new_gctx)\n{\n\tunion {\n\t\tprof_gctx_t\t*p;\n\t\tvoid\t\t*v;\n\t} gctx;\n\tunion {\n\t\tprof_bt_t\t*p;\n\t\tvoid\t\t*v;\n\t} btkey;\n\tbool new_gctx;\n\n\tprof_enter(tsd, tdata);\n\tif (ckh_search(&bt2gctx, bt, &btkey.v, &gctx.v)) {\n\t\t/* bt has never been seen before.  Insert it. */\n\t\tgctx.p = prof_gctx_create(tsd, bt);\n\t\tif (gctx.v == NULL) {\n\t\t\tprof_leave(tsd, tdata);\n\t\t\treturn (true);\n\t\t}\n\t\tbtkey.p = &gctx.p->bt;\n\t\tif (ckh_insert(tsd, &bt2gctx, btkey.v, gctx.v)) {\n\t\t\t/* OOM. */\n\t\t\tprof_leave(tsd, tdata);\n\t\t\tidalloctm(tsd, gctx.v, tcache_get(tsd, false), true,\n\t\t\t    true);\n\t\t\treturn (true);\n\t\t}\n\t\tnew_gctx = true;\n\t} else {\n\t\t/*\n\t\t * Increment nlimbo, in order to avoid a race condition with\n\t\t * prof_tctx_destroy()/prof_gctx_try_destroy().\n\t\t */\n\t\tmalloc_mutex_lock(gctx.p->lock);\n\t\tgctx.p->nlimbo++;\n\t\tmalloc_mutex_unlock(gctx.p->lock);\n\t\tnew_gctx = false;\n\t}\n\tprof_leave(tsd, tdata);\n\n\t*p_btkey = btkey.v;\n\t*p_gctx = gctx.p;\n\t*p_new_gctx = new_gctx;\n\treturn (false);\n}\n\nprof_tctx_t *\nprof_lookup(tsd_t *tsd, prof_bt_t *bt)\n{\n\tunion {\n\t\tprof_tctx_t\t*p;\n\t\tvoid\t\t*v;\n\t} ret;\n\tprof_tdata_t *tdata;\n\tbool not_found;\n\n\tcassert(config_prof);\n\n\ttdata = prof_tdata_get(tsd, false);\n\tif (tdata == NULL)\n\t\treturn (NULL);\n\n\tmalloc_mutex_lock(tdata->lock);\n\tnot_found = ckh_search(&tdata->bt2tctx, bt, NULL, &ret.v);\n\tif (!not_found) /* Note double negative! */\n\t\tret.p->prepared = true;\n\tmalloc_mutex_unlock(tdata->lock);\n\tif (not_found) {\n\t\ttcache_t *tcache;\n\t\tvoid *btkey;\n\t\tprof_gctx_t *gctx;\n\t\tbool new_gctx, error;\n\n\t\t/*\n\t\t * This thread's cache lacks bt.  Look for it in the global\n\t\t * cache.\n\t\t */\n\t\tif (prof_lookup_global(tsd, bt, tdata, &btkey, &gctx,\n\t\t    &new_gctx))\n\t\t\treturn (NULL);\n\n\t\t/* Link a prof_tctx_t into gctx for this thread. */\n\t\ttcache = tcache_get(tsd, true);\n\t\tret.v = iallocztm(tsd, sizeof(prof_tctx_t),\n\t\t    size2index(sizeof(prof_tctx_t)), false, tcache, true, NULL,\n\t\t    true);\n\t\tif (ret.p == NULL) {\n\t\t\tif (new_gctx)\n\t\t\t\tprof_gctx_try_destroy(tsd, tdata, gctx, tdata);\n\t\t\treturn (NULL);\n\t\t}\n\t\tret.p->tdata = tdata;\n\t\tret.p->thr_uid = tdata->thr_uid;\n\t\tret.p->thr_discrim = tdata->thr_discrim;\n\t\tmemset(&ret.p->cnts, 0, sizeof(prof_cnt_t));\n\t\tret.p->gctx = gctx;\n\t\tret.p->tctx_uid = tdata->tctx_uid_next++;\n\t\tret.p->prepared = true;\n\t\tret.p->state = prof_tctx_state_initializing;\n\t\tmalloc_mutex_lock(tdata->lock);\n\t\terror = ckh_insert(tsd, &tdata->bt2tctx, btkey, ret.v);\n\t\tmalloc_mutex_unlock(tdata->lock);\n\t\tif (error) {\n\t\t\tif (new_gctx)\n\t\t\t\tprof_gctx_try_destroy(tsd, tdata, gctx, tdata);\n\t\t\tidalloctm(tsd, ret.v, tcache, true, true);\n\t\t\treturn (NULL);\n\t\t}\n\t\tmalloc_mutex_lock(gctx->lock);\n\t\tret.p->state = prof_tctx_state_nominal;\n\t\ttctx_tree_insert(&gctx->tctxs, ret.p);\n\t\tgctx->nlimbo--;\n\t\tmalloc_mutex_unlock(gctx->lock);\n\t}\n\n\treturn (ret.p);\n}\n\nvoid\nprof_sample_threshold_update(prof_tdata_t *tdata)\n{\n\t/*\n\t * The body of this function is compiled out unless heap profiling is\n\t * enabled, so that it is possible to compile jemalloc with floating\n\t * point support completely disabled.  Avoiding floating point code is\n\t * important on memory-constrained systems, but it also enables a\n\t * workaround for versions of glibc that don't properly save/restore\n\t * floating point registers during dynamic lazy symbol loading (which\n\t * internally calls into whatever malloc implementation happens to be\n\t * integrated into the application).  Note that some compilers (e.g.\n\t * gcc 4.8) may use floating point registers for fast memory moves, so\n\t * jemalloc must be compiled with such optimizations disabled (e.g.\n\t * -mno-sse) in order for the workaround to be complete.\n\t */\n#ifdef JEMALLOC_PROF\n\tuint64_t r;\n\tdouble u;\n\n\tif (!config_prof)\n\t\treturn;\n\n\tif (lg_prof_sample == 0) {\n\t\ttdata->bytes_until_sample = 0;\n\t\treturn;\n\t}\n\n\t/*\n\t * Compute sample interval as a geometrically distributed random\n\t * variable with mean (2^lg_prof_sample).\n\t *\n\t *                             __        __\n\t *                             |  log(u)  |                     1\n\t * tdata->bytes_until_sample = | -------- |, where p = ---------------\n\t *                             | log(1-p) |             lg_prof_sample\n\t *                                                     2\n\t *\n\t * For more information on the math, see:\n\t *\n\t *   Non-Uniform Random Variate Generation\n\t *   Luc Devroye\n\t *   Springer-Verlag, New York, 1986\n\t *   pp 500\n\t *   (http://luc.devroye.org/rnbookindex.html)\n\t */\n\tr = prng_lg_range(&tdata->prng_state, 53);\n\tu = (double)r * (1.0/9007199254740992.0L);\n\ttdata->bytes_until_sample = (uint64_t)(log(u) /\n\t    log(1.0 - (1.0 / (double)((uint64_t)1U << lg_prof_sample))))\n\t    + (uint64_t)1U;\n#endif\n}\n\n#ifdef JEMALLOC_JET\nstatic prof_tdata_t *\nprof_tdata_count_iter(prof_tdata_tree_t *tdatas, prof_tdata_t *tdata, void *arg)\n{\n\tsize_t *tdata_count = (size_t *)arg;\n\n\t(*tdata_count)++;\n\n\treturn (NULL);\n}\n\nsize_t\nprof_tdata_count(void)\n{\n\tsize_t tdata_count = 0;\n\n\tmalloc_mutex_lock(&tdatas_mtx);\n\ttdata_tree_iter(&tdatas, NULL, prof_tdata_count_iter,\n\t    (void *)&tdata_count);\n\tmalloc_mutex_unlock(&tdatas_mtx);\n\n\treturn (tdata_count);\n}\n#endif\n\n#ifdef JEMALLOC_JET\nsize_t\nprof_bt_count(void)\n{\n\tsize_t bt_count;\n\ttsd_t *tsd;\n\tprof_tdata_t *tdata;\n\n\ttsd = tsd_fetch();\n\ttdata = prof_tdata_get(tsd, false);\n\tif (tdata == NULL)\n\t\treturn (0);\n\n\tmalloc_mutex_lock(&bt2gctx_mtx);\n\tbt_count = ckh_count(&bt2gctx);\n\tmalloc_mutex_unlock(&bt2gctx_mtx);\n\n\treturn (bt_count);\n}\n#endif\n\n#ifdef JEMALLOC_JET\n#undef prof_dump_open\n#define\tprof_dump_open JEMALLOC_N(prof_dump_open_impl)\n#endif\nstatic int\nprof_dump_open(bool propagate_err, const char *filename)\n{\n\tint fd;\n\n\tfd = creat(filename, 0644);\n\tif (fd == -1 && !propagate_err) {\n\t\tmalloc_printf(\"<jemalloc>: creat(\\\"%s\\\"), 0644) failed\\n\",\n\t\t    filename);\n\t\tif (opt_abort)\n\t\t\tabort();\n\t}\n\n\treturn (fd);\n}\n#ifdef JEMALLOC_JET\n#undef prof_dump_open\n#define\tprof_dump_open JEMALLOC_N(prof_dump_open)\nprof_dump_open_t *prof_dump_open = JEMALLOC_N(prof_dump_open_impl);\n#endif\n\nstatic bool\nprof_dump_flush(bool propagate_err)\n{\n\tbool ret = false;\n\tssize_t err;\n\n\tcassert(config_prof);\n\n\terr = write(prof_dump_fd, prof_dump_buf, prof_dump_buf_end);\n\tif (err == -1) {\n\t\tif (!propagate_err) {\n\t\t\tmalloc_write(\"<jemalloc>: write() failed during heap \"\n\t\t\t    \"profile flush\\n\");\n\t\t\tif (opt_abort)\n\t\t\t\tabort();\n\t\t}\n\t\tret = true;\n\t}\n\tprof_dump_buf_end = 0;\n\n\treturn (ret);\n}\n\nstatic bool\nprof_dump_close(bool propagate_err)\n{\n\tbool ret;\n\n\tassert(prof_dump_fd != -1);\n\tret = prof_dump_flush(propagate_err);\n\tclose(prof_dump_fd);\n\tprof_dump_fd = -1;\n\n\treturn (ret);\n}\n\nstatic bool\nprof_dump_write(bool propagate_err, const char *s)\n{\n\tsize_t i, slen, n;\n\n\tcassert(config_prof);\n\n\ti = 0;\n\tslen = strlen(s);\n\twhile (i < slen) {\n\t\t/* Flush the buffer if it is full. */\n\t\tif (prof_dump_buf_end == PROF_DUMP_BUFSIZE)\n\t\t\tif (prof_dump_flush(propagate_err) && propagate_err)\n\t\t\t\treturn (true);\n\n\t\tif (prof_dump_buf_end + slen <= PROF_DUMP_BUFSIZE) {\n\t\t\t/* Finish writing. */\n\t\t\tn = slen - i;\n\t\t} else {\n\t\t\t/* Write as much of s as will fit. */\n\t\t\tn = PROF_DUMP_BUFSIZE - prof_dump_buf_end;\n\t\t}\n\t\tmemcpy(&prof_dump_buf[prof_dump_buf_end], &s[i], n);\n\t\tprof_dump_buf_end += n;\n\t\ti += n;\n\t}\n\n\treturn (false);\n}\n\nJEMALLOC_FORMAT_PRINTF(2, 3)\nstatic bool\nprof_dump_printf(bool propagate_err, const char *format, ...)\n{\n\tbool ret;\n\tva_list ap;\n\tchar buf[PROF_PRINTF_BUFSIZE];\n\n\tva_start(ap, format);\n\tmalloc_vsnprintf(buf, sizeof(buf), format, ap);\n\tva_end(ap);\n\tret = prof_dump_write(propagate_err, buf);\n\n\treturn (ret);\n}\n\n/* tctx->tdata->lock is held. */\nstatic void\nprof_tctx_merge_tdata(prof_tctx_t *tctx, prof_tdata_t *tdata)\n{\n\n\tmalloc_mutex_lock(tctx->gctx->lock);\n\n\tswitch (tctx->state) {\n\tcase prof_tctx_state_initializing:\n\t\tmalloc_mutex_unlock(tctx->gctx->lock);\n\t\treturn;\n\tcase prof_tctx_state_nominal:\n\t\ttctx->state = prof_tctx_state_dumping;\n\t\tmalloc_mutex_unlock(tctx->gctx->lock);\n\n\t\tmemcpy(&tctx->dump_cnts, &tctx->cnts, sizeof(prof_cnt_t));\n\n\t\ttdata->cnt_summed.curobjs += tctx->dump_cnts.curobjs;\n\t\ttdata->cnt_summed.curbytes += tctx->dump_cnts.curbytes;\n\t\tif (opt_prof_accum) {\n\t\t\ttdata->cnt_summed.accumobjs +=\n\t\t\t    tctx->dump_cnts.accumobjs;\n\t\t\ttdata->cnt_summed.accumbytes +=\n\t\t\t    tctx->dump_cnts.accumbytes;\n\t\t}\n\t\tbreak;\n\tcase prof_tctx_state_dumping:\n\tcase prof_tctx_state_purgatory:\n\t\tnot_reached();\n\t}\n}\n\n/* gctx->lock is held. */\nstatic void\nprof_tctx_merge_gctx(prof_tctx_t *tctx, prof_gctx_t *gctx)\n{\n\n\tgctx->cnt_summed.curobjs += tctx->dump_cnts.curobjs;\n\tgctx->cnt_summed.curbytes += tctx->dump_cnts.curbytes;\n\tif (opt_prof_accum) {\n\t\tgctx->cnt_summed.accumobjs += tctx->dump_cnts.accumobjs;\n\t\tgctx->cnt_summed.accumbytes += tctx->dump_cnts.accumbytes;\n\t}\n}\n\n/* tctx->gctx is held. */\nstatic prof_tctx_t *\nprof_tctx_merge_iter(prof_tctx_tree_t *tctxs, prof_tctx_t *tctx, void *arg)\n{\n\n\tswitch (tctx->state) {\n\tcase prof_tctx_state_nominal:\n\t\t/* New since dumping started; ignore. */\n\t\tbreak;\n\tcase prof_tctx_state_dumping:\n\tcase prof_tctx_state_purgatory:\n\t\tprof_tctx_merge_gctx(tctx, tctx->gctx);\n\t\tbreak;\n\tdefault:\n\t\tnot_reached();\n\t}\n\n\treturn (NULL);\n}\n\n/* gctx->lock is held. */\nstatic prof_tctx_t *\nprof_tctx_dump_iter(prof_tctx_tree_t *tctxs, prof_tctx_t *tctx, void *arg)\n{\n\tbool propagate_err = *(bool *)arg;\n\n\tswitch (tctx->state) {\n\tcase prof_tctx_state_initializing:\n\tcase prof_tctx_state_nominal:\n\t\t/* Not captured by this dump. */\n\t\tbreak;\n\tcase prof_tctx_state_dumping:\n\tcase prof_tctx_state_purgatory:\n\t\tif (prof_dump_printf(propagate_err,\n\t\t    \"  t%\"FMTu64\": %\"FMTu64\": %\"FMTu64\" [%\"FMTu64\": \"\n\t\t    \"%\"FMTu64\"]\\n\", tctx->thr_uid, tctx->dump_cnts.curobjs,\n\t\t    tctx->dump_cnts.curbytes, tctx->dump_cnts.accumobjs,\n\t\t    tctx->dump_cnts.accumbytes))\n\t\t\treturn (tctx);\n\t\tbreak;\n\tdefault:\n\t\tnot_reached();\n\t}\n\treturn (NULL);\n}\n\n/* tctx->gctx is held. */\nstatic prof_tctx_t *\nprof_tctx_finish_iter(prof_tctx_tree_t *tctxs, prof_tctx_t *tctx, void *arg)\n{\n\tprof_tctx_t *ret;\n\n\tswitch (tctx->state) {\n\tcase prof_tctx_state_nominal:\n\t\t/* New since dumping started; ignore. */\n\t\tbreak;\n\tcase prof_tctx_state_dumping:\n\t\ttctx->state = prof_tctx_state_nominal;\n\t\tbreak;\n\tcase prof_tctx_state_purgatory:\n\t\tret = tctx;\n\t\tgoto label_return;\n\tdefault:\n\t\tnot_reached();\n\t}\n\n\tret = NULL;\nlabel_return:\n\treturn (ret);\n}\n\nstatic void\nprof_dump_gctx_prep(prof_gctx_t *gctx, prof_gctx_tree_t *gctxs)\n{\n\n\tcassert(config_prof);\n\n\tmalloc_mutex_lock(gctx->lock);\n\n\t/*\n\t * Increment nlimbo so that gctx won't go away before dump.\n\t * Additionally, link gctx into the dump list so that it is included in\n\t * prof_dump()'s second pass.\n\t */\n\tgctx->nlimbo++;\n\tgctx_tree_insert(gctxs, gctx);\n\n\tmemset(&gctx->cnt_summed, 0, sizeof(prof_cnt_t));\n\n\tmalloc_mutex_unlock(gctx->lock);\n}\n\nstatic prof_gctx_t *\nprof_gctx_merge_iter(prof_gctx_tree_t *gctxs, prof_gctx_t *gctx, void *arg)\n{\n\tsize_t *leak_ngctx = (size_t *)arg;\n\n\tmalloc_mutex_lock(gctx->lock);\n\ttctx_tree_iter(&gctx->tctxs, NULL, prof_tctx_merge_iter, NULL);\n\tif (gctx->cnt_summed.curobjs != 0)\n\t\t(*leak_ngctx)++;\n\tmalloc_mutex_unlock(gctx->lock);\n\n\treturn (NULL);\n}\n\nstatic void\nprof_gctx_finish(tsd_t *tsd, prof_gctx_tree_t *gctxs)\n{\n\tprof_tdata_t *tdata = prof_tdata_get(tsd, false);\n\tprof_gctx_t *gctx;\n\n\t/*\n\t * Standard tree iteration won't work here, because as soon as we\n\t * decrement gctx->nlimbo and unlock gctx, another thread can\n\t * concurrently destroy it, which will corrupt the tree.  Therefore,\n\t * tear down the tree one node at a time during iteration.\n\t */\n\twhile ((gctx = gctx_tree_first(gctxs)) != NULL) {\n\t\tgctx_tree_remove(gctxs, gctx);\n\t\tmalloc_mutex_lock(gctx->lock);\n\t\t{\n\t\t\tprof_tctx_t *next;\n\n\t\t\tnext = NULL;\n\t\t\tdo {\n\t\t\t\tprof_tctx_t *to_destroy =\n\t\t\t\t    tctx_tree_iter(&gctx->tctxs, next,\n\t\t\t\t    prof_tctx_finish_iter, NULL);\n\t\t\t\tif (to_destroy != NULL) {\n\t\t\t\t\tnext = tctx_tree_next(&gctx->tctxs,\n\t\t\t\t\t    to_destroy);\n\t\t\t\t\ttctx_tree_remove(&gctx->tctxs,\n\t\t\t\t\t    to_destroy);\n\t\t\t\t\tidalloctm(tsd, to_destroy,\n\t\t\t\t\t    tcache_get(tsd, false), true, true);\n\t\t\t\t} else\n\t\t\t\t\tnext = NULL;\n\t\t\t} while (next != NULL);\n\t\t}\n\t\tgctx->nlimbo--;\n\t\tif (prof_gctx_should_destroy(gctx)) {\n\t\t\tgctx->nlimbo++;\n\t\t\tmalloc_mutex_unlock(gctx->lock);\n\t\t\tprof_gctx_try_destroy(tsd, tdata, gctx, tdata);\n\t\t} else\n\t\t\tmalloc_mutex_unlock(gctx->lock);\n\t}\n}\n\nstatic prof_tdata_t *\nprof_tdata_merge_iter(prof_tdata_tree_t *tdatas, prof_tdata_t *tdata, void *arg)\n{\n\tprof_cnt_t *cnt_all = (prof_cnt_t *)arg;\n\n\tmalloc_mutex_lock(tdata->lock);\n\tif (!tdata->expired) {\n\t\tsize_t tabind;\n\t\tunion {\n\t\t\tprof_tctx_t\t*p;\n\t\t\tvoid\t\t*v;\n\t\t} tctx;\n\n\t\ttdata->dumping = true;\n\t\tmemset(&tdata->cnt_summed, 0, sizeof(prof_cnt_t));\n\t\tfor (tabind = 0; !ckh_iter(&tdata->bt2tctx, &tabind, NULL,\n\t\t    &tctx.v);)\n\t\t\tprof_tctx_merge_tdata(tctx.p, tdata);\n\n\t\tcnt_all->curobjs += tdata->cnt_summed.curobjs;\n\t\tcnt_all->curbytes += tdata->cnt_summed.curbytes;\n\t\tif (opt_prof_accum) {\n\t\t\tcnt_all->accumobjs += tdata->cnt_summed.accumobjs;\n\t\t\tcnt_all->accumbytes += tdata->cnt_summed.accumbytes;\n\t\t}\n\t} else\n\t\ttdata->dumping = false;\n\tmalloc_mutex_unlock(tdata->lock);\n\n\treturn (NULL);\n}\n\nstatic prof_tdata_t *\nprof_tdata_dump_iter(prof_tdata_tree_t *tdatas, prof_tdata_t *tdata, void *arg)\n{\n\tbool propagate_err = *(bool *)arg;\n\n\tif (!tdata->dumping)\n\t\treturn (NULL);\n\n\tif (prof_dump_printf(propagate_err,\n\t    \"  t%\"FMTu64\": %\"FMTu64\": %\"FMTu64\" [%\"FMTu64\": %\"FMTu64\"]%s%s\\n\",\n\t    tdata->thr_uid, tdata->cnt_summed.curobjs,\n\t    tdata->cnt_summed.curbytes, tdata->cnt_summed.accumobjs,\n\t    tdata->cnt_summed.accumbytes,\n\t    (tdata->thread_name != NULL) ? \" \" : \"\",\n\t    (tdata->thread_name != NULL) ? tdata->thread_name : \"\"))\n\t\treturn (tdata);\n\treturn (NULL);\n}\n\n#ifdef JEMALLOC_JET\n#undef prof_dump_header\n#define\tprof_dump_header JEMALLOC_N(prof_dump_header_impl)\n#endif\nstatic bool\nprof_dump_header(bool propagate_err, const prof_cnt_t *cnt_all)\n{\n\tbool ret;\n\n\tif (prof_dump_printf(propagate_err,\n\t    \"heap_v2/%\"FMTu64\"\\n\"\n\t    \"  t*: %\"FMTu64\": %\"FMTu64\" [%\"FMTu64\": %\"FMTu64\"]\\n\",\n\t    ((uint64_t)1U << lg_prof_sample), cnt_all->curobjs,\n\t    cnt_all->curbytes, cnt_all->accumobjs, cnt_all->accumbytes))\n\t\treturn (true);\n\n\tmalloc_mutex_lock(&tdatas_mtx);\n\tret = (tdata_tree_iter(&tdatas, NULL, prof_tdata_dump_iter,\n\t    (void *)&propagate_err) != NULL);\n\tmalloc_mutex_unlock(&tdatas_mtx);\n\treturn (ret);\n}\n#ifdef JEMALLOC_JET\n#undef prof_dump_header\n#define\tprof_dump_header JEMALLOC_N(prof_dump_header)\nprof_dump_header_t *prof_dump_header = JEMALLOC_N(prof_dump_header_impl);\n#endif\n\n/* gctx->lock is held. */\nstatic bool\nprof_dump_gctx(bool propagate_err, prof_gctx_t *gctx, const prof_bt_t *bt,\n    prof_gctx_tree_t *gctxs)\n{\n\tbool ret;\n\tunsigned i;\n\n\tcassert(config_prof);\n\n\t/* Avoid dumping such gctx's that have no useful data. */\n\tif ((!opt_prof_accum && gctx->cnt_summed.curobjs == 0) ||\n\t    (opt_prof_accum && gctx->cnt_summed.accumobjs == 0)) {\n\t\tassert(gctx->cnt_summed.curobjs == 0);\n\t\tassert(gctx->cnt_summed.curbytes == 0);\n\t\tassert(gctx->cnt_summed.accumobjs == 0);\n\t\tassert(gctx->cnt_summed.accumbytes == 0);\n\t\tret = false;\n\t\tgoto label_return;\n\t}\n\n\tif (prof_dump_printf(propagate_err, \"@\")) {\n\t\tret = true;\n\t\tgoto label_return;\n\t}\n\tfor (i = 0; i < bt->len; i++) {\n\t\tif (prof_dump_printf(propagate_err, \" %#\"FMTxPTR,\n\t\t    (uintptr_t)bt->vec[i])) {\n\t\t\tret = true;\n\t\t\tgoto label_return;\n\t\t}\n\t}\n\n\tif (prof_dump_printf(propagate_err,\n\t    \"\\n\"\n\t    \"  t*: %\"FMTu64\": %\"FMTu64\" [%\"FMTu64\": %\"FMTu64\"]\\n\",\n\t    gctx->cnt_summed.curobjs, gctx->cnt_summed.curbytes,\n\t    gctx->cnt_summed.accumobjs, gctx->cnt_summed.accumbytes)) {\n\t\tret = true;\n\t\tgoto label_return;\n\t}\n\n\tif (tctx_tree_iter(&gctx->tctxs, NULL, prof_tctx_dump_iter,\n\t    (void *)&propagate_err) != NULL) {\n\t\tret = true;\n\t\tgoto label_return;\n\t}\n\n\tret = false;\nlabel_return:\n\treturn (ret);\n}\n\n#ifndef _WIN32\nJEMALLOC_FORMAT_PRINTF(1, 2)\nstatic int\nprof_open_maps(const char *format, ...)\n{\n\tint mfd;\n\tva_list ap;\n\tchar filename[PATH_MAX + 1];\n\n\tva_start(ap, format);\n\tmalloc_vsnprintf(filename, sizeof(filename), format, ap);\n\tva_end(ap);\n\tmfd = open(filename, O_RDONLY);\n\n\treturn (mfd);\n}\n#endif\n\nstatic int\nprof_getpid(void)\n{\n\n#ifdef _WIN32\n\treturn (GetCurrentProcessId());\n#else\n\treturn (getpid());\n#endif\n}\n\nstatic bool\nprof_dump_maps(bool propagate_err)\n{\n\tbool ret;\n\tint mfd;\n\n\tcassert(config_prof);\n#ifdef __FreeBSD__\n\tmfd = prof_open_maps(\"/proc/curproc/map\");\n#elif defined(_WIN32)\n\tmfd = -1; // Not implemented\n#else\n\t{\n\t\tint pid = prof_getpid();\n\n\t\tmfd = prof_open_maps(\"/proc/%d/task/%d/maps\", pid, pid);\n\t\tif (mfd == -1)\n\t\t\tmfd = prof_open_maps(\"/proc/%d/maps\", pid);\n\t}\n#endif\n\tif (mfd != -1) {\n\t\tssize_t nread;\n\n\t\tif (prof_dump_write(propagate_err, \"\\nMAPPED_LIBRARIES:\\n\") &&\n\t\t    propagate_err) {\n\t\t\tret = true;\n\t\t\tgoto label_return;\n\t\t}\n\t\tnread = 0;\n\t\tdo {\n\t\t\tprof_dump_buf_end += nread;\n\t\t\tif (prof_dump_buf_end == PROF_DUMP_BUFSIZE) {\n\t\t\t\t/* Make space in prof_dump_buf before read(). */\n\t\t\t\tif (prof_dump_flush(propagate_err) &&\n\t\t\t\t    propagate_err) {\n\t\t\t\t\tret = true;\n\t\t\t\t\tgoto label_return;\n\t\t\t\t}\n\t\t\t}\n\t\t\tnread = read(mfd, &prof_dump_buf[prof_dump_buf_end],\n\t\t\t    PROF_DUMP_BUFSIZE - prof_dump_buf_end);\n\t\t} while (nread > 0);\n\t} else {\n\t\tret = true;\n\t\tgoto label_return;\n\t}\n\n\tret = false;\nlabel_return:\n\tif (mfd != -1)\n\t\tclose(mfd);\n\treturn (ret);\n}\n\nstatic void\nprof_leakcheck(const prof_cnt_t *cnt_all, size_t leak_ngctx,\n    const char *filename)\n{\n\n\tif (cnt_all->curbytes != 0) {\n\t\tmalloc_printf(\"<jemalloc>: Leak summary: %\"FMTu64\" byte%s, %\"\n\t\t    FMTu64\" object%s, %zu context%s\\n\",\n\t\t    cnt_all->curbytes, (cnt_all->curbytes != 1) ? \"s\" : \"\",\n\t\t    cnt_all->curobjs, (cnt_all->curobjs != 1) ? \"s\" : \"\",\n\t\t    leak_ngctx, (leak_ngctx != 1) ? \"s\" : \"\");\n\t\tmalloc_printf(\n\t\t    \"<jemalloc>: Run jeprof on \\\"%s\\\" for leak detail\\n\",\n\t\t    filename);\n\t}\n}\n\nstatic prof_gctx_t *\nprof_gctx_dump_iter(prof_gctx_tree_t *gctxs, prof_gctx_t *gctx, void *arg)\n{\n\tprof_gctx_t *ret;\n\tbool propagate_err = *(bool *)arg;\n\n\tmalloc_mutex_lock(gctx->lock);\n\n\tif (prof_dump_gctx(propagate_err, gctx, &gctx->bt, gctxs)) {\n\t\tret = gctx;\n\t\tgoto label_return;\n\t}\n\n\tret = NULL;\nlabel_return:\n\tmalloc_mutex_unlock(gctx->lock);\n\treturn (ret);\n}\n\nstatic bool\nprof_dump(tsd_t *tsd, bool propagate_err, const char *filename, bool leakcheck)\n{\n\tprof_tdata_t *tdata;\n\tprof_cnt_t cnt_all;\n\tsize_t tabind;\n\tunion {\n\t\tprof_gctx_t\t*p;\n\t\tvoid\t\t*v;\n\t} gctx;\n\tsize_t leak_ngctx;\n\tprof_gctx_tree_t gctxs;\n\n\tcassert(config_prof);\n\n\ttdata = prof_tdata_get(tsd, true);\n\tif (tdata == NULL)\n\t\treturn (true);\n\n\tmalloc_mutex_lock(&prof_dump_mtx);\n\tprof_enter(tsd, tdata);\n\n\t/*\n\t * Put gctx's in limbo and clear their counters in preparation for\n\t * summing.\n\t */\n\tgctx_tree_new(&gctxs);\n\tfor (tabind = 0; !ckh_iter(&bt2gctx, &tabind, NULL, &gctx.v);)\n\t\tprof_dump_gctx_prep(gctx.p, &gctxs);\n\n\t/*\n\t * Iterate over tdatas, and for the non-expired ones snapshot their tctx\n\t * stats and merge them into the associated gctx's.\n\t */\n\tmemset(&cnt_all, 0, sizeof(prof_cnt_t));\n\tmalloc_mutex_lock(&tdatas_mtx);\n\ttdata_tree_iter(&tdatas, NULL, prof_tdata_merge_iter, (void *)&cnt_all);\n\tmalloc_mutex_unlock(&tdatas_mtx);\n\n\t/* Merge tctx stats into gctx's. */\n\tleak_ngctx = 0;\n\tgctx_tree_iter(&gctxs, NULL, prof_gctx_merge_iter, (void *)&leak_ngctx);\n\n\tprof_leave(tsd, tdata);\n\n\t/* Create dump file. */\n\tif ((prof_dump_fd = prof_dump_open(propagate_err, filename)) == -1)\n\t\tgoto label_open_close_error;\n\n\t/* Dump profile header. */\n\tif (prof_dump_header(propagate_err, &cnt_all))\n\t\tgoto label_write_error;\n\n\t/* Dump per gctx profile stats. */\n\tif (gctx_tree_iter(&gctxs, NULL, prof_gctx_dump_iter,\n\t    (void *)&propagate_err) != NULL)\n\t\tgoto label_write_error;\n\n\t/* Dump /proc/<pid>/maps if possible. */\n\tif (prof_dump_maps(propagate_err))\n\t\tgoto label_write_error;\n\n\tif (prof_dump_close(propagate_err))\n\t\tgoto label_open_close_error;\n\n\tprof_gctx_finish(tsd, &gctxs);\n\tmalloc_mutex_unlock(&prof_dump_mtx);\n\n\tif (leakcheck)\n\t\tprof_leakcheck(&cnt_all, leak_ngctx, filename);\n\n\treturn (false);\nlabel_write_error:\n\tprof_dump_close(propagate_err);\nlabel_open_close_error:\n\tprof_gctx_finish(tsd, &gctxs);\n\tmalloc_mutex_unlock(&prof_dump_mtx);\n\treturn (true);\n}\n\n#define\tDUMP_FILENAME_BUFSIZE\t(PATH_MAX + 1)\n#define\tVSEQ_INVALID\t\tUINT64_C(0xffffffffffffffff)\nstatic void\nprof_dump_filename(char *filename, char v, uint64_t vseq)\n{\n\n\tcassert(config_prof);\n\n\tif (vseq != VSEQ_INVALID) {\n\t        /* \"<prefix>.<pid>.<seq>.v<vseq>.heap\" */\n\t\tmalloc_snprintf(filename, DUMP_FILENAME_BUFSIZE,\n\t\t    \"%s.%d.%\"FMTu64\".%c%\"FMTu64\".heap\",\n\t\t    opt_prof_prefix, prof_getpid(), prof_dump_seq, v, vseq);\n\t} else {\n\t        /* \"<prefix>.<pid>.<seq>.<v>.heap\" */\n\t\tmalloc_snprintf(filename, DUMP_FILENAME_BUFSIZE,\n\t\t    \"%s.%d.%\"FMTu64\".%c.heap\",\n\t\t    opt_prof_prefix, prof_getpid(), prof_dump_seq, v);\n\t}\n\tprof_dump_seq++;\n}\n\nstatic void\nprof_fdump(void)\n{\n\ttsd_t *tsd;\n\tchar filename[DUMP_FILENAME_BUFSIZE];\n\n\tcassert(config_prof);\n\tassert(opt_prof_final);\n\tassert(opt_prof_prefix[0] != '\\0');\n\n\tif (!prof_booted)\n\t\treturn;\n\ttsd = tsd_fetch();\n\n\tmalloc_mutex_lock(&prof_dump_seq_mtx);\n\tprof_dump_filename(filename, 'f', VSEQ_INVALID);\n\tmalloc_mutex_unlock(&prof_dump_seq_mtx);\n\tprof_dump(tsd, false, filename, opt_prof_leak);\n}\n\nvoid\nprof_idump(void)\n{\n\ttsd_t *tsd;\n\tprof_tdata_t *tdata;\n\n\tcassert(config_prof);\n\n\tif (!prof_booted)\n\t\treturn;\n\ttsd = tsd_fetch();\n\ttdata = prof_tdata_get(tsd, false);\n\tif (tdata == NULL)\n\t\treturn;\n\tif (tdata->enq) {\n\t\ttdata->enq_idump = true;\n\t\treturn;\n\t}\n\n\tif (opt_prof_prefix[0] != '\\0') {\n\t\tchar filename[PATH_MAX + 1];\n\t\tmalloc_mutex_lock(&prof_dump_seq_mtx);\n\t\tprof_dump_filename(filename, 'i', prof_dump_iseq);\n\t\tprof_dump_iseq++;\n\t\tmalloc_mutex_unlock(&prof_dump_seq_mtx);\n\t\tprof_dump(tsd, false, filename, false);\n\t}\n}\n\nbool\nprof_mdump(const char *filename)\n{\n\ttsd_t *tsd;\n\tchar filename_buf[DUMP_FILENAME_BUFSIZE];\n\n\tcassert(config_prof);\n\n\tif (!opt_prof || !prof_booted)\n\t\treturn (true);\n\ttsd = tsd_fetch();\n\n\tif (filename == NULL) {\n\t\t/* No filename specified, so automatically generate one. */\n\t\tif (opt_prof_prefix[0] == '\\0')\n\t\t\treturn (true);\n\t\tmalloc_mutex_lock(&prof_dump_seq_mtx);\n\t\tprof_dump_filename(filename_buf, 'm', prof_dump_mseq);\n\t\tprof_dump_mseq++;\n\t\tmalloc_mutex_unlock(&prof_dump_seq_mtx);\n\t\tfilename = filename_buf;\n\t}\n\treturn (prof_dump(tsd, true, filename, false));\n}\n\nvoid\nprof_gdump(void)\n{\n\ttsd_t *tsd;\n\tprof_tdata_t *tdata;\n\n\tcassert(config_prof);\n\n\tif (!prof_booted)\n\t\treturn;\n\ttsd = tsd_fetch();\n\ttdata = prof_tdata_get(tsd, false);\n\tif (tdata == NULL)\n\t\treturn;\n\tif (tdata->enq) {\n\t\ttdata->enq_gdump = true;\n\t\treturn;\n\t}\n\n\tif (opt_prof_prefix[0] != '\\0') {\n\t\tchar filename[DUMP_FILENAME_BUFSIZE];\n\t\tmalloc_mutex_lock(&prof_dump_seq_mtx);\n\t\tprof_dump_filename(filename, 'u', prof_dump_useq);\n\t\tprof_dump_useq++;\n\t\tmalloc_mutex_unlock(&prof_dump_seq_mtx);\n\t\tprof_dump(tsd, false, filename, false);\n\t}\n}\n\nstatic void\nprof_bt_hash(const void *key, size_t r_hash[2])\n{\n\tprof_bt_t *bt = (prof_bt_t *)key;\n\n\tcassert(config_prof);\n\n\thash(bt->vec, bt->len * sizeof(void *), 0x94122f33U, r_hash);\n}\n\nstatic bool\nprof_bt_keycomp(const void *k1, const void *k2)\n{\n\tconst prof_bt_t *bt1 = (prof_bt_t *)k1;\n\tconst prof_bt_t *bt2 = (prof_bt_t *)k2;\n\n\tcassert(config_prof);\n\n\tif (bt1->len != bt2->len)\n\t\treturn (false);\n\treturn (memcmp(bt1->vec, bt2->vec, bt1->len * sizeof(void *)) == 0);\n}\n\nJEMALLOC_INLINE_C uint64_t\nprof_thr_uid_alloc(void)\n{\n\tuint64_t thr_uid;\n\n\tmalloc_mutex_lock(&next_thr_uid_mtx);\n\tthr_uid = next_thr_uid;\n\tnext_thr_uid++;\n\tmalloc_mutex_unlock(&next_thr_uid_mtx);\n\n\treturn (thr_uid);\n}\n\nstatic prof_tdata_t *\nprof_tdata_init_impl(tsd_t *tsd, uint64_t thr_uid, uint64_t thr_discrim,\n    char *thread_name, bool active)\n{\n\tprof_tdata_t *tdata;\n\ttcache_t *tcache;\n\n\tcassert(config_prof);\n\n\t/* Initialize an empty cache for this thread. */\n\ttcache = tcache_get(tsd, true);\n\ttdata = (prof_tdata_t *)iallocztm(tsd, sizeof(prof_tdata_t),\n\t    size2index(sizeof(prof_tdata_t)), false, tcache, true, NULL, true);\n\tif (tdata == NULL)\n\t\treturn (NULL);\n\n\ttdata->lock = prof_tdata_mutex_choose(thr_uid);\n\ttdata->thr_uid = thr_uid;\n\ttdata->thr_discrim = thr_discrim;\n\ttdata->thread_name = thread_name;\n\ttdata->attached = true;\n\ttdata->expired = false;\n\ttdata->tctx_uid_next = 0;\n\n\tif (ckh_new(tsd, &tdata->bt2tctx, PROF_CKH_MINITEMS,\n\t    prof_bt_hash, prof_bt_keycomp)) {\n\t\tidalloctm(tsd, tdata, tcache, true, true);\n\t\treturn (NULL);\n\t}\n\n\ttdata->prng_state = (uint64_t)(uintptr_t)tdata;\n\tprof_sample_threshold_update(tdata);\n\n\ttdata->enq = false;\n\ttdata->enq_idump = false;\n\ttdata->enq_gdump = false;\n\n\ttdata->dumping = false;\n\ttdata->active = active;\n\n\tmalloc_mutex_lock(&tdatas_mtx);\n\ttdata_tree_insert(&tdatas, tdata);\n\tmalloc_mutex_unlock(&tdatas_mtx);\n\n\treturn (tdata);\n}\n\nprof_tdata_t *\nprof_tdata_init(tsd_t *tsd)\n{\n\n\treturn (prof_tdata_init_impl(tsd, prof_thr_uid_alloc(), 0, NULL,\n\t    prof_thread_active_init_get()));\n}\n\n/* tdata->lock must be held. */\nstatic bool\nprof_tdata_should_destroy(prof_tdata_t *tdata, bool even_if_attached)\n{\n\n\tif (tdata->attached && !even_if_attached)\n\t\treturn (false);\n\tif (ckh_count(&tdata->bt2tctx) != 0)\n\t\treturn (false);\n\treturn (true);\n}\n\n/* tdatas_mtx must be held. */\nstatic void\nprof_tdata_destroy_locked(tsd_t *tsd, prof_tdata_t *tdata,\n    bool even_if_attached)\n{\n\ttcache_t *tcache;\n\n\tassert(prof_tdata_should_destroy(tdata, even_if_attached));\n\tassert(tsd_prof_tdata_get(tsd) != tdata);\n\n\ttdata_tree_remove(&tdatas, tdata);\n\n\ttcache = tcache_get(tsd, false);\n\tif (tdata->thread_name != NULL)\n\t\tidalloctm(tsd, tdata->thread_name, tcache, true, true);\n\tckh_delete(tsd, &tdata->bt2tctx);\n\tidalloctm(tsd, tdata, tcache, true, true);\n}\n\nstatic void\nprof_tdata_destroy(tsd_t *tsd, prof_tdata_t *tdata, bool even_if_attached)\n{\n\n\tmalloc_mutex_lock(&tdatas_mtx);\n\tprof_tdata_destroy_locked(tsd, tdata, even_if_attached);\n\tmalloc_mutex_unlock(&tdatas_mtx);\n}\n\nstatic void\nprof_tdata_detach(tsd_t *tsd, prof_tdata_t *tdata)\n{\n\tbool destroy_tdata;\n\n\tmalloc_mutex_lock(tdata->lock);\n\tif (tdata->attached) {\n\t\tdestroy_tdata = prof_tdata_should_destroy(tdata, true);\n\t\t/*\n\t\t * Only detach if !destroy_tdata, because detaching would allow\n\t\t * another thread to win the race to destroy tdata.\n\t\t */\n\t\tif (!destroy_tdata)\n\t\t\ttdata->attached = false;\n\t\ttsd_prof_tdata_set(tsd, NULL);\n\t} else\n\t\tdestroy_tdata = false;\n\tmalloc_mutex_unlock(tdata->lock);\n\tif (destroy_tdata)\n\t\tprof_tdata_destroy(tsd, tdata, true);\n}\n\nprof_tdata_t *\nprof_tdata_reinit(tsd_t *tsd, prof_tdata_t *tdata)\n{\n\tuint64_t thr_uid = tdata->thr_uid;\n\tuint64_t thr_discrim = tdata->thr_discrim + 1;\n\tchar *thread_name = (tdata->thread_name != NULL) ?\n\t    prof_thread_name_alloc(tsd, tdata->thread_name) : NULL;\n\tbool active = tdata->active;\n\n\tprof_tdata_detach(tsd, tdata);\n\treturn (prof_tdata_init_impl(tsd, thr_uid, thr_discrim, thread_name,\n\t    active));\n}\n\nstatic bool\nprof_tdata_expire(prof_tdata_t *tdata)\n{\n\tbool destroy_tdata;\n\n\tmalloc_mutex_lock(tdata->lock);\n\tif (!tdata->expired) {\n\t\ttdata->expired = true;\n\t\tdestroy_tdata = tdata->attached ? false :\n\t\t    prof_tdata_should_destroy(tdata, false);\n\t} else\n\t\tdestroy_tdata = false;\n\tmalloc_mutex_unlock(tdata->lock);\n\n\treturn (destroy_tdata);\n}\n\nstatic prof_tdata_t *\nprof_tdata_reset_iter(prof_tdata_tree_t *tdatas, prof_tdata_t *tdata, void *arg)\n{\n\n\treturn (prof_tdata_expire(tdata) ? tdata : NULL);\n}\n\nvoid\nprof_reset(tsd_t *tsd, size_t lg_sample)\n{\n\tprof_tdata_t *next;\n\n\tassert(lg_sample < (sizeof(uint64_t) << 3));\n\n\tmalloc_mutex_lock(&prof_dump_mtx);\n\tmalloc_mutex_lock(&tdatas_mtx);\n\n\tlg_prof_sample = lg_sample;\n\n\tnext = NULL;\n\tdo {\n\t\tprof_tdata_t *to_destroy = tdata_tree_iter(&tdatas, next,\n\t\t    prof_tdata_reset_iter, NULL);\n\t\tif (to_destroy != NULL) {\n\t\t\tnext = tdata_tree_next(&tdatas, to_destroy);\n\t\t\tprof_tdata_destroy_locked(tsd, to_destroy, false);\n\t\t} else\n\t\t\tnext = NULL;\n\t} while (next != NULL);\n\n\tmalloc_mutex_unlock(&tdatas_mtx);\n\tmalloc_mutex_unlock(&prof_dump_mtx);\n}\n\nvoid\nprof_tdata_cleanup(tsd_t *tsd)\n{\n\tprof_tdata_t *tdata;\n\n\tif (!config_prof)\n\t\treturn;\n\n\ttdata = tsd_prof_tdata_get(tsd);\n\tif (tdata != NULL)\n\t\tprof_tdata_detach(tsd, tdata);\n}\n\nbool\nprof_active_get(void)\n{\n\tbool prof_active_current;\n\n\tmalloc_mutex_lock(&prof_active_mtx);\n\tprof_active_current = prof_active;\n\tmalloc_mutex_unlock(&prof_active_mtx);\n\treturn (prof_active_current);\n}\n\nbool\nprof_active_set(bool active)\n{\n\tbool prof_active_old;\n\n\tmalloc_mutex_lock(&prof_active_mtx);\n\tprof_active_old = prof_active;\n\tprof_active = active;\n\tmalloc_mutex_unlock(&prof_active_mtx);\n\treturn (prof_active_old);\n}\n\nconst char *\nprof_thread_name_get(void)\n{\n\ttsd_t *tsd;\n\tprof_tdata_t *tdata;\n\n\ttsd = tsd_fetch();\n\ttdata = prof_tdata_get(tsd, true);\n\tif (tdata == NULL)\n\t\treturn (\"\");\n\treturn (tdata->thread_name != NULL ? tdata->thread_name : \"\");\n}\n\nstatic char *\nprof_thread_name_alloc(tsd_t *tsd, const char *thread_name)\n{\n\tchar *ret;\n\tsize_t size;\n\n\tif (thread_name == NULL)\n\t\treturn (NULL);\n\n\tsize = strlen(thread_name) + 1;\n\tif (size == 1)\n\t\treturn (\"\");\n\n\tret = iallocztm(tsd, size, size2index(size), false, tcache_get(tsd,\n\t    true), true, NULL, true);\n\tif (ret == NULL)\n\t\treturn (NULL);\n\tmemcpy(ret, thread_name, size);\n\treturn (ret);\n}\n\nint\nprof_thread_name_set(tsd_t *tsd, const char *thread_name)\n{\n\tprof_tdata_t *tdata;\n\tunsigned i;\n\tchar *s;\n\n\ttdata = prof_tdata_get(tsd, true);\n\tif (tdata == NULL)\n\t\treturn (EAGAIN);\n\n\t/* Validate input. */\n\tif (thread_name == NULL)\n\t\treturn (EFAULT);\n\tfor (i = 0; thread_name[i] != '\\0'; i++) {\n\t\tchar c = thread_name[i];\n\t\tif (!isgraph(c) && !isblank(c))\n\t\t\treturn (EFAULT);\n\t}\n\n\ts = prof_thread_name_alloc(tsd, thread_name);\n\tif (s == NULL)\n\t\treturn (EAGAIN);\n\n\tif (tdata->thread_name != NULL) {\n\t\tidalloctm(tsd, tdata->thread_name, tcache_get(tsd, false),\n\t\t    true, true);\n\t\ttdata->thread_name = NULL;\n\t}\n\tif (strlen(s) > 0)\n\t\ttdata->thread_name = s;\n\treturn (0);\n}\n\nbool\nprof_thread_active_get(void)\n{\n\ttsd_t *tsd;\n\tprof_tdata_t *tdata;\n\n\ttsd = tsd_fetch();\n\ttdata = prof_tdata_get(tsd, true);\n\tif (tdata == NULL)\n\t\treturn (false);\n\treturn (tdata->active);\n}\n\nbool\nprof_thread_active_set(bool active)\n{\n\ttsd_t *tsd;\n\tprof_tdata_t *tdata;\n\n\ttsd = tsd_fetch();\n\ttdata = prof_tdata_get(tsd, true);\n\tif (tdata == NULL)\n\t\treturn (true);\n\ttdata->active = active;\n\treturn (false);\n}\n\nbool\nprof_thread_active_init_get(void)\n{\n\tbool active_init;\n\n\tmalloc_mutex_lock(&prof_thread_active_init_mtx);\n\tactive_init = prof_thread_active_init;\n\tmalloc_mutex_unlock(&prof_thread_active_init_mtx);\n\treturn (active_init);\n}\n\nbool\nprof_thread_active_init_set(bool active_init)\n{\n\tbool active_init_old;\n\n\tmalloc_mutex_lock(&prof_thread_active_init_mtx);\n\tactive_init_old = prof_thread_active_init;\n\tprof_thread_active_init = active_init;\n\tmalloc_mutex_unlock(&prof_thread_active_init_mtx);\n\treturn (active_init_old);\n}\n\nbool\nprof_gdump_get(void)\n{\n\tbool prof_gdump_current;\n\n\tmalloc_mutex_lock(&prof_gdump_mtx);\n\tprof_gdump_current = prof_gdump_val;\n\tmalloc_mutex_unlock(&prof_gdump_mtx);\n\treturn (prof_gdump_current);\n}\n\nbool\nprof_gdump_set(bool gdump)\n{\n\tbool prof_gdump_old;\n\n\tmalloc_mutex_lock(&prof_gdump_mtx);\n\tprof_gdump_old = prof_gdump_val;\n\tprof_gdump_val = gdump;\n\tmalloc_mutex_unlock(&prof_gdump_mtx);\n\treturn (prof_gdump_old);\n}\n\nvoid\nprof_boot0(void)\n{\n\n\tcassert(config_prof);\n\n\tmemcpy(opt_prof_prefix, PROF_PREFIX_DEFAULT,\n\t    sizeof(PROF_PREFIX_DEFAULT));\n}\n\nvoid\nprof_boot1(void)\n{\n\n\tcassert(config_prof);\n\n\t/*\n\t * opt_prof must be in its final state before any arenas are\n\t * initialized, so this function must be executed early.\n\t */\n\n\tif (opt_prof_leak && !opt_prof) {\n\t\t/*\n\t\t * Enable opt_prof, but in such a way that profiles are never\n\t\t * automatically dumped.\n\t\t */\n\t\topt_prof = true;\n\t\topt_prof_gdump = false;\n\t} else if (opt_prof) {\n\t\tif (opt_lg_prof_interval >= 0) {\n\t\t\tprof_interval = (((uint64_t)1U) <<\n\t\t\t    opt_lg_prof_interval);\n\t\t}\n\t}\n}\n\nbool\nprof_boot2(void)\n{\n\n\tcassert(config_prof);\n\n\tif (opt_prof) {\n\t\ttsd_t *tsd;\n\t\tunsigned i;\n\n\t\tlg_prof_sample = opt_lg_prof_sample;\n\n\t\tprof_active = opt_prof_active;\n\t\tif (malloc_mutex_init(&prof_active_mtx))\n\t\t\treturn (true);\n\n\t\tprof_gdump_val = opt_prof_gdump;\n\t\tif (malloc_mutex_init(&prof_gdump_mtx))\n\t\t\treturn (true);\n\n\t\tprof_thread_active_init = opt_prof_thread_active_init;\n\t\tif (malloc_mutex_init(&prof_thread_active_init_mtx))\n\t\t\treturn (true);\n\n\t\ttsd = tsd_fetch();\n\t\tif (ckh_new(tsd, &bt2gctx, PROF_CKH_MINITEMS, prof_bt_hash,\n\t\t    prof_bt_keycomp))\n\t\t\treturn (true);\n\t\tif (malloc_mutex_init(&bt2gctx_mtx))\n\t\t\treturn (true);\n\n\t\ttdata_tree_new(&tdatas);\n\t\tif (malloc_mutex_init(&tdatas_mtx))\n\t\t\treturn (true);\n\n\t\tnext_thr_uid = 0;\n\t\tif (malloc_mutex_init(&next_thr_uid_mtx))\n\t\t\treturn (true);\n\n\t\tif (malloc_mutex_init(&prof_dump_seq_mtx))\n\t\t\treturn (true);\n\t\tif (malloc_mutex_init(&prof_dump_mtx))\n\t\t\treturn (true);\n\n\t\tif (opt_prof_final && opt_prof_prefix[0] != '\\0' &&\n\t\t    atexit(prof_fdump) != 0) {\n\t\t\tmalloc_write(\"<jemalloc>: Error in atexit()\\n\");\n\t\t\tif (opt_abort)\n\t\t\t\tabort();\n\t\t}\n\n\t\tgctx_locks = (malloc_mutex_t *)base_alloc(PROF_NCTX_LOCKS *\n\t\t    sizeof(malloc_mutex_t));\n\t\tif (gctx_locks == NULL)\n\t\t\treturn (true);\n\t\tfor (i = 0; i < PROF_NCTX_LOCKS; i++) {\n\t\t\tif (malloc_mutex_init(&gctx_locks[i]))\n\t\t\t\treturn (true);\n\t\t}\n\n\t\ttdata_locks = (malloc_mutex_t *)base_alloc(PROF_NTDATA_LOCKS *\n\t\t    sizeof(malloc_mutex_t));\n\t\tif (tdata_locks == NULL)\n\t\t\treturn (true);\n\t\tfor (i = 0; i < PROF_NTDATA_LOCKS; i++) {\n\t\t\tif (malloc_mutex_init(&tdata_locks[i]))\n\t\t\t\treturn (true);\n\t\t}\n\t}\n\n#ifdef JEMALLOC_PROF_LIBGCC\n\t/*\n\t * Cause the backtracing machinery to allocate its internal state\n\t * before enabling profiling.\n\t */\n\t_Unwind_Backtrace(prof_unwind_init_callback, NULL);\n#endif\n\n\tprof_booted = true;\n\n\treturn (false);\n}\n\nvoid\nprof_prefork(void)\n{\n\n\tif (opt_prof) {\n\t\tunsigned i;\n\n\t\tmalloc_mutex_prefork(&tdatas_mtx);\n\t\tmalloc_mutex_prefork(&bt2gctx_mtx);\n\t\tmalloc_mutex_prefork(&next_thr_uid_mtx);\n\t\tmalloc_mutex_prefork(&prof_dump_seq_mtx);\n\t\tfor (i = 0; i < PROF_NCTX_LOCKS; i++)\n\t\t\tmalloc_mutex_prefork(&gctx_locks[i]);\n\t\tfor (i = 0; i < PROF_NTDATA_LOCKS; i++)\n\t\t\tmalloc_mutex_prefork(&tdata_locks[i]);\n\t}\n}\n\nvoid\nprof_postfork_parent(void)\n{\n\n\tif (opt_prof) {\n\t\tunsigned i;\n\n\t\tfor (i = 0; i < PROF_NTDATA_LOCKS; i++)\n\t\t\tmalloc_mutex_postfork_parent(&tdata_locks[i]);\n\t\tfor (i = 0; i < PROF_NCTX_LOCKS; i++)\n\t\t\tmalloc_mutex_postfork_parent(&gctx_locks[i]);\n\t\tmalloc_mutex_postfork_parent(&prof_dump_seq_mtx);\n\t\tmalloc_mutex_postfork_parent(&next_thr_uid_mtx);\n\t\tmalloc_mutex_postfork_parent(&bt2gctx_mtx);\n\t\tmalloc_mutex_postfork_parent(&tdatas_mtx);\n\t}\n}\n\nvoid\nprof_postfork_child(void)\n{\n\n\tif (opt_prof) {\n\t\tunsigned i;\n\n\t\tfor (i = 0; i < PROF_NTDATA_LOCKS; i++)\n\t\t\tmalloc_mutex_postfork_child(&tdata_locks[i]);\n\t\tfor (i = 0; i < PROF_NCTX_LOCKS; i++)\n\t\t\tmalloc_mutex_postfork_child(&gctx_locks[i]);\n\t\tmalloc_mutex_postfork_child(&prof_dump_seq_mtx);\n\t\tmalloc_mutex_postfork_child(&next_thr_uid_mtx);\n\t\tmalloc_mutex_postfork_child(&bt2gctx_mtx);\n\t\tmalloc_mutex_postfork_child(&tdatas_mtx);\n\t}\n}\n\n/******************************************************************************/\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/quarantine.c",
    "content": "#define\tJEMALLOC_QUARANTINE_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n/*\n * Quarantine pointers close to NULL are used to encode state information that\n * is used for cleaning up during thread shutdown.\n */\n#define\tQUARANTINE_STATE_REINCARNATED\t((quarantine_t *)(uintptr_t)1)\n#define\tQUARANTINE_STATE_PURGATORY\t((quarantine_t *)(uintptr_t)2)\n#define\tQUARANTINE_STATE_MAX\t\tQUARANTINE_STATE_PURGATORY\n\n/******************************************************************************/\n/* Function prototypes for non-inline static functions. */\n\nstatic quarantine_t\t*quarantine_grow(tsd_t *tsd, quarantine_t *quarantine);\nstatic void\tquarantine_drain_one(tsd_t *tsd, quarantine_t *quarantine);\nstatic void\tquarantine_drain(tsd_t *tsd, quarantine_t *quarantine,\n    size_t upper_bound);\n\n/******************************************************************************/\n\nstatic quarantine_t *\nquarantine_init(tsd_t *tsd, size_t lg_maxobjs)\n{\n\tquarantine_t *quarantine;\n\tsize_t size;\n\n\tassert(tsd_nominal(tsd));\n\n\tsize = offsetof(quarantine_t, objs) + ((ZU(1) << lg_maxobjs) *\n\t    sizeof(quarantine_obj_t));\n\tquarantine = (quarantine_t *)iallocztm(tsd, size, size2index(size),\n\t    false, tcache_get(tsd, true), true, NULL, true);\n\tif (quarantine == NULL)\n\t\treturn (NULL);\n\tquarantine->curbytes = 0;\n\tquarantine->curobjs = 0;\n\tquarantine->first = 0;\n\tquarantine->lg_maxobjs = lg_maxobjs;\n\n\treturn (quarantine);\n}\n\nvoid\nquarantine_alloc_hook_work(tsd_t *tsd)\n{\n\tquarantine_t *quarantine;\n\n\tif (!tsd_nominal(tsd))\n\t\treturn;\n\n\tquarantine = quarantine_init(tsd, LG_MAXOBJS_INIT);\n\t/*\n\t * Check again whether quarantine has been initialized, because\n\t * quarantine_init() may have triggered recursive initialization.\n\t */\n\tif (tsd_quarantine_get(tsd) == NULL)\n\t\ttsd_quarantine_set(tsd, quarantine);\n\telse\n\t\tidalloctm(tsd, quarantine, tcache_get(tsd, false), true, true);\n}\n\nstatic quarantine_t *\nquarantine_grow(tsd_t *tsd, quarantine_t *quarantine)\n{\n\tquarantine_t *ret;\n\n\tret = quarantine_init(tsd, quarantine->lg_maxobjs + 1);\n\tif (ret == NULL) {\n\t\tquarantine_drain_one(tsd, quarantine);\n\t\treturn (quarantine);\n\t}\n\n\tret->curbytes = quarantine->curbytes;\n\tret->curobjs = quarantine->curobjs;\n\tif (quarantine->first + quarantine->curobjs <= (ZU(1) <<\n\t    quarantine->lg_maxobjs)) {\n\t\t/* objs ring buffer data are contiguous. */\n\t\tmemcpy(ret->objs, &quarantine->objs[quarantine->first],\n\t\t    quarantine->curobjs * sizeof(quarantine_obj_t));\n\t} else {\n\t\t/* objs ring buffer data wrap around. */\n\t\tsize_t ncopy_a = (ZU(1) << quarantine->lg_maxobjs) -\n\t\t    quarantine->first;\n\t\tsize_t ncopy_b = quarantine->curobjs - ncopy_a;\n\n\t\tmemcpy(ret->objs, &quarantine->objs[quarantine->first], ncopy_a\n\t\t    * sizeof(quarantine_obj_t));\n\t\tmemcpy(&ret->objs[ncopy_a], quarantine->objs, ncopy_b *\n\t\t    sizeof(quarantine_obj_t));\n\t}\n\tidalloctm(tsd, quarantine, tcache_get(tsd, false), true, true);\n\n\ttsd_quarantine_set(tsd, ret);\n\treturn (ret);\n}\n\nstatic void\nquarantine_drain_one(tsd_t *tsd, quarantine_t *quarantine)\n{\n\tquarantine_obj_t *obj = &quarantine->objs[quarantine->first];\n\tassert(obj->usize == isalloc(obj->ptr, config_prof));\n\tidalloctm(tsd, obj->ptr, NULL, false, true);\n\tquarantine->curbytes -= obj->usize;\n\tquarantine->curobjs--;\n\tquarantine->first = (quarantine->first + 1) & ((ZU(1) <<\n\t    quarantine->lg_maxobjs) - 1);\n}\n\nstatic void\nquarantine_drain(tsd_t *tsd, quarantine_t *quarantine, size_t upper_bound)\n{\n\n\twhile (quarantine->curbytes > upper_bound && quarantine->curobjs > 0)\n\t\tquarantine_drain_one(tsd, quarantine);\n}\n\nvoid\nquarantine(tsd_t *tsd, void *ptr)\n{\n\tquarantine_t *quarantine;\n\tsize_t usize = isalloc(ptr, config_prof);\n\n\tcassert(config_fill);\n\tassert(opt_quarantine);\n\n\tif ((quarantine = tsd_quarantine_get(tsd)) == NULL) {\n\t\tidalloctm(tsd, ptr, NULL, false, true);\n\t\treturn;\n\t}\n\t/*\n\t * Drain one or more objects if the quarantine size limit would be\n\t * exceeded by appending ptr.\n\t */\n\tif (quarantine->curbytes + usize > opt_quarantine) {\n\t\tsize_t upper_bound = (opt_quarantine >= usize) ? opt_quarantine\n\t\t    - usize : 0;\n\t\tquarantine_drain(tsd, quarantine, upper_bound);\n\t}\n\t/* Grow the quarantine ring buffer if it's full. */\n\tif (quarantine->curobjs == (ZU(1) << quarantine->lg_maxobjs))\n\t\tquarantine = quarantine_grow(tsd, quarantine);\n\t/* quarantine_grow() must free a slot if it fails to grow. */\n\tassert(quarantine->curobjs < (ZU(1) << quarantine->lg_maxobjs));\n\t/* Append ptr if its size doesn't exceed the quarantine size. */\n\tif (quarantine->curbytes + usize <= opt_quarantine) {\n\t\tsize_t offset = (quarantine->first + quarantine->curobjs) &\n\t\t    ((ZU(1) << quarantine->lg_maxobjs) - 1);\n\t\tquarantine_obj_t *obj = &quarantine->objs[offset];\n\t\tobj->ptr = ptr;\n\t\tobj->usize = usize;\n\t\tquarantine->curbytes += usize;\n\t\tquarantine->curobjs++;\n\t\tif (config_fill && unlikely(opt_junk_free)) {\n\t\t\t/*\n\t\t\t * Only do redzone validation if Valgrind isn't in\n\t\t\t * operation.\n\t\t\t */\n\t\t\tif ((!config_valgrind || likely(!in_valgrind))\n\t\t\t    && usize <= SMALL_MAXCLASS)\n\t\t\t\tarena_quarantine_junk_small(ptr, usize);\n\t\t\telse\n\t\t\t\tmemset(ptr, 0x5a, usize);\n\t\t}\n\t} else {\n\t\tassert(quarantine->curbytes == 0);\n\t\tidalloctm(tsd, ptr, NULL, false, true);\n\t}\n}\n\nvoid\nquarantine_cleanup(tsd_t *tsd)\n{\n\tquarantine_t *quarantine;\n\n\tif (!config_fill)\n\t\treturn;\n\n\tquarantine = tsd_quarantine_get(tsd);\n\tif (quarantine != NULL) {\n\t\tquarantine_drain(tsd, quarantine, 0);\n\t\tidalloctm(tsd, quarantine, tcache_get(tsd, false), true, true);\n\t\ttsd_quarantine_set(tsd, NULL);\n\t}\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/rtree.c",
    "content": "#define\tJEMALLOC_RTREE_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\nstatic unsigned\nhmin(unsigned ha, unsigned hb)\n{\n\n\treturn (ha < hb ? ha : hb);\n}\n\n/* Only the most significant bits of keys passed to rtree_[gs]et() are used. */\nbool\nrtree_new(rtree_t *rtree, unsigned bits, rtree_node_alloc_t *alloc,\n    rtree_node_dalloc_t *dalloc)\n{\n\tunsigned bits_in_leaf, height, i;\n\n\tassert(bits > 0 && bits <= (sizeof(uintptr_t) << 3));\n\n\tbits_in_leaf = (bits % RTREE_BITS_PER_LEVEL) == 0 ? RTREE_BITS_PER_LEVEL\n\t    : (bits % RTREE_BITS_PER_LEVEL);\n\tif (bits > bits_in_leaf) {\n\t\theight = 1 + (bits - bits_in_leaf) / RTREE_BITS_PER_LEVEL;\n\t\tif ((height-1) * RTREE_BITS_PER_LEVEL + bits_in_leaf != bits)\n\t\t\theight++;\n\t} else\n\t\theight = 1;\n\tassert((height-1) * RTREE_BITS_PER_LEVEL + bits_in_leaf == bits);\n\n\trtree->alloc = alloc;\n\trtree->dalloc = dalloc;\n\trtree->height = height;\n\n\t/* Root level. */\n\trtree->levels[0].subtree = NULL;\n\trtree->levels[0].bits = (height > 1) ? RTREE_BITS_PER_LEVEL :\n\t    bits_in_leaf;\n\trtree->levels[0].cumbits = rtree->levels[0].bits;\n\t/* Interior levels. */\n\tfor (i = 1; i < height-1; i++) {\n\t\trtree->levels[i].subtree = NULL;\n\t\trtree->levels[i].bits = RTREE_BITS_PER_LEVEL;\n\t\trtree->levels[i].cumbits = rtree->levels[i-1].cumbits +\n\t\t    RTREE_BITS_PER_LEVEL;\n\t}\n\t/* Leaf level. */\n\tif (height > 1) {\n\t\trtree->levels[height-1].subtree = NULL;\n\t\trtree->levels[height-1].bits = bits_in_leaf;\n\t\trtree->levels[height-1].cumbits = bits;\n\t}\n\n\t/* Compute lookup table to be used by rtree_start_level(). */\n\tfor (i = 0; i < RTREE_HEIGHT_MAX; i++) {\n\t\trtree->start_level[i] = hmin(RTREE_HEIGHT_MAX - 1 - i, height -\n\t\t    1);\n\t}\n\n\treturn (false);\n}\n\nstatic void\nrtree_delete_subtree(rtree_t *rtree, rtree_node_elm_t *node, unsigned level)\n{\n\n\tif (level + 1 < rtree->height) {\n\t\tsize_t nchildren, i;\n\n\t\tnchildren = ZU(1) << rtree->levels[level].bits;\n\t\tfor (i = 0; i < nchildren; i++) {\n\t\t\trtree_node_elm_t *child = node[i].child;\n\t\t\tif (child != NULL)\n\t\t\t\trtree_delete_subtree(rtree, child, level + 1);\n\t\t}\n\t}\n\trtree->dalloc(node);\n}\n\nvoid\nrtree_delete(rtree_t *rtree)\n{\n\tunsigned i;\n\n\tfor (i = 0; i < rtree->height; i++) {\n\t\trtree_node_elm_t *subtree = rtree->levels[i].subtree;\n\t\tif (subtree != NULL)\n\t\t\trtree_delete_subtree(rtree, subtree, i);\n\t}\n}\n\nstatic rtree_node_elm_t *\nrtree_node_init(rtree_t *rtree, unsigned level, rtree_node_elm_t **elmp)\n{\n\trtree_node_elm_t *node;\n\n\tif (atomic_cas_p((void **)elmp, NULL, RTREE_NODE_INITIALIZING)) {\n\t\t/*\n\t\t * Another thread is already in the process of initializing.\n\t\t * Spin-wait until initialization is complete.\n\t\t */\n\t\tdo {\n\t\t\tCPU_SPINWAIT;\n\t\t\tnode = atomic_read_p((void **)elmp);\n\t\t} while (node == RTREE_NODE_INITIALIZING);\n\t} else {\n\t\tnode = rtree->alloc(ZU(1) << rtree->levels[level].bits);\n\t\tif (node == NULL)\n\t\t\treturn (NULL);\n\t\tatomic_write_p((void **)elmp, node);\n\t}\n\n\treturn (node);\n}\n\nrtree_node_elm_t *\nrtree_subtree_read_hard(rtree_t *rtree, unsigned level)\n{\n\n\treturn (rtree_node_init(rtree, level, &rtree->levels[level].subtree));\n}\n\nrtree_node_elm_t *\nrtree_child_read_hard(rtree_t *rtree, rtree_node_elm_t *elm, unsigned level)\n{\n\n\treturn (rtree_node_init(rtree, level, &elm->child));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/stats.c",
    "content": "#define\tJEMALLOC_STATS_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n#define\tCTL_GET(n, v, t) do {\t\t\t\t\t\t\\\n\tsize_t sz = sizeof(t);\t\t\t\t\t\t\\\n\txmallctl(n, v, &sz, NULL, 0);\t\t\t\t\t\\\n} while (0)\n\n#define\tCTL_M2_GET(n, i, v, t) do {\t\t\t\t\t\\\n\tsize_t mib[6];\t\t\t\t\t\t\t\\\n\tsize_t miblen = sizeof(mib) / sizeof(size_t);\t\t\t\\\n\tsize_t sz = sizeof(t);\t\t\t\t\t\t\\\n\txmallctlnametomib(n, mib, &miblen);\t\t\t\t\\\n\tmib[2] = (i);\t\t\t\t\t\t\t\\\n\txmallctlbymib(mib, miblen, v, &sz, NULL, 0);\t\t\t\\\n} while (0)\n\n#define\tCTL_M2_M4_GET(n, i, j, v, t) do {\t\t\t\t\\\n\tsize_t mib[6];\t\t\t\t\t\t\t\\\n\tsize_t miblen = sizeof(mib) / sizeof(size_t);\t\t\t\\\n\tsize_t sz = sizeof(t);\t\t\t\t\t\t\\\n\txmallctlnametomib(n, mib, &miblen);\t\t\t\t\\\n\tmib[2] = (i);\t\t\t\t\t\t\t\\\n\tmib[4] = (j);\t\t\t\t\t\t\t\\\n\txmallctlbymib(mib, miblen, v, &sz, NULL, 0);\t\t\t\\\n} while (0)\n\n/******************************************************************************/\n/* Data. */\n\nbool\topt_stats_print = false;\n\nsize_t\tstats_cactive = 0;\n\n/******************************************************************************/\n/* Function prototypes for non-inline static functions. */\n\nstatic void\tstats_arena_bins_print(void (*write_cb)(void *, const char *),\n    void *cbopaque, unsigned i);\nstatic void\tstats_arena_lruns_print(void (*write_cb)(void *, const char *),\n    void *cbopaque, unsigned i);\nstatic void\tstats_arena_hchunks_print(\n    void (*write_cb)(void *, const char *), void *cbopaque, unsigned i);\nstatic void\tstats_arena_print(void (*write_cb)(void *, const char *),\n    void *cbopaque, unsigned i, bool bins, bool large, bool huge);\n\n/******************************************************************************/\n\nstatic void\nstats_arena_bins_print(void (*write_cb)(void *, const char *), void *cbopaque,\n    unsigned i)\n{\n\tsize_t page;\n\tbool config_tcache, in_gap;\n\tunsigned nbins, j;\n\n\tCTL_GET(\"arenas.page\", &page, size_t);\n\n\tCTL_GET(\"config.tcache\", &config_tcache, bool);\n\tif (config_tcache) {\n\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t    \"bins:           size ind    allocated      nmalloc\"\n\t\t    \"      ndalloc    nrequests      curregs      curruns regs\"\n\t\t    \" pgs  util       nfills     nflushes      newruns\"\n\t\t    \"       reruns\\n\");\n\t} else {\n\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t    \"bins:           size ind    allocated      nmalloc\"\n\t\t    \"      ndalloc    nrequests      curregs      curruns regs\"\n\t\t    \" pgs  util      newruns       reruns\\n\");\n\t}\n\tCTL_GET(\"arenas.nbins\", &nbins, unsigned);\n\tfor (j = 0, in_gap = false; j < nbins; j++) {\n\t\tuint64_t nruns;\n\n\t\tCTL_M2_M4_GET(\"stats.arenas.0.bins.0.nruns\", i, j, &nruns,\n\t\t    uint64_t);\n\t\tif (nruns == 0)\n\t\t\tin_gap = true;\n\t\telse {\n\t\t\tsize_t reg_size, run_size, curregs, availregs, milli;\n\t\t\tsize_t curruns;\n\t\t\tuint32_t nregs;\n\t\t\tuint64_t nmalloc, ndalloc, nrequests, nfills, nflushes;\n\t\t\tuint64_t reruns;\n\t\t\tchar util[6]; /* \"x.yyy\". */\n\n\t\t\tif (in_gap) {\n\t\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t\t    \"                     ---\\n\");\n\t\t\t\tin_gap = false;\n\t\t\t}\n\t\t\tCTL_M2_GET(\"arenas.bin.0.size\", j, &reg_size, size_t);\n\t\t\tCTL_M2_GET(\"arenas.bin.0.nregs\", j, &nregs, uint32_t);\n\t\t\tCTL_M2_GET(\"arenas.bin.0.run_size\", j, &run_size,\n\t\t\t    size_t);\n\t\t\tCTL_M2_M4_GET(\"stats.arenas.0.bins.0.nmalloc\", i, j,\n\t\t\t    &nmalloc, uint64_t);\n\t\t\tCTL_M2_M4_GET(\"stats.arenas.0.bins.0.ndalloc\", i, j,\n\t\t\t    &ndalloc, uint64_t);\n\t\t\tCTL_M2_M4_GET(\"stats.arenas.0.bins.0.curregs\", i, j,\n\t\t\t    &curregs, size_t);\n\t\t\tCTL_M2_M4_GET(\"stats.arenas.0.bins.0.nrequests\", i, j,\n\t\t\t    &nrequests, uint64_t);\n\t\t\tif (config_tcache) {\n\t\t\t\tCTL_M2_M4_GET(\"stats.arenas.0.bins.0.nfills\", i,\n\t\t\t\t    j, &nfills, uint64_t);\n\t\t\t\tCTL_M2_M4_GET(\"stats.arenas.0.bins.0.nflushes\",\n\t\t\t\t    i, j, &nflushes, uint64_t);\n\t\t\t}\n\t\t\tCTL_M2_M4_GET(\"stats.arenas.0.bins.0.nreruns\", i, j,\n\t\t\t    &reruns, uint64_t);\n\t\t\tCTL_M2_M4_GET(\"stats.arenas.0.bins.0.curruns\", i, j,\n\t\t\t    &curruns, size_t);\n\n\t\t\tavailregs = nregs * curruns;\n\t\t\tmilli = (availregs != 0) ? (1000 * curregs) / availregs\n\t\t\t    : 1000;\n\t\t\tassert(milli <= 1000);\n\t\t\tif (milli < 10) {\n\t\t\t\tmalloc_snprintf(util, sizeof(util),\n\t\t\t\t    \"0.00%zu\", milli);\n\t\t\t} else if (milli < 100) {\n\t\t\t\tmalloc_snprintf(util, sizeof(util), \"0.0%zu\",\n\t\t\t\t    milli);\n\t\t\t} else if (milli < 1000) {\n\t\t\t\tmalloc_snprintf(util, sizeof(util), \"0.%zu\",\n\t\t\t\t    milli);\n\t\t\t} else\n\t\t\t\tmalloc_snprintf(util, sizeof(util), \"1\");\n\n\t\t\tif (config_tcache) {\n\t\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t\t    \"%20zu %3u %12zu %12\"FMTu64\n\t\t\t\t    \" %12\"FMTu64\" %12\"FMTu64\" %12zu\"\n\t\t\t\t    \" %12zu %4u %3zu %-5s %12\"FMTu64\n\t\t\t\t    \" %12\"FMTu64\" %12\"FMTu64\" %12\"FMTu64\"\\n\",\n\t\t\t\t    reg_size, j, curregs * reg_size, nmalloc,\n\t\t\t\t    ndalloc, nrequests, curregs, curruns, nregs,\n\t\t\t\t    run_size / page, util, nfills, nflushes,\n\t\t\t\t    nruns, reruns);\n\t\t\t} else {\n\t\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t\t    \"%20zu %3u %12zu %12\"FMTu64\n\t\t\t\t    \" %12\"FMTu64\" %12\"FMTu64\" %12zu\"\n\t\t\t\t    \" %12zu %4u %3zu %-5s %12\"FMTu64\n\t\t\t\t    \" %12\"FMTu64\"\\n\",\n\t\t\t\t    reg_size, j, curregs * reg_size, nmalloc,\n\t\t\t\t    ndalloc, nrequests, curregs, curruns, nregs,\n\t\t\t\t    run_size / page, util, nruns, reruns);\n\t\t\t}\n\t\t}\n\t}\n\tif (in_gap) {\n\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t    \"                     ---\\n\");\n\t}\n}\n\nstatic void\nstats_arena_lruns_print(void (*write_cb)(void *, const char *), void *cbopaque,\n    unsigned i)\n{\n\tunsigned nbins, nlruns, j;\n\tbool in_gap;\n\n\tmalloc_cprintf(write_cb, cbopaque,\n\t    \"large:          size ind    allocated      nmalloc      ndalloc\"\n\t    \"    nrequests      curruns\\n\");\n\tCTL_GET(\"arenas.nbins\", &nbins, unsigned);\n\tCTL_GET(\"arenas.nlruns\", &nlruns, unsigned);\n\tfor (j = 0, in_gap = false; j < nlruns; j++) {\n\t\tuint64_t nmalloc, ndalloc, nrequests;\n\t\tsize_t run_size, curruns;\n\n\t\tCTL_M2_M4_GET(\"stats.arenas.0.lruns.0.nmalloc\", i, j, &nmalloc,\n\t\t    uint64_t);\n\t\tCTL_M2_M4_GET(\"stats.arenas.0.lruns.0.ndalloc\", i, j, &ndalloc,\n\t\t    uint64_t);\n\t\tCTL_M2_M4_GET(\"stats.arenas.0.lruns.0.nrequests\", i, j,\n\t\t    &nrequests, uint64_t);\n\t\tif (nrequests == 0)\n\t\t\tin_gap = true;\n\t\telse {\n\t\t\tCTL_M2_GET(\"arenas.lrun.0.size\", j, &run_size, size_t);\n\t\t\tCTL_M2_M4_GET(\"stats.arenas.0.lruns.0.curruns\", i, j,\n\t\t\t    &curruns, size_t);\n\t\t\tif (in_gap) {\n\t\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t\t    \"                     ---\\n\");\n\t\t\t\tin_gap = false;\n\t\t\t}\n\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t    \"%20zu %3u %12zu %12\"FMTu64\" %12\"FMTu64\n\t\t\t    \" %12\"FMTu64\" %12zu\\n\",\n\t\t\t    run_size, nbins + j, curruns * run_size, nmalloc,\n\t\t\t    ndalloc, nrequests, curruns);\n\t\t}\n\t}\n\tif (in_gap) {\n\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t    \"                     ---\\n\");\n\t}\n}\n\nstatic void\nstats_arena_hchunks_print(void (*write_cb)(void *, const char *),\n    void *cbopaque, unsigned i)\n{\n\tunsigned nbins, nlruns, nhchunks, j;\n\tbool in_gap;\n\n\tmalloc_cprintf(write_cb, cbopaque,\n\t    \"huge:           size ind    allocated      nmalloc      ndalloc\"\n\t    \"    nrequests   curhchunks\\n\");\n\tCTL_GET(\"arenas.nbins\", &nbins, unsigned);\n\tCTL_GET(\"arenas.nlruns\", &nlruns, unsigned);\n\tCTL_GET(\"arenas.nhchunks\", &nhchunks, unsigned);\n\tfor (j = 0, in_gap = false; j < nhchunks; j++) {\n\t\tuint64_t nmalloc, ndalloc, nrequests;\n\t\tsize_t hchunk_size, curhchunks;\n\n\t\tCTL_M2_M4_GET(\"stats.arenas.0.hchunks.0.nmalloc\", i, j,\n\t\t    &nmalloc, uint64_t);\n\t\tCTL_M2_M4_GET(\"stats.arenas.0.hchunks.0.ndalloc\", i, j,\n\t\t    &ndalloc, uint64_t);\n\t\tCTL_M2_M4_GET(\"stats.arenas.0.hchunks.0.nrequests\", i, j,\n\t\t    &nrequests, uint64_t);\n\t\tif (nrequests == 0)\n\t\t\tin_gap = true;\n\t\telse {\n\t\t\tCTL_M2_GET(\"arenas.hchunk.0.size\", j, &hchunk_size,\n\t\t\t    size_t);\n\t\t\tCTL_M2_M4_GET(\"stats.arenas.0.hchunks.0.curhchunks\", i,\n\t\t\t    j, &curhchunks, size_t);\n\t\t\tif (in_gap) {\n\t\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t\t    \"                     ---\\n\");\n\t\t\t\tin_gap = false;\n\t\t\t}\n\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t    \"%20zu %3u %12zu %12\"FMTu64\" %12\"FMTu64\n\t\t\t    \" %12\"FMTu64\" %12zu\\n\",\n\t\t\t    hchunk_size, nbins + nlruns + j,\n\t\t\t    curhchunks * hchunk_size, nmalloc, ndalloc,\n\t\t\t    nrequests, curhchunks);\n\t\t}\n\t}\n\tif (in_gap) {\n\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t    \"                     ---\\n\");\n\t}\n}\n\nstatic void\nstats_arena_print(void (*write_cb)(void *, const char *), void *cbopaque,\n    unsigned i, bool bins, bool large, bool huge)\n{\n\tunsigned nthreads;\n\tconst char *dss;\n\tssize_t lg_dirty_mult, decay_time;\n\tsize_t page, pactive, pdirty, mapped;\n\tsize_t metadata_mapped, metadata_allocated;\n\tuint64_t npurge, nmadvise, purged;\n\tsize_t small_allocated;\n\tuint64_t small_nmalloc, small_ndalloc, small_nrequests;\n\tsize_t large_allocated;\n\tuint64_t large_nmalloc, large_ndalloc, large_nrequests;\n\tsize_t huge_allocated;\n\tuint64_t huge_nmalloc, huge_ndalloc, huge_nrequests;\n\n\tCTL_GET(\"arenas.page\", &page, size_t);\n\n\tCTL_M2_GET(\"stats.arenas.0.nthreads\", i, &nthreads, unsigned);\n\tmalloc_cprintf(write_cb, cbopaque,\n\t    \"assigned threads: %u\\n\", nthreads);\n\tCTL_M2_GET(\"stats.arenas.0.dss\", i, &dss, const char *);\n\tmalloc_cprintf(write_cb, cbopaque, \"dss allocation precedence: %s\\n\",\n\t    dss);\n\tCTL_M2_GET(\"stats.arenas.0.lg_dirty_mult\", i, &lg_dirty_mult, ssize_t);\n\tif (opt_purge == purge_mode_ratio) {\n\t\tif (lg_dirty_mult >= 0) {\n\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t    \"min active:dirty page ratio: %u:1\\n\",\n\t\t\t    (1U << lg_dirty_mult));\n\t\t} else {\n\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t    \"min active:dirty page ratio: N/A\\n\");\n\t\t}\n\t}\n\tCTL_M2_GET(\"stats.arenas.0.decay_time\", i, &decay_time, ssize_t);\n\tif (opt_purge == purge_mode_decay) {\n\t\tif (decay_time >= 0) {\n\t\t\tmalloc_cprintf(write_cb, cbopaque, \"decay time: %zd\\n\",\n\t\t\t    decay_time);\n\t\t} else\n\t\t\tmalloc_cprintf(write_cb, cbopaque, \"decay time: N/A\\n\");\n\t}\n\tCTL_M2_GET(\"stats.arenas.0.pactive\", i, &pactive, size_t);\n\tCTL_M2_GET(\"stats.arenas.0.pdirty\", i, &pdirty, size_t);\n\tCTL_M2_GET(\"stats.arenas.0.npurge\", i, &npurge, uint64_t);\n\tCTL_M2_GET(\"stats.arenas.0.nmadvise\", i, &nmadvise, uint64_t);\n\tCTL_M2_GET(\"stats.arenas.0.purged\", i, &purged, uint64_t);\n\tmalloc_cprintf(write_cb, cbopaque,\n\t    \"purging: dirty: %zu, sweeps: %\"FMTu64\", madvises: %\"FMTu64\", \"\n\t    \"purged: %\"FMTu64\"\\n\", pdirty, npurge, nmadvise, purged);\n\n\tmalloc_cprintf(write_cb, cbopaque,\n\t    \"                            allocated      nmalloc      ndalloc\"\n\t    \"    nrequests\\n\");\n\tCTL_M2_GET(\"stats.arenas.0.small.allocated\", i, &small_allocated,\n\t    size_t);\n\tCTL_M2_GET(\"stats.arenas.0.small.nmalloc\", i, &small_nmalloc, uint64_t);\n\tCTL_M2_GET(\"stats.arenas.0.small.ndalloc\", i, &small_ndalloc, uint64_t);\n\tCTL_M2_GET(\"stats.arenas.0.small.nrequests\", i, &small_nrequests,\n\t    uint64_t);\n\tmalloc_cprintf(write_cb, cbopaque,\n\t    \"small:                   %12zu %12\"FMTu64\" %12\"FMTu64\n\t    \" %12\"FMTu64\"\\n\",\n\t    small_allocated, small_nmalloc, small_ndalloc, small_nrequests);\n\tCTL_M2_GET(\"stats.arenas.0.large.allocated\", i, &large_allocated,\n\t    size_t);\n\tCTL_M2_GET(\"stats.arenas.0.large.nmalloc\", i, &large_nmalloc, uint64_t);\n\tCTL_M2_GET(\"stats.arenas.0.large.ndalloc\", i, &large_ndalloc, uint64_t);\n\tCTL_M2_GET(\"stats.arenas.0.large.nrequests\", i, &large_nrequests,\n\t    uint64_t);\n\tmalloc_cprintf(write_cb, cbopaque,\n\t    \"large:                   %12zu %12\"FMTu64\" %12\"FMTu64\n\t    \" %12\"FMTu64\"\\n\",\n\t    large_allocated, large_nmalloc, large_ndalloc, large_nrequests);\n\tCTL_M2_GET(\"stats.arenas.0.huge.allocated\", i, &huge_allocated, size_t);\n\tCTL_M2_GET(\"stats.arenas.0.huge.nmalloc\", i, &huge_nmalloc, uint64_t);\n\tCTL_M2_GET(\"stats.arenas.0.huge.ndalloc\", i, &huge_ndalloc, uint64_t);\n\tCTL_M2_GET(\"stats.arenas.0.huge.nrequests\", i, &huge_nrequests,\n\t    uint64_t);\n\tmalloc_cprintf(write_cb, cbopaque,\n\t    \"huge:                    %12zu %12\"FMTu64\" %12\"FMTu64\n\t    \" %12\"FMTu64\"\\n\",\n\t    huge_allocated, huge_nmalloc, huge_ndalloc, huge_nrequests);\n\tmalloc_cprintf(write_cb, cbopaque,\n\t    \"total:                   %12zu %12\"FMTu64\" %12\"FMTu64\n\t    \" %12\"FMTu64\"\\n\",\n\t    small_allocated + large_allocated + huge_allocated,\n\t    small_nmalloc + large_nmalloc + huge_nmalloc,\n\t    small_ndalloc + large_ndalloc + huge_ndalloc,\n\t    small_nrequests + large_nrequests + huge_nrequests);\n\tmalloc_cprintf(write_cb, cbopaque,\n\t    \"active:                  %12zu\\n\", pactive * page);\n\tCTL_M2_GET(\"stats.arenas.0.mapped\", i, &mapped, size_t);\n\tmalloc_cprintf(write_cb, cbopaque,\n\t    \"mapped:                  %12zu\\n\", mapped);\n\tCTL_M2_GET(\"stats.arenas.0.metadata.mapped\", i, &metadata_mapped,\n\t    size_t);\n\tCTL_M2_GET(\"stats.arenas.0.metadata.allocated\", i, &metadata_allocated,\n\t    size_t);\n\tmalloc_cprintf(write_cb, cbopaque,\n\t    \"metadata: mapped: %zu, allocated: %zu\\n\",\n\t    metadata_mapped, metadata_allocated);\n\n\tif (bins)\n\t\tstats_arena_bins_print(write_cb, cbopaque, i);\n\tif (large)\n\t\tstats_arena_lruns_print(write_cb, cbopaque, i);\n\tif (huge)\n\t\tstats_arena_hchunks_print(write_cb, cbopaque, i);\n}\n\nvoid\nstats_print(void (*write_cb)(void *, const char *), void *cbopaque,\n    const char *opts)\n{\n\tint err;\n\tuint64_t epoch;\n\tsize_t u64sz;\n\tbool general = true;\n\tbool merged = true;\n\tbool unmerged = true;\n\tbool bins = true;\n\tbool large = true;\n\tbool huge = true;\n\n\t/*\n\t * Refresh stats, in case mallctl() was called by the application.\n\t *\n\t * Check for OOM here, since refreshing the ctl cache can trigger\n\t * allocation.  In practice, none of the subsequent mallctl()-related\n\t * calls in this function will cause OOM if this one succeeds.\n\t * */\n\tepoch = 1;\n\tu64sz = sizeof(uint64_t);\n\terr = je_mallctl(\"epoch\", &epoch, &u64sz, &epoch, sizeof(uint64_t));\n\tif (err != 0) {\n\t\tif (err == EAGAIN) {\n\t\t\tmalloc_write(\"<jemalloc>: Memory allocation failure in \"\n\t\t\t    \"mallctl(\\\"epoch\\\", ...)\\n\");\n\t\t\treturn;\n\t\t}\n\t\tmalloc_write(\"<jemalloc>: Failure in mallctl(\\\"epoch\\\", \"\n\t\t    \"...)\\n\");\n\t\tabort();\n\t}\n\n\tif (opts != NULL) {\n\t\tunsigned i;\n\n\t\tfor (i = 0; opts[i] != '\\0'; i++) {\n\t\t\tswitch (opts[i]) {\n\t\t\tcase 'g':\n\t\t\t\tgeneral = false;\n\t\t\t\tbreak;\n\t\t\tcase 'm':\n\t\t\t\tmerged = false;\n\t\t\t\tbreak;\n\t\t\tcase 'a':\n\t\t\t\tunmerged = false;\n\t\t\t\tbreak;\n\t\t\tcase 'b':\n\t\t\t\tbins = false;\n\t\t\t\tbreak;\n\t\t\tcase 'l':\n\t\t\t\tlarge = false;\n\t\t\t\tbreak;\n\t\t\tcase 'h':\n\t\t\t\thuge = false;\n\t\t\t\tbreak;\n\t\t\tdefault:;\n\t\t\t}\n\t\t}\n\t}\n\n\tmalloc_cprintf(write_cb, cbopaque,\n\t    \"___ Begin jemalloc statistics ___\\n\");\n\tif (general) {\n\t\tconst char *cpv;\n\t\tbool bv;\n\t\tunsigned uv;\n\t\tssize_t ssv;\n\t\tsize_t sv, bsz, usz, ssz, sssz, cpsz;\n\n\t\tbsz = sizeof(bool);\n\t\tusz = sizeof(unsigned);\n\t\tssz = sizeof(size_t);\n\t\tsssz = sizeof(ssize_t);\n\t\tcpsz = sizeof(const char *);\n\n\t\tCTL_GET(\"version\", &cpv, const char *);\n\t\tmalloc_cprintf(write_cb, cbopaque, \"Version: %s\\n\", cpv);\n\t\tCTL_GET(\"config.debug\", &bv, bool);\n\t\tmalloc_cprintf(write_cb, cbopaque, \"Assertions %s\\n\",\n\t\t    bv ? \"enabled\" : \"disabled\");\n\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t    \"config.malloc_conf: \\\"%s\\\"\\n\", config_malloc_conf);\n\n#define\tOPT_WRITE_BOOL(n)\t\t\t\t\t\t\\\n\t\tif (je_mallctl(\"opt.\"#n, &bv, &bsz, NULL, 0) == 0) {\t\\\n\t\t\tmalloc_cprintf(write_cb, cbopaque,\t\t\\\n\t\t\t    \"  opt.\"#n\": %s\\n\", bv ? \"true\" : \"false\");\t\\\n\t\t}\n#define\tOPT_WRITE_BOOL_MUTABLE(n, m) {\t\t\t\t\t\\\n\t\tbool bv2;\t\t\t\t\t\t\\\n\t\tif (je_mallctl(\"opt.\"#n, &bv, &bsz, NULL, 0) == 0 &&\t\\\n\t\t    je_mallctl(#m, &bv2, &bsz, NULL, 0) == 0) {\t\t\\\n\t\t\tmalloc_cprintf(write_cb, cbopaque,\t\t\\\n\t\t\t    \"  opt.\"#n\": %s (\"#m\": %s)\\n\", bv ? \"true\"\t\\\n\t\t\t    : \"false\", bv2 ? \"true\" : \"false\");\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n}\n#define\tOPT_WRITE_UNSIGNED(n)\t\t\t\t\t\t\\\n\t\tif (je_mallctl(\"opt.\"#n, &uv, &usz, NULL, 0) == 0) {\t\\\n\t\t\tmalloc_cprintf(write_cb, cbopaque,\t\t\\\n\t\t\t\"  opt.\"#n\": %zu\\n\", sv);\t\t\t\\\n\t\t}\n#define\tOPT_WRITE_SIZE_T(n)\t\t\t\t\t\t\\\n\t\tif (je_mallctl(\"opt.\"#n, &sv, &ssz, NULL, 0) == 0) {\t\\\n\t\t\tmalloc_cprintf(write_cb, cbopaque,\t\t\\\n\t\t\t\"  opt.\"#n\": %zu\\n\", sv);\t\t\t\\\n\t\t}\n#define\tOPT_WRITE_SSIZE_T(n)\t\t\t\t\t\t\\\n\t\tif (je_mallctl(\"opt.\"#n, &ssv, &sssz, NULL, 0) == 0) {\t\\\n\t\t\tmalloc_cprintf(write_cb, cbopaque,\t\t\\\n\t\t\t    \"  opt.\"#n\": %zd\\n\", ssv);\t\t\t\\\n\t\t}\n#define\tOPT_WRITE_SSIZE_T_MUTABLE(n, m) {\t\t\t\t\\\n\t\tssize_t ssv2;\t\t\t\t\t\t\\\n\t\tif (je_mallctl(\"opt.\"#n, &ssv, &sssz, NULL, 0) == 0 &&\t\\\n\t\t    je_mallctl(#m, &ssv2, &sssz, NULL, 0) == 0) {\t\\\n\t\t\tmalloc_cprintf(write_cb, cbopaque,\t\t\\\n\t\t\t    \"  opt.\"#n\": %zd (\"#m\": %zd)\\n\",\t\t\\\n\t\t\t    ssv, ssv2);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n}\n#define\tOPT_WRITE_CHAR_P(n)\t\t\t\t\t\t\\\n\t\tif (je_mallctl(\"opt.\"#n, &cpv, &cpsz, NULL, 0) == 0) {\t\\\n\t\t\tmalloc_cprintf(write_cb, cbopaque,\t\t\\\n\t\t\t    \"  opt.\"#n\": \\\"%s\\\"\\n\", cpv);\t\t\\\n\t\t}\n\n\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t    \"Run-time option settings:\\n\");\n\t\tOPT_WRITE_BOOL(abort)\n\t\tOPT_WRITE_SIZE_T(lg_chunk)\n\t\tOPT_WRITE_CHAR_P(dss)\n\t\tOPT_WRITE_UNSIGNED(narenas)\n\t\tOPT_WRITE_CHAR_P(purge)\n\t\tif (opt_purge == purge_mode_ratio) {\n\t\t\tOPT_WRITE_SSIZE_T_MUTABLE(lg_dirty_mult,\n\t\t\t    arenas.lg_dirty_mult)\n\t\t}\n\t\tif (opt_purge == purge_mode_decay)\n\t\t\tOPT_WRITE_SSIZE_T_MUTABLE(decay_time, arenas.decay_time)\n\t\tOPT_WRITE_BOOL(stats_print)\n\t\tOPT_WRITE_CHAR_P(junk)\n\t\tOPT_WRITE_SIZE_T(quarantine)\n\t\tOPT_WRITE_BOOL(redzone)\n\t\tOPT_WRITE_BOOL(zero)\n\t\tOPT_WRITE_BOOL(utrace)\n\t\tOPT_WRITE_BOOL(valgrind)\n\t\tOPT_WRITE_BOOL(xmalloc)\n\t\tOPT_WRITE_BOOL(tcache)\n\t\tOPT_WRITE_SSIZE_T(lg_tcache_max)\n\t\tOPT_WRITE_BOOL(prof)\n\t\tOPT_WRITE_CHAR_P(prof_prefix)\n\t\tOPT_WRITE_BOOL_MUTABLE(prof_active, prof.active)\n\t\tOPT_WRITE_BOOL_MUTABLE(prof_thread_active_init,\n\t\t    prof.thread_active_init)\n\t\tOPT_WRITE_SSIZE_T(lg_prof_sample)\n\t\tOPT_WRITE_BOOL(prof_accum)\n\t\tOPT_WRITE_SSIZE_T(lg_prof_interval)\n\t\tOPT_WRITE_BOOL(prof_gdump)\n\t\tOPT_WRITE_BOOL(prof_final)\n\t\tOPT_WRITE_BOOL(prof_leak)\n\n#undef OPT_WRITE_BOOL\n#undef OPT_WRITE_BOOL_MUTABLE\n#undef OPT_WRITE_SIZE_T\n#undef OPT_WRITE_SSIZE_T\n#undef OPT_WRITE_CHAR_P\n\n\t\tmalloc_cprintf(write_cb, cbopaque, \"CPUs: %u\\n\", ncpus);\n\n\t\tCTL_GET(\"arenas.narenas\", &uv, unsigned);\n\t\tmalloc_cprintf(write_cb, cbopaque, \"Arenas: %u\\n\", uv);\n\n\t\tmalloc_cprintf(write_cb, cbopaque, \"Pointer size: %zu\\n\",\n\t\t    sizeof(void *));\n\n\t\tCTL_GET(\"arenas.quantum\", &sv, size_t);\n\t\tmalloc_cprintf(write_cb, cbopaque, \"Quantum size: %zu\\n\",\n\t\t    sv);\n\n\t\tCTL_GET(\"arenas.page\", &sv, size_t);\n\t\tmalloc_cprintf(write_cb, cbopaque, \"Page size: %zu\\n\", sv);\n\n\t\tCTL_GET(\"arenas.lg_dirty_mult\", &ssv, ssize_t);\n\t\tif (opt_purge == purge_mode_ratio) {\n\t\t\tif (ssv >= 0) {\n\t\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t\t    \"Min active:dirty page ratio per arena: \"\n\t\t\t\t    \"%u:1\\n\", (1U << ssv));\n\t\t\t} else {\n\t\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t\t    \"Min active:dirty page ratio per arena: \"\n\t\t\t\t    \"N/A\\n\");\n\t\t\t}\n\t\t}\n\t\tCTL_GET(\"arenas.decay_time\", &ssv, ssize_t);\n\t\tif (opt_purge == purge_mode_decay) {\n\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t    \"Unused dirty page decay time: %zd%s\\n\",\n\t\t\t    ssv, (ssv < 0) ? \" (no decay)\" : \"\");\n\t\t}\n\t\tif (je_mallctl(\"arenas.tcache_max\", &sv, &ssz, NULL, 0) == 0) {\n\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t    \"Maximum thread-cached size class: %zu\\n\", sv);\n\t\t}\n\t\tif (je_mallctl(\"opt.prof\", &bv, &bsz, NULL, 0) == 0 && bv) {\n\t\t\tCTL_GET(\"prof.lg_sample\", &sv, size_t);\n\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t    \"Average profile sample interval: %\"FMTu64\n\t\t\t    \" (2^%zu)\\n\", (((uint64_t)1U) << sv), sv);\n\n\t\t\tCTL_GET(\"opt.lg_prof_interval\", &ssv, ssize_t);\n\t\t\tif (ssv >= 0) {\n\t\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t\t    \"Average profile dump interval: %\"FMTu64\n\t\t\t\t    \" (2^%zd)\\n\",\n\t\t\t\t    (((uint64_t)1U) << ssv), ssv);\n\t\t\t} else {\n\t\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t\t    \"Average profile dump interval: N/A\\n\");\n\t\t\t}\n\t\t}\n\t\tCTL_GET(\"opt.lg_chunk\", &sv, size_t);\n\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t    \"Chunk size: %zu (2^%zu)\\n\", (ZU(1) << sv), sv);\n\t}\n\n\tif (config_stats) {\n\t\tsize_t *cactive;\n\t\tsize_t allocated, active, metadata, resident, mapped;\n\n\t\tCTL_GET(\"stats.cactive\", &cactive, size_t *);\n\t\tCTL_GET(\"stats.allocated\", &allocated, size_t);\n\t\tCTL_GET(\"stats.active\", &active, size_t);\n\t\tCTL_GET(\"stats.metadata\", &metadata, size_t);\n\t\tCTL_GET(\"stats.resident\", &resident, size_t);\n\t\tCTL_GET(\"stats.mapped\", &mapped, size_t);\n\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t    \"Allocated: %zu, active: %zu, metadata: %zu,\"\n\t\t    \" resident: %zu, mapped: %zu\\n\",\n\t\t    allocated, active, metadata, resident, mapped);\n\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t    \"Current active ceiling: %zu\\n\",\n\t\t    atomic_read_z(cactive));\n\n\t\tif (merged) {\n\t\t\tunsigned narenas;\n\n\t\t\tCTL_GET(\"arenas.narenas\", &narenas, unsigned);\n\t\t\t{\n\t\t\t\tVARIABLE_ARRAY(bool, initialized, narenas);\n\t\t\t\tsize_t isz;\n\t\t\t\tunsigned i, ninitialized;\n\n\t\t\t\tisz = sizeof(bool) * narenas;\n\t\t\t\txmallctl(\"arenas.initialized\", initialized,\n\t\t\t\t    &isz, NULL, 0);\n\t\t\t\tfor (i = ninitialized = 0; i < narenas; i++) {\n\t\t\t\t\tif (initialized[i])\n\t\t\t\t\t\tninitialized++;\n\t\t\t\t}\n\n\t\t\t\tif (ninitialized > 1 || !unmerged) {\n\t\t\t\t\t/* Print merged arena stats. */\n\t\t\t\t\tmalloc_cprintf(write_cb, cbopaque,\n\t\t\t\t\t    \"\\nMerged arenas stats:\\n\");\n\t\t\t\t\tstats_arena_print(write_cb, cbopaque,\n\t\t\t\t\t    narenas, bins, large, huge);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (unmerged) {\n\t\t\tunsigned narenas;\n\n\t\t\t/* Print stats for each arena. */\n\n\t\t\tCTL_GET(\"arenas.narenas\", &narenas, unsigned);\n\t\t\t{\n\t\t\t\tVARIABLE_ARRAY(bool, initialized, narenas);\n\t\t\t\tsize_t isz;\n\t\t\t\tunsigned i;\n\n\t\t\t\tisz = sizeof(bool) * narenas;\n\t\t\t\txmallctl(\"arenas.initialized\", initialized,\n\t\t\t\t    &isz, NULL, 0);\n\n\t\t\t\tfor (i = 0; i < narenas; i++) {\n\t\t\t\t\tif (initialized[i]) {\n\t\t\t\t\t\tmalloc_cprintf(write_cb,\n\t\t\t\t\t\t    cbopaque,\n\t\t\t\t\t\t    \"\\narenas[%u]:\\n\", i);\n\t\t\t\t\t\tstats_arena_print(write_cb,\n\t\t\t\t\t\t    cbopaque, i, bins, large,\n\t\t\t\t\t\t    huge);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tmalloc_cprintf(write_cb, cbopaque, \"--- End jemalloc statistics ---\\n\");\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/tcache.c",
    "content": "#define\tJEMALLOC_TCACHE_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n/******************************************************************************/\n/* Data. */\n\nbool\topt_tcache = true;\nssize_t\topt_lg_tcache_max = LG_TCACHE_MAXCLASS_DEFAULT;\n\ntcache_bin_info_t\t*tcache_bin_info;\nstatic unsigned\t\tstack_nelms; /* Total stack elms per tcache. */\n\nunsigned\t\tnhbins;\nsize_t\t\t\ttcache_maxclass;\n\ntcaches_t\t\t*tcaches;\n\n/* Index of first element within tcaches that has never been used. */\nstatic unsigned\t\ttcaches_past;\n\n/* Head of singly linked list tracking available tcaches elements. */\nstatic tcaches_t\t*tcaches_avail;\n\n/******************************************************************************/\n\nsize_t\ttcache_salloc(const void *ptr)\n{\n\n\treturn (arena_salloc(ptr, false));\n}\n\nvoid\ntcache_event_hard(tsd_t *tsd, tcache_t *tcache)\n{\n\tszind_t binind = tcache->next_gc_bin;\n\ttcache_bin_t *tbin = &tcache->tbins[binind];\n\ttcache_bin_info_t *tbin_info = &tcache_bin_info[binind];\n\n\tif (tbin->low_water > 0) {\n\t\t/*\n\t\t * Flush (ceiling) 3/4 of the objects below the low water mark.\n\t\t */\n\t\tif (binind < NBINS) {\n\t\t\ttcache_bin_flush_small(tsd, tcache, tbin, binind,\n\t\t\t    tbin->ncached - tbin->low_water + (tbin->low_water\n\t\t\t    >> 2));\n\t\t} else {\n\t\t\ttcache_bin_flush_large(tsd, tbin, binind, tbin->ncached\n\t\t\t    - tbin->low_water + (tbin->low_water >> 2), tcache);\n\t\t}\n\t\t/*\n\t\t * Reduce fill count by 2X.  Limit lg_fill_div such that the\n\t\t * fill count is always at least 1.\n\t\t */\n\t\tif ((tbin_info->ncached_max >> (tbin->lg_fill_div+1)) >= 1)\n\t\t\ttbin->lg_fill_div++;\n\t} else if (tbin->low_water < 0) {\n\t\t/*\n\t\t * Increase fill count by 2X.  Make sure lg_fill_div stays\n\t\t * greater than 0.\n\t\t */\n\t\tif (tbin->lg_fill_div > 1)\n\t\t\ttbin->lg_fill_div--;\n\t}\n\ttbin->low_water = tbin->ncached;\n\n\ttcache->next_gc_bin++;\n\tif (tcache->next_gc_bin == nhbins)\n\t\ttcache->next_gc_bin = 0;\n}\n\nvoid *\ntcache_alloc_small_hard(tsd_t *tsd, arena_t *arena, tcache_t *tcache,\n    tcache_bin_t *tbin, szind_t binind, bool *tcache_success)\n{\n\tvoid *ret;\n\n\tarena_tcache_fill_small(tsd, arena, tbin, binind, config_prof ?\n\t    tcache->prof_accumbytes : 0);\n\tif (config_prof)\n\t\ttcache->prof_accumbytes = 0;\n\tret = tcache_alloc_easy(tbin, tcache_success);\n\n\treturn (ret);\n}\n\nvoid\ntcache_bin_flush_small(tsd_t *tsd, tcache_t *tcache, tcache_bin_t *tbin,\n    szind_t binind, unsigned rem)\n{\n\tarena_t *arena;\n\tvoid *ptr;\n\tunsigned i, nflush, ndeferred;\n\tbool merged_stats = false;\n\n\tassert(binind < NBINS);\n\tassert(rem <= tbin->ncached);\n\n\tarena = arena_choose(tsd, NULL);\n\tassert(arena != NULL);\n\tfor (nflush = tbin->ncached - rem; nflush > 0; nflush = ndeferred) {\n\t\t/* Lock the arena bin associated with the first object. */\n\t\tarena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(\n\t\t    *(tbin->avail - 1));\n\t\tarena_t *bin_arena = extent_node_arena_get(&chunk->node);\n\t\tarena_bin_t *bin = &bin_arena->bins[binind];\n\n\t\tif (config_prof && bin_arena == arena) {\n\t\t\tif (arena_prof_accum(arena, tcache->prof_accumbytes))\n\t\t\t\tprof_idump();\n\t\t\ttcache->prof_accumbytes = 0;\n\t\t}\n\n\t\tmalloc_mutex_lock(&bin->lock);\n\t\tif (config_stats && bin_arena == arena) {\n\t\t\tassert(!merged_stats);\n\t\t\tmerged_stats = true;\n\t\t\tbin->stats.nflushes++;\n\t\t\tbin->stats.nrequests += tbin->tstats.nrequests;\n\t\t\ttbin->tstats.nrequests = 0;\n\t\t}\n\t\tndeferred = 0;\n\t\tfor (i = 0; i < nflush; i++) {\n\t\t\tptr = *(tbin->avail - 1 - i);\n\t\t\tassert(ptr != NULL);\n\t\t\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);\n\t\t\tif (extent_node_arena_get(&chunk->node) == bin_arena) {\n\t\t\t\tsize_t pageind = ((uintptr_t)ptr -\n\t\t\t\t    (uintptr_t)chunk) >> LG_PAGE;\n\t\t\t\tarena_chunk_map_bits_t *bitselm =\n\t\t\t\t    arena_bitselm_get(chunk, pageind);\n\t\t\t\tarena_dalloc_bin_junked_locked(bin_arena, chunk,\n\t\t\t\t    ptr, bitselm);\n\t\t\t} else {\n\t\t\t\t/*\n\t\t\t\t * This object was allocated via a different\n\t\t\t\t * arena bin than the one that is currently\n\t\t\t\t * locked.  Stash the object, so that it can be\n\t\t\t\t * handled in a future pass.\n\t\t\t\t */\n\t\t\t\t*(tbin->avail - 1 - ndeferred) = ptr;\n\t\t\t\tndeferred++;\n\t\t\t}\n\t\t}\n\t\tmalloc_mutex_unlock(&bin->lock);\n\t\tarena_decay_ticks(tsd, bin_arena, nflush - ndeferred);\n\t}\n\tif (config_stats && !merged_stats) {\n\t\t/*\n\t\t * The flush loop didn't happen to flush to this thread's\n\t\t * arena, so the stats didn't get merged.  Manually do so now.\n\t\t */\n\t\tarena_bin_t *bin = &arena->bins[binind];\n\t\tmalloc_mutex_lock(&bin->lock);\n\t\tbin->stats.nflushes++;\n\t\tbin->stats.nrequests += tbin->tstats.nrequests;\n\t\ttbin->tstats.nrequests = 0;\n\t\tmalloc_mutex_unlock(&bin->lock);\n\t}\n\n\tmemmove(tbin->avail - rem, tbin->avail - tbin->ncached, rem *\n\t    sizeof(void *));\n\ttbin->ncached = rem;\n\tif ((int)tbin->ncached < tbin->low_water)\n\t\ttbin->low_water = tbin->ncached;\n}\n\nvoid\ntcache_bin_flush_large(tsd_t *tsd, tcache_bin_t *tbin, szind_t binind,\n    unsigned rem, tcache_t *tcache)\n{\n\tarena_t *arena;\n\tvoid *ptr;\n\tunsigned i, nflush, ndeferred;\n\tbool merged_stats = false;\n\n\tassert(binind < nhbins);\n\tassert(rem <= tbin->ncached);\n\n\tarena = arena_choose(tsd, NULL);\n\tassert(arena != NULL);\n\tfor (nflush = tbin->ncached - rem; nflush > 0; nflush = ndeferred) {\n\t\t/* Lock the arena associated with the first object. */\n\t\tarena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(\n\t\t    *(tbin->avail - 1));\n\t\tarena_t *locked_arena = extent_node_arena_get(&chunk->node);\n\t\tUNUSED bool idump;\n\n\t\tif (config_prof)\n\t\t\tidump = false;\n\t\tmalloc_mutex_lock(&locked_arena->lock);\n\t\tif ((config_prof || config_stats) && locked_arena == arena) {\n\t\t\tif (config_prof) {\n\t\t\t\tidump = arena_prof_accum_locked(arena,\n\t\t\t\t    tcache->prof_accumbytes);\n\t\t\t\ttcache->prof_accumbytes = 0;\n\t\t\t}\n\t\t\tif (config_stats) {\n\t\t\t\tmerged_stats = true;\n\t\t\t\tarena->stats.nrequests_large +=\n\t\t\t\t    tbin->tstats.nrequests;\n\t\t\t\tarena->stats.lstats[binind - NBINS].nrequests +=\n\t\t\t\t    tbin->tstats.nrequests;\n\t\t\t\ttbin->tstats.nrequests = 0;\n\t\t\t}\n\t\t}\n\t\tndeferred = 0;\n\t\tfor (i = 0; i < nflush; i++) {\n\t\t\tptr = *(tbin->avail - 1 - i);\n\t\t\tassert(ptr != NULL);\n\t\t\tchunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);\n\t\t\tif (extent_node_arena_get(&chunk->node) ==\n\t\t\t    locked_arena) {\n\t\t\t\tarena_dalloc_large_junked_locked(locked_arena,\n\t\t\t\t    chunk, ptr);\n\t\t\t} else {\n\t\t\t\t/*\n\t\t\t\t * This object was allocated via a different\n\t\t\t\t * arena than the one that is currently locked.\n\t\t\t\t * Stash the object, so that it can be handled\n\t\t\t\t * in a future pass.\n\t\t\t\t */\n\t\t\t\t*(tbin->avail - 1 - ndeferred) = ptr;\n\t\t\t\tndeferred++;\n\t\t\t}\n\t\t}\n\t\tmalloc_mutex_unlock(&locked_arena->lock);\n\t\tif (config_prof && idump)\n\t\t\tprof_idump();\n\t\tarena_decay_ticks(tsd, locked_arena, nflush - ndeferred);\n\t}\n\tif (config_stats && !merged_stats) {\n\t\t/*\n\t\t * The flush loop didn't happen to flush to this thread's\n\t\t * arena, so the stats didn't get merged.  Manually do so now.\n\t\t */\n\t\tmalloc_mutex_lock(&arena->lock);\n\t\tarena->stats.nrequests_large += tbin->tstats.nrequests;\n\t\tarena->stats.lstats[binind - NBINS].nrequests +=\n\t\t    tbin->tstats.nrequests;\n\t\ttbin->tstats.nrequests = 0;\n\t\tmalloc_mutex_unlock(&arena->lock);\n\t}\n\n\tmemmove(tbin->avail - rem, tbin->avail - tbin->ncached, rem *\n\t    sizeof(void *));\n\ttbin->ncached = rem;\n\tif ((int)tbin->ncached < tbin->low_water)\n\t\ttbin->low_water = tbin->ncached;\n}\n\nvoid\ntcache_arena_associate(tcache_t *tcache, arena_t *arena)\n{\n\n\tif (config_stats) {\n\t\t/* Link into list of extant tcaches. */\n\t\tmalloc_mutex_lock(&arena->lock);\n\t\tql_elm_new(tcache, link);\n\t\tql_tail_insert(&arena->tcache_ql, tcache, link);\n\t\tmalloc_mutex_unlock(&arena->lock);\n\t}\n}\n\nvoid\ntcache_arena_reassociate(tcache_t *tcache, arena_t *oldarena, arena_t *newarena)\n{\n\n\ttcache_arena_dissociate(tcache, oldarena);\n\ttcache_arena_associate(tcache, newarena);\n}\n\nvoid\ntcache_arena_dissociate(tcache_t *tcache, arena_t *arena)\n{\n\n\tif (config_stats) {\n\t\t/* Unlink from list of extant tcaches. */\n\t\tmalloc_mutex_lock(&arena->lock);\n\t\tif (config_debug) {\n\t\t\tbool in_ql = false;\n\t\t\ttcache_t *iter;\n\t\t\tql_foreach(iter, &arena->tcache_ql, link) {\n\t\t\t\tif (iter == tcache) {\n\t\t\t\t\tin_ql = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tassert(in_ql);\n\t\t}\n\t\tql_remove(&arena->tcache_ql, tcache, link);\n\t\ttcache_stats_merge(tcache, arena);\n\t\tmalloc_mutex_unlock(&arena->lock);\n\t}\n}\n\ntcache_t *\ntcache_get_hard(tsd_t *tsd)\n{\n\tarena_t *arena;\n\n\tif (!tcache_enabled_get()) {\n\t\tif (tsd_nominal(tsd))\n\t\t\ttcache_enabled_set(false); /* Memoize. */\n\t\treturn (NULL);\n\t}\n\tarena = arena_choose(tsd, NULL);\n\tif (unlikely(arena == NULL))\n\t\treturn (NULL);\n\treturn (tcache_create(tsd, arena));\n}\n\ntcache_t *\ntcache_create(tsd_t *tsd, arena_t *arena)\n{\n\ttcache_t *tcache;\n\tsize_t size, stack_offset;\n\tunsigned i;\n\n\tsize = offsetof(tcache_t, tbins) + (sizeof(tcache_bin_t) * nhbins);\n\t/* Naturally align the pointer stacks. */\n\tsize = PTR_CEILING(size);\n\tstack_offset = size;\n\tsize += stack_nelms * sizeof(void *);\n\t/* Avoid false cacheline sharing. */\n\tsize = sa2u(size, CACHELINE);\n\n\ttcache = ipallocztm(tsd, size, CACHELINE, true, false, true,\n\t    arena_get(0, false));\n\tif (tcache == NULL)\n\t\treturn (NULL);\n\n\ttcache_arena_associate(tcache, arena);\n\n\tticker_init(&tcache->gc_ticker, TCACHE_GC_INCR);\n\n\tassert((TCACHE_NSLOTS_SMALL_MAX & 1U) == 0);\n\tfor (i = 0; i < nhbins; i++) {\n\t\ttcache->tbins[i].lg_fill_div = 1;\n\t\tstack_offset += tcache_bin_info[i].ncached_max * sizeof(void *);\n\t\t/*\n\t\t * avail points past the available space.  Allocations will\n\t\t * access the slots toward higher addresses (for the benefit of\n\t\t * prefetch).\n\t\t */\n\t\ttcache->tbins[i].avail = (void **)((uintptr_t)tcache +\n\t\t    (uintptr_t)stack_offset);\n\t}\n\n\treturn (tcache);\n}\n\nstatic void\ntcache_destroy(tsd_t *tsd, tcache_t *tcache)\n{\n\tarena_t *arena;\n\tunsigned i;\n\n\tarena = arena_choose(tsd, NULL);\n\ttcache_arena_dissociate(tcache, arena);\n\n\tfor (i = 0; i < NBINS; i++) {\n\t\ttcache_bin_t *tbin = &tcache->tbins[i];\n\t\ttcache_bin_flush_small(tsd, tcache, tbin, i, 0);\n\n\t\tif (config_stats && tbin->tstats.nrequests != 0) {\n\t\t\tarena_bin_t *bin = &arena->bins[i];\n\t\t\tmalloc_mutex_lock(&bin->lock);\n\t\t\tbin->stats.nrequests += tbin->tstats.nrequests;\n\t\t\tmalloc_mutex_unlock(&bin->lock);\n\t\t}\n\t}\n\n\tfor (; i < nhbins; i++) {\n\t\ttcache_bin_t *tbin = &tcache->tbins[i];\n\t\ttcache_bin_flush_large(tsd, tbin, i, 0, tcache);\n\n\t\tif (config_stats && tbin->tstats.nrequests != 0) {\n\t\t\tmalloc_mutex_lock(&arena->lock);\n\t\t\tarena->stats.nrequests_large += tbin->tstats.nrequests;\n\t\t\tarena->stats.lstats[i - NBINS].nrequests +=\n\t\t\t    tbin->tstats.nrequests;\n\t\t\tmalloc_mutex_unlock(&arena->lock);\n\t\t}\n\t}\n\n\tif (config_prof && tcache->prof_accumbytes > 0 &&\n\t    arena_prof_accum(arena, tcache->prof_accumbytes))\n\t\tprof_idump();\n\n\tidalloctm(tsd, tcache, false, true, true);\n}\n\nvoid\ntcache_cleanup(tsd_t *tsd)\n{\n\ttcache_t *tcache;\n\n\tif (!config_tcache)\n\t\treturn;\n\n\tif ((tcache = tsd_tcache_get(tsd)) != NULL) {\n\t\ttcache_destroy(tsd, tcache);\n\t\ttsd_tcache_set(tsd, NULL);\n\t}\n}\n\nvoid\ntcache_enabled_cleanup(tsd_t *tsd)\n{\n\n\t/* Do nothing. */\n}\n\n/* Caller must own arena->lock. */\nvoid\ntcache_stats_merge(tcache_t *tcache, arena_t *arena)\n{\n\tunsigned i;\n\n\tcassert(config_stats);\n\n\t/* Merge and reset tcache stats. */\n\tfor (i = 0; i < NBINS; i++) {\n\t\tarena_bin_t *bin = &arena->bins[i];\n\t\ttcache_bin_t *tbin = &tcache->tbins[i];\n\t\tmalloc_mutex_lock(&bin->lock);\n\t\tbin->stats.nrequests += tbin->tstats.nrequests;\n\t\tmalloc_mutex_unlock(&bin->lock);\n\t\ttbin->tstats.nrequests = 0;\n\t}\n\n\tfor (; i < nhbins; i++) {\n\t\tmalloc_large_stats_t *lstats = &arena->stats.lstats[i - NBINS];\n\t\ttcache_bin_t *tbin = &tcache->tbins[i];\n\t\tarena->stats.nrequests_large += tbin->tstats.nrequests;\n\t\tlstats->nrequests += tbin->tstats.nrequests;\n\t\ttbin->tstats.nrequests = 0;\n\t}\n}\n\nbool\ntcaches_create(tsd_t *tsd, unsigned *r_ind)\n{\n\ttcache_t *tcache;\n\ttcaches_t *elm;\n\n\tif (tcaches == NULL) {\n\t\ttcaches = base_alloc(sizeof(tcache_t *) *\n\t\t    (MALLOCX_TCACHE_MAX+1));\n\t\tif (tcaches == NULL)\n\t\t\treturn (true);\n\t}\n\n\tif (tcaches_avail == NULL && tcaches_past > MALLOCX_TCACHE_MAX)\n\t\treturn (true);\n\ttcache = tcache_create(tsd, arena_get(0, false));\n\tif (tcache == NULL)\n\t\treturn (true);\n\n\tif (tcaches_avail != NULL) {\n\t\telm = tcaches_avail;\n\t\ttcaches_avail = tcaches_avail->next;\n\t\telm->tcache = tcache;\n\t\t*r_ind = (unsigned)(elm - tcaches);\n\t} else {\n\t\telm = &tcaches[tcaches_past];\n\t\telm->tcache = tcache;\n\t\t*r_ind = tcaches_past;\n\t\ttcaches_past++;\n\t}\n\n\treturn (false);\n}\n\nstatic void\ntcaches_elm_flush(tsd_t *tsd, tcaches_t *elm)\n{\n\n\tif (elm->tcache == NULL)\n\t\treturn;\n\ttcache_destroy(tsd, elm->tcache);\n\telm->tcache = NULL;\n}\n\nvoid\ntcaches_flush(tsd_t *tsd, unsigned ind)\n{\n\n\ttcaches_elm_flush(tsd, &tcaches[ind]);\n}\n\nvoid\ntcaches_destroy(tsd_t *tsd, unsigned ind)\n{\n\ttcaches_t *elm = &tcaches[ind];\n\ttcaches_elm_flush(tsd, elm);\n\telm->next = tcaches_avail;\n\ttcaches_avail = elm;\n}\n\nbool\ntcache_boot(void)\n{\n\tunsigned i;\n\n\t/*\n\t * If necessary, clamp opt_lg_tcache_max, now that large_maxclass is\n\t * known.\n\t */\n\tif (opt_lg_tcache_max < 0 || (1U << opt_lg_tcache_max) < SMALL_MAXCLASS)\n\t\ttcache_maxclass = SMALL_MAXCLASS;\n\telse if ((1U << opt_lg_tcache_max) > large_maxclass)\n\t\ttcache_maxclass = large_maxclass;\n\telse\n\t\ttcache_maxclass = (1U << opt_lg_tcache_max);\n\n\tnhbins = size2index(tcache_maxclass) + 1;\n\n\t/* Initialize tcache_bin_info. */\n\ttcache_bin_info = (tcache_bin_info_t *)base_alloc(nhbins *\n\t    sizeof(tcache_bin_info_t));\n\tif (tcache_bin_info == NULL)\n\t\treturn (true);\n\tstack_nelms = 0;\n\tfor (i = 0; i < NBINS; i++) {\n\t\tif ((arena_bin_info[i].nregs << 1) <= TCACHE_NSLOTS_SMALL_MIN) {\n\t\t\ttcache_bin_info[i].ncached_max =\n\t\t\t    TCACHE_NSLOTS_SMALL_MIN;\n\t\t} else if ((arena_bin_info[i].nregs << 1) <=\n\t\t    TCACHE_NSLOTS_SMALL_MAX) {\n\t\t\ttcache_bin_info[i].ncached_max =\n\t\t\t    (arena_bin_info[i].nregs << 1);\n\t\t} else {\n\t\t\ttcache_bin_info[i].ncached_max =\n\t\t\t    TCACHE_NSLOTS_SMALL_MAX;\n\t\t}\n\t\tstack_nelms += tcache_bin_info[i].ncached_max;\n\t}\n\tfor (; i < nhbins; i++) {\n\t\ttcache_bin_info[i].ncached_max = TCACHE_NSLOTS_LARGE;\n\t\tstack_nelms += tcache_bin_info[i].ncached_max;\n\t}\n\n\treturn (false);\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/ticker.c",
    "content": "#define\tJEMALLOC_TICKER_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/tsd.c",
    "content": "#define\tJEMALLOC_TSD_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n/******************************************************************************/\n/* Data. */\n\nstatic unsigned ncleanups;\nstatic malloc_tsd_cleanup_t cleanups[MALLOC_TSD_CLEANUPS_MAX];\n\nmalloc_tsd_data(, , tsd_t, TSD_INITIALIZER)\n\n/******************************************************************************/\n\nvoid *\nmalloc_tsd_malloc(size_t size)\n{\n\n\treturn (a0malloc(CACHELINE_CEILING(size)));\n}\n\nvoid\nmalloc_tsd_dalloc(void *wrapper)\n{\n\n\ta0dalloc(wrapper);\n}\n\nvoid\nmalloc_tsd_no_cleanup(void *arg)\n{\n\n\tnot_reached();\n}\n\n#if defined(JEMALLOC_MALLOC_THREAD_CLEANUP) || defined(_WIN32)\n#ifndef _WIN32\nJEMALLOC_EXPORT\n#endif\nvoid\n_malloc_thread_cleanup(void)\n{\n\tbool pending[MALLOC_TSD_CLEANUPS_MAX], again;\n\tunsigned i;\n\n\tfor (i = 0; i < ncleanups; i++)\n\t\tpending[i] = true;\n\n\tdo {\n\t\tagain = false;\n\t\tfor (i = 0; i < ncleanups; i++) {\n\t\t\tif (pending[i]) {\n\t\t\t\tpending[i] = cleanups[i]();\n\t\t\t\tif (pending[i])\n\t\t\t\t\tagain = true;\n\t\t\t}\n\t\t}\n\t} while (again);\n}\n#endif\n\nvoid\nmalloc_tsd_cleanup_register(bool (*f)(void))\n{\n\n\tassert(ncleanups < MALLOC_TSD_CLEANUPS_MAX);\n\tcleanups[ncleanups] = f;\n\tncleanups++;\n}\n\nvoid\ntsd_cleanup(void *arg)\n{\n\ttsd_t *tsd = (tsd_t *)arg;\n\n\tswitch (tsd->state) {\n\tcase tsd_state_uninitialized:\n\t\t/* Do nothing. */\n\t\tbreak;\n\tcase tsd_state_nominal:\n#define O(n, t)\t\t\t\t\t\t\t\t\\\n\t\tn##_cleanup(tsd);\nMALLOC_TSD\n#undef O\n\t\ttsd->state = tsd_state_purgatory;\n\t\ttsd_set(tsd);\n\t\tbreak;\n\tcase tsd_state_purgatory:\n\t\t/*\n\t\t * The previous time this destructor was called, we set the\n\t\t * state to tsd_state_purgatory so that other destructors\n\t\t * wouldn't cause re-creation of the tsd.  This time, do\n\t\t * nothing, and do not request another callback.\n\t\t */\n\t\tbreak;\n\tcase tsd_state_reincarnated:\n\t\t/*\n\t\t * Another destructor deallocated memory after this destructor\n\t\t * was called.  Reset state to tsd_state_purgatory and request\n\t\t * another callback.\n\t\t */\n\t\ttsd->state = tsd_state_purgatory;\n\t\ttsd_set(tsd);\n\t\tbreak;\n\tdefault:\n\t\tnot_reached();\n\t}\n}\n\nbool\nmalloc_tsd_boot0(void)\n{\n\n\tncleanups = 0;\n\tif (tsd_boot0())\n\t\treturn (true);\n\t*tsd_arenas_tdata_bypassp_get(tsd_fetch()) = true;\n\treturn (false);\n}\n\nvoid\nmalloc_tsd_boot1(void)\n{\n\n\ttsd_boot1();\n\t*tsd_arenas_tdata_bypassp_get(tsd_fetch()) = false;\n}\n\n#ifdef _WIN32\nstatic BOOL WINAPI\n_tls_callback(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)\n{\n\n\tswitch (fdwReason) {\n#ifdef JEMALLOC_LAZY_LOCK\n\tcase DLL_THREAD_ATTACH:\n\t\tisthreaded = true;\n\t\tbreak;\n#endif\n\tcase DLL_THREAD_DETACH:\n\t\t_malloc_thread_cleanup();\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\treturn (true);\n}\n\n#ifdef _MSC_VER\n#  ifdef _M_IX86\n#    pragma comment(linker, \"/INCLUDE:__tls_used\")\n#    pragma comment(linker, \"/INCLUDE:_tls_callback\")\n#  else\n#    pragma comment(linker, \"/INCLUDE:_tls_used\")\n#    pragma comment(linker, \"/INCLUDE:tls_callback\")\n#  endif\n#  pragma section(\".CRT$XLY\",long,read)\n#endif\nJEMALLOC_SECTION(\".CRT$XLY\") JEMALLOC_ATTR(used)\nBOOL\t(WINAPI *const tls_callback)(HINSTANCE hinstDLL,\n    DWORD fdwReason, LPVOID lpvReserved) = _tls_callback;\n#endif\n\n#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \\\n    !defined(_WIN32))\nvoid *\ntsd_init_check_recursion(tsd_init_head_t *head, tsd_init_block_t *block)\n{\n\tpthread_t self = pthread_self();\n\ttsd_init_block_t *iter;\n\n\t/* Check whether this thread has already inserted into the list. */\n\tmalloc_mutex_lock(&head->lock);\n\tql_foreach(iter, &head->blocks, link) {\n\t\tif (iter->thread == self) {\n\t\t\tmalloc_mutex_unlock(&head->lock);\n\t\t\treturn (iter->data);\n\t\t}\n\t}\n\t/* Insert block into list. */\n\tql_elm_new(block, link);\n\tblock->thread = self;\n\tql_tail_insert(&head->blocks, block, link);\n\tmalloc_mutex_unlock(&head->lock);\n\treturn (NULL);\n}\n\nvoid\ntsd_init_finish(tsd_init_head_t *head, tsd_init_block_t *block)\n{\n\n\tmalloc_mutex_lock(&head->lock);\n\tql_remove(&head->blocks, block, link);\n\tmalloc_mutex_unlock(&head->lock);\n}\n#endif\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/util.c",
    "content": "/*\n * Define simple versions of assertion macros that won't recurse in case\n * of assertion failures in malloc_*printf().\n */\n#define\tassert(e) do {\t\t\t\t\t\t\t\\\n\tif (config_debug && !(e)) {\t\t\t\t\t\\\n\t\tmalloc_write(\"<jemalloc>: Failed assertion\\n\");\t\t\\\n\t\tabort();\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tnot_reached() do {\t\t\t\t\t\t\\\n\tif (config_debug) {\t\t\t\t\t\t\\\n\t\tmalloc_write(\"<jemalloc>: Unreachable code reached\\n\");\t\\\n\t\tabort();\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tnot_implemented() do {\t\t\t\t\t\t\\\n\tif (config_debug) {\t\t\t\t\t\t\\\n\t\tmalloc_write(\"<jemalloc>: Not implemented\\n\");\t\t\\\n\t\tabort();\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tJEMALLOC_UTIL_C_\n#include \"jemalloc/internal/jemalloc_internal.h\"\n\n/******************************************************************************/\n/* Function prototypes for non-inline static functions. */\n\nstatic void\twrtmessage(void *cbopaque, const char *s);\n#define\tU2S_BUFSIZE\t((1U << (LG_SIZEOF_INTMAX_T + 3)) + 1)\nstatic char\t*u2s(uintmax_t x, unsigned base, bool uppercase, char *s,\n    size_t *slen_p);\n#define\tD2S_BUFSIZE\t(1 + U2S_BUFSIZE)\nstatic char\t*d2s(intmax_t x, char sign, char *s, size_t *slen_p);\n#define\tO2S_BUFSIZE\t(1 + U2S_BUFSIZE)\nstatic char\t*o2s(uintmax_t x, bool alt_form, char *s, size_t *slen_p);\n#define\tX2S_BUFSIZE\t(2 + U2S_BUFSIZE)\nstatic char\t*x2s(uintmax_t x, bool alt_form, bool uppercase, char *s,\n    size_t *slen_p);\n\n/******************************************************************************/\n\n/* malloc_message() setup. */\nstatic void\nwrtmessage(void *cbopaque, const char *s)\n{\n\n#ifdef SYS_write\n\t/*\n\t * Use syscall(2) rather than write(2) when possible in order to avoid\n\t * the possibility of memory allocation within libc.  This is necessary\n\t * on FreeBSD; most operating systems do not have this problem though.\n\t *\n\t * syscall() returns long or int, depending on platform, so capture the\n\t * unused result in the widest plausible type to avoid compiler\n\t * warnings.\n\t */\n\tUNUSED long result = syscall(SYS_write, STDERR_FILENO, s, strlen(s));\n#else\n\tUNUSED ssize_t result = write(STDERR_FILENO, s, strlen(s));\n#endif\n}\n\nJEMALLOC_EXPORT void\t(*je_malloc_message)(void *, const char *s);\n\n/*\n * Wrapper around malloc_message() that avoids the need for\n * je_malloc_message(...) throughout the code.\n */\nvoid\nmalloc_write(const char *s)\n{\n\n\tif (je_malloc_message != NULL)\n\t\tje_malloc_message(NULL, s);\n\telse\n\t\twrtmessage(NULL, s);\n}\n\n/*\n * glibc provides a non-standard strerror_r() when _GNU_SOURCE is defined, so\n * provide a wrapper.\n */\nint\nbuferror(int err, char *buf, size_t buflen)\n{\n\n#ifdef _WIN32\n\tFormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0,\n\t    (LPSTR)buf, (DWORD)buflen, NULL);\n\treturn (0);\n#elif defined(__GLIBC__) && defined(_GNU_SOURCE)\n\tchar *b = strerror_r(err, buf, buflen);\n\tif (b != buf) {\n\t\tstrncpy(buf, b, buflen);\n\t\tbuf[buflen-1] = '\\0';\n\t}\n\treturn (0);\n#else\n\treturn (strerror_r(err, buf, buflen));\n#endif\n}\n\nuintmax_t\nmalloc_strtoumax(const char *restrict nptr, char **restrict endptr, int base)\n{\n\tuintmax_t ret, digit;\n\tunsigned b;\n\tbool neg;\n\tconst char *p, *ns;\n\n\tp = nptr;\n\tif (base < 0 || base == 1 || base > 36) {\n\t\tns = p;\n\t\tset_errno(EINVAL);\n\t\tret = UINTMAX_MAX;\n\t\tgoto label_return;\n\t}\n\tb = base;\n\n\t/* Swallow leading whitespace and get sign, if any. */\n\tneg = false;\n\twhile (true) {\n\t\tswitch (*p) {\n\t\tcase '\\t': case '\\n': case '\\v': case '\\f': case '\\r': case ' ':\n\t\t\tp++;\n\t\t\tbreak;\n\t\tcase '-':\n\t\t\tneg = true;\n\t\t\t/* Fall through. */\n\t\tcase '+':\n\t\t\tp++;\n\t\t\t/* Fall through. */\n\t\tdefault:\n\t\t\tgoto label_prefix;\n\t\t}\n\t}\n\n\t/* Get prefix, if any. */\n\tlabel_prefix:\n\t/*\n\t * Note where the first non-whitespace/sign character is so that it is\n\t * possible to tell whether any digits are consumed (e.g., \"  0\" vs.\n\t * \"  -x\").\n\t */\n\tns = p;\n\tif (*p == '0') {\n\t\tswitch (p[1]) {\n\t\tcase '0': case '1': case '2': case '3': case '4': case '5':\n\t\tcase '6': case '7':\n\t\t\tif (b == 0)\n\t\t\t\tb = 8;\n\t\t\tif (b == 8)\n\t\t\t\tp++;\n\t\t\tbreak;\n\t\tcase 'X': case 'x':\n\t\t\tswitch (p[2]) {\n\t\t\tcase '0': case '1': case '2': case '3': case '4':\n\t\t\tcase '5': case '6': case '7': case '8': case '9':\n\t\t\tcase 'A': case 'B': case 'C': case 'D': case 'E':\n\t\t\tcase 'F':\n\t\t\tcase 'a': case 'b': case 'c': case 'd': case 'e':\n\t\t\tcase 'f':\n\t\t\t\tif (b == 0)\n\t\t\t\t\tb = 16;\n\t\t\t\tif (b == 16)\n\t\t\t\t\tp += 2;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tp++;\n\t\t\tret = 0;\n\t\t\tgoto label_return;\n\t\t}\n\t}\n\tif (b == 0)\n\t\tb = 10;\n\n\t/* Convert. */\n\tret = 0;\n\twhile ((*p >= '0' && *p <= '9' && (digit = *p - '0') < b)\n\t    || (*p >= 'A' && *p <= 'Z' && (digit = 10 + *p - 'A') < b)\n\t    || (*p >= 'a' && *p <= 'z' && (digit = 10 + *p - 'a') < b)) {\n\t\tuintmax_t pret = ret;\n\t\tret *= b;\n\t\tret += digit;\n\t\tif (ret < pret) {\n\t\t\t/* Overflow. */\n\t\t\tset_errno(ERANGE);\n\t\t\tret = UINTMAX_MAX;\n\t\t\tgoto label_return;\n\t\t}\n\t\tp++;\n\t}\n\tif (neg)\n\t\tret = -ret;\n\n\tif (p == ns) {\n\t\t/* No conversion performed. */\n\t\tset_errno(EINVAL);\n\t\tret = UINTMAX_MAX;\n\t\tgoto label_return;\n\t}\n\nlabel_return:\n\tif (endptr != NULL) {\n\t\tif (p == ns) {\n\t\t\t/* No characters were converted. */\n\t\t\t*endptr = (char *)nptr;\n\t\t} else\n\t\t\t*endptr = (char *)p;\n\t}\n\treturn (ret);\n}\n\nstatic char *\nu2s(uintmax_t x, unsigned base, bool uppercase, char *s, size_t *slen_p)\n{\n\tunsigned i;\n\n\ti = U2S_BUFSIZE - 1;\n\ts[i] = '\\0';\n\tswitch (base) {\n\tcase 10:\n\t\tdo {\n\t\t\ti--;\n\t\t\ts[i] = \"0123456789\"[x % (uint64_t)10];\n\t\t\tx /= (uint64_t)10;\n\t\t} while (x > 0);\n\t\tbreak;\n\tcase 16: {\n\t\tconst char *digits = (uppercase)\n\t\t    ? \"0123456789ABCDEF\"\n\t\t    : \"0123456789abcdef\";\n\n\t\tdo {\n\t\t\ti--;\n\t\t\ts[i] = digits[x & 0xf];\n\t\t\tx >>= 4;\n\t\t} while (x > 0);\n\t\tbreak;\n\t} default: {\n\t\tconst char *digits = (uppercase)\n\t\t    ? \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n\t\t    : \"0123456789abcdefghijklmnopqrstuvwxyz\";\n\n\t\tassert(base >= 2 && base <= 36);\n\t\tdo {\n\t\t\ti--;\n\t\t\ts[i] = digits[x % (uint64_t)base];\n\t\t\tx /= (uint64_t)base;\n\t\t} while (x > 0);\n\t}}\n\n\t*slen_p = U2S_BUFSIZE - 1 - i;\n\treturn (&s[i]);\n}\n\nstatic char *\nd2s(intmax_t x, char sign, char *s, size_t *slen_p)\n{\n\tbool neg;\n\n\tif ((neg = (x < 0)))\n\t\tx = -x;\n\ts = u2s(x, 10, false, s, slen_p);\n\tif (neg)\n\t\tsign = '-';\n\tswitch (sign) {\n\tcase '-':\n\t\tif (!neg)\n\t\t\tbreak;\n\t\t/* Fall through. */\n\tcase ' ':\n\tcase '+':\n\t\ts--;\n\t\t(*slen_p)++;\n\t\t*s = sign;\n\t\tbreak;\n\tdefault: not_reached();\n\t}\n\treturn (s);\n}\n\nstatic char *\no2s(uintmax_t x, bool alt_form, char *s, size_t *slen_p)\n{\n\n\ts = u2s(x, 8, false, s, slen_p);\n\tif (alt_form && *s != '0') {\n\t\ts--;\n\t\t(*slen_p)++;\n\t\t*s = '0';\n\t}\n\treturn (s);\n}\n\nstatic char *\nx2s(uintmax_t x, bool alt_form, bool uppercase, char *s, size_t *slen_p)\n{\n\n\ts = u2s(x, 16, uppercase, s, slen_p);\n\tif (alt_form) {\n\t\ts -= 2;\n\t\t(*slen_p) += 2;\n\t\tmemcpy(s, uppercase ? \"0X\" : \"0x\", 2);\n\t}\n\treturn (s);\n}\n\nint\nmalloc_vsnprintf(char *str, size_t size, const char *format, va_list ap)\n{\n\tint ret;\n\tsize_t i;\n\tconst char *f;\n\n#define\tAPPEND_C(c) do {\t\t\t\t\t\t\\\n\tif (i < size)\t\t\t\t\t\t\t\\\n\t\tstr[i] = (c);\t\t\t\t\t\t\\\n\ti++;\t\t\t\t\t\t\t\t\\\n} while (0)\n#define\tAPPEND_S(s, slen) do {\t\t\t\t\t\t\\\n\tif (i < size) {\t\t\t\t\t\t\t\\\n\t\tsize_t cpylen = (slen <= size - i) ? slen : size - i;\t\\\n\t\tmemcpy(&str[i], s, cpylen);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\ti += slen;\t\t\t\t\t\t\t\\\n} while (0)\n#define\tAPPEND_PADDED_S(s, slen, width, left_justify) do {\t\t\\\n\t/* Left padding. */\t\t\t\t\t\t\\\n\tsize_t pad_len = (width == -1) ? 0 : ((slen < (size_t)width) ?\t\\\n\t    (size_t)width - slen : 0);\t\t\t\t\t\\\n\tif (!left_justify && pad_len != 0) {\t\t\t\t\\\n\t\tsize_t j;\t\t\t\t\t\t\\\n\t\tfor (j = 0; j < pad_len; j++)\t\t\t\t\\\n\t\t\tAPPEND_C(' ');\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\t/* Value. */\t\t\t\t\t\t\t\\\n\tAPPEND_S(s, slen);\t\t\t\t\t\t\\\n\t/* Right padding. */\t\t\t\t\t\t\\\n\tif (left_justify && pad_len != 0) {\t\t\t\t\\\n\t\tsize_t j;\t\t\t\t\t\t\\\n\t\tfor (j = 0; j < pad_len; j++)\t\t\t\t\\\n\t\t\tAPPEND_C(' ');\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n#define\tGET_ARG_NUMERIC(val, len) do {\t\t\t\t\t\\\n\tswitch (len) {\t\t\t\t\t\t\t\\\n\tcase '?':\t\t\t\t\t\t\t\\\n\t\tval = va_arg(ap, int);\t\t\t\t\t\\\n\t\tbreak;\t\t\t\t\t\t\t\\\n\tcase '?' | 0x80:\t\t\t\t\t\t\\\n\t\tval = va_arg(ap, unsigned int);\t\t\t\t\\\n\t\tbreak;\t\t\t\t\t\t\t\\\n\tcase 'l':\t\t\t\t\t\t\t\\\n\t\tval = va_arg(ap, long);\t\t\t\t\t\\\n\t\tbreak;\t\t\t\t\t\t\t\\\n\tcase 'l' | 0x80:\t\t\t\t\t\t\\\n\t\tval = va_arg(ap, unsigned long);\t\t\t\\\n\t\tbreak;\t\t\t\t\t\t\t\\\n\tcase 'q':\t\t\t\t\t\t\t\\\n\t\tval = va_arg(ap, long long);\t\t\t\t\\\n\t\tbreak;\t\t\t\t\t\t\t\\\n\tcase 'q' | 0x80:\t\t\t\t\t\t\\\n\t\tval = va_arg(ap, unsigned long long);\t\t\t\\\n\t\tbreak;\t\t\t\t\t\t\t\\\n\tcase 'j':\t\t\t\t\t\t\t\\\n\t\tval = va_arg(ap, intmax_t);\t\t\t\t\\\n\t\tbreak;\t\t\t\t\t\t\t\\\n\tcase 'j' | 0x80:\t\t\t\t\t\t\\\n\t\tval = va_arg(ap, uintmax_t);\t\t\t\t\\\n\t\tbreak;\t\t\t\t\t\t\t\\\n\tcase 't':\t\t\t\t\t\t\t\\\n\t\tval = va_arg(ap, ptrdiff_t);\t\t\t\t\\\n\t\tbreak;\t\t\t\t\t\t\t\\\n\tcase 'z':\t\t\t\t\t\t\t\\\n\t\tval = va_arg(ap, ssize_t);\t\t\t\t\\\n\t\tbreak;\t\t\t\t\t\t\t\\\n\tcase 'z' | 0x80:\t\t\t\t\t\t\\\n\t\tval = va_arg(ap, size_t);\t\t\t\t\\\n\t\tbreak;\t\t\t\t\t\t\t\\\n\tcase 'p': /* Synthetic; used for %p. */\t\t\t\t\\\n\t\tval = va_arg(ap, uintptr_t);\t\t\t\t\\\n\t\tbreak;\t\t\t\t\t\t\t\\\n\tdefault:\t\t\t\t\t\t\t\\\n\t\tnot_reached();\t\t\t\t\t\t\\\n\t\tval = 0;\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n\ti = 0;\n\tf = format;\n\twhile (true) {\n\t\tswitch (*f) {\n\t\tcase '\\0': goto label_out;\n\t\tcase '%': {\n\t\t\tbool alt_form = false;\n\t\t\tbool left_justify = false;\n\t\t\tbool plus_space = false;\n\t\t\tbool plus_plus = false;\n\t\t\tint prec = -1;\n\t\t\tint width = -1;\n\t\t\tunsigned char len = '?';\n\n\t\t\tf++;\n\t\t\t/* Flags. */\n\t\t\twhile (true) {\n\t\t\t\tswitch (*f) {\n\t\t\t\tcase '#':\n\t\t\t\t\tassert(!alt_form);\n\t\t\t\t\talt_form = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase '-':\n\t\t\t\t\tassert(!left_justify);\n\t\t\t\t\tleft_justify = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ' ':\n\t\t\t\t\tassert(!plus_space);\n\t\t\t\t\tplus_space = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase '+':\n\t\t\t\t\tassert(!plus_plus);\n\t\t\t\t\tplus_plus = true;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault: goto label_width;\n\t\t\t\t}\n\t\t\t\tf++;\n\t\t\t}\n\t\t\t/* Width. */\n\t\t\tlabel_width:\n\t\t\tswitch (*f) {\n\t\t\tcase '*':\n\t\t\t\twidth = va_arg(ap, int);\n\t\t\t\tf++;\n\t\t\t\tif (width < 0) {\n\t\t\t\t\tleft_justify = true;\n\t\t\t\t\twidth = -width;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase '0': case '1': case '2': case '3': case '4':\n\t\t\tcase '5': case '6': case '7': case '8': case '9': {\n\t\t\t\tuintmax_t uwidth;\n\t\t\t\tset_errno(0);\n\t\t\t\tuwidth = malloc_strtoumax(f, (char **)&f, 10);\n\t\t\t\tassert(uwidth != UINTMAX_MAX || get_errno() !=\n\t\t\t\t    ERANGE);\n\t\t\t\twidth = (int)uwidth;\n\t\t\t\tbreak;\n\t\t\t} default:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t/* Width/precision separator. */\n\t\t\tif (*f == '.')\n\t\t\t\tf++;\n\t\t\telse\n\t\t\t\tgoto label_length;\n\t\t\t/* Precision. */\n\t\t\tswitch (*f) {\n\t\t\tcase '*':\n\t\t\t\tprec = va_arg(ap, int);\n\t\t\t\tf++;\n\t\t\t\tbreak;\n\t\t\tcase '0': case '1': case '2': case '3': case '4':\n\t\t\tcase '5': case '6': case '7': case '8': case '9': {\n\t\t\t\tuintmax_t uprec;\n\t\t\t\tset_errno(0);\n\t\t\t\tuprec = malloc_strtoumax(f, (char **)&f, 10);\n\t\t\t\tassert(uprec != UINTMAX_MAX || get_errno() !=\n\t\t\t\t    ERANGE);\n\t\t\t\tprec = (int)uprec;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: break;\n\t\t\t}\n\t\t\t/* Length. */\n\t\t\tlabel_length:\n\t\t\tswitch (*f) {\n\t\t\tcase 'l':\n\t\t\t\tf++;\n\t\t\t\tif (*f == 'l') {\n\t\t\t\t\tlen = 'q';\n\t\t\t\t\tf++;\n\t\t\t\t} else\n\t\t\t\t\tlen = 'l';\n\t\t\t\tbreak;\n\t\t\tcase 'q': case 'j': case 't': case 'z':\n\t\t\t\tlen = *f;\n\t\t\t\tf++;\n\t\t\t\tbreak;\n\t\t\tdefault: break;\n\t\t\t}\n\t\t\t/* Conversion specifier. */\n\t\t\tswitch (*f) {\n\t\t\t\tchar *s;\n\t\t\t\tsize_t slen;\n\t\t\tcase '%':\n\t\t\t\t/* %% */\n\t\t\t\tAPPEND_C(*f);\n\t\t\t\tf++;\n\t\t\t\tbreak;\n\t\t\tcase 'd': case 'i': {\n\t\t\t\tintmax_t val JEMALLOC_CC_SILENCE_INIT(0);\n\t\t\t\tchar buf[D2S_BUFSIZE];\n\n\t\t\t\tGET_ARG_NUMERIC(val, len);\n\t\t\t\ts = d2s(val, (plus_plus ? '+' : (plus_space ?\n\t\t\t\t    ' ' : '-')), buf, &slen);\n\t\t\t\tAPPEND_PADDED_S(s, slen, width, left_justify);\n\t\t\t\tf++;\n\t\t\t\tbreak;\n\t\t\t} case 'o': {\n\t\t\t\tuintmax_t val JEMALLOC_CC_SILENCE_INIT(0);\n\t\t\t\tchar buf[O2S_BUFSIZE];\n\n\t\t\t\tGET_ARG_NUMERIC(val, len | 0x80);\n\t\t\t\ts = o2s(val, alt_form, buf, &slen);\n\t\t\t\tAPPEND_PADDED_S(s, slen, width, left_justify);\n\t\t\t\tf++;\n\t\t\t\tbreak;\n\t\t\t} case 'u': {\n\t\t\t\tuintmax_t val JEMALLOC_CC_SILENCE_INIT(0);\n\t\t\t\tchar buf[U2S_BUFSIZE];\n\n\t\t\t\tGET_ARG_NUMERIC(val, len | 0x80);\n\t\t\t\ts = u2s(val, 10, false, buf, &slen);\n\t\t\t\tAPPEND_PADDED_S(s, slen, width, left_justify);\n\t\t\t\tf++;\n\t\t\t\tbreak;\n\t\t\t} case 'x': case 'X': {\n\t\t\t\tuintmax_t val JEMALLOC_CC_SILENCE_INIT(0);\n\t\t\t\tchar buf[X2S_BUFSIZE];\n\n\t\t\t\tGET_ARG_NUMERIC(val, len | 0x80);\n\t\t\t\ts = x2s(val, alt_form, *f == 'X', buf, &slen);\n\t\t\t\tAPPEND_PADDED_S(s, slen, width, left_justify);\n\t\t\t\tf++;\n\t\t\t\tbreak;\n\t\t\t} case 'c': {\n\t\t\t\tunsigned char val;\n\t\t\t\tchar buf[2];\n\n\t\t\t\tassert(len == '?' || len == 'l');\n\t\t\t\tassert_not_implemented(len != 'l');\n\t\t\t\tval = va_arg(ap, int);\n\t\t\t\tbuf[0] = val;\n\t\t\t\tbuf[1] = '\\0';\n\t\t\t\tAPPEND_PADDED_S(buf, 1, width, left_justify);\n\t\t\t\tf++;\n\t\t\t\tbreak;\n\t\t\t} case 's':\n\t\t\t\tassert(len == '?' || len == 'l');\n\t\t\t\tassert_not_implemented(len != 'l');\n\t\t\t\ts = va_arg(ap, char *);\n\t\t\t\tslen = (prec < 0) ? strlen(s) : (size_t)prec;\n\t\t\t\tAPPEND_PADDED_S(s, slen, width, left_justify);\n\t\t\t\tf++;\n\t\t\t\tbreak;\n\t\t\tcase 'p': {\n\t\t\t\tuintmax_t val;\n\t\t\t\tchar buf[X2S_BUFSIZE];\n\n\t\t\t\tGET_ARG_NUMERIC(val, 'p');\n\t\t\t\ts = x2s(val, true, false, buf, &slen);\n\t\t\t\tAPPEND_PADDED_S(s, slen, width, left_justify);\n\t\t\t\tf++;\n\t\t\t\tbreak;\n\t\t\t} default: not_reached();\n\t\t\t}\n\t\t\tbreak;\n\t\t} default: {\n\t\t\tAPPEND_C(*f);\n\t\t\tf++;\n\t\t\tbreak;\n\t\t}}\n\t}\n\tlabel_out:\n\tif (i < size)\n\t\tstr[i] = '\\0';\n\telse\n\t\tstr[size - 1] = '\\0';\n\tassert(i < INT_MAX);\n\tret = (int)i;\n\n#undef APPEND_C\n#undef APPEND_S\n#undef APPEND_PADDED_S\n#undef GET_ARG_NUMERIC\n\treturn (ret);\n}\n\nJEMALLOC_FORMAT_PRINTF(3, 4)\nint\nmalloc_snprintf(char *str, size_t size, const char *format, ...)\n{\n\tint ret;\n\tva_list ap;\n\n\tva_start(ap, format);\n\tret = malloc_vsnprintf(str, size, format, ap);\n\tva_end(ap);\n\n\treturn (ret);\n}\n\nvoid\nmalloc_vcprintf(void (*write_cb)(void *, const char *), void *cbopaque,\n    const char *format, va_list ap)\n{\n\tchar buf[MALLOC_PRINTF_BUFSIZE];\n\n\tif (write_cb == NULL) {\n\t\t/*\n\t\t * The caller did not provide an alternate write_cb callback\n\t\t * function, so use the default one.  malloc_write() is an\n\t\t * inline function, so use malloc_message() directly here.\n\t\t */\n\t\twrite_cb = (je_malloc_message != NULL) ? je_malloc_message :\n\t\t    wrtmessage;\n\t\tcbopaque = NULL;\n\t}\n\n\tmalloc_vsnprintf(buf, sizeof(buf), format, ap);\n\twrite_cb(cbopaque, buf);\n}\n\n/*\n * Print to a callback function in such a way as to (hopefully) avoid memory\n * allocation.\n */\nJEMALLOC_FORMAT_PRINTF(3, 4)\nvoid\nmalloc_cprintf(void (*write_cb)(void *, const char *), void *cbopaque,\n    const char *format, ...)\n{\n\tva_list ap;\n\n\tva_start(ap, format);\n\tmalloc_vcprintf(write_cb, cbopaque, format, ap);\n\tva_end(ap);\n}\n\n/* Print to stderr in such a way as to avoid memory allocation. */\nJEMALLOC_FORMAT_PRINTF(1, 2)\nvoid\nmalloc_printf(const char *format, ...)\n{\n\tva_list ap;\n\n\tva_start(ap, format);\n\tmalloc_vcprintf(NULL, NULL, format, ap);\n\tva_end(ap);\n}\n\n/*\n * Restore normal assertion macros, in order to make it possible to compile all\n * C files as a single concatenation.\n */\n#undef assert\n#undef not_reached\n#undef not_implemented\n#include \"jemalloc/internal/assert.h\"\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/valgrind.c",
    "content": "#include \"jemalloc/internal/jemalloc_internal.h\"\n#ifndef JEMALLOC_VALGRIND\n#  error \"This source file is for Valgrind integration.\"\n#endif\n\n#include <valgrind/memcheck.h>\n\nvoid\nvalgrind_make_mem_noaccess(void *ptr, size_t usize)\n{\n\n\tVALGRIND_MAKE_MEM_NOACCESS(ptr, usize);\n}\n\nvoid\nvalgrind_make_mem_undefined(void *ptr, size_t usize)\n{\n\n\tVALGRIND_MAKE_MEM_UNDEFINED(ptr, usize);\n}\n\nvoid\nvalgrind_make_mem_defined(void *ptr, size_t usize)\n{\n\n\tVALGRIND_MAKE_MEM_DEFINED(ptr, usize);\n}\n\nvoid\nvalgrind_freelike_block(void *ptr, size_t usize)\n{\n\n\tVALGRIND_FREELIKE_BLOCK(ptr, usize);\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/src/zone.c",
    "content": "#include \"jemalloc/internal/jemalloc_internal.h\"\n#ifndef JEMALLOC_ZONE\n#  error \"This source file is for zones on Darwin (OS X).\"\n#endif\n\n/*\n * The malloc_default_purgeable_zone function is only available on >= 10.6.\n * We need to check whether it is present at runtime, thus the weak_import.\n */\nextern malloc_zone_t *malloc_default_purgeable_zone(void)\nJEMALLOC_ATTR(weak_import);\n\n/******************************************************************************/\n/* Data. */\n\nstatic malloc_zone_t zone;\nstatic struct malloc_introspection_t zone_introspect;\n\n/******************************************************************************/\n/* Function prototypes for non-inline static functions. */\n\nstatic size_t\tzone_size(malloc_zone_t *zone, void *ptr);\nstatic void\t*zone_malloc(malloc_zone_t *zone, size_t size);\nstatic void\t*zone_calloc(malloc_zone_t *zone, size_t num, size_t size);\nstatic void\t*zone_valloc(malloc_zone_t *zone, size_t size);\nstatic void\tzone_free(malloc_zone_t *zone, void *ptr);\nstatic void\t*zone_realloc(malloc_zone_t *zone, void *ptr, size_t size);\n#if (JEMALLOC_ZONE_VERSION >= 5)\nstatic void\t*zone_memalign(malloc_zone_t *zone, size_t alignment,\n#endif\n#if (JEMALLOC_ZONE_VERSION >= 6)\n    size_t size);\nstatic void\tzone_free_definite_size(malloc_zone_t *zone, void *ptr,\n    size_t size);\n#endif\nstatic void\t*zone_destroy(malloc_zone_t *zone);\nstatic size_t\tzone_good_size(malloc_zone_t *zone, size_t size);\nstatic void\tzone_force_lock(malloc_zone_t *zone);\nstatic void\tzone_force_unlock(malloc_zone_t *zone);\n\n/******************************************************************************/\n/*\n * Functions.\n */\n\nstatic size_t\nzone_size(malloc_zone_t *zone, void *ptr)\n{\n\n\t/*\n\t * There appear to be places within Darwin (such as setenv(3)) that\n\t * cause calls to this function with pointers that *no* zone owns.  If\n\t * we knew that all pointers were owned by *some* zone, we could split\n\t * our zone into two parts, and use one as the default allocator and\n\t * the other as the default deallocator/reallocator.  Since that will\n\t * not work in practice, we must check all pointers to assure that they\n\t * reside within a mapped chunk before determining size.\n\t */\n\treturn (ivsalloc(ptr, config_prof));\n}\n\nstatic void *\nzone_malloc(malloc_zone_t *zone, size_t size)\n{\n\n\treturn (je_malloc(size));\n}\n\nstatic void *\nzone_calloc(malloc_zone_t *zone, size_t num, size_t size)\n{\n\n\treturn (je_calloc(num, size));\n}\n\nstatic void *\nzone_valloc(malloc_zone_t *zone, size_t size)\n{\n\tvoid *ret = NULL; /* Assignment avoids useless compiler warning. */\n\n\tje_posix_memalign(&ret, PAGE, size);\n\n\treturn (ret);\n}\n\nstatic void\nzone_free(malloc_zone_t *zone, void *ptr)\n{\n\n\tif (ivsalloc(ptr, config_prof) != 0) {\n\t\tje_free(ptr);\n\t\treturn;\n\t}\n\n\tfree(ptr);\n}\n\nstatic void *\nzone_realloc(malloc_zone_t *zone, void *ptr, size_t size)\n{\n\n\tif (ivsalloc(ptr, config_prof) != 0)\n\t\treturn (je_realloc(ptr, size));\n\n\treturn (realloc(ptr, size));\n}\n\n#if (JEMALLOC_ZONE_VERSION >= 5)\nstatic void *\nzone_memalign(malloc_zone_t *zone, size_t alignment, size_t size)\n{\n\tvoid *ret = NULL; /* Assignment avoids useless compiler warning. */\n\n\tje_posix_memalign(&ret, alignment, size);\n\n\treturn (ret);\n}\n#endif\n\n#if (JEMALLOC_ZONE_VERSION >= 6)\nstatic void\nzone_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size)\n{\n\tsize_t alloc_size;\n\n\talloc_size = ivsalloc(ptr, config_prof);\n\tif (alloc_size != 0) {\n\t\tassert(alloc_size == size);\n\t\tje_free(ptr);\n\t\treturn;\n\t}\n\n\tfree(ptr);\n}\n#endif\n\nstatic void *\nzone_destroy(malloc_zone_t *zone)\n{\n\n\t/* This function should never be called. */\n\tnot_reached();\n\treturn (NULL);\n}\n\nstatic size_t\nzone_good_size(malloc_zone_t *zone, size_t size)\n{\n\n\tif (size == 0)\n\t\tsize = 1;\n\treturn (s2u(size));\n}\n\nstatic void\nzone_force_lock(malloc_zone_t *zone)\n{\n\n\tif (isthreaded)\n\t\tjemalloc_prefork();\n}\n\nstatic void\nzone_force_unlock(malloc_zone_t *zone)\n{\n\n\tif (isthreaded)\n\t\tjemalloc_postfork_parent();\n}\n\nJEMALLOC_ATTR(constructor)\nvoid\nregister_zone(void)\n{\n\n\t/*\n\t * If something else replaced the system default zone allocator, don't\n\t * register jemalloc's.\n\t */\n\tmalloc_zone_t *default_zone = malloc_default_zone();\n\tmalloc_zone_t *purgeable_zone = NULL;\n\tif (!default_zone->zone_name ||\n\t    strcmp(default_zone->zone_name, \"DefaultMallocZone\") != 0) {\n\t\treturn;\n\t}\n\n\tzone.size = (void *)zone_size;\n\tzone.malloc = (void *)zone_malloc;\n\tzone.calloc = (void *)zone_calloc;\n\tzone.valloc = (void *)zone_valloc;\n\tzone.free = (void *)zone_free;\n\tzone.realloc = (void *)zone_realloc;\n\tzone.destroy = (void *)zone_destroy;\n\tzone.zone_name = \"jemalloc_zone\";\n\tzone.batch_malloc = NULL;\n\tzone.batch_free = NULL;\n\tzone.introspect = &zone_introspect;\n\tzone.version = JEMALLOC_ZONE_VERSION;\n#if (JEMALLOC_ZONE_VERSION >= 5)\n\tzone.memalign = zone_memalign;\n#endif\n#if (JEMALLOC_ZONE_VERSION >= 6)\n\tzone.free_definite_size = zone_free_definite_size;\n#endif\n#if (JEMALLOC_ZONE_VERSION >= 8)\n\tzone.pressure_relief = NULL;\n#endif\n\n\tzone_introspect.enumerator = NULL;\n\tzone_introspect.good_size = (void *)zone_good_size;\n\tzone_introspect.check = NULL;\n\tzone_introspect.print = NULL;\n\tzone_introspect.log = NULL;\n\tzone_introspect.force_lock = (void *)zone_force_lock;\n\tzone_introspect.force_unlock = (void *)zone_force_unlock;\n\tzone_introspect.statistics = NULL;\n#if (JEMALLOC_ZONE_VERSION >= 6)\n\tzone_introspect.zone_locked = NULL;\n#endif\n#if (JEMALLOC_ZONE_VERSION >= 7)\n\tzone_introspect.enable_discharge_checking = NULL;\n\tzone_introspect.disable_discharge_checking = NULL;\n\tzone_introspect.discharge = NULL;\n#ifdef __BLOCKS__\n\tzone_introspect.enumerate_discharged_pointers = NULL;\n#else\n\tzone_introspect.enumerate_unavailable_without_blocks = NULL;\n#endif\n#endif\n\n\t/*\n\t * The default purgeable zone is created lazily by OSX's libc.  It uses\n\t * the default zone when it is created for \"small\" allocations\n\t * (< 15 KiB), but assumes the default zone is a scalable_zone.  This\n\t * obviously fails when the default zone is the jemalloc zone, so\n\t * malloc_default_purgeable_zone is called beforehand so that the\n\t * default purgeable zone is created when the default zone is still\n\t * a scalable_zone.  As purgeable zones only exist on >= 10.6, we need\n\t * to check for the existence of malloc_default_purgeable_zone() at\n\t * run time.\n\t */\n\tif (malloc_default_purgeable_zone != NULL)\n\t\tpurgeable_zone = malloc_default_purgeable_zone();\n\n\t/* Register the custom zone.  At this point it won't be the default. */\n\tmalloc_zone_register(&zone);\n\n\tdo {\n\t\tdefault_zone = malloc_default_zone();\n\t\t/*\n\t\t * Unregister and reregister the default zone.  On OSX >= 10.6,\n\t\t * unregistering takes the last registered zone and places it\n\t\t * at the location of the specified zone.  Unregistering the\n\t\t * default zone thus makes the last registered one the default.\n\t\t * On OSX < 10.6, unregistering shifts all registered zones.\n\t\t * The first registered zone then becomes the default.\n\t\t */\n\t\tmalloc_zone_unregister(default_zone);\n\t\tmalloc_zone_register(default_zone);\n\t\t/*\n\t\t * On OSX 10.6, having the default purgeable zone appear before\n\t\t * the default zone makes some things crash because it thinks it\n\t\t * owns the default zone allocated pointers.  We thus\n\t\t * unregister/re-register it in order to ensure it's always\n\t\t * after the default zone.  On OSX < 10.6, there is no purgeable\n\t\t * zone, so this does nothing.  On OSX >= 10.6, unregistering\n\t\t * replaces the purgeable zone with the last registered zone\n\t\t * above, i.e. the default zone.  Registering it again then puts\n\t\t * it at the end, obviously after the default zone.\n\t\t */\n\t\tif (purgeable_zone) {\n\t\t\tmalloc_zone_unregister(purgeable_zone);\n\t\t\tmalloc_zone_register(purgeable_zone);\n\t\t}\n\t} while (malloc_default_zone() != &zone);\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/SFMT-alti.h",
    "content": "/*\n * This file derives from SFMT 1.3.3\n * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was\n * released under the terms of the following license:\n *\n *   Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n *   University. 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\n *         disclaimer in the documentation and/or other materials provided\n *         with the distribution.\n *       * Neither the name of the Hiroshima University nor the names of\n *         its contributors may be used to endorse or promote products\n *         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\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 * @file SFMT-alti.h \n *\n * @brief SIMD oriented Fast Mersenne Twister(SFMT)\n * pseudorandom number generator\n *\n * @author Mutsuo Saito (Hiroshima University)\n * @author Makoto Matsumoto (Hiroshima University)\n *\n * Copyright (C) 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n * University. All rights reserved.\n *\n * The new BSD License is applied to this software.\n * see LICENSE.txt\n */\n\n#ifndef SFMT_ALTI_H\n#define SFMT_ALTI_H\n\n/**\n * This function represents the recursion formula in AltiVec and BIG ENDIAN.\n * @param a a 128-bit part of the interal state array\n * @param b a 128-bit part of the interal state array\n * @param c a 128-bit part of the interal state array\n * @param d a 128-bit part of the interal state array\n * @return output\n */\nJEMALLOC_ALWAYS_INLINE\nvector unsigned int vec_recursion(vector unsigned int a,\n\t\t\t\t\t\tvector unsigned int b,\n\t\t\t\t\t\tvector unsigned int c,\n\t\t\t\t\t\tvector unsigned int d) {\n\n    const vector unsigned int sl1 = ALTI_SL1;\n    const vector unsigned int sr1 = ALTI_SR1;\n#ifdef ONLY64\n    const vector unsigned int mask = ALTI_MSK64;\n    const vector unsigned char perm_sl = ALTI_SL2_PERM64;\n    const vector unsigned char perm_sr = ALTI_SR2_PERM64;\n#else\n    const vector unsigned int mask = ALTI_MSK;\n    const vector unsigned char perm_sl = ALTI_SL2_PERM;\n    const vector unsigned char perm_sr = ALTI_SR2_PERM;\n#endif\n    vector unsigned int v, w, x, y, z;\n    x = vec_perm(a, (vector unsigned int)perm_sl, perm_sl);\n    v = a;\n    y = vec_sr(b, sr1);\n    z = vec_perm(c, (vector unsigned int)perm_sr, perm_sr);\n    w = vec_sl(d, sl1);\n    z = vec_xor(z, w);\n    y = vec_and(y, mask);\n    v = vec_xor(v, x);\n    z = vec_xor(z, y);\n    z = vec_xor(z, v);\n    return z;\n}\n\n/**\n * This function fills the internal state array with pseudorandom\n * integers.\n */\nJEMALLOC_INLINE void gen_rand_all(sfmt_t *ctx) {\n    int i;\n    vector unsigned int r, r1, r2;\n\n    r1 = ctx->sfmt[N - 2].s;\n    r2 = ctx->sfmt[N - 1].s;\n    for (i = 0; i < N - POS1; i++) {\n\tr = vec_recursion(ctx->sfmt[i].s, ctx->sfmt[i + POS1].s, r1, r2);\n\tctx->sfmt[i].s = r;\n\tr1 = r2;\n\tr2 = r;\n    }\n    for (; i < N; i++) {\n\tr = vec_recursion(ctx->sfmt[i].s, ctx->sfmt[i + POS1 - N].s, r1, r2);\n\tctx->sfmt[i].s = r;\n\tr1 = r2;\n\tr2 = r;\n    }\n}\n\n/**\n * This function fills the user-specified array with pseudorandom\n * integers.\n *\n * @param array an 128-bit array to be filled by pseudorandom numbers.  \n * @param size number of 128-bit pesudorandom numbers to be generated.\n */\nJEMALLOC_INLINE void gen_rand_array(sfmt_t *ctx, w128_t *array, int size) {\n    int i, j;\n    vector unsigned int r, r1, r2;\n\n    r1 = ctx->sfmt[N - 2].s;\n    r2 = ctx->sfmt[N - 1].s;\n    for (i = 0; i < N - POS1; i++) {\n\tr = vec_recursion(ctx->sfmt[i].s, ctx->sfmt[i + POS1].s, r1, r2);\n\tarray[i].s = r;\n\tr1 = r2;\n\tr2 = r;\n    }\n    for (; i < N; i++) {\n\tr = vec_recursion(ctx->sfmt[i].s, array[i + POS1 - N].s, r1, r2);\n\tarray[i].s = r;\n\tr1 = r2;\n\tr2 = r;\n    }\n    /* main loop */\n    for (; i < size - N; i++) {\n\tr = vec_recursion(array[i - N].s, array[i + POS1 - N].s, r1, r2);\n\tarray[i].s = r;\n\tr1 = r2;\n\tr2 = r;\n    }\n    for (j = 0; j < 2 * N - size; j++) {\n\tctx->sfmt[j].s = array[j + size - N].s;\n    }\n    for (; i < size; i++) {\n\tr = vec_recursion(array[i - N].s, array[i + POS1 - N].s, r1, r2);\n\tarray[i].s = r;\n\tctx->sfmt[j++].s = r;\n\tr1 = r2;\n\tr2 = r;\n    }\n}\n\n#ifndef ONLY64\n#if defined(__APPLE__)\n#define ALTI_SWAP (vector unsigned char) \\\n\t(4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11)\n#else\n#define ALTI_SWAP {4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11}\n#endif\n/**\n * This function swaps high and low 32-bit of 64-bit integers in user\n * specified array.\n *\n * @param array an 128-bit array to be swaped.\n * @param size size of 128-bit array.\n */\nJEMALLOC_INLINE void swap(w128_t *array, int size) {\n    int i;\n    const vector unsigned char perm = ALTI_SWAP;\n\n    for (i = 0; i < size; i++) {\n\tarray[i].s = vec_perm(array[i].s, (vector unsigned int)perm, perm);\n    }\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/SFMT-params.h",
    "content": "/*\n * This file derives from SFMT 1.3.3\n * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was\n * released under the terms of the following license:\n *\n *   Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n *   University. 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\n *         disclaimer in the documentation and/or other materials provided\n *         with the distribution.\n *       * Neither the name of the Hiroshima University nor the names of\n *         its contributors may be used to endorse or promote products\n *         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\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 SFMT_PARAMS_H\n#define SFMT_PARAMS_H\n\n#if !defined(MEXP)\n#ifdef __GNUC__\n  #warning \"MEXP is not defined. I assume MEXP is 19937.\"\n#endif\n  #define MEXP 19937\n#endif\n/*-----------------\n  BASIC DEFINITIONS\n  -----------------*/\n/** Mersenne Exponent. The period of the sequence \n *  is a multiple of 2^MEXP-1.\n * #define MEXP 19937 */\n/** SFMT generator has an internal state array of 128-bit integers,\n * and N is its size. */\n#define N (MEXP / 128 + 1)\n/** N32 is the size of internal state array when regarded as an array\n * of 32-bit integers.*/\n#define N32 (N * 4)\n/** N64 is the size of internal state array when regarded as an array\n * of 64-bit integers.*/\n#define N64 (N * 2)\n\n/*----------------------\n  the parameters of SFMT\n  following definitions are in paramsXXXX.h file.\n  ----------------------*/\n/** the pick up position of the array.\n#define POS1 122 \n*/\n\n/** the parameter of shift left as four 32-bit registers.\n#define SL1 18\n */\n\n/** the parameter of shift left as one 128-bit register. \n * The 128-bit integer is shifted by (SL2 * 8) bits. \n#define SL2 1 \n*/\n\n/** the parameter of shift right as four 32-bit registers.\n#define SR1 11\n*/\n\n/** the parameter of shift right as one 128-bit register. \n * The 128-bit integer is shifted by (SL2 * 8) bits. \n#define SR2 1 \n*/\n\n/** A bitmask, used in the recursion.  These parameters are introduced\n * to break symmetry of SIMD.\n#define MSK1 0xdfffffefU\n#define MSK2 0xddfecb7fU\n#define MSK3 0xbffaffffU\n#define MSK4 0xbffffff6U \n*/\n\n/** These definitions are part of a 128-bit period certification vector.\n#define PARITY1\t0x00000001U\n#define PARITY2\t0x00000000U\n#define PARITY3\t0x00000000U\n#define PARITY4\t0xc98e126aU\n*/\n\n#if MEXP == 607\n  #include \"test/SFMT-params607.h\"\n#elif MEXP == 1279\n  #include \"test/SFMT-params1279.h\"\n#elif MEXP == 2281\n  #include \"test/SFMT-params2281.h\"\n#elif MEXP == 4253\n  #include \"test/SFMT-params4253.h\"\n#elif MEXP == 11213\n  #include \"test/SFMT-params11213.h\"\n#elif MEXP == 19937\n  #include \"test/SFMT-params19937.h\"\n#elif MEXP == 44497\n  #include \"test/SFMT-params44497.h\"\n#elif MEXP == 86243\n  #include \"test/SFMT-params86243.h\"\n#elif MEXP == 132049\n  #include \"test/SFMT-params132049.h\"\n#elif MEXP == 216091\n  #include \"test/SFMT-params216091.h\"\n#else\n#ifdef __GNUC__\n  #error \"MEXP is not valid.\"\n  #undef MEXP\n#else\n  #undef MEXP\n#endif\n\n#endif\n\n#endif /* SFMT_PARAMS_H */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/SFMT-params11213.h",
    "content": "/*\n * This file derives from SFMT 1.3.3\n * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was\n * released under the terms of the following license:\n *\n *   Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n *   University. 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\n *         disclaimer in the documentation and/or other materials provided\n *         with the distribution.\n *       * Neither the name of the Hiroshima University nor the names of\n *         its contributors may be used to endorse or promote products\n *         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\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 SFMT_PARAMS11213_H\n#define SFMT_PARAMS11213_H\n\n#define POS1\t68\n#define SL1\t14\n#define SL2\t3\n#define SR1\t7\n#define SR2\t3\n#define MSK1\t0xeffff7fbU\n#define MSK2\t0xffffffefU\n#define MSK3\t0xdfdfbfffU\n#define MSK4\t0x7fffdbfdU\n#define PARITY1\t0x00000001U\n#define PARITY2\t0x00000000U\n#define PARITY3\t0xe8148000U\n#define PARITY4\t0xd0c7afa3U\n\n\n/* PARAMETERS FOR ALTIVEC */\n#if defined(__APPLE__)\t/* For OSX */\n    #define ALTI_SL1\t(vector unsigned int)(SL1, SL1, SL1, SL1)\n    #define ALTI_SR1\t(vector unsigned int)(SR1, SR1, SR1, SR1)\n    #define ALTI_MSK\t(vector unsigned int)(MSK1, MSK2, MSK3, MSK4)\n    #define ALTI_MSK64 \\\n\t(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)\n    #define ALTI_SL2_PERM \\\n\t(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)\n    #define ALTI_SL2_PERM64 \\\n\t(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)\n    #define ALTI_SR2_PERM \\\n\t(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)\n    #define ALTI_SR2_PERM64 \\\n\t(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)\n#else\t/* For OTHER OSs(Linux?) */\n    #define ALTI_SL1\t{SL1, SL1, SL1, SL1}\n    #define ALTI_SR1\t{SR1, SR1, SR1, SR1}\n    #define ALTI_MSK\t{MSK1, MSK2, MSK3, MSK4}\n    #define ALTI_MSK64\t{MSK2, MSK1, MSK4, MSK3}\n    #define ALTI_SL2_PERM\t{3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}\n    #define ALTI_SL2_PERM64\t{3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}\n    #define ALTI_SR2_PERM\t{5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}\n    #define ALTI_SR2_PERM64\t{13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}\n#endif\t/* For OSX */\n#define IDSTR\t\"SFMT-11213:68-14-3-7-3:effff7fb-ffffffef-dfdfbfff-7fffdbfd\"\n\n#endif /* SFMT_PARAMS11213_H */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/SFMT-params1279.h",
    "content": "/*\n * This file derives from SFMT 1.3.3\n * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was\n * released under the terms of the following license:\n *\n *   Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n *   University. 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\n *         disclaimer in the documentation and/or other materials provided\n *         with the distribution.\n *       * Neither the name of the Hiroshima University nor the names of\n *         its contributors may be used to endorse or promote products\n *         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\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 SFMT_PARAMS1279_H\n#define SFMT_PARAMS1279_H\n\n#define POS1\t7\n#define SL1\t14\n#define SL2\t3\n#define SR1\t5\n#define SR2\t1\n#define MSK1\t0xf7fefffdU\n#define MSK2\t0x7fefcfffU\n#define MSK3\t0xaff3ef3fU\n#define MSK4\t0xb5ffff7fU\n#define PARITY1\t0x00000001U\n#define PARITY2\t0x00000000U\n#define PARITY3\t0x00000000U\n#define PARITY4\t0x20000000U\n\n\n/* PARAMETERS FOR ALTIVEC */\n#if defined(__APPLE__)\t/* For OSX */\n    #define ALTI_SL1\t(vector unsigned int)(SL1, SL1, SL1, SL1)\n    #define ALTI_SR1\t(vector unsigned int)(SR1, SR1, SR1, SR1)\n    #define ALTI_MSK\t(vector unsigned int)(MSK1, MSK2, MSK3, MSK4)\n    #define ALTI_MSK64 \\\n\t(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)\n    #define ALTI_SL2_PERM \\\n\t(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)\n    #define ALTI_SL2_PERM64 \\\n\t(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)\n    #define ALTI_SR2_PERM \\\n\t(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)\n    #define ALTI_SR2_PERM64 \\\n\t(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)\n#else\t/* For OTHER OSs(Linux?) */\n    #define ALTI_SL1\t{SL1, SL1, SL1, SL1}\n    #define ALTI_SR1\t{SR1, SR1, SR1, SR1}\n    #define ALTI_MSK\t{MSK1, MSK2, MSK3, MSK4}\n    #define ALTI_MSK64\t{MSK2, MSK1, MSK4, MSK3}\n    #define ALTI_SL2_PERM\t{3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}\n    #define ALTI_SL2_PERM64\t{3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}\n    #define ALTI_SR2_PERM\t{7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}\n    #define ALTI_SR2_PERM64\t{15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}\n#endif\t/* For OSX */\n#define IDSTR\t\"SFMT-1279:7-14-3-5-1:f7fefffd-7fefcfff-aff3ef3f-b5ffff7f\"\n\n#endif /* SFMT_PARAMS1279_H */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/SFMT-params132049.h",
    "content": "/*\n * This file derives from SFMT 1.3.3\n * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was\n * released under the terms of the following license:\n *\n *   Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n *   University. 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\n *         disclaimer in the documentation and/or other materials provided\n *         with the distribution.\n *       * Neither the name of the Hiroshima University nor the names of\n *         its contributors may be used to endorse or promote products\n *         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\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 SFMT_PARAMS132049_H\n#define SFMT_PARAMS132049_H\n\n#define POS1\t110\n#define SL1\t19\n#define SL2\t1\n#define SR1\t21\n#define SR2\t1\n#define MSK1\t0xffffbb5fU\n#define MSK2\t0xfb6ebf95U\n#define MSK3\t0xfffefffaU\n#define MSK4\t0xcff77fffU\n#define PARITY1\t0x00000001U\n#define PARITY2\t0x00000000U\n#define PARITY3\t0xcb520000U\n#define PARITY4\t0xc7e91c7dU\n\n\n/* PARAMETERS FOR ALTIVEC */\n#if defined(__APPLE__)\t/* For OSX */\n    #define ALTI_SL1\t(vector unsigned int)(SL1, SL1, SL1, SL1)\n    #define ALTI_SR1\t(vector unsigned int)(SR1, SR1, SR1, SR1)\n    #define ALTI_MSK\t(vector unsigned int)(MSK1, MSK2, MSK3, MSK4)\n    #define ALTI_MSK64 \\\n\t(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)\n    #define ALTI_SL2_PERM \\\n\t(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)\n    #define ALTI_SL2_PERM64 \\\n\t(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)\n    #define ALTI_SR2_PERM \\\n\t(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)\n    #define ALTI_SR2_PERM64 \\\n\t(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)\n#else\t/* For OTHER OSs(Linux?) */\n    #define ALTI_SL1\t{SL1, SL1, SL1, SL1}\n    #define ALTI_SR1\t{SR1, SR1, SR1, SR1}\n    #define ALTI_MSK\t{MSK1, MSK2, MSK3, MSK4}\n    #define ALTI_MSK64\t{MSK2, MSK1, MSK4, MSK3}\n    #define ALTI_SL2_PERM\t{1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}\n    #define ALTI_SL2_PERM64\t{1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}\n    #define ALTI_SR2_PERM\t{7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}\n    #define ALTI_SR2_PERM64\t{15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}\n#endif\t/* For OSX */\n#define IDSTR\t\"SFMT-132049:110-19-1-21-1:ffffbb5f-fb6ebf95-fffefffa-cff77fff\"\n\n#endif /* SFMT_PARAMS132049_H */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/SFMT-params19937.h",
    "content": "/*\n * This file derives from SFMT 1.3.3\n * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was\n * released under the terms of the following license:\n *\n *   Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n *   University. 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\n *         disclaimer in the documentation and/or other materials provided\n *         with the distribution.\n *       * Neither the name of the Hiroshima University nor the names of\n *         its contributors may be used to endorse or promote products\n *         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\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 SFMT_PARAMS19937_H\n#define SFMT_PARAMS19937_H\n\n#define POS1\t122\n#define SL1\t18\n#define SL2\t1\n#define SR1\t11\n#define SR2\t1\n#define MSK1\t0xdfffffefU\n#define MSK2\t0xddfecb7fU\n#define MSK3\t0xbffaffffU\n#define MSK4\t0xbffffff6U\n#define PARITY1\t0x00000001U\n#define PARITY2\t0x00000000U\n#define PARITY3\t0x00000000U\n#define PARITY4\t0x13c9e684U\n\n\n/* PARAMETERS FOR ALTIVEC */\n#if defined(__APPLE__)\t/* For OSX */\n    #define ALTI_SL1\t(vector unsigned int)(SL1, SL1, SL1, SL1)\n    #define ALTI_SR1\t(vector unsigned int)(SR1, SR1, SR1, SR1)\n    #define ALTI_MSK\t(vector unsigned int)(MSK1, MSK2, MSK3, MSK4)\n    #define ALTI_MSK64 \\\n\t(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)\n    #define ALTI_SL2_PERM \\\n\t(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)\n    #define ALTI_SL2_PERM64 \\\n\t(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)\n    #define ALTI_SR2_PERM \\\n\t(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)\n    #define ALTI_SR2_PERM64 \\\n\t(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)\n#else\t/* For OTHER OSs(Linux?) */\n    #define ALTI_SL1\t{SL1, SL1, SL1, SL1}\n    #define ALTI_SR1\t{SR1, SR1, SR1, SR1}\n    #define ALTI_MSK\t{MSK1, MSK2, MSK3, MSK4}\n    #define ALTI_MSK64\t{MSK2, MSK1, MSK4, MSK3}\n    #define ALTI_SL2_PERM\t{1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}\n    #define ALTI_SL2_PERM64\t{1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}\n    #define ALTI_SR2_PERM\t{7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}\n    #define ALTI_SR2_PERM64\t{15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}\n#endif\t/* For OSX */\n#define IDSTR\t\"SFMT-19937:122-18-1-11-1:dfffffef-ddfecb7f-bffaffff-bffffff6\"\n\n#endif /* SFMT_PARAMS19937_H */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/SFMT-params216091.h",
    "content": "/*\n * This file derives from SFMT 1.3.3\n * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was\n * released under the terms of the following license:\n *\n *   Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n *   University. 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\n *         disclaimer in the documentation and/or other materials provided\n *         with the distribution.\n *       * Neither the name of the Hiroshima University nor the names of\n *         its contributors may be used to endorse or promote products\n *         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\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 SFMT_PARAMS216091_H\n#define SFMT_PARAMS216091_H\n\n#define POS1\t627\n#define SL1\t11\n#define SL2\t3\n#define SR1\t10\n#define SR2\t1\n#define MSK1\t0xbff7bff7U\n#define MSK2\t0xbfffffffU\n#define MSK3\t0xbffffa7fU\n#define MSK4\t0xffddfbfbU\n#define PARITY1\t0xf8000001U\n#define PARITY2\t0x89e80709U\n#define PARITY3\t0x3bd2b64bU\n#define PARITY4\t0x0c64b1e4U\n\n\n/* PARAMETERS FOR ALTIVEC */\n#if defined(__APPLE__)\t/* For OSX */\n    #define ALTI_SL1\t(vector unsigned int)(SL1, SL1, SL1, SL1)\n    #define ALTI_SR1\t(vector unsigned int)(SR1, SR1, SR1, SR1)\n    #define ALTI_MSK\t(vector unsigned int)(MSK1, MSK2, MSK3, MSK4)\n    #define ALTI_MSK64 \\\n\t(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)\n    #define ALTI_SL2_PERM \\\n\t(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)\n    #define ALTI_SL2_PERM64 \\\n\t(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)\n    #define ALTI_SR2_PERM \\\n\t(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)\n    #define ALTI_SR2_PERM64 \\\n\t(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)\n#else\t/* For OTHER OSs(Linux?) */\n    #define ALTI_SL1\t{SL1, SL1, SL1, SL1}\n    #define ALTI_SR1\t{SR1, SR1, SR1, SR1}\n    #define ALTI_MSK\t{MSK1, MSK2, MSK3, MSK4}\n    #define ALTI_MSK64\t{MSK2, MSK1, MSK4, MSK3}\n    #define ALTI_SL2_PERM\t{3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}\n    #define ALTI_SL2_PERM64\t{3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}\n    #define ALTI_SR2_PERM\t{7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}\n    #define ALTI_SR2_PERM64\t{15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}\n#endif\t/* For OSX */\n#define IDSTR\t\"SFMT-216091:627-11-3-10-1:bff7bff7-bfffffff-bffffa7f-ffddfbfb\"\n\n#endif /* SFMT_PARAMS216091_H */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/SFMT-params2281.h",
    "content": "/*\n * This file derives from SFMT 1.3.3\n * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was\n * released under the terms of the following license:\n *\n *   Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n *   University. 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\n *         disclaimer in the documentation and/or other materials provided\n *         with the distribution.\n *       * Neither the name of the Hiroshima University nor the names of\n *         its contributors may be used to endorse or promote products\n *         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\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 SFMT_PARAMS2281_H\n#define SFMT_PARAMS2281_H\n\n#define POS1\t12\n#define SL1\t19\n#define SL2\t1\n#define SR1\t5\n#define SR2\t1\n#define MSK1\t0xbff7ffbfU\n#define MSK2\t0xfdfffffeU\n#define MSK3\t0xf7ffef7fU\n#define MSK4\t0xf2f7cbbfU\n#define PARITY1\t0x00000001U\n#define PARITY2\t0x00000000U\n#define PARITY3\t0x00000000U\n#define PARITY4\t0x41dfa600U\n\n\n/* PARAMETERS FOR ALTIVEC */\n#if defined(__APPLE__)\t/* For OSX */\n    #define ALTI_SL1\t(vector unsigned int)(SL1, SL1, SL1, SL1)\n    #define ALTI_SR1\t(vector unsigned int)(SR1, SR1, SR1, SR1)\n    #define ALTI_MSK\t(vector unsigned int)(MSK1, MSK2, MSK3, MSK4)\n    #define ALTI_MSK64 \\\n\t(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)\n    #define ALTI_SL2_PERM \\\n\t(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)\n    #define ALTI_SL2_PERM64 \\\n\t(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)\n    #define ALTI_SR2_PERM \\\n\t(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)\n    #define ALTI_SR2_PERM64 \\\n\t(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)\n#else\t/* For OTHER OSs(Linux?) */\n    #define ALTI_SL1\t{SL1, SL1, SL1, SL1}\n    #define ALTI_SR1\t{SR1, SR1, SR1, SR1}\n    #define ALTI_MSK\t{MSK1, MSK2, MSK3, MSK4}\n    #define ALTI_MSK64\t{MSK2, MSK1, MSK4, MSK3}\n    #define ALTI_SL2_PERM\t{1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}\n    #define ALTI_SL2_PERM64\t{1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}\n    #define ALTI_SR2_PERM\t{7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}\n    #define ALTI_SR2_PERM64\t{15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}\n#endif\t/* For OSX */\n#define IDSTR\t\"SFMT-2281:12-19-1-5-1:bff7ffbf-fdfffffe-f7ffef7f-f2f7cbbf\"\n\n#endif /* SFMT_PARAMS2281_H */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/SFMT-params4253.h",
    "content": "/*\n * This file derives from SFMT 1.3.3\n * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was\n * released under the terms of the following license:\n *\n *   Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n *   University. 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\n *         disclaimer in the documentation and/or other materials provided\n *         with the distribution.\n *       * Neither the name of the Hiroshima University nor the names of\n *         its contributors may be used to endorse or promote products\n *         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\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 SFMT_PARAMS4253_H\n#define SFMT_PARAMS4253_H\n\n#define POS1\t17\n#define SL1\t20\n#define SL2\t1\n#define SR1\t7\n#define SR2\t1\n#define MSK1\t0x9f7bffffU\n#define MSK2\t0x9fffff5fU\n#define MSK3\t0x3efffffbU\n#define MSK4\t0xfffff7bbU\n#define PARITY1\t0xa8000001U\n#define PARITY2\t0xaf5390a3U\n#define PARITY3\t0xb740b3f8U\n#define PARITY4\t0x6c11486dU\n\n\n/* PARAMETERS FOR ALTIVEC */\n#if defined(__APPLE__)\t/* For OSX */\n    #define ALTI_SL1\t(vector unsigned int)(SL1, SL1, SL1, SL1)\n    #define ALTI_SR1\t(vector unsigned int)(SR1, SR1, SR1, SR1)\n    #define ALTI_MSK\t(vector unsigned int)(MSK1, MSK2, MSK3, MSK4)\n    #define ALTI_MSK64 \\\n\t(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)\n    #define ALTI_SL2_PERM \\\n\t(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)\n    #define ALTI_SL2_PERM64 \\\n\t(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)\n    #define ALTI_SR2_PERM \\\n\t(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)\n    #define ALTI_SR2_PERM64 \\\n\t(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)\n#else\t/* For OTHER OSs(Linux?) */\n    #define ALTI_SL1\t{SL1, SL1, SL1, SL1}\n    #define ALTI_SR1\t{SR1, SR1, SR1, SR1}\n    #define ALTI_MSK\t{MSK1, MSK2, MSK3, MSK4}\n    #define ALTI_MSK64\t{MSK2, MSK1, MSK4, MSK3}\n    #define ALTI_SL2_PERM\t{1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}\n    #define ALTI_SL2_PERM64\t{1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}\n    #define ALTI_SR2_PERM\t{7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}\n    #define ALTI_SR2_PERM64\t{15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}\n#endif\t/* For OSX */\n#define IDSTR\t\"SFMT-4253:17-20-1-7-1:9f7bffff-9fffff5f-3efffffb-fffff7bb\"\n\n#endif /* SFMT_PARAMS4253_H */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/SFMT-params44497.h",
    "content": "/*\n * This file derives from SFMT 1.3.3\n * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was\n * released under the terms of the following license:\n *\n *   Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n *   University. 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\n *         disclaimer in the documentation and/or other materials provided\n *         with the distribution.\n *       * Neither the name of the Hiroshima University nor the names of\n *         its contributors may be used to endorse or promote products\n *         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\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 SFMT_PARAMS44497_H\n#define SFMT_PARAMS44497_H\n\n#define POS1\t330\n#define SL1\t5\n#define SL2\t3\n#define SR1\t9\n#define SR2\t3\n#define MSK1\t0xeffffffbU\n#define MSK2\t0xdfbebfffU\n#define MSK3\t0xbfbf7befU\n#define MSK4\t0x9ffd7bffU\n#define PARITY1\t0x00000001U\n#define PARITY2\t0x00000000U\n#define PARITY3\t0xa3ac4000U\n#define PARITY4\t0xecc1327aU\n\n\n/* PARAMETERS FOR ALTIVEC */\n#if defined(__APPLE__)\t/* For OSX */\n    #define ALTI_SL1\t(vector unsigned int)(SL1, SL1, SL1, SL1)\n    #define ALTI_SR1\t(vector unsigned int)(SR1, SR1, SR1, SR1)\n    #define ALTI_MSK\t(vector unsigned int)(MSK1, MSK2, MSK3, MSK4)\n    #define ALTI_MSK64 \\\n\t(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)\n    #define ALTI_SL2_PERM \\\n\t(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)\n    #define ALTI_SL2_PERM64 \\\n\t(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)\n    #define ALTI_SR2_PERM \\\n\t(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)\n    #define ALTI_SR2_PERM64 \\\n\t(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)\n#else\t/* For OTHER OSs(Linux?) */\n    #define ALTI_SL1\t{SL1, SL1, SL1, SL1}\n    #define ALTI_SR1\t{SR1, SR1, SR1, SR1}\n    #define ALTI_MSK\t{MSK1, MSK2, MSK3, MSK4}\n    #define ALTI_MSK64\t{MSK2, MSK1, MSK4, MSK3}\n    #define ALTI_SL2_PERM\t{3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}\n    #define ALTI_SL2_PERM64\t{3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}\n    #define ALTI_SR2_PERM\t{5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}\n    #define ALTI_SR2_PERM64\t{13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}\n#endif\t/* For OSX */\n#define IDSTR\t\"SFMT-44497:330-5-3-9-3:effffffb-dfbebfff-bfbf7bef-9ffd7bff\"\n\n#endif /* SFMT_PARAMS44497_H */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/SFMT-params607.h",
    "content": "/*\n * This file derives from SFMT 1.3.3\n * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was\n * released under the terms of the following license:\n *\n *   Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n *   University. 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\n *         disclaimer in the documentation and/or other materials provided\n *         with the distribution.\n *       * Neither the name of the Hiroshima University nor the names of\n *         its contributors may be used to endorse or promote products\n *         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\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 SFMT_PARAMS607_H\n#define SFMT_PARAMS607_H\n\n#define POS1\t2\n#define SL1\t15\n#define SL2\t3\n#define SR1\t13\n#define SR2\t3\n#define MSK1\t0xfdff37ffU\n#define MSK2\t0xef7f3f7dU\n#define MSK3\t0xff777b7dU\n#define MSK4\t0x7ff7fb2fU\n#define PARITY1\t0x00000001U\n#define PARITY2\t0x00000000U\n#define PARITY3\t0x00000000U\n#define PARITY4\t0x5986f054U\n\n\n/* PARAMETERS FOR ALTIVEC */\n#if defined(__APPLE__)\t/* For OSX */\n    #define ALTI_SL1\t(vector unsigned int)(SL1, SL1, SL1, SL1)\n    #define ALTI_SR1\t(vector unsigned int)(SR1, SR1, SR1, SR1)\n    #define ALTI_MSK\t(vector unsigned int)(MSK1, MSK2, MSK3, MSK4)\n    #define ALTI_MSK64 \\\n\t(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)\n    #define ALTI_SL2_PERM \\\n\t(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)\n    #define ALTI_SL2_PERM64 \\\n\t(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)\n    #define ALTI_SR2_PERM \\\n\t(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)\n    #define ALTI_SR2_PERM64 \\\n\t(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)\n#else\t/* For OTHER OSs(Linux?) */\n    #define ALTI_SL1\t{SL1, SL1, SL1, SL1}\n    #define ALTI_SR1\t{SR1, SR1, SR1, SR1}\n    #define ALTI_MSK\t{MSK1, MSK2, MSK3, MSK4}\n    #define ALTI_MSK64\t{MSK2, MSK1, MSK4, MSK3}\n    #define ALTI_SL2_PERM\t{3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}\n    #define ALTI_SL2_PERM64\t{3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}\n    #define ALTI_SR2_PERM\t{5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}\n    #define ALTI_SR2_PERM64\t{13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}\n#endif\t/* For OSX */\n#define IDSTR\t\"SFMT-607:2-15-3-13-3:fdff37ff-ef7f3f7d-ff777b7d-7ff7fb2f\"\n\n#endif /* SFMT_PARAMS607_H */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/SFMT-params86243.h",
    "content": "/*\n * This file derives from SFMT 1.3.3\n * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was\n * released under the terms of the following license:\n *\n *   Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n *   University. 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\n *         disclaimer in the documentation and/or other materials provided\n *         with the distribution.\n *       * Neither the name of the Hiroshima University nor the names of\n *         its contributors may be used to endorse or promote products\n *         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\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 SFMT_PARAMS86243_H\n#define SFMT_PARAMS86243_H\n\n#define POS1\t366\n#define SL1\t6\n#define SL2\t7\n#define SR1\t19\n#define SR2\t1\n#define MSK1\t0xfdbffbffU\n#define MSK2\t0xbff7ff3fU\n#define MSK3\t0xfd77efffU\n#define MSK4\t0xbf9ff3ffU\n#define PARITY1\t0x00000001U\n#define PARITY2\t0x00000000U\n#define PARITY3\t0x00000000U\n#define PARITY4\t0xe9528d85U\n\n\n/* PARAMETERS FOR ALTIVEC */\n#if defined(__APPLE__)\t/* For OSX */\n    #define ALTI_SL1\t(vector unsigned int)(SL1, SL1, SL1, SL1)\n    #define ALTI_SR1\t(vector unsigned int)(SR1, SR1, SR1, SR1)\n    #define ALTI_MSK\t(vector unsigned int)(MSK1, MSK2, MSK3, MSK4)\n    #define ALTI_MSK64 \\\n\t(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)\n    #define ALTI_SL2_PERM \\\n\t(vector unsigned char)(25,25,25,25,3,25,25,25,7,0,1,2,11,4,5,6)\n    #define ALTI_SL2_PERM64 \\\n\t(vector unsigned char)(7,25,25,25,25,25,25,25,15,0,1,2,3,4,5,6)\n    #define ALTI_SR2_PERM \\\n\t(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)\n    #define ALTI_SR2_PERM64 \\\n\t(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)\n#else\t/* For OTHER OSs(Linux?) */\n    #define ALTI_SL1\t{SL1, SL1, SL1, SL1}\n    #define ALTI_SR1\t{SR1, SR1, SR1, SR1}\n    #define ALTI_MSK\t{MSK1, MSK2, MSK3, MSK4}\n    #define ALTI_MSK64\t{MSK2, MSK1, MSK4, MSK3}\n    #define ALTI_SL2_PERM\t{25,25,25,25,3,25,25,25,7,0,1,2,11,4,5,6}\n    #define ALTI_SL2_PERM64\t{7,25,25,25,25,25,25,25,15,0,1,2,3,4,5,6}\n    #define ALTI_SR2_PERM\t{7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}\n    #define ALTI_SR2_PERM64\t{15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}\n#endif\t/* For OSX */\n#define IDSTR\t\"SFMT-86243:366-6-7-19-1:fdbffbff-bff7ff3f-fd77efff-bf9ff3ff\"\n\n#endif /* SFMT_PARAMS86243_H */\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/SFMT-sse2.h",
    "content": "/*\n * This file derives from SFMT 1.3.3\n * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was\n * released under the terms of the following license:\n *\n *   Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n *   University. 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\n *         disclaimer in the documentation and/or other materials provided\n *         with the distribution.\n *       * Neither the name of the Hiroshima University nor the names of\n *         its contributors may be used to endorse or promote products\n *         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\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 * @file  SFMT-sse2.h\n * @brief SIMD oriented Fast Mersenne Twister(SFMT) for Intel SSE2\n *\n * @author Mutsuo Saito (Hiroshima University)\n * @author Makoto Matsumoto (Hiroshima University)\n *\n * @note We assume LITTLE ENDIAN in this file\n *\n * Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n * University. All rights reserved.\n *\n * The new BSD License is applied to this software, see LICENSE.txt\n */\n\n#ifndef SFMT_SSE2_H\n#define SFMT_SSE2_H\n\n/**\n * This function represents the recursion formula.\n * @param a a 128-bit part of the interal state array\n * @param b a 128-bit part of the interal state array\n * @param c a 128-bit part of the interal state array\n * @param d a 128-bit part of the interal state array\n * @param mask 128-bit mask\n * @return output\n */\nJEMALLOC_ALWAYS_INLINE __m128i mm_recursion(__m128i *a, __m128i *b, \n\t\t\t\t   __m128i c, __m128i d, __m128i mask) {\n    __m128i v, x, y, z;\n    \n    x = _mm_load_si128(a);\n    y = _mm_srli_epi32(*b, SR1);\n    z = _mm_srli_si128(c, SR2);\n    v = _mm_slli_epi32(d, SL1);\n    z = _mm_xor_si128(z, x);\n    z = _mm_xor_si128(z, v);\n    x = _mm_slli_si128(x, SL2);\n    y = _mm_and_si128(y, mask);\n    z = _mm_xor_si128(z, x);\n    z = _mm_xor_si128(z, y);\n    return z;\n}\n\n/**\n * This function fills the internal state array with pseudorandom\n * integers.\n */\nJEMALLOC_INLINE void gen_rand_all(sfmt_t *ctx) {\n    int i;\n    __m128i r, r1, r2, mask;\n    mask = _mm_set_epi32(MSK4, MSK3, MSK2, MSK1);\n\n    r1 = _mm_load_si128(&ctx->sfmt[N - 2].si);\n    r2 = _mm_load_si128(&ctx->sfmt[N - 1].si);\n    for (i = 0; i < N - POS1; i++) {\n\tr = mm_recursion(&ctx->sfmt[i].si, &ctx->sfmt[i + POS1].si, r1, r2,\n\t  mask);\n\t_mm_store_si128(&ctx->sfmt[i].si, r);\n\tr1 = r2;\n\tr2 = r;\n    }\n    for (; i < N; i++) {\n\tr = mm_recursion(&ctx->sfmt[i].si, &ctx->sfmt[i + POS1 - N].si, r1, r2,\n\t  mask);\n\t_mm_store_si128(&ctx->sfmt[i].si, r);\n\tr1 = r2;\n\tr2 = r;\n    }\n}\n\n/**\n * This function fills the user-specified array with pseudorandom\n * integers.\n *\n * @param array an 128-bit array to be filled by pseudorandom numbers.  \n * @param size number of 128-bit pesudorandom numbers to be generated.\n */\nJEMALLOC_INLINE void gen_rand_array(sfmt_t *ctx, w128_t *array, int size) {\n    int i, j;\n    __m128i r, r1, r2, mask;\n    mask = _mm_set_epi32(MSK4, MSK3, MSK2, MSK1);\n\n    r1 = _mm_load_si128(&ctx->sfmt[N - 2].si);\n    r2 = _mm_load_si128(&ctx->sfmt[N - 1].si);\n    for (i = 0; i < N - POS1; i++) {\n\tr = mm_recursion(&ctx->sfmt[i].si, &ctx->sfmt[i + POS1].si, r1, r2,\n\t  mask);\n\t_mm_store_si128(&array[i].si, r);\n\tr1 = r2;\n\tr2 = r;\n    }\n    for (; i < N; i++) {\n\tr = mm_recursion(&ctx->sfmt[i].si, &array[i + POS1 - N].si, r1, r2,\n\t  mask);\n\t_mm_store_si128(&array[i].si, r);\n\tr1 = r2;\n\tr2 = r;\n    }\n    /* main loop */\n    for (; i < size - N; i++) {\n\tr = mm_recursion(&array[i - N].si, &array[i + POS1 - N].si, r1, r2,\n\t\t\t mask);\n\t_mm_store_si128(&array[i].si, r);\n\tr1 = r2;\n\tr2 = r;\n    }\n    for (j = 0; j < 2 * N - size; j++) {\n\tr = _mm_load_si128(&array[j + size - N].si);\n\t_mm_store_si128(&ctx->sfmt[j].si, r);\n    }\n    for (; i < size; i++) {\n\tr = mm_recursion(&array[i - N].si, &array[i + POS1 - N].si, r1, r2,\n\t\t\t mask);\n\t_mm_store_si128(&array[i].si, r);\n\t_mm_store_si128(&ctx->sfmt[j++].si, r);\n\tr1 = r2;\n\tr2 = r;\n    }\n}\n\n#endif\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/SFMT.h",
    "content": "/*\n * This file derives from SFMT 1.3.3\n * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was\n * released under the terms of the following license:\n *\n *   Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n *   University. 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\n *         disclaimer in the documentation and/or other materials provided\n *         with the distribution.\n *       * Neither the name of the Hiroshima University nor the names of\n *         its contributors may be used to endorse or promote products\n *         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\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 * @file SFMT.h \n *\n * @brief SIMD oriented Fast Mersenne Twister(SFMT) pseudorandom\n * number generator\n *\n * @author Mutsuo Saito (Hiroshima University)\n * @author Makoto Matsumoto (Hiroshima University)\n *\n * Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n * University. All rights reserved.\n *\n * The new BSD License is applied to this software.\n * see LICENSE.txt\n *\n * @note We assume that your system has inttypes.h.  If your system\n * doesn't have inttypes.h, you have to typedef uint32_t and uint64_t,\n * and you have to define PRIu64 and PRIx64 in this file as follows:\n * @verbatim\n typedef unsigned int uint32_t\n typedef unsigned long long uint64_t  \n #define PRIu64 \"llu\"\n #define PRIx64 \"llx\"\n@endverbatim\n * uint32_t must be exactly 32-bit unsigned integer type (no more, no\n * less), and uint64_t must be exactly 64-bit unsigned integer type.\n * PRIu64 and PRIx64 are used for printf function to print 64-bit\n * unsigned int and 64-bit unsigned int in hexadecimal format.\n */\n\n#ifndef SFMT_H\n#define SFMT_H\n\ntypedef struct sfmt_s sfmt_t;\n\nuint32_t gen_rand32(sfmt_t *ctx);\nuint32_t gen_rand32_range(sfmt_t *ctx, uint32_t limit);\nuint64_t gen_rand64(sfmt_t *ctx);\nuint64_t gen_rand64_range(sfmt_t *ctx, uint64_t limit);\nvoid fill_array32(sfmt_t *ctx, uint32_t *array, int size);\nvoid fill_array64(sfmt_t *ctx, uint64_t *array, int size);\nsfmt_t *init_gen_rand(uint32_t seed);\nsfmt_t *init_by_array(uint32_t *init_key, int key_length);\nvoid fini_gen_rand(sfmt_t *ctx);\nconst char *get_idstring(void);\nint get_min_array_size32(void);\nint get_min_array_size64(void);\n\n#ifndef JEMALLOC_ENABLE_INLINE\ndouble to_real1(uint32_t v);\ndouble genrand_real1(sfmt_t *ctx);\ndouble to_real2(uint32_t v);\ndouble genrand_real2(sfmt_t *ctx);\ndouble to_real3(uint32_t v);\ndouble genrand_real3(sfmt_t *ctx);\ndouble to_res53(uint64_t v);\ndouble to_res53_mix(uint32_t x, uint32_t y);\ndouble genrand_res53(sfmt_t *ctx);\ndouble genrand_res53_mix(sfmt_t *ctx);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(SFMT_C_))\n/* These real versions are due to Isaku Wada */\n/** generates a random number on [0,1]-real-interval */\nJEMALLOC_INLINE double to_real1(uint32_t v)\n{\n    return v * (1.0/4294967295.0); \n    /* divided by 2^32-1 */ \n}\n\n/** generates a random number on [0,1]-real-interval */\nJEMALLOC_INLINE double genrand_real1(sfmt_t *ctx)\n{\n    return to_real1(gen_rand32(ctx));\n}\n\n/** generates a random number on [0,1)-real-interval */\nJEMALLOC_INLINE double to_real2(uint32_t v)\n{\n    return v * (1.0/4294967296.0); \n    /* divided by 2^32 */\n}\n\n/** generates a random number on [0,1)-real-interval */\nJEMALLOC_INLINE double genrand_real2(sfmt_t *ctx)\n{\n    return to_real2(gen_rand32(ctx));\n}\n\n/** generates a random number on (0,1)-real-interval */\nJEMALLOC_INLINE double to_real3(uint32_t v)\n{\n    return (((double)v) + 0.5)*(1.0/4294967296.0); \n    /* divided by 2^32 */\n}\n\n/** generates a random number on (0,1)-real-interval */\nJEMALLOC_INLINE double genrand_real3(sfmt_t *ctx)\n{\n    return to_real3(gen_rand32(ctx));\n}\n/** These real versions are due to Isaku Wada */\n\n/** generates a random number on [0,1) with 53-bit resolution*/\nJEMALLOC_INLINE double to_res53(uint64_t v) \n{ \n    return v * (1.0/18446744073709551616.0L);\n}\n\n/** generates a random number on [0,1) with 53-bit resolution from two\n * 32 bit integers */\nJEMALLOC_INLINE double to_res53_mix(uint32_t x, uint32_t y) \n{ \n    return to_res53(x | ((uint64_t)y << 32));\n}\n\n/** generates a random number on [0,1) with 53-bit resolution\n */\nJEMALLOC_INLINE double genrand_res53(sfmt_t *ctx) \n{ \n    return to_res53(gen_rand64(ctx));\n} \n\n/** generates a random number on [0,1) with 53-bit resolution\n    using 32bit integer.\n */\nJEMALLOC_INLINE double genrand_res53_mix(sfmt_t *ctx) \n{ \n    uint32_t x, y;\n\n    x = gen_rand32(ctx);\n    y = gen_rand32(ctx);\n    return to_res53_mix(x, y);\n} \n#endif\n#endif\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/btalloc.h",
    "content": "/* btalloc() provides a mechanism for allocating via permuted backtraces. */\nvoid\t*btalloc(size_t size, unsigned bits);\n\n#define\tbtalloc_n_proto(n)\t\t\t\t\t\t\\\nvoid\t*btalloc_##n(size_t size, unsigned bits);\nbtalloc_n_proto(0)\nbtalloc_n_proto(1)\n\n#define\tbtalloc_n_gen(n)\t\t\t\t\t\t\\\nvoid *\t\t\t\t\t\t\t\t\t\\\nbtalloc_##n(size_t size, unsigned bits)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tvoid *p;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tif (bits == 0)\t\t\t\t\t\t\t\\\n\t\tp = mallocx(size, 0);\t\t\t\t\t\\\n\telse {\t\t\t\t\t\t\t\t\\\n\t\tswitch (bits & 0x1U) {\t\t\t\t\t\\\n\t\tcase 0:\t\t\t\t\t\t\t\\\n\t\t\tp = (btalloc_0(size, bits >> 1));\t\t\\\n\t\t\tbreak;\t\t\t\t\t\t\\\n\t\tcase 1:\t\t\t\t\t\t\t\\\n\t\t\tp = (btalloc_1(size, bits >> 1));\t\t\\\n\t\t\tbreak;\t\t\t\t\t\t\\\n\t\tdefault: not_reached();\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\t/* Intentionally sabotage tail call optimization. */\t\t\\\n\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\t\t\\\n\treturn (p);\t\t\t\t\t\t\t\\\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/jemalloc_test.h.in",
    "content": "#include <limits.h>\n#ifndef SIZE_T_MAX\n#  define SIZE_T_MAX\tSIZE_MAX\n#endif\n#include <stdlib.h>\n#include <stdarg.h>\n#include <stdbool.h>\n#include <errno.h>\n#include <math.h>\n#include <string.h>\n#ifdef _WIN32\n#  include \"msvc_compat/strings.h\"\n#endif\n\n#ifdef _WIN32\n#  include <windows.h>\n#  include \"msvc_compat/windows_extra.h\"\n#else\n#  include <pthread.h>\n#endif\n\n/******************************************************************************/\n/*\n * Define always-enabled assertion macros, so that test assertions execute even\n * if assertions are disabled in the library code.  These definitions must\n * exist prior to including \"jemalloc/internal/util.h\".\n */\n#define\tassert(e) do {\t\t\t\t\t\t\t\\\n\tif (!(e)) {\t\t\t\t\t\t\t\\\n\t\tmalloc_printf(\t\t\t\t\t\t\\\n\t\t    \"<jemalloc>: %s:%d: Failed assertion: \\\"%s\\\"\\n\",\t\\\n\t\t    __FILE__, __LINE__, #e);\t\t\t\t\\\n\t\tabort();\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tnot_reached() do {\t\t\t\t\t\t\\\n\tmalloc_printf(\t\t\t\t\t\t\t\\\n\t    \"<jemalloc>: %s:%d: Unreachable code reached\\n\",\t\t\\\n\t    __FILE__, __LINE__);\t\t\t\t\t\\\n\tabort();\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tnot_implemented() do {\t\t\t\t\t\t\\\n\tmalloc_printf(\"<jemalloc>: %s:%d: Not implemented\\n\",\t\t\\\n\t    __FILE__, __LINE__);\t\t\t\t\t\\\n\tabort();\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tassert_not_implemented(e) do {\t\t\t\t\t\\\n\tif (!(e))\t\t\t\t\t\t\t\\\n\t\tnot_implemented();\t\t\t\t\t\\\n} while (0)\n\n#include \"test/jemalloc_test_defs.h\"\n\n#ifdef JEMALLOC_OSSPIN\n#  include <libkern/OSAtomic.h>\n#endif\n\n#if defined(HAVE_ALTIVEC) && !defined(__APPLE__)\n#  include <altivec.h>\n#endif\n#ifdef HAVE_SSE2\n#  include <emmintrin.h>\n#endif\n\n/******************************************************************************/\n/*\n * For unit tests, expose all public and private interfaces.\n */\n#ifdef JEMALLOC_UNIT_TEST\n#  define JEMALLOC_JET\n#  define JEMALLOC_MANGLE\n#  include \"jemalloc/internal/jemalloc_internal.h\"\n\n/******************************************************************************/\n/*\n * For integration tests, expose the public jemalloc interfaces, but only\n * expose the minimum necessary internal utility code (to avoid re-implementing\n * essentially identical code within the test infrastructure).\n */\n#elif defined(JEMALLOC_INTEGRATION_TEST)\n#  define JEMALLOC_MANGLE\n#  include \"jemalloc/jemalloc@install_suffix@.h\"\n#  include \"jemalloc/internal/jemalloc_internal_defs.h\"\n#  include \"jemalloc/internal/jemalloc_internal_macros.h\"\n\n#  define JEMALLOC_N(n) @private_namespace@##n\n#  include \"jemalloc/internal/private_namespace.h\"\n\n#  define JEMALLOC_H_TYPES\n#  define JEMALLOC_H_STRUCTS\n#  define JEMALLOC_H_EXTERNS\n#  define JEMALLOC_H_INLINES\n#  include \"jemalloc/internal/nstime.h\"\n#  include \"jemalloc/internal/util.h\"\n#  include \"jemalloc/internal/qr.h\"\n#  include \"jemalloc/internal/ql.h\"\n#  undef JEMALLOC_H_TYPES\n#  undef JEMALLOC_H_STRUCTS\n#  undef JEMALLOC_H_EXTERNS\n#  undef JEMALLOC_H_INLINES\n\n/******************************************************************************/\n/*\n * For stress tests, expose the public jemalloc interfaces with name mangling\n * so that they can be tested as e.g. malloc() and free().  Also expose the\n * public jemalloc interfaces with jet_ prefixes, so that stress tests can use\n * a separate allocator for their internal data structures.\n */\n#elif defined(JEMALLOC_STRESS_TEST)\n#  include \"jemalloc/jemalloc@install_suffix@.h\"\n\n#  include \"jemalloc/jemalloc_protos_jet.h\"\n\n#  define JEMALLOC_JET\n#  include \"jemalloc/internal/jemalloc_internal.h\"\n#  include \"jemalloc/internal/public_unnamespace.h\"\n#  undef JEMALLOC_JET\n\n#  include \"jemalloc/jemalloc_rename.h\"\n#  define JEMALLOC_MANGLE\n#  ifdef JEMALLOC_STRESS_TESTLIB\n#    include \"jemalloc/jemalloc_mangle_jet.h\"\n#  else\n#    include \"jemalloc/jemalloc_mangle.h\"\n#  endif\n\n/******************************************************************************/\n/*\n * This header does dangerous things, the effects of which only test code\n * should be subject to.\n */\n#else\n#  error \"This header cannot be included outside a testing context\"\n#endif\n\n/******************************************************************************/\n/*\n * Common test utilities.\n */\n#include \"test/btalloc.h\"\n#include \"test/math.h\"\n#include \"test/mtx.h\"\n#include \"test/mq.h\"\n#include \"test/test.h\"\n#include \"test/timer.h\"\n#include \"test/thd.h\"\n#define\tMEXP 19937\n#include \"test/SFMT.h\"\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/jemalloc_test_defs.h.in",
    "content": "#include \"jemalloc/internal/jemalloc_internal_defs.h\"\n#include \"jemalloc/internal/jemalloc_internal_decls.h\"\n\n/*\n * For use by SFMT.  configure.ac doesn't actually define HAVE_SSE2 because its\n * dependencies are notoriously unportable in practice.\n */\n#undef HAVE_SSE2\n#undef HAVE_ALTIVEC\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/math.h",
    "content": "#ifndef JEMALLOC_ENABLE_INLINE\ndouble\tln_gamma(double x);\ndouble\ti_gamma(double x, double p, double ln_gamma_p);\ndouble\tpt_norm(double p);\ndouble\tpt_chi2(double p, double df, double ln_gamma_df_2);\ndouble\tpt_gamma(double p, double shape, double scale, double ln_gamma_shape);\n#endif\n\n#if (defined(JEMALLOC_ENABLE_INLINE) || defined(MATH_C_))\n/*\n * Compute the natural log of Gamma(x), accurate to 10 decimal places.\n *\n * This implementation is based on:\n *\n *   Pike, M.C., I.D. Hill (1966) Algorithm 291: Logarithm of Gamma function\n *   [S14].  Communications of the ACM 9(9):684.\n */\nJEMALLOC_INLINE double\nln_gamma(double x)\n{\n\tdouble f, z;\n\n\tassert(x > 0.0);\n\n\tif (x < 7.0) {\n\t\tf = 1.0;\n\t\tz = x;\n\t\twhile (z < 7.0) {\n\t\t\tf *= z;\n\t\t\tz += 1.0;\n\t\t}\n\t\tx = z;\n\t\tf = -log(f);\n\t} else\n\t\tf = 0.0;\n\n\tz = 1.0 / (x * x);\n\n\treturn (f + (x-0.5) * log(x) - x + 0.918938533204673 +\n\t    (((-0.000595238095238 * z + 0.000793650793651) * z -\n\t    0.002777777777778) * z + 0.083333333333333) / x);\n}\n\n/*\n * Compute the incomplete Gamma ratio for [0..x], where p is the shape\n * parameter, and ln_gamma_p is ln_gamma(p).\n *\n * This implementation is based on:\n *\n *   Bhattacharjee, G.P. (1970) Algorithm AS 32: The incomplete Gamma integral.\n *   Applied Statistics 19:285-287.\n */\nJEMALLOC_INLINE double\ni_gamma(double x, double p, double ln_gamma_p)\n{\n\tdouble acu, factor, oflo, gin, term, rn, a, b, an, dif;\n\tdouble pn[6];\n\tunsigned i;\n\n\tassert(p > 0.0);\n\tassert(x >= 0.0);\n\n\tif (x == 0.0)\n\t\treturn (0.0);\n\n\tacu = 1.0e-10;\n\toflo = 1.0e30;\n\tgin = 0.0;\n\tfactor = exp(p * log(x) - x - ln_gamma_p);\n\n\tif (x <= 1.0 || x < p) {\n\t\t/* Calculation by series expansion. */\n\t\tgin = 1.0;\n\t\tterm = 1.0;\n\t\trn = p;\n\n\t\twhile (true) {\n\t\t\trn += 1.0;\n\t\t\tterm *= x / rn;\n\t\t\tgin += term;\n\t\t\tif (term <= acu) {\n\t\t\t\tgin *= factor / p;\n\t\t\t\treturn (gin);\n\t\t\t}\n\t\t}\n\t} else {\n\t\t/* Calculation by continued fraction. */\n\t\ta = 1.0 - p;\n\t\tb = a + x + 1.0;\n\t\tterm = 0.0;\n\t\tpn[0] = 1.0;\n\t\tpn[1] = x;\n\t\tpn[2] = x + 1.0;\n\t\tpn[3] = x * b;\n\t\tgin = pn[2] / pn[3];\n\n\t\twhile (true) {\n\t\t\ta += 1.0;\n\t\t\tb += 2.0;\n\t\t\tterm += 1.0;\n\t\t\tan = a * term;\n\t\t\tfor (i = 0; i < 2; i++)\n\t\t\t\tpn[i+4] = b * pn[i+2] - an * pn[i];\n\t\t\tif (pn[5] != 0.0) {\n\t\t\t\trn = pn[4] / pn[5];\n\t\t\t\tdif = fabs(gin - rn);\n\t\t\t\tif (dif <= acu && dif <= acu * rn) {\n\t\t\t\t\tgin = 1.0 - factor * gin;\n\t\t\t\t\treturn (gin);\n\t\t\t\t}\n\t\t\t\tgin = rn;\n\t\t\t}\n\t\t\tfor (i = 0; i < 4; i++)\n\t\t\t\tpn[i] = pn[i+2];\n\n\t\t\tif (fabs(pn[4]) >= oflo) {\n\t\t\t\tfor (i = 0; i < 4; i++)\n\t\t\t\t\tpn[i] /= oflo;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/*\n * Given a value p in [0..1] of the lower tail area of the normal distribution,\n * compute the limit on the definite integral from [-inf..z] that satisfies p,\n * accurate to 16 decimal places.\n *\n * This implementation is based on:\n *\n *   Wichura, M.J. (1988) Algorithm AS 241: The percentage points of the normal\n *   distribution.  Applied Statistics 37(3):477-484.\n */\nJEMALLOC_INLINE double\npt_norm(double p)\n{\n\tdouble q, r, ret;\n\n\tassert(p > 0.0 && p < 1.0);\n\n\tq = p - 0.5;\n\tif (fabs(q) <= 0.425) {\n\t\t/* p close to 1/2. */\n\t\tr = 0.180625 - q * q;\n\t\treturn (q * (((((((2.5090809287301226727e3 * r +\n\t\t    3.3430575583588128105e4) * r + 6.7265770927008700853e4) * r\n\t\t    + 4.5921953931549871457e4) * r + 1.3731693765509461125e4) *\n\t\t    r + 1.9715909503065514427e3) * r + 1.3314166789178437745e2)\n\t\t    * r + 3.3871328727963666080e0) /\n\t\t    (((((((5.2264952788528545610e3 * r +\n\t\t    2.8729085735721942674e4) * r + 3.9307895800092710610e4) * r\n\t\t    + 2.1213794301586595867e4) * r + 5.3941960214247511077e3) *\n\t\t    r + 6.8718700749205790830e2) * r + 4.2313330701600911252e1)\n\t\t    * r + 1.0));\n\t} else {\n\t\tif (q < 0.0)\n\t\t\tr = p;\n\t\telse\n\t\t\tr = 1.0 - p;\n\t\tassert(r > 0.0);\n\n\t\tr = sqrt(-log(r));\n\t\tif (r <= 5.0) {\n\t\t\t/* p neither close to 1/2 nor 0 or 1. */\n\t\t\tr -= 1.6;\n\t\t\tret = ((((((((7.74545014278341407640e-4 * r +\n\t\t\t    2.27238449892691845833e-2) * r +\n\t\t\t    2.41780725177450611770e-1) * r +\n\t\t\t    1.27045825245236838258e0) * r +\n\t\t\t    3.64784832476320460504e0) * r +\n\t\t\t    5.76949722146069140550e0) * r +\n\t\t\t    4.63033784615654529590e0) * r +\n\t\t\t    1.42343711074968357734e0) /\n\t\t\t    (((((((1.05075007164441684324e-9 * r +\n\t\t\t    5.47593808499534494600e-4) * r +\n\t\t\t    1.51986665636164571966e-2)\n\t\t\t    * r + 1.48103976427480074590e-1) * r +\n\t\t\t    6.89767334985100004550e-1) * r +\n\t\t\t    1.67638483018380384940e0) * r +\n\t\t\t    2.05319162663775882187e0) * r + 1.0));\n\t\t} else {\n\t\t\t/* p near 0 or 1. */\n\t\t\tr -= 5.0;\n\t\t\tret = ((((((((2.01033439929228813265e-7 * r +\n\t\t\t    2.71155556874348757815e-5) * r +\n\t\t\t    1.24266094738807843860e-3) * r +\n\t\t\t    2.65321895265761230930e-2) * r +\n\t\t\t    2.96560571828504891230e-1) * r +\n\t\t\t    1.78482653991729133580e0) * r +\n\t\t\t    5.46378491116411436990e0) * r +\n\t\t\t    6.65790464350110377720e0) /\n\t\t\t    (((((((2.04426310338993978564e-15 * r +\n\t\t\t    1.42151175831644588870e-7) * r +\n\t\t\t    1.84631831751005468180e-5) * r +\n\t\t\t    7.86869131145613259100e-4) * r +\n\t\t\t    1.48753612908506148525e-2) * r +\n\t\t\t    1.36929880922735805310e-1) * r +\n\t\t\t    5.99832206555887937690e-1)\n\t\t\t    * r + 1.0));\n\t\t}\n\t\tif (q < 0.0)\n\t\t\tret = -ret;\n\t\treturn (ret);\n\t}\n}\n\n/*\n * Given a value p in [0..1] of the lower tail area of the Chi^2 distribution\n * with df degrees of freedom, where ln_gamma_df_2 is ln_gamma(df/2.0), compute\n * the upper limit on the definite integral from [0..z] that satisfies p,\n * accurate to 12 decimal places.\n *\n * This implementation is based on:\n *\n *   Best, D.J., D.E. Roberts (1975) Algorithm AS 91: The percentage points of\n *   the Chi^2 distribution.  Applied Statistics 24(3):385-388.\n *\n *   Shea, B.L. (1991) Algorithm AS R85: A remark on AS 91: The percentage\n *   points of the Chi^2 distribution.  Applied Statistics 40(1):233-235.\n */\nJEMALLOC_INLINE double\npt_chi2(double p, double df, double ln_gamma_df_2)\n{\n\tdouble e, aa, xx, c, ch, a, q, p1, p2, t, x, b, s1, s2, s3, s4, s5, s6;\n\tunsigned i;\n\n\tassert(p >= 0.0 && p < 1.0);\n\tassert(df > 0.0);\n\n\te = 5.0e-7;\n\taa = 0.6931471805;\n\n\txx = 0.5 * df;\n\tc = xx - 1.0;\n\n\tif (df < -1.24 * log(p)) {\n\t\t/* Starting approximation for small Chi^2. */\n\t\tch = pow(p * xx * exp(ln_gamma_df_2 + xx * aa), 1.0 / xx);\n\t\tif (ch - e < 0.0)\n\t\t\treturn (ch);\n\t} else {\n\t\tif (df > 0.32) {\n\t\t\tx = pt_norm(p);\n\t\t\t/*\n\t\t\t * Starting approximation using Wilson and Hilferty\n\t\t\t * estimate.\n\t\t\t */\n\t\t\tp1 = 0.222222 / df;\n\t\t\tch = df * pow(x * sqrt(p1) + 1.0 - p1, 3.0);\n\t\t\t/* Starting approximation for p tending to 1. */\n\t\t\tif (ch > 2.2 * df + 6.0) {\n\t\t\t\tch = -2.0 * (log(1.0 - p) - c * log(0.5 * ch) +\n\t\t\t\t    ln_gamma_df_2);\n\t\t\t}\n\t\t} else {\n\t\t\tch = 0.4;\n\t\t\ta = log(1.0 - p);\n\t\t\twhile (true) {\n\t\t\t\tq = ch;\n\t\t\t\tp1 = 1.0 + ch * (4.67 + ch);\n\t\t\t\tp2 = ch * (6.73 + ch * (6.66 + ch));\n\t\t\t\tt = -0.5 + (4.67 + 2.0 * ch) / p1 - (6.73 + ch\n\t\t\t\t    * (13.32 + 3.0 * ch)) / p2;\n\t\t\t\tch -= (1.0 - exp(a + ln_gamma_df_2 + 0.5 * ch +\n\t\t\t\t    c * aa) * p2 / p1) / t;\n\t\t\t\tif (fabs(q / ch - 1.0) - 0.01 <= 0.0)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (i = 0; i < 20; i++) {\n\t\t/* Calculation of seven-term Taylor series. */\n\t\tq = ch;\n\t\tp1 = 0.5 * ch;\n\t\tif (p1 < 0.0)\n\t\t\treturn (-1.0);\n\t\tp2 = p - i_gamma(p1, xx, ln_gamma_df_2);\n\t\tt = p2 * exp(xx * aa + ln_gamma_df_2 + p1 - c * log(ch));\n\t\tb = t / ch;\n\t\ta = 0.5 * t - b * c;\n\t\ts1 = (210.0 + a * (140.0 + a * (105.0 + a * (84.0 + a * (70.0 +\n\t\t    60.0 * a))))) / 420.0;\n\t\ts2 = (420.0 + a * (735.0 + a * (966.0 + a * (1141.0 + 1278.0 *\n\t\t    a)))) / 2520.0;\n\t\ts3 = (210.0 + a * (462.0 + a * (707.0 + 932.0 * a))) / 2520.0;\n\t\ts4 = (252.0 + a * (672.0 + 1182.0 * a) + c * (294.0 + a *\n\t\t    (889.0 + 1740.0 * a))) / 5040.0;\n\t\ts5 = (84.0 + 264.0 * a + c * (175.0 + 606.0 * a)) / 2520.0;\n\t\ts6 = (120.0 + c * (346.0 + 127.0 * c)) / 5040.0;\n\t\tch += t * (1.0 + 0.5 * t * s1 - b * c * (s1 - b * (s2 - b * (s3\n\t\t    - b * (s4 - b * (s5 - b * s6))))));\n\t\tif (fabs(q / ch - 1.0) <= e)\n\t\t\tbreak;\n\t}\n\n\treturn (ch);\n}\n\n/*\n * Given a value p in [0..1] and Gamma distribution shape and scale parameters,\n * compute the upper limit on the definite integral from [0..z] that satisfies\n * p.\n */\nJEMALLOC_INLINE double\npt_gamma(double p, double shape, double scale, double ln_gamma_shape)\n{\n\n\treturn (pt_chi2(p, shape * 2.0, ln_gamma_shape) * 0.5 * scale);\n}\n#endif\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/mq.h",
    "content": "void\tmq_nanosleep(unsigned ns);\n\n/*\n * Simple templated message queue implementation that relies on only mutexes for\n * synchronization (which reduces portability issues).  Given the following\n * setup:\n *\n *   typedef struct mq_msg_s mq_msg_t;\n *   struct mq_msg_s {\n *           mq_msg(mq_msg_t) link;\n *           [message data]\n *   };\n *   mq_gen(, mq_, mq_t, mq_msg_t, link)\n *\n * The API is as follows:\n *\n *   bool mq_init(mq_t *mq);\n *   void mq_fini(mq_t *mq);\n *   unsigned mq_count(mq_t *mq);\n *   mq_msg_t *mq_tryget(mq_t *mq);\n *   mq_msg_t *mq_get(mq_t *mq);\n *   void mq_put(mq_t *mq, mq_msg_t *msg);\n *\n * The message queue linkage embedded in each message is to be treated as\n * externally opaque (no need to initialize or clean up externally).  mq_fini()\n * does not perform any cleanup of messages, since it knows nothing of their\n * payloads.\n */\n#define\tmq_msg(a_mq_msg_type)\tql_elm(a_mq_msg_type)\n\n#define\tmq_gen(a_attr, a_prefix, a_mq_type, a_mq_msg_type, a_field)\t\\\ntypedef struct {\t\t\t\t\t\t\t\\\n\tmtx_t\t\t\tlock;\t\t\t\t\t\\\n\tql_head(a_mq_msg_type)\tmsgs;\t\t\t\t\t\\\n\tunsigned\t\tcount;\t\t\t\t\t\\\n} a_mq_type;\t\t\t\t\t\t\t\t\\\na_attr bool\t\t\t\t\t\t\t\t\\\na_prefix##init(a_mq_type *mq) {\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tif (mtx_init(&mq->lock))\t\t\t\t\t\\\n\t\treturn (true);\t\t\t\t\t\t\\\n\tql_new(&mq->msgs);\t\t\t\t\t\t\\\n\tmq->count = 0;\t\t\t\t\t\t\t\\\n\treturn (false);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr void\t\t\t\t\t\t\t\t\\\na_prefix##fini(a_mq_type *mq)\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\tmtx_fini(&mq->lock);\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr unsigned\t\t\t\t\t\t\t\t\\\na_prefix##count(a_mq_type *mq)\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tunsigned count;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tmtx_lock(&mq->lock);\t\t\t\t\t\t\\\n\tcount = mq->count;\t\t\t\t\t\t\\\n\tmtx_unlock(&mq->lock);\t\t\t\t\t\t\\\n\treturn (count);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr a_mq_msg_type *\t\t\t\t\t\t\t\\\na_prefix##tryget(a_mq_type *mq)\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\ta_mq_msg_type *msg;\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tmtx_lock(&mq->lock);\t\t\t\t\t\t\\\n\tmsg = ql_first(&mq->msgs);\t\t\t\t\t\\\n\tif (msg != NULL) {\t\t\t\t\t\t\\\n\t\tql_head_remove(&mq->msgs, a_mq_msg_type, a_field);\t\\\n\t\tmq->count--;\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tmtx_unlock(&mq->lock);\t\t\t\t\t\t\\\n\treturn (msg);\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\na_attr a_mq_msg_type *\t\t\t\t\t\t\t\\\na_prefix##get(a_mq_type *mq)\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\ta_mq_msg_type *msg;\t\t\t\t\t\t\\\n\tunsigned ns;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tmsg = a_prefix##tryget(mq);\t\t\t\t\t\\\n\tif (msg != NULL)\t\t\t\t\t\t\\\n\t\treturn (msg);\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tns = 1;\t\t\t\t\t\t\t\t\\\n\twhile (true) {\t\t\t\t\t\t\t\\\n\t\tmq_nanosleep(ns);\t\t\t\t\t\\\n\t\tmsg = a_prefix##tryget(mq);\t\t\t\t\\\n\t\tif (msg != NULL)\t\t\t\t\t\\\n\t\t\treturn (msg);\t\t\t\t\t\\\n\t\tif (ns < 1000*1000*1000) {\t\t\t\t\\\n\t\t\t/* Double sleep time, up to max 1 second. */\t\\\n\t\t\tns <<= 1;\t\t\t\t\t\\\n\t\t\tif (ns > 1000*1000*1000)\t\t\t\\\n\t\t\t\tns = 1000*1000*1000;\t\t\t\\\n\t\t}\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\\\na_attr void\t\t\t\t\t\t\t\t\\\na_prefix##put(a_mq_type *mq, a_mq_msg_type *msg)\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tmtx_lock(&mq->lock);\t\t\t\t\t\t\\\n\tql_elm_new(msg, a_field);\t\t\t\t\t\\\n\tql_tail_insert(&mq->msgs, msg, a_field);\t\t\t\\\n\tmq->count++;\t\t\t\t\t\t\t\\\n\tmtx_unlock(&mq->lock);\t\t\t\t\t\t\\\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/mtx.h",
    "content": "/*\n * mtx is a slightly simplified version of malloc_mutex.  This code duplication\n * is unfortunate, but there are allocator bootstrapping considerations that\n * would leak into the test infrastructure if malloc_mutex were used directly\n * in tests.\n */\n\ntypedef struct {\n#ifdef _WIN32\n\tCRITICAL_SECTION\tlock;\n#elif (defined(JEMALLOC_OSSPIN))\n\tOSSpinLock\t\tlock;\n#else\n\tpthread_mutex_t\t\tlock;\n#endif\n} mtx_t;\n\nbool\tmtx_init(mtx_t *mtx);\nvoid\tmtx_fini(mtx_t *mtx);\nvoid\tmtx_lock(mtx_t *mtx);\nvoid\tmtx_unlock(mtx_t *mtx);\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/test.h",
    "content": "#define\tASSERT_BUFSIZE\t256\n\n#define\tassert_cmp(t, a, b, cmp, neg_cmp, pri, ...) do {\t\t\\\n\tt a_ = (a);\t\t\t\t\t\t\t\\\n\tt b_ = (b);\t\t\t\t\t\t\t\\\n\tif (!(a_ cmp b_)) {\t\t\t\t\t\t\\\n\t\tchar prefix[ASSERT_BUFSIZE];\t\t\t\t\\\n\t\tchar message[ASSERT_BUFSIZE];\t\t\t\t\\\n\t\tmalloc_snprintf(prefix, sizeof(prefix),\t\t\t\\\n\t\t    \"%s:%s:%d: Failed assertion: \"\t\t\t\\\n\t\t    \"(%s) \"#cmp\" (%s) --> \"\t\t\t\t\\\n\t\t    \"%\"pri\" \"#neg_cmp\" %\"pri\": \",\t\t\t\\\n\t\t    __func__, __FILE__, __LINE__,\t\t\t\\\n\t\t    #a, #b, a_, b_);\t\t\t\t\t\\\n\t\tmalloc_snprintf(message, sizeof(message), __VA_ARGS__);\t\\\n\t\tp_test_fail(prefix, message);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tassert_ptr_eq(a, b, ...)\tassert_cmp(void *, a, b, ==,\t\\\n    !=, \"p\", __VA_ARGS__)\n#define\tassert_ptr_ne(a, b, ...)\tassert_cmp(void *, a, b, !=,\t\\\n    ==, \"p\", __VA_ARGS__)\n#define\tassert_ptr_null(a, ...)\t\tassert_cmp(void *, a, NULL, ==,\t\\\n    !=, \"p\", __VA_ARGS__)\n#define\tassert_ptr_not_null(a, ...)\tassert_cmp(void *, a, NULL, !=,\t\\\n    ==, \"p\", __VA_ARGS__)\n\n#define\tassert_c_eq(a, b, ...)\tassert_cmp(char, a, b, ==, !=, \"c\", __VA_ARGS__)\n#define\tassert_c_ne(a, b, ...)\tassert_cmp(char, a, b, !=, ==, \"c\", __VA_ARGS__)\n#define\tassert_c_lt(a, b, ...)\tassert_cmp(char, a, b, <, >=, \"c\", __VA_ARGS__)\n#define\tassert_c_le(a, b, ...)\tassert_cmp(char, a, b, <=, >, \"c\", __VA_ARGS__)\n#define\tassert_c_ge(a, b, ...)\tassert_cmp(char, a, b, >=, <, \"c\", __VA_ARGS__)\n#define\tassert_c_gt(a, b, ...)\tassert_cmp(char, a, b, >, <=, \"c\", __VA_ARGS__)\n\n#define\tassert_x_eq(a, b, ...)\tassert_cmp(int, a, b, ==, !=, \"#x\", __VA_ARGS__)\n#define\tassert_x_ne(a, b, ...)\tassert_cmp(int, a, b, !=, ==, \"#x\", __VA_ARGS__)\n#define\tassert_x_lt(a, b, ...)\tassert_cmp(int, a, b, <, >=, \"#x\", __VA_ARGS__)\n#define\tassert_x_le(a, b, ...)\tassert_cmp(int, a, b, <=, >, \"#x\", __VA_ARGS__)\n#define\tassert_x_ge(a, b, ...)\tassert_cmp(int, a, b, >=, <, \"#x\", __VA_ARGS__)\n#define\tassert_x_gt(a, b, ...)\tassert_cmp(int, a, b, >, <=, \"#x\", __VA_ARGS__)\n\n#define\tassert_d_eq(a, b, ...)\tassert_cmp(int, a, b, ==, !=, \"d\", __VA_ARGS__)\n#define\tassert_d_ne(a, b, ...)\tassert_cmp(int, a, b, !=, ==, \"d\", __VA_ARGS__)\n#define\tassert_d_lt(a, b, ...)\tassert_cmp(int, a, b, <, >=, \"d\", __VA_ARGS__)\n#define\tassert_d_le(a, b, ...)\tassert_cmp(int, a, b, <=, >, \"d\", __VA_ARGS__)\n#define\tassert_d_ge(a, b, ...)\tassert_cmp(int, a, b, >=, <, \"d\", __VA_ARGS__)\n#define\tassert_d_gt(a, b, ...)\tassert_cmp(int, a, b, >, <=, \"d\", __VA_ARGS__)\n\n#define\tassert_u_eq(a, b, ...)\tassert_cmp(int, a, b, ==, !=, \"u\", __VA_ARGS__)\n#define\tassert_u_ne(a, b, ...)\tassert_cmp(int, a, b, !=, ==, \"u\", __VA_ARGS__)\n#define\tassert_u_lt(a, b, ...)\tassert_cmp(int, a, b, <, >=, \"u\", __VA_ARGS__)\n#define\tassert_u_le(a, b, ...)\tassert_cmp(int, a, b, <=, >, \"u\", __VA_ARGS__)\n#define\tassert_u_ge(a, b, ...)\tassert_cmp(int, a, b, >=, <, \"u\", __VA_ARGS__)\n#define\tassert_u_gt(a, b, ...)\tassert_cmp(int, a, b, >, <=, \"u\", __VA_ARGS__)\n\n#define\tassert_ld_eq(a, b, ...)\tassert_cmp(long, a, b, ==,\t\\\n    !=, \"ld\", __VA_ARGS__)\n#define\tassert_ld_ne(a, b, ...)\tassert_cmp(long, a, b, !=,\t\\\n    ==, \"ld\", __VA_ARGS__)\n#define\tassert_ld_lt(a, b, ...)\tassert_cmp(long, a, b, <,\t\\\n    >=, \"ld\", __VA_ARGS__)\n#define\tassert_ld_le(a, b, ...)\tassert_cmp(long, a, b, <=,\t\\\n    >, \"ld\", __VA_ARGS__)\n#define\tassert_ld_ge(a, b, ...)\tassert_cmp(long, a, b, >=,\t\\\n    <, \"ld\", __VA_ARGS__)\n#define\tassert_ld_gt(a, b, ...)\tassert_cmp(long, a, b, >,\t\\\n    <=, \"ld\", __VA_ARGS__)\n\n#define\tassert_lu_eq(a, b, ...)\tassert_cmp(unsigned long,\t\\\n    a, b, ==, !=, \"lu\", __VA_ARGS__)\n#define\tassert_lu_ne(a, b, ...)\tassert_cmp(unsigned long,\t\\\n    a, b, !=, ==, \"lu\", __VA_ARGS__)\n#define\tassert_lu_lt(a, b, ...)\tassert_cmp(unsigned long,\t\\\n    a, b, <, >=, \"lu\", __VA_ARGS__)\n#define\tassert_lu_le(a, b, ...)\tassert_cmp(unsigned long,\t\\\n    a, b, <=, >, \"lu\", __VA_ARGS__)\n#define\tassert_lu_ge(a, b, ...)\tassert_cmp(unsigned long,\t\\\n    a, b, >=, <, \"lu\", __VA_ARGS__)\n#define\tassert_lu_gt(a, b, ...)\tassert_cmp(unsigned long,\t\\\n    a, b, >, <=, \"lu\", __VA_ARGS__)\n\n#define\tassert_qd_eq(a, b, ...)\tassert_cmp(long long, a, b, ==,\t\\\n    !=, \"qd\", __VA_ARGS__)\n#define\tassert_qd_ne(a, b, ...)\tassert_cmp(long long, a, b, !=,\t\\\n    ==, \"qd\", __VA_ARGS__)\n#define\tassert_qd_lt(a, b, ...)\tassert_cmp(long long, a, b, <,\t\\\n    >=, \"qd\", __VA_ARGS__)\n#define\tassert_qd_le(a, b, ...)\tassert_cmp(long long, a, b, <=,\t\\\n    >, \"qd\", __VA_ARGS__)\n#define\tassert_qd_ge(a, b, ...)\tassert_cmp(long long, a, b, >=,\t\\\n    <, \"qd\", __VA_ARGS__)\n#define\tassert_qd_gt(a, b, ...)\tassert_cmp(long long, a, b, >,\t\\\n    <=, \"qd\", __VA_ARGS__)\n\n#define\tassert_qu_eq(a, b, ...)\tassert_cmp(unsigned long long,\t\\\n    a, b, ==, !=, \"qu\", __VA_ARGS__)\n#define\tassert_qu_ne(a, b, ...)\tassert_cmp(unsigned long long,\t\\\n    a, b, !=, ==, \"qu\", __VA_ARGS__)\n#define\tassert_qu_lt(a, b, ...)\tassert_cmp(unsigned long long,\t\\\n    a, b, <, >=, \"qu\", __VA_ARGS__)\n#define\tassert_qu_le(a, b, ...)\tassert_cmp(unsigned long long,\t\\\n    a, b, <=, >, \"qu\", __VA_ARGS__)\n#define\tassert_qu_ge(a, b, ...)\tassert_cmp(unsigned long long,\t\\\n    a, b, >=, <, \"qu\", __VA_ARGS__)\n#define\tassert_qu_gt(a, b, ...)\tassert_cmp(unsigned long long,\t\\\n    a, b, >, <=, \"qu\", __VA_ARGS__)\n\n#define\tassert_jd_eq(a, b, ...)\tassert_cmp(intmax_t, a, b, ==,\t\\\n    !=, \"jd\", __VA_ARGS__)\n#define\tassert_jd_ne(a, b, ...)\tassert_cmp(intmax_t, a, b, !=,\t\\\n    ==, \"jd\", __VA_ARGS__)\n#define\tassert_jd_lt(a, b, ...)\tassert_cmp(intmax_t, a, b, <,\t\\\n    >=, \"jd\", __VA_ARGS__)\n#define\tassert_jd_le(a, b, ...)\tassert_cmp(intmax_t, a, b, <=,\t\\\n    >, \"jd\", __VA_ARGS__)\n#define\tassert_jd_ge(a, b, ...)\tassert_cmp(intmax_t, a, b, >=,\t\\\n    <, \"jd\", __VA_ARGS__)\n#define\tassert_jd_gt(a, b, ...)\tassert_cmp(intmax_t, a, b, >,\t\\\n    <=, \"jd\", __VA_ARGS__)\n\n#define\tassert_ju_eq(a, b, ...)\tassert_cmp(uintmax_t, a, b, ==,\t\\\n    !=, \"ju\", __VA_ARGS__)\n#define\tassert_ju_ne(a, b, ...)\tassert_cmp(uintmax_t, a, b, !=,\t\\\n    ==, \"ju\", __VA_ARGS__)\n#define\tassert_ju_lt(a, b, ...)\tassert_cmp(uintmax_t, a, b, <,\t\\\n    >=, \"ju\", __VA_ARGS__)\n#define\tassert_ju_le(a, b, ...)\tassert_cmp(uintmax_t, a, b, <=,\t\\\n    >, \"ju\", __VA_ARGS__)\n#define\tassert_ju_ge(a, b, ...)\tassert_cmp(uintmax_t, a, b, >=,\t\\\n    <, \"ju\", __VA_ARGS__)\n#define\tassert_ju_gt(a, b, ...)\tassert_cmp(uintmax_t, a, b, >,\t\\\n    <=, \"ju\", __VA_ARGS__)\n\n#define\tassert_zd_eq(a, b, ...)\tassert_cmp(ssize_t, a, b, ==,\t\\\n    !=, \"zd\", __VA_ARGS__)\n#define\tassert_zd_ne(a, b, ...)\tassert_cmp(ssize_t, a, b, !=,\t\\\n    ==, \"zd\", __VA_ARGS__)\n#define\tassert_zd_lt(a, b, ...)\tassert_cmp(ssize_t, a, b, <,\t\\\n    >=, \"zd\", __VA_ARGS__)\n#define\tassert_zd_le(a, b, ...)\tassert_cmp(ssize_t, a, b, <=,\t\\\n    >, \"zd\", __VA_ARGS__)\n#define\tassert_zd_ge(a, b, ...)\tassert_cmp(ssize_t, a, b, >=,\t\\\n    <, \"zd\", __VA_ARGS__)\n#define\tassert_zd_gt(a, b, ...)\tassert_cmp(ssize_t, a, b, >,\t\\\n    <=, \"zd\", __VA_ARGS__)\n\n#define\tassert_zu_eq(a, b, ...)\tassert_cmp(size_t, a, b, ==,\t\\\n    !=, \"zu\", __VA_ARGS__)\n#define\tassert_zu_ne(a, b, ...)\tassert_cmp(size_t, a, b, !=,\t\\\n    ==, \"zu\", __VA_ARGS__)\n#define\tassert_zu_lt(a, b, ...)\tassert_cmp(size_t, a, b, <,\t\\\n    >=, \"zu\", __VA_ARGS__)\n#define\tassert_zu_le(a, b, ...)\tassert_cmp(size_t, a, b, <=,\t\\\n    >, \"zu\", __VA_ARGS__)\n#define\tassert_zu_ge(a, b, ...)\tassert_cmp(size_t, a, b, >=,\t\\\n    <, \"zu\", __VA_ARGS__)\n#define\tassert_zu_gt(a, b, ...)\tassert_cmp(size_t, a, b, >,\t\\\n    <=, \"zu\", __VA_ARGS__)\n\n#define\tassert_d32_eq(a, b, ...)\tassert_cmp(int32_t, a, b, ==,\t\\\n    !=, FMTd32, __VA_ARGS__)\n#define\tassert_d32_ne(a, b, ...)\tassert_cmp(int32_t, a, b, !=,\t\\\n    ==, FMTd32, __VA_ARGS__)\n#define\tassert_d32_lt(a, b, ...)\tassert_cmp(int32_t, a, b, <,\t\\\n    >=, FMTd32, __VA_ARGS__)\n#define\tassert_d32_le(a, b, ...)\tassert_cmp(int32_t, a, b, <=,\t\\\n    >, FMTd32, __VA_ARGS__)\n#define\tassert_d32_ge(a, b, ...)\tassert_cmp(int32_t, a, b, >=,\t\\\n    <, FMTd32, __VA_ARGS__)\n#define\tassert_d32_gt(a, b, ...)\tassert_cmp(int32_t, a, b, >,\t\\\n    <=, FMTd32, __VA_ARGS__)\n\n#define\tassert_u32_eq(a, b, ...)\tassert_cmp(uint32_t, a, b, ==,\t\\\n    !=, FMTu32, __VA_ARGS__)\n#define\tassert_u32_ne(a, b, ...)\tassert_cmp(uint32_t, a, b, !=,\t\\\n    ==, FMTu32, __VA_ARGS__)\n#define\tassert_u32_lt(a, b, ...)\tassert_cmp(uint32_t, a, b, <,\t\\\n    >=, FMTu32, __VA_ARGS__)\n#define\tassert_u32_le(a, b, ...)\tassert_cmp(uint32_t, a, b, <=,\t\\\n    >, FMTu32, __VA_ARGS__)\n#define\tassert_u32_ge(a, b, ...)\tassert_cmp(uint32_t, a, b, >=,\t\\\n    <, FMTu32, __VA_ARGS__)\n#define\tassert_u32_gt(a, b, ...)\tassert_cmp(uint32_t, a, b, >,\t\\\n    <=, FMTu32, __VA_ARGS__)\n\n#define\tassert_d64_eq(a, b, ...)\tassert_cmp(int64_t, a, b, ==,\t\\\n    !=, FMTd64, __VA_ARGS__)\n#define\tassert_d64_ne(a, b, ...)\tassert_cmp(int64_t, a, b, !=,\t\\\n    ==, FMTd64, __VA_ARGS__)\n#define\tassert_d64_lt(a, b, ...)\tassert_cmp(int64_t, a, b, <,\t\\\n    >=, FMTd64, __VA_ARGS__)\n#define\tassert_d64_le(a, b, ...)\tassert_cmp(int64_t, a, b, <=,\t\\\n    >, FMTd64, __VA_ARGS__)\n#define\tassert_d64_ge(a, b, ...)\tassert_cmp(int64_t, a, b, >=,\t\\\n    <, FMTd64, __VA_ARGS__)\n#define\tassert_d64_gt(a, b, ...)\tassert_cmp(int64_t, a, b, >,\t\\\n    <=, FMTd64, __VA_ARGS__)\n\n#define\tassert_u64_eq(a, b, ...)\tassert_cmp(uint64_t, a, b, ==,\t\\\n    !=, FMTu64, __VA_ARGS__)\n#define\tassert_u64_ne(a, b, ...)\tassert_cmp(uint64_t, a, b, !=,\t\\\n    ==, FMTu64, __VA_ARGS__)\n#define\tassert_u64_lt(a, b, ...)\tassert_cmp(uint64_t, a, b, <,\t\\\n    >=, FMTu64, __VA_ARGS__)\n#define\tassert_u64_le(a, b, ...)\tassert_cmp(uint64_t, a, b, <=,\t\\\n    >, FMTu64, __VA_ARGS__)\n#define\tassert_u64_ge(a, b, ...)\tassert_cmp(uint64_t, a, b, >=,\t\\\n    <, FMTu64, __VA_ARGS__)\n#define\tassert_u64_gt(a, b, ...)\tassert_cmp(uint64_t, a, b, >,\t\\\n    <=, FMTu64, __VA_ARGS__)\n\n#define\tassert_b_eq(a, b, ...) do {\t\t\t\t\t\\\n\tbool a_ = (a);\t\t\t\t\t\t\t\\\n\tbool b_ = (b);\t\t\t\t\t\t\t\\\n\tif (!(a_ == b_)) {\t\t\t\t\t\t\\\n\t\tchar prefix[ASSERT_BUFSIZE];\t\t\t\t\\\n\t\tchar message[ASSERT_BUFSIZE];\t\t\t\t\\\n\t\tmalloc_snprintf(prefix, sizeof(prefix),\t\t\t\\\n\t\t    \"%s:%s:%d: Failed assertion: \"\t\t\t\\\n\t\t    \"(%s) == (%s) --> %s != %s: \",\t\t\t\\\n\t\t    __func__, __FILE__, __LINE__,\t\t\t\\\n\t\t    #a, #b, a_ ? \"true\" : \"false\",\t\t\t\\\n\t\t    b_ ? \"true\" : \"false\");\t\t\t\t\\\n\t\tmalloc_snprintf(message, sizeof(message), __VA_ARGS__);\t\\\n\t\tp_test_fail(prefix, message);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n#define\tassert_b_ne(a, b, ...) do {\t\t\t\t\t\\\n\tbool a_ = (a);\t\t\t\t\t\t\t\\\n\tbool b_ = (b);\t\t\t\t\t\t\t\\\n\tif (!(a_ != b_)) {\t\t\t\t\t\t\\\n\t\tchar prefix[ASSERT_BUFSIZE];\t\t\t\t\\\n\t\tchar message[ASSERT_BUFSIZE];\t\t\t\t\\\n\t\tmalloc_snprintf(prefix, sizeof(prefix),\t\t\t\\\n\t\t    \"%s:%s:%d: Failed assertion: \"\t\t\t\\\n\t\t    \"(%s) != (%s) --> %s == %s: \",\t\t\t\\\n\t\t    __func__, __FILE__, __LINE__,\t\t\t\\\n\t\t    #a, #b, a_ ? \"true\" : \"false\",\t\t\t\\\n\t\t    b_ ? \"true\" : \"false\");\t\t\t\t\\\n\t\tmalloc_snprintf(message, sizeof(message), __VA_ARGS__);\t\\\n\t\tp_test_fail(prefix, message);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n#define\tassert_true(a, ...)\tassert_b_eq(a, true, __VA_ARGS__)\n#define\tassert_false(a, ...)\tassert_b_eq(a, false, __VA_ARGS__)\n\n#define\tassert_str_eq(a, b, ...) do {\t\t\t\t\\\n\tif (strcmp((a), (b))) {\t\t\t\t\t\t\\\n\t\tchar prefix[ASSERT_BUFSIZE];\t\t\t\t\\\n\t\tchar message[ASSERT_BUFSIZE];\t\t\t\t\\\n\t\tmalloc_snprintf(prefix, sizeof(prefix),\t\t\t\\\n\t\t    \"%s:%s:%d: Failed assertion: \"\t\t\t\\\n\t\t    \"(%s) same as (%s) --> \"\t\t\t\t\\\n\t\t    \"\\\"%s\\\" differs from \\\"%s\\\": \",\t\t\t\\\n\t\t    __func__, __FILE__, __LINE__, #a, #b, a, b);\t\\\n\t\tmalloc_snprintf(message, sizeof(message), __VA_ARGS__);\t\\\n\t\tp_test_fail(prefix, message);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n#define\tassert_str_ne(a, b, ...) do {\t\t\t\t\\\n\tif (!strcmp((a), (b))) {\t\t\t\t\t\\\n\t\tchar prefix[ASSERT_BUFSIZE];\t\t\t\t\\\n\t\tchar message[ASSERT_BUFSIZE];\t\t\t\t\\\n\t\tmalloc_snprintf(prefix, sizeof(prefix),\t\t\t\\\n\t\t    \"%s:%s:%d: Failed assertion: \"\t\t\t\\\n\t\t    \"(%s) differs from (%s) --> \"\t\t\t\\\n\t\t    \"\\\"%s\\\" same as \\\"%s\\\": \",\t\t\t\t\\\n\t\t    __func__, __FILE__, __LINE__, #a, #b, a, b);\t\\\n\t\tmalloc_snprintf(message, sizeof(message), __VA_ARGS__);\t\\\n\t\tp_test_fail(prefix, message);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tassert_not_reached(...) do {\t\t\t\t\t\\\n\tchar prefix[ASSERT_BUFSIZE];\t\t\t\t\t\\\n\tchar message[ASSERT_BUFSIZE];\t\t\t\t\t\\\n\tmalloc_snprintf(prefix, sizeof(prefix),\t\t\t\t\\\n\t    \"%s:%s:%d: Unreachable code reached: \",\t\t\t\\\n\t    __func__, __FILE__, __LINE__);\t\t\t\t\\\n\tmalloc_snprintf(message, sizeof(message), __VA_ARGS__);\t\t\\\n\tp_test_fail(prefix, message);\t\t\t\t\t\\\n} while (0)\n\n/*\n * If this enum changes, corresponding changes in test/test.sh.in are also\n * necessary.\n */\ntypedef enum {\n\ttest_status_pass = 0,\n\ttest_status_skip = 1,\n\ttest_status_fail = 2,\n\n\ttest_status_count = 3\n} test_status_t;\n\ntypedef void (test_t)(void);\n\n#define\tTEST_BEGIN(f)\t\t\t\t\t\t\t\\\nstatic void\t\t\t\t\t\t\t\t\\\nf(void)\t\t\t\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tp_test_init(#f);\n\n#define\tTEST_END\t\t\t\t\t\t\t\\\n\tgoto label_test_end;\t\t\t\t\t\t\\\nlabel_test_end:\t\t\t\t\t\t\t\t\\\n\tp_test_fini();\t\t\t\t\t\t\t\\\n}\n\n#define\ttest(...)\t\t\t\t\t\t\t\\\n\tp_test(__VA_ARGS__, NULL)\n\n#define\ttest_skip_if(e) do {\t\t\t\t\t\t\\\n\tif (e) {\t\t\t\t\t\t\t\\\n\t\ttest_skip(\"%s:%s:%d: Test skipped: (%s)\",\t\t\\\n\t\t    __func__, __FILE__, __LINE__, #e);\t\t\t\\\n\t\tgoto label_test_end;\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\nvoid\ttest_skip(const char *format, ...) JEMALLOC_FORMAT_PRINTF(1, 2);\nvoid\ttest_fail(const char *format, ...) JEMALLOC_FORMAT_PRINTF(1, 2);\n\n/* For private use by macros. */\ntest_status_t\tp_test(test_t *t, ...);\nvoid\tp_test_init(const char *name);\nvoid\tp_test_fini(void);\nvoid\tp_test_fail(const char *prefix, const char *message);\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/thd.h",
    "content": "/* Abstraction layer for threading in tests. */\n#ifdef _WIN32\ntypedef HANDLE thd_t;\n#else\ntypedef pthread_t thd_t;\n#endif\n\nvoid\tthd_create(thd_t *thd, void *(*proc)(void *), void *arg);\nvoid\tthd_join(thd_t thd, void **ret);\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/include/test/timer.h",
    "content": "/* Simple timer, for use in benchmark reporting. */\n\ntypedef struct {\n\tnstime_t t0;\n\tnstime_t t1;\n} timedelta_t;\n\nvoid\ttimer_start(timedelta_t *timer);\nvoid\ttimer_stop(timedelta_t *timer);\nuint64_t\ttimer_usec(const timedelta_t *timer);\nvoid\ttimer_ratio(timedelta_t *a, timedelta_t *b, char *buf, size_t buflen);\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/integration/MALLOCX_ARENA.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#define\tNTHREADS 10\n\nstatic bool have_dss =\n#ifdef JEMALLOC_DSS\n    true\n#else\n    false\n#endif\n    ;\n\nvoid *\nthd_start(void *arg)\n{\n\tunsigned thread_ind = (unsigned)(uintptr_t)arg;\n\tunsigned arena_ind;\n\tvoid *p;\n\tsize_t sz;\n\n\tsz = sizeof(arena_ind);\n\tassert_d_eq(mallctl(\"arenas.extend\", &arena_ind, &sz, NULL, 0), 0,\n\t    \"Error in arenas.extend\");\n\n\tif (thread_ind % 4 != 3) {\n\t\tsize_t mib[3];\n\t\tsize_t miblen = sizeof(mib) / sizeof(size_t);\n\t\tconst char *dss_precs[] = {\"disabled\", \"primary\", \"secondary\"};\n\t\tunsigned prec_ind = thread_ind %\n\t\t    (sizeof(dss_precs)/sizeof(char*));\n\t\tconst char *dss = dss_precs[prec_ind];\n\t\tint expected_err = (have_dss || prec_ind == 0) ? 0 : EFAULT;\n\t\tassert_d_eq(mallctlnametomib(\"arena.0.dss\", mib, &miblen), 0,\n\t\t    \"Error in mallctlnametomib()\");\n\t\tmib[1] = arena_ind;\n\t\tassert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, (void *)&dss,\n\t\t    sizeof(const char *)), expected_err,\n\t\t    \"Error in mallctlbymib()\");\n\t}\n\n\tp = mallocx(1, MALLOCX_ARENA(arena_ind));\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\tdallocx(p, 0);\n\n\treturn (NULL);\n}\n\nTEST_BEGIN(test_MALLOCX_ARENA)\n{\n\tthd_t thds[NTHREADS];\n\tunsigned i;\n\n\tfor (i = 0; i < NTHREADS; i++) {\n\t\tthd_create(&thds[i], thd_start,\n\t\t    (void *)(uintptr_t)i);\n\t}\n\n\tfor (i = 0; i < NTHREADS; i++)\n\t\tthd_join(thds[i], NULL);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_MALLOCX_ARENA));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/integration/aligned_alloc.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#define\tCHUNK 0x400000\n/* #define MAXALIGN ((size_t)UINT64_C(0x80000000000)) */\n#define\tMAXALIGN ((size_t)0x2000000LU)\n#define\tNITER 4\n\nTEST_BEGIN(test_alignment_errors)\n{\n\tsize_t alignment;\n\tvoid *p;\n\n\talignment = 0;\n\tset_errno(0);\n\tp = aligned_alloc(alignment, 1);\n\tassert_false(p != NULL || get_errno() != EINVAL,\n\t    \"Expected error for invalid alignment %zu\", alignment);\n\n\tfor (alignment = sizeof(size_t); alignment < MAXALIGN;\n\t    alignment <<= 1) {\n\t\tset_errno(0);\n\t\tp = aligned_alloc(alignment + 1, 1);\n\t\tassert_false(p != NULL || get_errno() != EINVAL,\n\t\t    \"Expected error for invalid alignment %zu\",\n\t\t    alignment + 1);\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_oom_errors)\n{\n\tsize_t alignment, size;\n\tvoid *p;\n\n#if LG_SIZEOF_PTR == 3\n\talignment = UINT64_C(0x8000000000000000);\n\tsize      = UINT64_C(0x8000000000000000);\n#else\n\talignment = 0x80000000LU;\n\tsize      = 0x80000000LU;\n#endif\n\tset_errno(0);\n\tp = aligned_alloc(alignment, size);\n\tassert_false(p != NULL || get_errno() != ENOMEM,\n\t    \"Expected error for aligned_alloc(%zu, %zu)\",\n\t    alignment, size);\n\n#if LG_SIZEOF_PTR == 3\n\talignment = UINT64_C(0x4000000000000000);\n\tsize      = UINT64_C(0xc000000000000001);\n#else\n\talignment = 0x40000000LU;\n\tsize      = 0xc0000001LU;\n#endif\n\tset_errno(0);\n\tp = aligned_alloc(alignment, size);\n\tassert_false(p != NULL || get_errno() != ENOMEM,\n\t    \"Expected error for aligned_alloc(%zu, %zu)\",\n\t    alignment, size);\n\n\talignment = 0x10LU;\n#if LG_SIZEOF_PTR == 3\n\tsize = UINT64_C(0xfffffffffffffff0);\n#else\n\tsize = 0xfffffff0LU;\n#endif\n\tset_errno(0);\n\tp = aligned_alloc(alignment, size);\n\tassert_false(p != NULL || get_errno() != ENOMEM,\n\t    \"Expected error for aligned_alloc(&p, %zu, %zu)\",\n\t    alignment, size);\n}\nTEST_END\n\nTEST_BEGIN(test_alignment_and_size)\n{\n\tsize_t alignment, size, total;\n\tunsigned i;\n\tvoid *ps[NITER];\n\n\tfor (i = 0; i < NITER; i++)\n\t\tps[i] = NULL;\n\n\tfor (alignment = 8;\n\t    alignment <= MAXALIGN;\n\t    alignment <<= 1) {\n\t\ttotal = 0;\n\t\tfor (size = 1;\n\t\t    size < 3 * alignment && size < (1U << 31);\n\t\t    size += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {\n\t\t\tfor (i = 0; i < NITER; i++) {\n\t\t\t\tps[i] = aligned_alloc(alignment, size);\n\t\t\t\tif (ps[i] == NULL) {\n\t\t\t\t\tchar buf[BUFERROR_BUF];\n\n\t\t\t\t\tbuferror(get_errno(), buf, sizeof(buf));\n\t\t\t\t\ttest_fail(\n\t\t\t\t\t    \"Error for alignment=%zu, \"\n\t\t\t\t\t    \"size=%zu (%#zx): %s\",\n\t\t\t\t\t    alignment, size, size, buf);\n\t\t\t\t}\n\t\t\t\ttotal += malloc_usable_size(ps[i]);\n\t\t\t\tif (total >= (MAXALIGN << 1))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tfor (i = 0; i < NITER; i++) {\n\t\t\t\tif (ps[i] != NULL) {\n\t\t\t\t\tfree(ps[i]);\n\t\t\t\t\tps[i] = NULL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_alignment_errors,\n\t    test_oom_errors,\n\t    test_alignment_and_size));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/integration/allocated.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nstatic const bool config_stats =\n#ifdef JEMALLOC_STATS\n    true\n#else\n    false\n#endif\n    ;\n\nvoid *\nthd_start(void *arg)\n{\n\tint err;\n\tvoid *p;\n\tuint64_t a0, a1, d0, d1;\n\tuint64_t *ap0, *ap1, *dp0, *dp1;\n\tsize_t sz, usize;\n\n\tsz = sizeof(a0);\n\tif ((err = mallctl(\"thread.allocated\", &a0, &sz, NULL, 0))) {\n\t\tif (err == ENOENT)\n\t\t\tgoto label_ENOENT;\n\t\ttest_fail(\"%s(): Error in mallctl(): %s\", __func__,\n\t\t    strerror(err));\n\t}\n\tsz = sizeof(ap0);\n\tif ((err = mallctl(\"thread.allocatedp\", &ap0, &sz, NULL, 0))) {\n\t\tif (err == ENOENT)\n\t\t\tgoto label_ENOENT;\n\t\ttest_fail(\"%s(): Error in mallctl(): %s\", __func__,\n\t\t    strerror(err));\n\t}\n\tassert_u64_eq(*ap0, a0,\n\t    \"\\\"thread.allocatedp\\\" should provide a pointer to internal \"\n\t    \"storage\");\n\n\tsz = sizeof(d0);\n\tif ((err = mallctl(\"thread.deallocated\", &d0, &sz, NULL, 0))) {\n\t\tif (err == ENOENT)\n\t\t\tgoto label_ENOENT;\n\t\ttest_fail(\"%s(): Error in mallctl(): %s\", __func__,\n\t\t    strerror(err));\n\t}\n\tsz = sizeof(dp0);\n\tif ((err = mallctl(\"thread.deallocatedp\", &dp0, &sz, NULL, 0))) {\n\t\tif (err == ENOENT)\n\t\t\tgoto label_ENOENT;\n\t\ttest_fail(\"%s(): Error in mallctl(): %s\", __func__,\n\t\t    strerror(err));\n\t}\n\tassert_u64_eq(*dp0, d0,\n\t    \"\\\"thread.deallocatedp\\\" should provide a pointer to internal \"\n\t    \"storage\");\n\n\tp = malloc(1);\n\tassert_ptr_not_null(p, \"Unexpected malloc() error\");\n\n\tsz = sizeof(a1);\n\tmallctl(\"thread.allocated\", &a1, &sz, NULL, 0);\n\tsz = sizeof(ap1);\n\tmallctl(\"thread.allocatedp\", &ap1, &sz, NULL, 0);\n\tassert_u64_eq(*ap1, a1,\n\t    \"Dereferenced \\\"thread.allocatedp\\\" value should equal \"\n\t    \"\\\"thread.allocated\\\" value\");\n\tassert_ptr_eq(ap0, ap1,\n\t    \"Pointer returned by \\\"thread.allocatedp\\\" should not change\");\n\n\tusize = malloc_usable_size(p);\n\tassert_u64_le(a0 + usize, a1,\n\t    \"Allocated memory counter should increase by at least the amount \"\n\t    \"explicitly allocated\");\n\n\tfree(p);\n\n\tsz = sizeof(d1);\n\tmallctl(\"thread.deallocated\", &d1, &sz, NULL, 0);\n\tsz = sizeof(dp1);\n\tmallctl(\"thread.deallocatedp\", &dp1, &sz, NULL, 0);\n\tassert_u64_eq(*dp1, d1,\n\t    \"Dereferenced \\\"thread.deallocatedp\\\" value should equal \"\n\t    \"\\\"thread.deallocated\\\" value\");\n\tassert_ptr_eq(dp0, dp1,\n\t    \"Pointer returned by \\\"thread.deallocatedp\\\" should not change\");\n\n\tassert_u64_le(d0 + usize, d1,\n\t    \"Deallocated memory counter should increase by at least the amount \"\n\t    \"explicitly deallocated\");\n\n\treturn (NULL);\nlabel_ENOENT:\n\tassert_false(config_stats,\n\t    \"ENOENT should only be returned if stats are disabled\");\n\ttest_skip(\"\\\"thread.allocated\\\" mallctl not available\");\n\treturn (NULL);\n}\n\nTEST_BEGIN(test_main_thread)\n{\n\n\tthd_start(NULL);\n}\nTEST_END\n\nTEST_BEGIN(test_subthread)\n{\n\tthd_t thd;\n\n\tthd_create(&thd, thd_start, NULL);\n\tthd_join(thd, NULL);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\t/* Run tests multiple times to check for bad interactions. */\n\treturn (test(\n\t    test_main_thread,\n\t    test_subthread,\n\t    test_main_thread,\n\t    test_subthread,\n\t    test_main_thread));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/integration/chunk.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#ifdef JEMALLOC_FILL\nconst char *malloc_conf = \"junk:false\";\n#endif\n\nstatic chunk_hooks_t orig_hooks;\nstatic chunk_hooks_t old_hooks;\n\nstatic bool do_dalloc = true;\nstatic bool do_decommit;\n\nstatic bool did_alloc;\nstatic bool did_dalloc;\nstatic bool did_commit;\nstatic bool did_decommit;\nstatic bool did_purge;\nstatic bool did_split;\nstatic bool did_merge;\n\n#if 0\n#  define TRACE_HOOK(fmt, ...) malloc_printf(fmt, __VA_ARGS__)\n#else\n#  define TRACE_HOOK(fmt, ...)\n#endif\n\nvoid *\nchunk_alloc(void *new_addr, size_t size, size_t alignment, bool *zero,\n    bool *commit, unsigned arena_ind)\n{\n\n\tTRACE_HOOK(\"%s(new_addr=%p, size=%zu, alignment=%zu, *zero=%s, \"\n\t    \"*commit=%s, arena_ind=%u)\\n\", __func__, new_addr, size, alignment,\n\t    *zero ?  \"true\" : \"false\", *commit ? \"true\" : \"false\", arena_ind);\n\tdid_alloc = true;\n\treturn (old_hooks.alloc(new_addr, size, alignment, zero, commit,\n\t    arena_ind));\n}\n\nbool\nchunk_dalloc(void *chunk, size_t size, bool committed, unsigned arena_ind)\n{\n\n\tTRACE_HOOK(\"%s(chunk=%p, size=%zu, committed=%s, arena_ind=%u)\\n\",\n\t    __func__, chunk, size, committed ? \"true\" : \"false\", arena_ind);\n\tdid_dalloc = true;\n\tif (!do_dalloc)\n\t\treturn (true);\n\treturn (old_hooks.dalloc(chunk, size, committed, arena_ind));\n}\n\nbool\nchunk_commit(void *chunk, size_t size, size_t offset, size_t length,\n    unsigned arena_ind)\n{\n\tbool err;\n\n\tTRACE_HOOK(\"%s(chunk=%p, size=%zu, offset=%zu, length=%zu, \"\n\t    \"arena_ind=%u)\\n\", __func__, chunk, size, offset, length,\n\t    arena_ind);\n\terr = old_hooks.commit(chunk, size, offset, length, arena_ind);\n\tdid_commit = !err;\n\treturn (err);\n}\n\nbool\nchunk_decommit(void *chunk, size_t size, size_t offset, size_t length,\n    unsigned arena_ind)\n{\n\tbool err;\n\n\tTRACE_HOOK(\"%s(chunk=%p, size=%zu, offset=%zu, length=%zu, \"\n\t    \"arena_ind=%u)\\n\", __func__, chunk, size, offset, length,\n\t    arena_ind);\n\tif (!do_decommit)\n\t\treturn (true);\n\terr = old_hooks.decommit(chunk, size, offset, length, arena_ind);\n\tdid_decommit = !err;\n\treturn (err);\n}\n\nbool\nchunk_purge(void *chunk, size_t size, size_t offset, size_t length,\n    unsigned arena_ind)\n{\n\n\tTRACE_HOOK(\"%s(chunk=%p, size=%zu, offset=%zu, length=%zu \"\n\t    \"arena_ind=%u)\\n\", __func__, chunk, size, offset, length,\n\t    arena_ind);\n\tdid_purge = true;\n\treturn (old_hooks.purge(chunk, size, offset, length, arena_ind));\n}\n\nbool\nchunk_split(void *chunk, size_t size, size_t size_a, size_t size_b,\n    bool committed, unsigned arena_ind)\n{\n\n\tTRACE_HOOK(\"%s(chunk=%p, size=%zu, size_a=%zu, size_b=%zu, \"\n\t    \"committed=%s, arena_ind=%u)\\n\", __func__, chunk, size, size_a,\n\t    size_b, committed ? \"true\" : \"false\", arena_ind);\n\tdid_split = true;\n\treturn (old_hooks.split(chunk, size, size_a, size_b, committed,\n\t    arena_ind));\n}\n\nbool\nchunk_merge(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b,\n    bool committed, unsigned arena_ind)\n{\n\n\tTRACE_HOOK(\"%s(chunk_a=%p, size_a=%zu, chunk_b=%p size_b=%zu, \"\n\t    \"committed=%s, arena_ind=%u)\\n\", __func__, chunk_a, size_a, chunk_b,\n\t    size_b, committed ? \"true\" : \"false\", arena_ind);\n\tdid_merge = true;\n\treturn (old_hooks.merge(chunk_a, size_a, chunk_b, size_b,\n\t    committed, arena_ind));\n}\n\nTEST_BEGIN(test_chunk)\n{\n\tvoid *p;\n\tsize_t old_size, new_size, large0, large1, huge0, huge1, huge2, sz;\n\tchunk_hooks_t new_hooks = {\n\t\tchunk_alloc,\n\t\tchunk_dalloc,\n\t\tchunk_commit,\n\t\tchunk_decommit,\n\t\tchunk_purge,\n\t\tchunk_split,\n\t\tchunk_merge\n\t};\n\tbool xallocx_success_a, xallocx_success_b, xallocx_success_c;\n\n\t/* Install custom chunk hooks. */\n\told_size = sizeof(chunk_hooks_t);\n\tnew_size = sizeof(chunk_hooks_t);\n\tassert_d_eq(mallctl(\"arena.0.chunk_hooks\", &old_hooks, &old_size,\n\t    &new_hooks, new_size), 0, \"Unexpected chunk_hooks error\");\n\torig_hooks = old_hooks;\n\tassert_ptr_ne(old_hooks.alloc, chunk_alloc, \"Unexpected alloc error\");\n\tassert_ptr_ne(old_hooks.dalloc, chunk_dalloc,\n\t    \"Unexpected dalloc error\");\n\tassert_ptr_ne(old_hooks.commit, chunk_commit,\n\t    \"Unexpected commit error\");\n\tassert_ptr_ne(old_hooks.decommit, chunk_decommit,\n\t    \"Unexpected decommit error\");\n\tassert_ptr_ne(old_hooks.purge, chunk_purge, \"Unexpected purge error\");\n\tassert_ptr_ne(old_hooks.split, chunk_split, \"Unexpected split error\");\n\tassert_ptr_ne(old_hooks.merge, chunk_merge, \"Unexpected merge error\");\n\n\t/* Get large size classes. */\n\tsz = sizeof(size_t);\n\tassert_d_eq(mallctl(\"arenas.lrun.0.size\", &large0, &sz, NULL, 0), 0,\n\t    \"Unexpected arenas.lrun.0.size failure\");\n\tassert_d_eq(mallctl(\"arenas.lrun.1.size\", &large1, &sz, NULL, 0), 0,\n\t    \"Unexpected arenas.lrun.1.size failure\");\n\n\t/* Get huge size classes. */\n\tassert_d_eq(mallctl(\"arenas.hchunk.0.size\", &huge0, &sz, NULL, 0), 0,\n\t    \"Unexpected arenas.hchunk.0.size failure\");\n\tassert_d_eq(mallctl(\"arenas.hchunk.1.size\", &huge1, &sz, NULL, 0), 0,\n\t    \"Unexpected arenas.hchunk.1.size failure\");\n\tassert_d_eq(mallctl(\"arenas.hchunk.2.size\", &huge2, &sz, NULL, 0), 0,\n\t    \"Unexpected arenas.hchunk.2.size failure\");\n\n\t/* Test dalloc/decommit/purge cascade. */\n\tdo_dalloc = false;\n\tdo_decommit = false;\n\tp = mallocx(huge0 * 2, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\tdid_dalloc = false;\n\tdid_decommit = false;\n\tdid_purge = false;\n\tdid_split = false;\n\txallocx_success_a = (xallocx(p, huge0, 0, 0) == huge0);\n\tassert_d_eq(mallctl(\"arena.0.purge\", NULL, NULL, NULL, 0), 0,\n\t    \"Unexpected arena.0.purge error\");\n\tif (xallocx_success_a) {\n\t\tassert_true(did_dalloc, \"Expected dalloc\");\n\t\tassert_false(did_decommit, \"Unexpected decommit\");\n\t\tassert_true(did_purge, \"Expected purge\");\n\t}\n\tassert_true(did_split, \"Expected split\");\n\tdallocx(p, 0);\n\tdo_dalloc = true;\n\n\t/* Test decommit/commit and observe split/merge. */\n\tdo_dalloc = false;\n\tdo_decommit = true;\n\tp = mallocx(huge0 * 2, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\tdid_decommit = false;\n\tdid_commit = false;\n\tdid_split = false;\n\tdid_merge = false;\n\txallocx_success_b = (xallocx(p, huge0, 0, 0) == huge0);\n\tassert_d_eq(mallctl(\"arena.0.purge\", NULL, NULL, NULL, 0), 0,\n\t    \"Unexpected arena.0.purge error\");\n\tif (xallocx_success_b)\n\t\tassert_true(did_split, \"Expected split\");\n\txallocx_success_c = (xallocx(p, huge0 * 2, 0, 0) == huge0 * 2);\n\tassert_b_eq(did_decommit, did_commit, \"Expected decommit/commit match\");\n\tif (xallocx_success_b && xallocx_success_c)\n\t\tassert_true(did_merge, \"Expected merge\");\n\tdallocx(p, 0);\n\tdo_dalloc = true;\n\tdo_decommit = false;\n\n\t/* Test purge for partial-chunk huge allocations. */\n\tif (huge0 * 2 > huge2) {\n\t\t/*\n\t\t * There are at least four size classes per doubling, so a\n\t\t * successful xallocx() from size=huge2 to size=huge1 is\n\t\t * guaranteed to leave trailing purgeable memory.\n\t\t */\n\t\tp = mallocx(huge2, 0);\n\t\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\t\tdid_purge = false;\n\t\tassert_zu_eq(xallocx(p, huge1, 0, 0), huge1,\n\t\t    \"Unexpected xallocx() failure\");\n\t\tassert_true(did_purge, \"Expected purge\");\n\t\tdallocx(p, 0);\n\t}\n\n\t/* Test decommit for large allocations. */\n\tdo_decommit = true;\n\tp = mallocx(large1, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\tassert_d_eq(mallctl(\"arena.0.purge\", NULL, NULL, NULL, 0), 0,\n\t    \"Unexpected arena.0.purge error\");\n\tdid_decommit = false;\n\tassert_zu_eq(xallocx(p, large0, 0, 0), large0,\n\t    \"Unexpected xallocx() failure\");\n\tassert_d_eq(mallctl(\"arena.0.purge\", NULL, NULL, NULL, 0), 0,\n\t    \"Unexpected arena.0.purge error\");\n\tdid_commit = false;\n\tassert_zu_eq(xallocx(p, large1, 0, 0), large1,\n\t    \"Unexpected xallocx() failure\");\n\tassert_b_eq(did_decommit, did_commit, \"Expected decommit/commit match\");\n\tdallocx(p, 0);\n\tdo_decommit = false;\n\n\t/* Make sure non-huge allocation succeeds. */\n\tp = mallocx(42, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\tdallocx(p, 0);\n\n\t/* Restore chunk hooks. */\n\tassert_d_eq(mallctl(\"arena.0.chunk_hooks\", NULL, NULL, &old_hooks,\n\t    new_size), 0, \"Unexpected chunk_hooks error\");\n\tassert_d_eq(mallctl(\"arena.0.chunk_hooks\", &old_hooks, &old_size,\n\t    NULL, 0), 0, \"Unexpected chunk_hooks error\");\n\tassert_ptr_eq(old_hooks.alloc, orig_hooks.alloc,\n\t    \"Unexpected alloc error\");\n\tassert_ptr_eq(old_hooks.dalloc, orig_hooks.dalloc,\n\t    \"Unexpected dalloc error\");\n\tassert_ptr_eq(old_hooks.commit, orig_hooks.commit,\n\t    \"Unexpected commit error\");\n\tassert_ptr_eq(old_hooks.decommit, orig_hooks.decommit,\n\t    \"Unexpected decommit error\");\n\tassert_ptr_eq(old_hooks.purge, orig_hooks.purge,\n\t    \"Unexpected purge error\");\n\tassert_ptr_eq(old_hooks.split, orig_hooks.split,\n\t    \"Unexpected split error\");\n\tassert_ptr_eq(old_hooks.merge, orig_hooks.merge,\n\t    \"Unexpected merge error\");\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(test_chunk));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/integration/mallocx.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nstatic unsigned\nget_nsizes_impl(const char *cmd)\n{\n\tunsigned ret;\n\tsize_t z;\n\n\tz = sizeof(unsigned);\n\tassert_d_eq(mallctl(cmd, &ret, &z, NULL, 0), 0,\n\t    \"Unexpected mallctl(\\\"%s\\\", ...) failure\", cmd);\n\n\treturn (ret);\n}\n\nstatic unsigned\nget_nhuge(void)\n{\n\n\treturn (get_nsizes_impl(\"arenas.nhchunks\"));\n}\n\nstatic size_t\nget_size_impl(const char *cmd, size_t ind)\n{\n\tsize_t ret;\n\tsize_t z;\n\tsize_t mib[4];\n\tsize_t miblen = 4;\n\n\tz = sizeof(size_t);\n\tassert_d_eq(mallctlnametomib(cmd, mib, &miblen),\n\t    0, \"Unexpected mallctlnametomib(\\\"%s\\\", ...) failure\", cmd);\n\tmib[2] = ind;\n\tz = sizeof(size_t);\n\tassert_d_eq(mallctlbymib(mib, miblen, &ret, &z, NULL, 0),\n\t    0, \"Unexpected mallctlbymib([\\\"%s\\\", %zu], ...) failure\", cmd, ind);\n\n\treturn (ret);\n}\n\nstatic size_t\nget_huge_size(size_t ind)\n{\n\n\treturn (get_size_impl(\"arenas.hchunk.0.size\", ind));\n}\n\nTEST_BEGIN(test_overflow)\n{\n\tsize_t hugemax;\n\n\thugemax = get_huge_size(get_nhuge()-1);\n\n\tassert_ptr_null(mallocx(hugemax+1, 0),\n\t    \"Expected OOM for mallocx(size=%#zx, 0)\", hugemax+1);\n\n\tassert_ptr_null(mallocx(ZU(PTRDIFF_MAX)+1, 0),\n\t    \"Expected OOM for mallocx(size=%#zx, 0)\", ZU(PTRDIFF_MAX)+1);\n\n\tassert_ptr_null(mallocx(SIZE_T_MAX, 0),\n\t    \"Expected OOM for mallocx(size=%#zx, 0)\", SIZE_T_MAX);\n\n\tassert_ptr_null(mallocx(1, MALLOCX_ALIGN(ZU(PTRDIFF_MAX)+1)),\n\t    \"Expected OOM for mallocx(size=1, MALLOCX_ALIGN(%#zx))\",\n\t    ZU(PTRDIFF_MAX)+1);\n}\nTEST_END\n\nTEST_BEGIN(test_oom)\n{\n\tsize_t hugemax, size, alignment;\n\n\thugemax = get_huge_size(get_nhuge()-1);\n\n\t/*\n\t * It should be impossible to allocate two objects that each consume\n\t * more than half the virtual address space.\n\t */\n\t{\n\t\tvoid *p;\n\n\t\tp = mallocx(hugemax, 0);\n\t\tif (p != NULL) {\n\t\t\tassert_ptr_null(mallocx(hugemax, 0),\n\t\t\t    \"Expected OOM for mallocx(size=%#zx, 0)\", hugemax);\n\t\t\tdallocx(p, 0);\n\t\t}\n\t}\n\n#if LG_SIZEOF_PTR == 3\n\tsize      = ZU(0x8000000000000000);\n\talignment = ZU(0x8000000000000000);\n#else\n\tsize      = ZU(0x80000000);\n\talignment = ZU(0x80000000);\n#endif\n\tassert_ptr_null(mallocx(size, MALLOCX_ALIGN(alignment)),\n\t    \"Expected OOM for mallocx(size=%#zx, MALLOCX_ALIGN(%#zx)\", size,\n\t    alignment);\n}\nTEST_END\n\nTEST_BEGIN(test_basic)\n{\n#define\tMAXSZ (((size_t)1) << 26)\n\tsize_t sz;\n\n\tfor (sz = 1; sz < MAXSZ; sz = nallocx(sz, 0) + 1) {\n\t\tsize_t nsz, rsz;\n\t\tvoid *p;\n\t\tnsz = nallocx(sz, 0);\n\t\tassert_zu_ne(nsz, 0, \"Unexpected nallocx() error\");\n\t\tp = mallocx(sz, 0);\n\t\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\t\trsz = sallocx(p, 0);\n\t\tassert_zu_ge(rsz, sz, \"Real size smaller than expected\");\n\t\tassert_zu_eq(nsz, rsz, \"nallocx()/sallocx() size mismatch\");\n\t\tdallocx(p, 0);\n\n\t\tp = mallocx(sz, 0);\n\t\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\t\tdallocx(p, 0);\n\n\t\tnsz = nallocx(sz, MALLOCX_ZERO);\n\t\tassert_zu_ne(nsz, 0, \"Unexpected nallocx() error\");\n\t\tp = mallocx(sz, MALLOCX_ZERO);\n\t\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\t\trsz = sallocx(p, 0);\n\t\tassert_zu_eq(nsz, rsz, \"nallocx()/sallocx() rsize mismatch\");\n\t\tdallocx(p, 0);\n\t}\n#undef MAXSZ\n}\nTEST_END\n\nTEST_BEGIN(test_alignment_and_size)\n{\n#define\tMAXALIGN (((size_t)1) << 25)\n#define\tNITER 4\n\tsize_t nsz, rsz, sz, alignment, total;\n\tunsigned i;\n\tvoid *ps[NITER];\n\n\tfor (i = 0; i < NITER; i++)\n\t\tps[i] = NULL;\n\n\tfor (alignment = 8;\n\t    alignment <= MAXALIGN;\n\t    alignment <<= 1) {\n\t\ttotal = 0;\n\t\tfor (sz = 1;\n\t\t    sz < 3 * alignment && sz < (1U << 31);\n\t\t    sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {\n\t\t\tfor (i = 0; i < NITER; i++) {\n\t\t\t\tnsz = nallocx(sz, MALLOCX_ALIGN(alignment) |\n\t\t\t\t    MALLOCX_ZERO);\n\t\t\t\tassert_zu_ne(nsz, 0,\n\t\t\t\t    \"nallocx() error for alignment=%zu, \"\n\t\t\t\t    \"size=%zu (%#zx)\", alignment, sz, sz);\n\t\t\t\tps[i] = mallocx(sz, MALLOCX_ALIGN(alignment) |\n\t\t\t\t    MALLOCX_ZERO);\n\t\t\t\tassert_ptr_not_null(ps[i],\n\t\t\t\t    \"mallocx() error for alignment=%zu, \"\n\t\t\t\t    \"size=%zu (%#zx)\", alignment, sz, sz);\n\t\t\t\trsz = sallocx(ps[i], 0);\n\t\t\t\tassert_zu_ge(rsz, sz,\n\t\t\t\t    \"Real size smaller than expected for \"\n\t\t\t\t    \"alignment=%zu, size=%zu\", alignment, sz);\n\t\t\t\tassert_zu_eq(nsz, rsz,\n\t\t\t\t    \"nallocx()/sallocx() size mismatch for \"\n\t\t\t\t    \"alignment=%zu, size=%zu\", alignment, sz);\n\t\t\t\tassert_ptr_null(\n\t\t\t\t    (void *)((uintptr_t)ps[i] & (alignment-1)),\n\t\t\t\t    \"%p inadequately aligned for\"\n\t\t\t\t    \" alignment=%zu, size=%zu\", ps[i],\n\t\t\t\t    alignment, sz);\n\t\t\t\ttotal += rsz;\n\t\t\t\tif (total >= (MAXALIGN << 1))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tfor (i = 0; i < NITER; i++) {\n\t\t\t\tif (ps[i] != NULL) {\n\t\t\t\t\tdallocx(ps[i], 0);\n\t\t\t\t\tps[i] = NULL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n#undef MAXALIGN\n#undef NITER\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_overflow,\n\t    test_oom,\n\t    test_basic,\n\t    test_alignment_and_size));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/integration/overflow.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nTEST_BEGIN(test_overflow)\n{\n\tunsigned nhchunks;\n\tsize_t mib[4];\n\tsize_t sz, miblen, max_size_class;\n\tvoid *p;\n\n\tsz = sizeof(unsigned);\n\tassert_d_eq(mallctl(\"arenas.nhchunks\", &nhchunks, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl() error\");\n\n\tmiblen = sizeof(mib) / sizeof(size_t);\n\tassert_d_eq(mallctlnametomib(\"arenas.hchunk.0.size\", mib, &miblen), 0,\n\t    \"Unexpected mallctlnametomib() error\");\n\tmib[2] = nhchunks - 1;\n\n\tsz = sizeof(size_t);\n\tassert_d_eq(mallctlbymib(mib, miblen, &max_size_class, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctlbymib() error\");\n\n\tassert_ptr_null(malloc(max_size_class + 1),\n\t    \"Expected OOM due to over-sized allocation request\");\n\tassert_ptr_null(malloc(SIZE_T_MAX),\n\t    \"Expected OOM due to over-sized allocation request\");\n\n\tassert_ptr_null(calloc(1, max_size_class + 1),\n\t    \"Expected OOM due to over-sized allocation request\");\n\tassert_ptr_null(calloc(1, SIZE_T_MAX),\n\t    \"Expected OOM due to over-sized allocation request\");\n\n\tp = malloc(1);\n\tassert_ptr_not_null(p, \"Unexpected malloc() OOM\");\n\tassert_ptr_null(realloc(p, max_size_class + 1),\n\t    \"Expected OOM due to over-sized allocation request\");\n\tassert_ptr_null(realloc(p, SIZE_T_MAX),\n\t    \"Expected OOM due to over-sized allocation request\");\n\tfree(p);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_overflow));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/integration/posix_memalign.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#define\tCHUNK 0x400000\n/* #define MAXALIGN ((size_t)UINT64_C(0x80000000000)) */\n#define\tMAXALIGN ((size_t)0x2000000LU)\n#define\tNITER 4\n\nTEST_BEGIN(test_alignment_errors)\n{\n\tsize_t alignment;\n\tvoid *p;\n\n\tfor (alignment = 0; alignment < sizeof(void *); alignment++) {\n\t\tassert_d_eq(posix_memalign(&p, alignment, 1), EINVAL,\n\t\t    \"Expected error for invalid alignment %zu\",\n\t\t    alignment);\n\t}\n\n\tfor (alignment = sizeof(size_t); alignment < MAXALIGN;\n\t    alignment <<= 1) {\n\t\tassert_d_ne(posix_memalign(&p, alignment + 1, 1), 0,\n\t\t    \"Expected error for invalid alignment %zu\",\n\t\t    alignment + 1);\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_oom_errors)\n{\n\tsize_t alignment, size;\n\tvoid *p;\n\n#if LG_SIZEOF_PTR == 3\n\talignment = UINT64_C(0x8000000000000000);\n\tsize      = UINT64_C(0x8000000000000000);\n#else\n\talignment = 0x80000000LU;\n\tsize      = 0x80000000LU;\n#endif\n\tassert_d_ne(posix_memalign(&p, alignment, size), 0,\n\t    \"Expected error for posix_memalign(&p, %zu, %zu)\",\n\t    alignment, size);\n\n#if LG_SIZEOF_PTR == 3\n\talignment = UINT64_C(0x4000000000000000);\n\tsize      = UINT64_C(0xc000000000000001);\n#else\n\talignment = 0x40000000LU;\n\tsize      = 0xc0000001LU;\n#endif\n\tassert_d_ne(posix_memalign(&p, alignment, size), 0,\n\t    \"Expected error for posix_memalign(&p, %zu, %zu)\",\n\t    alignment, size);\n\n\talignment = 0x10LU;\n#if LG_SIZEOF_PTR == 3\n\tsize = UINT64_C(0xfffffffffffffff0);\n#else\n\tsize = 0xfffffff0LU;\n#endif\n\tassert_d_ne(posix_memalign(&p, alignment, size), 0,\n\t    \"Expected error for posix_memalign(&p, %zu, %zu)\",\n\t    alignment, size);\n}\nTEST_END\n\nTEST_BEGIN(test_alignment_and_size)\n{\n\tsize_t alignment, size, total;\n\tunsigned i;\n\tint err;\n\tvoid *ps[NITER];\n\n\tfor (i = 0; i < NITER; i++)\n\t\tps[i] = NULL;\n\n\tfor (alignment = 8;\n\t    alignment <= MAXALIGN;\n\t    alignment <<= 1) {\n\t\ttotal = 0;\n\t\tfor (size = 1;\n\t\t    size < 3 * alignment && size < (1U << 31);\n\t\t    size += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {\n\t\t\tfor (i = 0; i < NITER; i++) {\n\t\t\t\terr = posix_memalign(&ps[i],\n\t\t\t\t    alignment, size);\n\t\t\t\tif (err) {\n\t\t\t\t\tchar buf[BUFERROR_BUF];\n\n\t\t\t\t\tbuferror(get_errno(), buf, sizeof(buf));\n\t\t\t\t\ttest_fail(\n\t\t\t\t\t    \"Error for alignment=%zu, \"\n\t\t\t\t\t    \"size=%zu (%#zx): %s\",\n\t\t\t\t\t    alignment, size, size, buf);\n\t\t\t\t}\n\t\t\t\ttotal += malloc_usable_size(ps[i]);\n\t\t\t\tif (total >= (MAXALIGN << 1))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tfor (i = 0; i < NITER; i++) {\n\t\t\t\tif (ps[i] != NULL) {\n\t\t\t\t\tfree(ps[i]);\n\t\t\t\t\tps[i] = NULL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_alignment_errors,\n\t    test_oom_errors,\n\t    test_alignment_and_size));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/integration/rallocx.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nstatic unsigned\nget_nsizes_impl(const char *cmd)\n{\n\tunsigned ret;\n\tsize_t z;\n\n\tz = sizeof(unsigned);\n\tassert_d_eq(mallctl(cmd, &ret, &z, NULL, 0), 0,\n\t    \"Unexpected mallctl(\\\"%s\\\", ...) failure\", cmd);\n\n\treturn (ret);\n}\n\nstatic unsigned\nget_nhuge(void)\n{\n\n\treturn (get_nsizes_impl(\"arenas.nhchunks\"));\n}\n\nstatic size_t\nget_size_impl(const char *cmd, size_t ind)\n{\n\tsize_t ret;\n\tsize_t z;\n\tsize_t mib[4];\n\tsize_t miblen = 4;\n\n\tz = sizeof(size_t);\n\tassert_d_eq(mallctlnametomib(cmd, mib, &miblen),\n\t    0, \"Unexpected mallctlnametomib(\\\"%s\\\", ...) failure\", cmd);\n\tmib[2] = ind;\n\tz = sizeof(size_t);\n\tassert_d_eq(mallctlbymib(mib, miblen, &ret, &z, NULL, 0),\n\t    0, \"Unexpected mallctlbymib([\\\"%s\\\", %zu], ...) failure\", cmd, ind);\n\n\treturn (ret);\n}\n\nstatic size_t\nget_huge_size(size_t ind)\n{\n\n\treturn (get_size_impl(\"arenas.hchunk.0.size\", ind));\n}\n\nTEST_BEGIN(test_grow_and_shrink)\n{\n\tvoid *p, *q;\n\tsize_t tsz;\n#define\tNCYCLES 3\n\tunsigned i, j;\n#define\tNSZS 2500\n\tsize_t szs[NSZS];\n#define\tMAXSZ ZU(12 * 1024 * 1024)\n\n\tp = mallocx(1, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\tszs[0] = sallocx(p, 0);\n\n\tfor (i = 0; i < NCYCLES; i++) {\n\t\tfor (j = 1; j < NSZS && szs[j-1] < MAXSZ; j++) {\n\t\t\tq = rallocx(p, szs[j-1]+1, 0);\n\t\t\tassert_ptr_not_null(q,\n\t\t\t    \"Unexpected rallocx() error for size=%zu-->%zu\",\n\t\t\t    szs[j-1], szs[j-1]+1);\n\t\t\tszs[j] = sallocx(q, 0);\n\t\t\tassert_zu_ne(szs[j], szs[j-1]+1,\n\t\t\t    \"Expected size to be at least: %zu\", szs[j-1]+1);\n\t\t\tp = q;\n\t\t}\n\n\t\tfor (j--; j > 0; j--) {\n\t\t\tq = rallocx(p, szs[j-1], 0);\n\t\t\tassert_ptr_not_null(q,\n\t\t\t    \"Unexpected rallocx() error for size=%zu-->%zu\",\n\t\t\t    szs[j], szs[j-1]);\n\t\t\ttsz = sallocx(q, 0);\n\t\t\tassert_zu_eq(tsz, szs[j-1],\n\t\t\t    \"Expected size=%zu, got size=%zu\", szs[j-1], tsz);\n\t\t\tp = q;\n\t\t}\n\t}\n\n\tdallocx(p, 0);\n#undef MAXSZ\n#undef NSZS\n#undef NCYCLES\n}\nTEST_END\n\nstatic bool\nvalidate_fill(const void *p, uint8_t c, size_t offset, size_t len)\n{\n\tbool ret = false;\n\tconst uint8_t *buf = (const uint8_t *)p;\n\tsize_t i;\n\n\tfor (i = 0; i < len; i++) {\n\t\tuint8_t b = buf[offset+i];\n\t\tif (b != c) {\n\t\t\ttest_fail(\"Allocation at %p (len=%zu) contains %#x \"\n\t\t\t    \"rather than %#x at offset %zu\", p, len, b, c,\n\t\t\t    offset+i);\n\t\t\tret = true;\n\t\t}\n\t}\n\n\treturn (ret);\n}\n\nTEST_BEGIN(test_zero)\n{\n\tvoid *p, *q;\n\tsize_t psz, qsz, i, j;\n\tsize_t start_sizes[] = {1, 3*1024, 63*1024, 4095*1024};\n#define\tFILL_BYTE 0xaaU\n#define\tRANGE 2048\n\n\tfor (i = 0; i < sizeof(start_sizes)/sizeof(size_t); i++) {\n\t\tsize_t start_size = start_sizes[i];\n\t\tp = mallocx(start_size, MALLOCX_ZERO);\n\t\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\t\tpsz = sallocx(p, 0);\n\n\t\tassert_false(validate_fill(p, 0, 0, psz),\n\t\t    \"Expected zeroed memory\");\n\t\tmemset(p, FILL_BYTE, psz);\n\t\tassert_false(validate_fill(p, FILL_BYTE, 0, psz),\n\t\t    \"Expected filled memory\");\n\n\t\tfor (j = 1; j < RANGE; j++) {\n\t\t\tq = rallocx(p, start_size+j, MALLOCX_ZERO);\n\t\t\tassert_ptr_not_null(q, \"Unexpected rallocx() error\");\n\t\t\tqsz = sallocx(q, 0);\n\t\t\tif (q != p || qsz != psz) {\n\t\t\t\tassert_false(validate_fill(q, FILL_BYTE, 0,\n\t\t\t\t    psz), \"Expected filled memory\");\n\t\t\t\tassert_false(validate_fill(q, 0, psz, qsz-psz),\n\t\t\t\t    \"Expected zeroed memory\");\n\t\t\t}\n\t\t\tif (psz != qsz) {\n\t\t\t\tmemset((void *)((uintptr_t)q+psz), FILL_BYTE,\n\t\t\t\t    qsz-psz);\n\t\t\t\tpsz = qsz;\n\t\t\t}\n\t\t\tp = q;\n\t\t}\n\t\tassert_false(validate_fill(p, FILL_BYTE, 0, psz),\n\t\t    \"Expected filled memory\");\n\t\tdallocx(p, 0);\n\t}\n#undef FILL_BYTE\n}\nTEST_END\n\nTEST_BEGIN(test_align)\n{\n\tvoid *p, *q;\n\tsize_t align;\n#define\tMAX_ALIGN (ZU(1) << 25)\n\n\talign = ZU(1);\n\tp = mallocx(1, MALLOCX_ALIGN(align));\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\n\tfor (align <<= 1; align <= MAX_ALIGN; align <<= 1) {\n\t\tq = rallocx(p, 1, MALLOCX_ALIGN(align));\n\t\tassert_ptr_not_null(q,\n\t\t    \"Unexpected rallocx() error for align=%zu\", align);\n\t\tassert_ptr_null(\n\t\t    (void *)((uintptr_t)q & (align-1)),\n\t\t    \"%p inadequately aligned for align=%zu\",\n\t\t    q, align);\n\t\tp = q;\n\t}\n\tdallocx(p, 0);\n#undef MAX_ALIGN\n}\nTEST_END\n\nTEST_BEGIN(test_lg_align_and_zero)\n{\n\tvoid *p, *q;\n\tunsigned lg_align;\n\tsize_t sz;\n#define\tMAX_LG_ALIGN 25\n#define\tMAX_VALIDATE (ZU(1) << 22)\n\n\tlg_align = 0;\n\tp = mallocx(1, MALLOCX_LG_ALIGN(lg_align)|MALLOCX_ZERO);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\n\tfor (lg_align++; lg_align <= MAX_LG_ALIGN; lg_align++) {\n\t\tq = rallocx(p, 1, MALLOCX_LG_ALIGN(lg_align)|MALLOCX_ZERO);\n\t\tassert_ptr_not_null(q,\n\t\t    \"Unexpected rallocx() error for lg_align=%u\", lg_align);\n\t\tassert_ptr_null(\n\t\t    (void *)((uintptr_t)q & ((ZU(1) << lg_align)-1)),\n\t\t    \"%p inadequately aligned for lg_align=%u\", q, lg_align);\n\t\tsz = sallocx(q, 0);\n\t\tif ((sz << 1) <= MAX_VALIDATE) {\n\t\t\tassert_false(validate_fill(q, 0, 0, sz),\n\t\t\t    \"Expected zeroed memory\");\n\t\t} else {\n\t\t\tassert_false(validate_fill(q, 0, 0, MAX_VALIDATE),\n\t\t\t    \"Expected zeroed memory\");\n\t\t\tassert_false(validate_fill(\n\t\t\t    (void *)((uintptr_t)q+sz-MAX_VALIDATE),\n\t\t\t    0, 0, MAX_VALIDATE), \"Expected zeroed memory\");\n\t\t}\n\t\tp = q;\n\t}\n\tdallocx(p, 0);\n#undef MAX_VALIDATE\n#undef MAX_LG_ALIGN\n}\nTEST_END\n\nTEST_BEGIN(test_overflow)\n{\n\tsize_t hugemax;\n\tvoid *p;\n\n\thugemax = get_huge_size(get_nhuge()-1);\n\n\tp = mallocx(1, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\n\tassert_ptr_null(rallocx(p, hugemax+1, 0),\n\t    \"Expected OOM for rallocx(p, size=%#zx, 0)\", hugemax+1);\n\n\tassert_ptr_null(rallocx(p, ZU(PTRDIFF_MAX)+1, 0),\n\t    \"Expected OOM for rallocx(p, size=%#zx, 0)\", ZU(PTRDIFF_MAX)+1);\n\n\tassert_ptr_null(rallocx(p, SIZE_T_MAX, 0),\n\t    \"Expected OOM for rallocx(p, size=%#zx, 0)\", SIZE_T_MAX);\n\n\tassert_ptr_null(rallocx(p, 1, MALLOCX_ALIGN(ZU(PTRDIFF_MAX)+1)),\n\t    \"Expected OOM for rallocx(p, size=1, MALLOCX_ALIGN(%#zx))\",\n\t    ZU(PTRDIFF_MAX)+1);\n\n\tdallocx(p, 0);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_grow_and_shrink,\n\t    test_zero,\n\t    test_align,\n\t    test_lg_align_and_zero,\n\t    test_overflow));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/integration/sdallocx.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#define\tMAXALIGN (((size_t)1) << 25)\n#define\tNITER 4\n\nTEST_BEGIN(test_basic)\n{\n\tvoid *ptr = mallocx(64, 0);\n\tsdallocx(ptr, 64, 0);\n}\nTEST_END\n\nTEST_BEGIN(test_alignment_and_size)\n{\n\tsize_t nsz, sz, alignment, total;\n\tunsigned i;\n\tvoid *ps[NITER];\n\n\tfor (i = 0; i < NITER; i++)\n\t\tps[i] = NULL;\n\n\tfor (alignment = 8;\n\t    alignment <= MAXALIGN;\n\t    alignment <<= 1) {\n\t\ttotal = 0;\n\t\tfor (sz = 1;\n\t\t    sz < 3 * alignment && sz < (1U << 31);\n\t\t    sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {\n\t\t\tfor (i = 0; i < NITER; i++) {\n\t\t\t\tnsz = nallocx(sz, MALLOCX_ALIGN(alignment) |\n\t\t\t\t    MALLOCX_ZERO);\n\t\t\t\tps[i] = mallocx(sz, MALLOCX_ALIGN(alignment) |\n\t\t\t\t    MALLOCX_ZERO);\n\t\t\t\ttotal += nsz;\n\t\t\t\tif (total >= (MAXALIGN << 1))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tfor (i = 0; i < NITER; i++) {\n\t\t\t\tif (ps[i] != NULL) {\n\t\t\t\t\tsdallocx(ps[i], sz,\n\t\t\t\t\t    MALLOCX_ALIGN(alignment));\n\t\t\t\t\tps[i] = NULL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_basic,\n\t    test_alignment_and_size));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/integration/thread_arena.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#define\tNTHREADS 10\n\nvoid *\nthd_start(void *arg)\n{\n\tunsigned main_arena_ind = *(unsigned *)arg;\n\tvoid *p;\n\tunsigned arena_ind;\n\tsize_t size;\n\tint err;\n\n\tp = malloc(1);\n\tassert_ptr_not_null(p, \"Error in malloc()\");\n\tfree(p);\n\n\tsize = sizeof(arena_ind);\n\tif ((err = mallctl(\"thread.arena\", &arena_ind, &size, &main_arena_ind,\n\t    sizeof(main_arena_ind)))) {\n\t\tchar buf[BUFERROR_BUF];\n\n\t\tbuferror(err, buf, sizeof(buf));\n\t\ttest_fail(\"Error in mallctl(): %s\", buf);\n\t}\n\n\tsize = sizeof(arena_ind);\n\tif ((err = mallctl(\"thread.arena\", &arena_ind, &size, NULL, 0))) {\n\t\tchar buf[BUFERROR_BUF];\n\n\t\tbuferror(err, buf, sizeof(buf));\n\t\ttest_fail(\"Error in mallctl(): %s\", buf);\n\t}\n\tassert_u_eq(arena_ind, main_arena_ind,\n\t    \"Arena index should be same as for main thread\");\n\n\treturn (NULL);\n}\n\nTEST_BEGIN(test_thread_arena)\n{\n\tvoid *p;\n\tunsigned arena_ind;\n\tsize_t size;\n\tint err;\n\tthd_t thds[NTHREADS];\n\tunsigned i;\n\n\tp = malloc(1);\n\tassert_ptr_not_null(p, \"Error in malloc()\");\n\n\tsize = sizeof(arena_ind);\n\tif ((err = mallctl(\"thread.arena\", &arena_ind, &size, NULL, 0))) {\n\t\tchar buf[BUFERROR_BUF];\n\n\t\tbuferror(err, buf, sizeof(buf));\n\t\ttest_fail(\"Error in mallctl(): %s\", buf);\n\t}\n\n\tfor (i = 0; i < NTHREADS; i++) {\n\t\tthd_create(&thds[i], thd_start,\n\t\t    (void *)&arena_ind);\n\t}\n\n\tfor (i = 0; i < NTHREADS; i++) {\n\t\tintptr_t join_ret;\n\t\tthd_join(thds[i], (void *)&join_ret);\n\t\tassert_zd_eq(join_ret, 0, \"Unexpected thread join error\");\n\t}\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_thread_arena));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/integration/thread_tcache_enabled.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nstatic const bool config_tcache =\n#ifdef JEMALLOC_TCACHE\n    true\n#else\n    false\n#endif\n    ;\n\nvoid *\nthd_start(void *arg)\n{\n\tint err;\n\tsize_t sz;\n\tbool e0, e1;\n\n\tsz = sizeof(bool);\n\tif ((err = mallctl(\"thread.tcache.enabled\", &e0, &sz, NULL, 0))) {\n\t\tif (err == ENOENT) {\n\t\t\tassert_false(config_tcache,\n\t\t\t    \"ENOENT should only be returned if tcache is \"\n\t\t\t    \"disabled\");\n\t\t}\n\t\tgoto label_ENOENT;\n\t}\n\n\tif (e0) {\n\t\te1 = false;\n\t\tassert_d_eq(mallctl(\"thread.tcache.enabled\", &e0, &sz, &e1, sz),\n\t\t    0, \"Unexpected mallctl() error\");\n\t\tassert_true(e0, \"tcache should be enabled\");\n\t}\n\n\te1 = true;\n\tassert_d_eq(mallctl(\"thread.tcache.enabled\", &e0, &sz, &e1, sz), 0,\n\t    \"Unexpected mallctl() error\");\n\tassert_false(e0, \"tcache should be disabled\");\n\n\te1 = true;\n\tassert_d_eq(mallctl(\"thread.tcache.enabled\", &e0, &sz, &e1, sz), 0,\n\t    \"Unexpected mallctl() error\");\n\tassert_true(e0, \"tcache should be enabled\");\n\n\te1 = false;\n\tassert_d_eq(mallctl(\"thread.tcache.enabled\", &e0, &sz, &e1, sz), 0,\n\t    \"Unexpected mallctl() error\");\n\tassert_true(e0, \"tcache should be enabled\");\n\n\te1 = false;\n\tassert_d_eq(mallctl(\"thread.tcache.enabled\", &e0, &sz, &e1, sz), 0,\n\t    \"Unexpected mallctl() error\");\n\tassert_false(e0, \"tcache should be disabled\");\n\n\tfree(malloc(1));\n\te1 = true;\n\tassert_d_eq(mallctl(\"thread.tcache.enabled\", &e0, &sz, &e1, sz), 0,\n\t    \"Unexpected mallctl() error\");\n\tassert_false(e0, \"tcache should be disabled\");\n\n\tfree(malloc(1));\n\te1 = true;\n\tassert_d_eq(mallctl(\"thread.tcache.enabled\", &e0, &sz, &e1, sz), 0,\n\t    \"Unexpected mallctl() error\");\n\tassert_true(e0, \"tcache should be enabled\");\n\n\tfree(malloc(1));\n\te1 = false;\n\tassert_d_eq(mallctl(\"thread.tcache.enabled\", &e0, &sz, &e1, sz), 0,\n\t    \"Unexpected mallctl() error\");\n\tassert_true(e0, \"tcache should be enabled\");\n\n\tfree(malloc(1));\n\te1 = false;\n\tassert_d_eq(mallctl(\"thread.tcache.enabled\", &e0, &sz, &e1, sz), 0,\n\t    \"Unexpected mallctl() error\");\n\tassert_false(e0, \"tcache should be disabled\");\n\n\tfree(malloc(1));\n\treturn (NULL);\nlabel_ENOENT:\n\ttest_skip(\"\\\"thread.tcache.enabled\\\" mallctl not available\");\n\treturn (NULL);\n}\n\nTEST_BEGIN(test_main_thread)\n{\n\n\tthd_start(NULL);\n}\nTEST_END\n\nTEST_BEGIN(test_subthread)\n{\n\tthd_t thd;\n\n\tthd_create(&thd, thd_start, NULL);\n\tthd_join(thd, NULL);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\t/* Run tests multiple times to check for bad interactions. */\n\treturn (test(\n\t    test_main_thread,\n\t    test_subthread,\n\t    test_main_thread,\n\t    test_subthread,\n\t    test_main_thread));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/integration/xallocx.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n/*\n * Use a separate arena for xallocx() extension/contraction tests so that\n * internal allocation e.g. by heap profiling can't interpose allocations where\n * xallocx() would ordinarily be able to extend.\n */\nstatic unsigned\narena_ind(void)\n{\n\tstatic unsigned ind = 0;\n\n\tif (ind == 0) {\n\t\tsize_t sz = sizeof(ind);\n\t\tassert_d_eq(mallctl(\"arenas.extend\", &ind, &sz, NULL, 0), 0,\n\t\t    \"Unexpected mallctl failure creating arena\");\n\t}\n\n\treturn (ind);\n}\n\nTEST_BEGIN(test_same_size)\n{\n\tvoid *p;\n\tsize_t sz, tsz;\n\n\tp = mallocx(42, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\tsz = sallocx(p, 0);\n\n\ttsz = xallocx(p, sz, 0, 0);\n\tassert_zu_eq(tsz, sz, \"Unexpected size change: %zu --> %zu\", sz, tsz);\n\n\tdallocx(p, 0);\n}\nTEST_END\n\nTEST_BEGIN(test_extra_no_move)\n{\n\tvoid *p;\n\tsize_t sz, tsz;\n\n\tp = mallocx(42, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\tsz = sallocx(p, 0);\n\n\ttsz = xallocx(p, sz, sz-42, 0);\n\tassert_zu_eq(tsz, sz, \"Unexpected size change: %zu --> %zu\", sz, tsz);\n\n\tdallocx(p, 0);\n}\nTEST_END\n\nTEST_BEGIN(test_no_move_fail)\n{\n\tvoid *p;\n\tsize_t sz, tsz;\n\n\tp = mallocx(42, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\tsz = sallocx(p, 0);\n\n\ttsz = xallocx(p, sz + 5, 0, 0);\n\tassert_zu_eq(tsz, sz, \"Unexpected size change: %zu --> %zu\", sz, tsz);\n\n\tdallocx(p, 0);\n}\nTEST_END\n\nstatic unsigned\nget_nsizes_impl(const char *cmd)\n{\n\tunsigned ret;\n\tsize_t z;\n\n\tz = sizeof(unsigned);\n\tassert_d_eq(mallctl(cmd, &ret, &z, NULL, 0), 0,\n\t    \"Unexpected mallctl(\\\"%s\\\", ...) failure\", cmd);\n\n\treturn (ret);\n}\n\nstatic unsigned\nget_nsmall(void)\n{\n\n\treturn (get_nsizes_impl(\"arenas.nbins\"));\n}\n\nstatic unsigned\nget_nlarge(void)\n{\n\n\treturn (get_nsizes_impl(\"arenas.nlruns\"));\n}\n\nstatic unsigned\nget_nhuge(void)\n{\n\n\treturn (get_nsizes_impl(\"arenas.nhchunks\"));\n}\n\nstatic size_t\nget_size_impl(const char *cmd, size_t ind)\n{\n\tsize_t ret;\n\tsize_t z;\n\tsize_t mib[4];\n\tsize_t miblen = 4;\n\n\tz = sizeof(size_t);\n\tassert_d_eq(mallctlnametomib(cmd, mib, &miblen),\n\t    0, \"Unexpected mallctlnametomib(\\\"%s\\\", ...) failure\", cmd);\n\tmib[2] = ind;\n\tz = sizeof(size_t);\n\tassert_d_eq(mallctlbymib(mib, miblen, &ret, &z, NULL, 0),\n\t    0, \"Unexpected mallctlbymib([\\\"%s\\\", %zu], ...) failure\", cmd, ind);\n\n\treturn (ret);\n}\n\nstatic size_t\nget_small_size(size_t ind)\n{\n\n\treturn (get_size_impl(\"arenas.bin.0.size\", ind));\n}\n\nstatic size_t\nget_large_size(size_t ind)\n{\n\n\treturn (get_size_impl(\"arenas.lrun.0.size\", ind));\n}\n\nstatic size_t\nget_huge_size(size_t ind)\n{\n\n\treturn (get_size_impl(\"arenas.hchunk.0.size\", ind));\n}\n\nTEST_BEGIN(test_size)\n{\n\tsize_t small0, hugemax;\n\tvoid *p;\n\n\t/* Get size classes. */\n\tsmall0 = get_small_size(0);\n\thugemax = get_huge_size(get_nhuge()-1);\n\n\tp = mallocx(small0, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\n\t/* Test smallest supported size. */\n\tassert_zu_eq(xallocx(p, 1, 0, 0), small0,\n\t    \"Unexpected xallocx() behavior\");\n\n\t/* Test largest supported size. */\n\tassert_zu_le(xallocx(p, hugemax, 0, 0), hugemax,\n\t    \"Unexpected xallocx() behavior\");\n\n\t/* Test size overflow. */\n\tassert_zu_le(xallocx(p, hugemax+1, 0, 0), hugemax,\n\t    \"Unexpected xallocx() behavior\");\n\tassert_zu_le(xallocx(p, SIZE_T_MAX, 0, 0), hugemax,\n\t    \"Unexpected xallocx() behavior\");\n\n\tdallocx(p, 0);\n}\nTEST_END\n\nTEST_BEGIN(test_size_extra_overflow)\n{\n\tsize_t small0, hugemax;\n\tvoid *p;\n\n\t/* Get size classes. */\n\tsmall0 = get_small_size(0);\n\thugemax = get_huge_size(get_nhuge()-1);\n\n\tp = mallocx(small0, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\n\t/* Test overflows that can be resolved by clamping extra. */\n\tassert_zu_le(xallocx(p, hugemax-1, 2, 0), hugemax,\n\t    \"Unexpected xallocx() behavior\");\n\tassert_zu_le(xallocx(p, hugemax, 1, 0), hugemax,\n\t    \"Unexpected xallocx() behavior\");\n\n\t/* Test overflow such that hugemax-size underflows. */\n\tassert_zu_le(xallocx(p, hugemax+1, 2, 0), hugemax,\n\t    \"Unexpected xallocx() behavior\");\n\tassert_zu_le(xallocx(p, hugemax+2, 3, 0), hugemax,\n\t    \"Unexpected xallocx() behavior\");\n\tassert_zu_le(xallocx(p, SIZE_T_MAX-2, 2, 0), hugemax,\n\t    \"Unexpected xallocx() behavior\");\n\tassert_zu_le(xallocx(p, SIZE_T_MAX-1, 1, 0), hugemax,\n\t    \"Unexpected xallocx() behavior\");\n\n\tdallocx(p, 0);\n}\nTEST_END\n\nTEST_BEGIN(test_extra_small)\n{\n\tsize_t small0, small1, hugemax;\n\tvoid *p;\n\n\t/* Get size classes. */\n\tsmall0 = get_small_size(0);\n\tsmall1 = get_small_size(1);\n\thugemax = get_huge_size(get_nhuge()-1);\n\n\tp = mallocx(small0, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\n\tassert_zu_eq(xallocx(p, small1, 0, 0), small0,\n\t    \"Unexpected xallocx() behavior\");\n\n\tassert_zu_eq(xallocx(p, small1, 0, 0), small0,\n\t    \"Unexpected xallocx() behavior\");\n\n\tassert_zu_eq(xallocx(p, small0, small1 - small0, 0), small0,\n\t    \"Unexpected xallocx() behavior\");\n\n\t/* Test size+extra overflow. */\n\tassert_zu_eq(xallocx(p, small0, hugemax - small0 + 1, 0), small0,\n\t    \"Unexpected xallocx() behavior\");\n\tassert_zu_eq(xallocx(p, small0, SIZE_T_MAX - small0, 0), small0,\n\t    \"Unexpected xallocx() behavior\");\n\n\tdallocx(p, 0);\n}\nTEST_END\n\nTEST_BEGIN(test_extra_large)\n{\n\tint flags = MALLOCX_ARENA(arena_ind());\n\tsize_t smallmax, large0, large1, large2, huge0, hugemax;\n\tvoid *p;\n\n\t/* Get size classes. */\n\tsmallmax = get_small_size(get_nsmall()-1);\n\tlarge0 = get_large_size(0);\n\tlarge1 = get_large_size(1);\n\tlarge2 = get_large_size(2);\n\thuge0 = get_huge_size(0);\n\thugemax = get_huge_size(get_nhuge()-1);\n\n\tp = mallocx(large2, flags);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\n\tassert_zu_eq(xallocx(p, large2, 0, flags), large2,\n\t    \"Unexpected xallocx() behavior\");\n\t/* Test size decrease with zero extra. */\n\tassert_zu_eq(xallocx(p, large0, 0, flags), large0,\n\t    \"Unexpected xallocx() behavior\");\n\tassert_zu_eq(xallocx(p, smallmax, 0, flags), large0,\n\t    \"Unexpected xallocx() behavior\");\n\n\tassert_zu_eq(xallocx(p, large2, 0, flags), large2,\n\t    \"Unexpected xallocx() behavior\");\n\t/* Test size decrease with non-zero extra. */\n\tassert_zu_eq(xallocx(p, large0, large2 - large0, flags), large2,\n\t    \"Unexpected xallocx() behavior\");\n\tassert_zu_eq(xallocx(p, large1, large2 - large1, flags), large2,\n\t    \"Unexpected xallocx() behavior\");\n\tassert_zu_eq(xallocx(p, large0, large1 - large0, flags), large1,\n\t    \"Unexpected xallocx() behavior\");\n\tassert_zu_eq(xallocx(p, smallmax, large0 - smallmax, flags), large0,\n\t    \"Unexpected xallocx() behavior\");\n\n\tassert_zu_eq(xallocx(p, large0, 0, flags), large0,\n\t    \"Unexpected xallocx() behavior\");\n\t/* Test size increase with zero extra. */\n\tassert_zu_eq(xallocx(p, large2, 0, flags), large2,\n\t    \"Unexpected xallocx() behavior\");\n\tassert_zu_eq(xallocx(p, huge0, 0, flags), large2,\n\t    \"Unexpected xallocx() behavior\");\n\n\tassert_zu_eq(xallocx(p, large0, 0, flags), large0,\n\t    \"Unexpected xallocx() behavior\");\n\t/* Test size increase with non-zero extra. */\n\tassert_zu_lt(xallocx(p, large0, huge0 - large0, flags), huge0,\n\t    \"Unexpected xallocx() behavior\");\n\n\tassert_zu_eq(xallocx(p, large0, 0, flags), large0,\n\t    \"Unexpected xallocx() behavior\");\n\t/* Test size increase with non-zero extra. */\n\tassert_zu_eq(xallocx(p, large0, large2 - large0, flags), large2,\n\t    \"Unexpected xallocx() behavior\");\n\n\tassert_zu_eq(xallocx(p, large2, 0, flags), large2,\n\t    \"Unexpected xallocx() behavior\");\n\t/* Test size+extra overflow. */\n\tassert_zu_lt(xallocx(p, large2, hugemax - large2 + 1, flags), huge0,\n\t    \"Unexpected xallocx() behavior\");\n\n\tdallocx(p, flags);\n}\nTEST_END\n\nTEST_BEGIN(test_extra_huge)\n{\n\tint flags = MALLOCX_ARENA(arena_ind());\n\tsize_t largemax, huge1, huge2, huge3, hugemax;\n\tvoid *p;\n\n\t/* Get size classes. */\n\tlargemax = get_large_size(get_nlarge()-1);\n\thuge1 = get_huge_size(1);\n\thuge2 = get_huge_size(2);\n\thuge3 = get_huge_size(3);\n\thugemax = get_huge_size(get_nhuge()-1);\n\n\tp = mallocx(huge3, flags);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\n\tassert_zu_eq(xallocx(p, huge3, 0, flags), huge3,\n\t    \"Unexpected xallocx() behavior\");\n\t/* Test size decrease with zero extra. */\n\tassert_zu_ge(xallocx(p, huge1, 0, flags), huge1,\n\t    \"Unexpected xallocx() behavior\");\n\tassert_zu_ge(xallocx(p, largemax, 0, flags), huge1,\n\t    \"Unexpected xallocx() behavior\");\n\n\tassert_zu_eq(xallocx(p, huge3, 0, flags), huge3,\n\t    \"Unexpected xallocx() behavior\");\n\t/* Test size decrease with non-zero extra. */\n\tassert_zu_eq(xallocx(p, huge1, huge3 - huge1, flags), huge3,\n\t    \"Unexpected xallocx() behavior\");\n\tassert_zu_eq(xallocx(p, huge2, huge3 - huge2, flags), huge3,\n\t    \"Unexpected xallocx() behavior\");\n\tassert_zu_eq(xallocx(p, huge1, huge2 - huge1, flags), huge2,\n\t    \"Unexpected xallocx() behavior\");\n\tassert_zu_ge(xallocx(p, largemax, huge1 - largemax, flags), huge1,\n\t    \"Unexpected xallocx() behavior\");\n\n\tassert_zu_ge(xallocx(p, huge1, 0, flags), huge1,\n\t    \"Unexpected xallocx() behavior\");\n\t/* Test size increase with zero extra. */\n\tassert_zu_le(xallocx(p, huge3, 0, flags), huge3,\n\t    \"Unexpected xallocx() behavior\");\n\tassert_zu_le(xallocx(p, hugemax+1, 0, flags), huge3,\n\t    \"Unexpected xallocx() behavior\");\n\n\tassert_zu_ge(xallocx(p, huge1, 0, flags), huge1,\n\t    \"Unexpected xallocx() behavior\");\n\t/* Test size increase with non-zero extra. */\n\tassert_zu_le(xallocx(p, huge1, SIZE_T_MAX - huge1, flags), hugemax,\n\t    \"Unexpected xallocx() behavior\");\n\n\tassert_zu_ge(xallocx(p, huge1, 0, flags), huge1,\n\t    \"Unexpected xallocx() behavior\");\n\t/* Test size increase with non-zero extra. */\n\tassert_zu_le(xallocx(p, huge1, huge3 - huge1, flags), huge3,\n\t    \"Unexpected xallocx() behavior\");\n\n\tassert_zu_eq(xallocx(p, huge3, 0, flags), huge3,\n\t    \"Unexpected xallocx() behavior\");\n\t/* Test size+extra overflow. */\n\tassert_zu_le(xallocx(p, huge3, hugemax - huge3 + 1, flags), hugemax,\n\t    \"Unexpected xallocx() behavior\");\n\n\tdallocx(p, flags);\n}\nTEST_END\n\nstatic void\nprint_filled_extents(const void *p, uint8_t c, size_t len)\n{\n\tconst uint8_t *pc = (const uint8_t *)p;\n\tsize_t i, range0;\n\tuint8_t c0;\n\n\tmalloc_printf(\"  p=%p, c=%#x, len=%zu:\", p, c, len);\n\trange0 = 0;\n\tc0 = pc[0];\n\tfor (i = 0; i < len; i++) {\n\t\tif (pc[i] != c0) {\n\t\t\tmalloc_printf(\" %#x[%zu..%zu)\", c0, range0, i);\n\t\t\trange0 = i;\n\t\t\tc0 = pc[i];\n\t\t}\n\t}\n\tmalloc_printf(\" %#x[%zu..%zu)\\n\", c0, range0, i);\n}\n\nstatic bool\nvalidate_fill(const void *p, uint8_t c, size_t offset, size_t len)\n{\n\tconst uint8_t *pc = (const uint8_t *)p;\n\tbool err;\n\tsize_t i;\n\n\tfor (i = offset, err = false; i < offset+len; i++) {\n\t\tif (pc[i] != c)\n\t\t\terr = true;\n\t}\n\n\tif (err)\n\t\tprint_filled_extents(p, c, offset + len);\n\n\treturn (err);\n}\n\nstatic void\ntest_zero(size_t szmin, size_t szmax)\n{\n\tint flags = MALLOCX_ARENA(arena_ind()) | MALLOCX_ZERO;\n\tsize_t sz, nsz;\n\tvoid *p;\n#define\tFILL_BYTE 0x7aU\n\n\tsz = szmax;\n\tp = mallocx(sz, flags);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() error\");\n\tassert_false(validate_fill(p, 0x00, 0, sz), \"Memory not filled: sz=%zu\",\n\t    sz);\n\n\t/*\n\t * Fill with non-zero so that non-debug builds are more likely to detect\n\t * errors.\n\t */\n\tmemset(p, FILL_BYTE, sz);\n\tassert_false(validate_fill(p, FILL_BYTE, 0, sz),\n\t    \"Memory not filled: sz=%zu\", sz);\n\n\t/* Shrink in place so that we can expect growing in place to succeed. */\n\tsz = szmin;\n\tassert_zu_eq(xallocx(p, sz, 0, flags), sz,\n\t    \"Unexpected xallocx() error\");\n\tassert_false(validate_fill(p, FILL_BYTE, 0, sz),\n\t    \"Memory not filled: sz=%zu\", sz);\n\n\tfor (sz = szmin; sz < szmax; sz = nsz) {\n\t\tnsz = nallocx(sz+1, flags);\n\t\tassert_zu_eq(xallocx(p, sz+1, 0, flags), nsz,\n\t\t    \"Unexpected xallocx() failure\");\n\t\tassert_false(validate_fill(p, FILL_BYTE, 0, sz),\n\t\t    \"Memory not filled: sz=%zu\", sz);\n\t\tassert_false(validate_fill(p, 0x00, sz, nsz-sz),\n\t\t    \"Memory not filled: sz=%zu, nsz-sz=%zu\", sz, nsz-sz);\n\t\tmemset((void *)((uintptr_t)p + sz), FILL_BYTE, nsz-sz);\n\t\tassert_false(validate_fill(p, FILL_BYTE, 0, nsz),\n\t\t    \"Memory not filled: nsz=%zu\", nsz);\n\t}\n\n\tdallocx(p, flags);\n}\n\nTEST_BEGIN(test_zero_large)\n{\n\tsize_t large0, largemax;\n\n\t/* Get size classes. */\n\tlarge0 = get_large_size(0);\n\tlargemax = get_large_size(get_nlarge()-1);\n\n\ttest_zero(large0, largemax);\n}\nTEST_END\n\nTEST_BEGIN(test_zero_huge)\n{\n\tsize_t huge0, huge1;\n\n\t/* Get size classes. */\n\thuge0 = get_huge_size(0);\n\thuge1 = get_huge_size(1);\n\n\ttest_zero(huge1, huge0 * 2);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_same_size,\n\t    test_extra_no_move,\n\t    test_no_move_fail,\n\t    test_size,\n\t    test_size_extra_overflow,\n\t    test_extra_small,\n\t    test_extra_large,\n\t    test_extra_huge,\n\t    test_zero_large,\n\t    test_zero_huge));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/src/SFMT.c",
    "content": "/*\n * This file derives from SFMT 1.3.3\n * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was\n * released under the terms of the following license:\n *\n *   Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n *   University. 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\n *         disclaimer in the documentation and/or other materials provided\n *         with the distribution.\n *       * Neither the name of the Hiroshima University nor the names of\n *         its contributors may be used to endorse or promote products\n *         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\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 * @file  SFMT.c\n * @brief SIMD oriented Fast Mersenne Twister(SFMT)\n *\n * @author Mutsuo Saito (Hiroshima University)\n * @author Makoto Matsumoto (Hiroshima University)\n *\n * Copyright (C) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n * University. All rights reserved.\n *\n * The new BSD License is applied to this software, see LICENSE.txt\n */\n#define\tSFMT_C_\n#include \"test/jemalloc_test.h\"\n#include \"test/SFMT-params.h\"\n\n#if defined(JEMALLOC_BIG_ENDIAN) && !defined(BIG_ENDIAN64)\n#define BIG_ENDIAN64 1\n#endif\n#if defined(__BIG_ENDIAN__) && !defined(__amd64) && !defined(BIG_ENDIAN64)\n#define BIG_ENDIAN64 1\n#endif\n#if defined(HAVE_ALTIVEC) && !defined(BIG_ENDIAN64)\n#define BIG_ENDIAN64 1\n#endif\n#if defined(ONLY64) && !defined(BIG_ENDIAN64)\n  #if defined(__GNUC__)\n    #error \"-DONLY64 must be specified with -DBIG_ENDIAN64\"\n  #endif\n#undef ONLY64\n#endif\n/*------------------------------------------------------\n  128-bit SIMD data type for Altivec, SSE2 or standard C\n  ------------------------------------------------------*/\n#if defined(HAVE_ALTIVEC)\n/** 128-bit data structure */\nunion W128_T {\n    vector unsigned int s;\n    uint32_t u[4];\n};\n/** 128-bit data type */\ntypedef union W128_T w128_t;\n\n#elif defined(HAVE_SSE2)\n/** 128-bit data structure */\nunion W128_T {\n    __m128i si;\n    uint32_t u[4];\n};\n/** 128-bit data type */\ntypedef union W128_T w128_t;\n\n#else\n\n/** 128-bit data structure */\nstruct W128_T {\n    uint32_t u[4];\n};\n/** 128-bit data type */\ntypedef struct W128_T w128_t;\n\n#endif\n\nstruct sfmt_s {\n    /** the 128-bit internal state array */\n    w128_t sfmt[N];\n    /** index counter to the 32-bit internal state array */\n    int idx;\n    /** a flag: it is 0 if and only if the internal state is not yet\n     * initialized. */\n    int initialized;\n};\n\n/*--------------------------------------\n  FILE GLOBAL VARIABLES\n  internal state, index counter and flag \n  --------------------------------------*/\n\n/** a parity check vector which certificate the period of 2^{MEXP} */\nstatic uint32_t parity[4] = {PARITY1, PARITY2, PARITY3, PARITY4};\n\n/*----------------\n  STATIC FUNCTIONS\n  ----------------*/\nJEMALLOC_INLINE_C int idxof(int i);\n#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))\nJEMALLOC_INLINE_C void rshift128(w128_t *out,  w128_t const *in, int shift);\nJEMALLOC_INLINE_C void lshift128(w128_t *out,  w128_t const *in, int shift);\n#endif\nJEMALLOC_INLINE_C void gen_rand_all(sfmt_t *ctx);\nJEMALLOC_INLINE_C void gen_rand_array(sfmt_t *ctx, w128_t *array, int size);\nJEMALLOC_INLINE_C uint32_t func1(uint32_t x);\nJEMALLOC_INLINE_C uint32_t func2(uint32_t x);\nstatic void period_certification(sfmt_t *ctx);\n#if defined(BIG_ENDIAN64) && !defined(ONLY64)\nJEMALLOC_INLINE_C void swap(w128_t *array, int size);\n#endif\n\n#if defined(HAVE_ALTIVEC)\n  #include \"test/SFMT-alti.h\"\n#elif defined(HAVE_SSE2)\n  #include \"test/SFMT-sse2.h\"\n#endif\n\n/**\n * This function simulate a 64-bit index of LITTLE ENDIAN \n * in BIG ENDIAN machine.\n */\n#ifdef ONLY64\nJEMALLOC_INLINE_C int idxof(int i) {\n    return i ^ 1;\n}\n#else\nJEMALLOC_INLINE_C int idxof(int i) {\n    return i;\n}\n#endif\n/**\n * This function simulates SIMD 128-bit right shift by the standard C.\n * The 128-bit integer given in in is shifted by (shift * 8) bits.\n * This function simulates the LITTLE ENDIAN SIMD.\n * @param out the output of this function\n * @param in the 128-bit data to be shifted\n * @param shift the shift value\n */\n#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))\n#ifdef ONLY64\nJEMALLOC_INLINE_C void rshift128(w128_t *out, w128_t const *in, int shift) {\n    uint64_t th, tl, oh, ol;\n\n    th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);\n    tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);\n\n    oh = th >> (shift * 8);\n    ol = tl >> (shift * 8);\n    ol |= th << (64 - shift * 8);\n    out->u[0] = (uint32_t)(ol >> 32);\n    out->u[1] = (uint32_t)ol;\n    out->u[2] = (uint32_t)(oh >> 32);\n    out->u[3] = (uint32_t)oh;\n}\n#else\nJEMALLOC_INLINE_C void rshift128(w128_t *out, w128_t const *in, int shift) {\n    uint64_t th, tl, oh, ol;\n\n    th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);\n    tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);\n\n    oh = th >> (shift * 8);\n    ol = tl >> (shift * 8);\n    ol |= th << (64 - shift * 8);\n    out->u[1] = (uint32_t)(ol >> 32);\n    out->u[0] = (uint32_t)ol;\n    out->u[3] = (uint32_t)(oh >> 32);\n    out->u[2] = (uint32_t)oh;\n}\n#endif\n/**\n * This function simulates SIMD 128-bit left shift by the standard C.\n * The 128-bit integer given in in is shifted by (shift * 8) bits.\n * This function simulates the LITTLE ENDIAN SIMD.\n * @param out the output of this function\n * @param in the 128-bit data to be shifted\n * @param shift the shift value\n */\n#ifdef ONLY64\nJEMALLOC_INLINE_C void lshift128(w128_t *out, w128_t const *in, int shift) {\n    uint64_t th, tl, oh, ol;\n\n    th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);\n    tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);\n\n    oh = th << (shift * 8);\n    ol = tl << (shift * 8);\n    oh |= tl >> (64 - shift * 8);\n    out->u[0] = (uint32_t)(ol >> 32);\n    out->u[1] = (uint32_t)ol;\n    out->u[2] = (uint32_t)(oh >> 32);\n    out->u[3] = (uint32_t)oh;\n}\n#else\nJEMALLOC_INLINE_C void lshift128(w128_t *out, w128_t const *in, int shift) {\n    uint64_t th, tl, oh, ol;\n\n    th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);\n    tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);\n\n    oh = th << (shift * 8);\n    ol = tl << (shift * 8);\n    oh |= tl >> (64 - shift * 8);\n    out->u[1] = (uint32_t)(ol >> 32);\n    out->u[0] = (uint32_t)ol;\n    out->u[3] = (uint32_t)(oh >> 32);\n    out->u[2] = (uint32_t)oh;\n}\n#endif\n#endif\n\n/**\n * This function represents the recursion formula.\n * @param r output\n * @param a a 128-bit part of the internal state array\n * @param b a 128-bit part of the internal state array\n * @param c a 128-bit part of the internal state array\n * @param d a 128-bit part of the internal state array\n */\n#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))\n#ifdef ONLY64\nJEMALLOC_INLINE_C void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,\n\t\t\t\tw128_t *d) {\n    w128_t x;\n    w128_t y;\n\n    lshift128(&x, a, SL2);\n    rshift128(&y, c, SR2);\n    r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK2) ^ y.u[0] \n\t^ (d->u[0] << SL1);\n    r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK1) ^ y.u[1] \n\t^ (d->u[1] << SL1);\n    r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK4) ^ y.u[2] \n\t^ (d->u[2] << SL1);\n    r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK3) ^ y.u[3] \n\t^ (d->u[3] << SL1);\n}\n#else\nJEMALLOC_INLINE_C void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,\n\t\t\t\tw128_t *d) {\n    w128_t x;\n    w128_t y;\n\n    lshift128(&x, a, SL2);\n    rshift128(&y, c, SR2);\n    r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK1) ^ y.u[0] \n\t^ (d->u[0] << SL1);\n    r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK2) ^ y.u[1] \n\t^ (d->u[1] << SL1);\n    r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK3) ^ y.u[2] \n\t^ (d->u[2] << SL1);\n    r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK4) ^ y.u[3] \n\t^ (d->u[3] << SL1);\n}\n#endif\n#endif\n\n#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))\n/**\n * This function fills the internal state array with pseudorandom\n * integers.\n */\nJEMALLOC_INLINE_C void gen_rand_all(sfmt_t *ctx) {\n    int i;\n    w128_t *r1, *r2;\n\n    r1 = &ctx->sfmt[N - 2];\n    r2 = &ctx->sfmt[N - 1];\n    for (i = 0; i < N - POS1; i++) {\n\tdo_recursion(&ctx->sfmt[i], &ctx->sfmt[i], &ctx->sfmt[i + POS1], r1,\n\t  r2);\n\tr1 = r2;\n\tr2 = &ctx->sfmt[i];\n    }\n    for (; i < N; i++) {\n\tdo_recursion(&ctx->sfmt[i], &ctx->sfmt[i], &ctx->sfmt[i + POS1 - N], r1,\n\t  r2);\n\tr1 = r2;\n\tr2 = &ctx->sfmt[i];\n    }\n}\n\n/**\n * This function fills the user-specified array with pseudorandom\n * integers.\n *\n * @param array an 128-bit array to be filled by pseudorandom numbers.  \n * @param size number of 128-bit pseudorandom numbers to be generated.\n */\nJEMALLOC_INLINE_C void gen_rand_array(sfmt_t *ctx, w128_t *array, int size) {\n    int i, j;\n    w128_t *r1, *r2;\n\n    r1 = &ctx->sfmt[N - 2];\n    r2 = &ctx->sfmt[N - 1];\n    for (i = 0; i < N - POS1; i++) {\n\tdo_recursion(&array[i], &ctx->sfmt[i], &ctx->sfmt[i + POS1], r1, r2);\n\tr1 = r2;\n\tr2 = &array[i];\n    }\n    for (; i < N; i++) {\n\tdo_recursion(&array[i], &ctx->sfmt[i], &array[i + POS1 - N], r1, r2);\n\tr1 = r2;\n\tr2 = &array[i];\n    }\n    for (; i < size - N; i++) {\n\tdo_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2);\n\tr1 = r2;\n\tr2 = &array[i];\n    }\n    for (j = 0; j < 2 * N - size; j++) {\n\tctx->sfmt[j] = array[j + size - N];\n    }\n    for (; i < size; i++, j++) {\n\tdo_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2);\n\tr1 = r2;\n\tr2 = &array[i];\n\tctx->sfmt[j] = array[i];\n    }\n}\n#endif\n\n#if defined(BIG_ENDIAN64) && !defined(ONLY64) && !defined(HAVE_ALTIVEC)\nJEMALLOC_INLINE_C void swap(w128_t *array, int size) {\n    int i;\n    uint32_t x, y;\n\n    for (i = 0; i < size; i++) {\n\tx = array[i].u[0];\n\ty = array[i].u[2];\n\tarray[i].u[0] = array[i].u[1];\n\tarray[i].u[2] = array[i].u[3];\n\tarray[i].u[1] = x;\n\tarray[i].u[3] = y;\n    }\n}\n#endif\n/**\n * This function represents a function used in the initialization\n * by init_by_array\n * @param x 32-bit integer\n * @return 32-bit integer\n */\nstatic uint32_t func1(uint32_t x) {\n    return (x ^ (x >> 27)) * (uint32_t)1664525UL;\n}\n\n/**\n * This function represents a function used in the initialization\n * by init_by_array\n * @param x 32-bit integer\n * @return 32-bit integer\n */\nstatic uint32_t func2(uint32_t x) {\n    return (x ^ (x >> 27)) * (uint32_t)1566083941UL;\n}\n\n/**\n * This function certificate the period of 2^{MEXP}\n */\nstatic void period_certification(sfmt_t *ctx) {\n    int inner = 0;\n    int i, j;\n    uint32_t work;\n    uint32_t *psfmt32 = &ctx->sfmt[0].u[0];\n\n    for (i = 0; i < 4; i++)\n\tinner ^= psfmt32[idxof(i)] & parity[i];\n    for (i = 16; i > 0; i >>= 1)\n\tinner ^= inner >> i;\n    inner &= 1;\n    /* check OK */\n    if (inner == 1) {\n\treturn;\n    }\n    /* check NG, and modification */\n    for (i = 0; i < 4; i++) {\n\twork = 1;\n\tfor (j = 0; j < 32; j++) {\n\t    if ((work & parity[i]) != 0) {\n\t\tpsfmt32[idxof(i)] ^= work;\n\t\treturn;\n\t    }\n\t    work = work << 1;\n\t}\n    }\n}\n\n/*----------------\n  PUBLIC FUNCTIONS\n  ----------------*/\n/**\n * This function returns the identification string.\n * The string shows the word size, the Mersenne exponent,\n * and all parameters of this generator.\n */\nconst char *get_idstring(void) {\n    return IDSTR;\n}\n\n/**\n * This function returns the minimum size of array used for \\b\n * fill_array32() function.\n * @return minimum size of array used for fill_array32() function.\n */\nint get_min_array_size32(void) {\n    return N32;\n}\n\n/**\n * This function returns the minimum size of array used for \\b\n * fill_array64() function.\n * @return minimum size of array used for fill_array64() function.\n */\nint get_min_array_size64(void) {\n    return N64;\n}\n\n#ifndef ONLY64\n/**\n * This function generates and returns 32-bit pseudorandom number.\n * init_gen_rand or init_by_array must be called before this function.\n * @return 32-bit pseudorandom number\n */\nuint32_t gen_rand32(sfmt_t *ctx) {\n    uint32_t r;\n    uint32_t *psfmt32 = &ctx->sfmt[0].u[0];\n\n    assert(ctx->initialized);\n    if (ctx->idx >= N32) {\n\tgen_rand_all(ctx);\n\tctx->idx = 0;\n    }\n    r = psfmt32[ctx->idx++];\n    return r;\n}\n\n/* Generate a random integer in [0..limit). */\nuint32_t gen_rand32_range(sfmt_t *ctx, uint32_t limit) {\n    uint32_t ret, above;\n\n    above = 0xffffffffU - (0xffffffffU % limit);\n    while (1) {\n\tret = gen_rand32(ctx);\n\tif (ret < above) {\n\t    ret %= limit;\n\t    break;\n\t}\n    }\n    return ret;\n}\n#endif\n/**\n * This function generates and returns 64-bit pseudorandom number.\n * init_gen_rand or init_by_array must be called before this function.\n * The function gen_rand64 should not be called after gen_rand32,\n * unless an initialization is again executed. \n * @return 64-bit pseudorandom number\n */\nuint64_t gen_rand64(sfmt_t *ctx) {\n#if defined(BIG_ENDIAN64) && !defined(ONLY64)\n    uint32_t r1, r2;\n    uint32_t *psfmt32 = &ctx->sfmt[0].u[0];\n#else\n    uint64_t r;\n    uint64_t *psfmt64 = (uint64_t *)&ctx->sfmt[0].u[0];\n#endif\n\n    assert(ctx->initialized);\n    assert(ctx->idx % 2 == 0);\n\n    if (ctx->idx >= N32) {\n\tgen_rand_all(ctx);\n\tctx->idx = 0;\n    }\n#if defined(BIG_ENDIAN64) && !defined(ONLY64)\n    r1 = psfmt32[ctx->idx];\n    r2 = psfmt32[ctx->idx + 1];\n    ctx->idx += 2;\n    return ((uint64_t)r2 << 32) | r1;\n#else\n    r = psfmt64[ctx->idx / 2];\n    ctx->idx += 2;\n    return r;\n#endif\n}\n\n/* Generate a random integer in [0..limit). */\nuint64_t gen_rand64_range(sfmt_t *ctx, uint64_t limit) {\n    uint64_t ret, above;\n\n    above = KQU(0xffffffffffffffff) - (KQU(0xffffffffffffffff) % limit);\n    while (1) {\n\tret = gen_rand64(ctx);\n\tif (ret < above) {\n\t    ret %= limit;\n\t    break;\n\t}\n    }\n    return ret;\n}\n\n#ifndef ONLY64\n/**\n * This function generates pseudorandom 32-bit integers in the\n * specified array[] by one call. The number of pseudorandom integers\n * is specified by the argument size, which must be at least 624 and a\n * multiple of four.  The generation by this function is much faster\n * than the following gen_rand function.\n *\n * For initialization, init_gen_rand or init_by_array must be called\n * before the first call of this function. This function can not be\n * used after calling gen_rand function, without initialization.\n *\n * @param array an array where pseudorandom 32-bit integers are filled\n * by this function.  The pointer to the array must be \\b \"aligned\"\n * (namely, must be a multiple of 16) in the SIMD version, since it\n * refers to the address of a 128-bit integer.  In the standard C\n * version, the pointer is arbitrary.\n *\n * @param size the number of 32-bit pseudorandom integers to be\n * generated.  size must be a multiple of 4, and greater than or equal\n * to (MEXP / 128 + 1) * 4.\n *\n * @note \\b memalign or \\b posix_memalign is available to get aligned\n * memory. Mac OSX doesn't have these functions, but \\b malloc of OSX\n * returns the pointer to the aligned memory block.\n */\nvoid fill_array32(sfmt_t *ctx, uint32_t *array, int size) {\n    assert(ctx->initialized);\n    assert(ctx->idx == N32);\n    assert(size % 4 == 0);\n    assert(size >= N32);\n\n    gen_rand_array(ctx, (w128_t *)array, size / 4);\n    ctx->idx = N32;\n}\n#endif\n\n/**\n * This function generates pseudorandom 64-bit integers in the\n * specified array[] by one call. The number of pseudorandom integers\n * is specified by the argument size, which must be at least 312 and a\n * multiple of two.  The generation by this function is much faster\n * than the following gen_rand function.\n *\n * For initialization, init_gen_rand or init_by_array must be called\n * before the first call of this function. This function can not be\n * used after calling gen_rand function, without initialization.\n *\n * @param array an array where pseudorandom 64-bit integers are filled\n * by this function.  The pointer to the array must be \"aligned\"\n * (namely, must be a multiple of 16) in the SIMD version, since it\n * refers to the address of a 128-bit integer.  In the standard C\n * version, the pointer is arbitrary.\n *\n * @param size the number of 64-bit pseudorandom integers to be\n * generated.  size must be a multiple of 2, and greater than or equal\n * to (MEXP / 128 + 1) * 2\n *\n * @note \\b memalign or \\b posix_memalign is available to get aligned\n * memory. Mac OSX doesn't have these functions, but \\b malloc of OSX\n * returns the pointer to the aligned memory block.\n */\nvoid fill_array64(sfmt_t *ctx, uint64_t *array, int size) {\n    assert(ctx->initialized);\n    assert(ctx->idx == N32);\n    assert(size % 2 == 0);\n    assert(size >= N64);\n\n    gen_rand_array(ctx, (w128_t *)array, size / 2);\n    ctx->idx = N32;\n\n#if defined(BIG_ENDIAN64) && !defined(ONLY64)\n    swap((w128_t *)array, size /2);\n#endif\n}\n\n/**\n * This function initializes the internal state array with a 32-bit\n * integer seed.\n *\n * @param seed a 32-bit integer used as the seed.\n */\nsfmt_t *init_gen_rand(uint32_t seed) {\n    void *p;\n    sfmt_t *ctx;\n    int i;\n    uint32_t *psfmt32;\n\n    if (posix_memalign(&p, sizeof(w128_t), sizeof(sfmt_t)) != 0) {\n\treturn NULL;\n    }\n    ctx = (sfmt_t *)p;\n    psfmt32 = &ctx->sfmt[0].u[0];\n\n    psfmt32[idxof(0)] = seed;\n    for (i = 1; i < N32; i++) {\n\tpsfmt32[idxof(i)] = 1812433253UL * (psfmt32[idxof(i - 1)] \n\t\t\t\t\t    ^ (psfmt32[idxof(i - 1)] >> 30))\n\t    + i;\n    }\n    ctx->idx = N32;\n    period_certification(ctx);\n    ctx->initialized = 1;\n\n    return ctx;\n}\n\n/**\n * This function initializes the internal state array,\n * with an array of 32-bit integers used as the seeds\n * @param init_key the array of 32-bit integers, used as a seed.\n * @param key_length the length of init_key.\n */\nsfmt_t *init_by_array(uint32_t *init_key, int key_length) {\n    void *p;\n    sfmt_t *ctx;\n    int i, j, count;\n    uint32_t r;\n    int lag;\n    int mid;\n    int size = N * 4;\n    uint32_t *psfmt32;\n\n    if (posix_memalign(&p, sizeof(w128_t), sizeof(sfmt_t)) != 0) {\n\treturn NULL;\n    }\n    ctx = (sfmt_t *)p;\n    psfmt32 = &ctx->sfmt[0].u[0];\n\n    if (size >= 623) {\n\tlag = 11;\n    } else if (size >= 68) {\n\tlag = 7;\n    } else if (size >= 39) {\n\tlag = 5;\n    } else {\n\tlag = 3;\n    }\n    mid = (size - lag) / 2;\n\n    memset(ctx->sfmt, 0x8b, sizeof(ctx->sfmt));\n    if (key_length + 1 > N32) {\n\tcount = key_length + 1;\n    } else {\n\tcount = N32;\n    }\n    r = func1(psfmt32[idxof(0)] ^ psfmt32[idxof(mid)] \n\t      ^ psfmt32[idxof(N32 - 1)]);\n    psfmt32[idxof(mid)] += r;\n    r += key_length;\n    psfmt32[idxof(mid + lag)] += r;\n    psfmt32[idxof(0)] = r;\n\n    count--;\n    for (i = 1, j = 0; (j < count) && (j < key_length); j++) {\n\tr = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)] \n\t\t  ^ psfmt32[idxof((i + N32 - 1) % N32)]);\n\tpsfmt32[idxof((i + mid) % N32)] += r;\n\tr += init_key[j] + i;\n\tpsfmt32[idxof((i + mid + lag) % N32)] += r;\n\tpsfmt32[idxof(i)] = r;\n\ti = (i + 1) % N32;\n    }\n    for (; j < count; j++) {\n\tr = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)] \n\t\t  ^ psfmt32[idxof((i + N32 - 1) % N32)]);\n\tpsfmt32[idxof((i + mid) % N32)] += r;\n\tr += i;\n\tpsfmt32[idxof((i + mid + lag) % N32)] += r;\n\tpsfmt32[idxof(i)] = r;\n\ti = (i + 1) % N32;\n    }\n    for (j = 0; j < N32; j++) {\n\tr = func2(psfmt32[idxof(i)] + psfmt32[idxof((i + mid) % N32)] \n\t\t  + psfmt32[idxof((i + N32 - 1) % N32)]);\n\tpsfmt32[idxof((i + mid) % N32)] ^= r;\n\tr -= i;\n\tpsfmt32[idxof((i + mid + lag) % N32)] ^= r;\n\tpsfmt32[idxof(i)] = r;\n\ti = (i + 1) % N32;\n    }\n\n    ctx->idx = N32;\n    period_certification(ctx);\n    ctx->initialized = 1;\n\n    return ctx;\n}\n\nvoid fini_gen_rand(sfmt_t *ctx) {\n    assert(ctx != NULL);\n\n    ctx->initialized = 0;\n    free(ctx);\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/src/btalloc.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nvoid *\nbtalloc(size_t size, unsigned bits)\n{\n\n\treturn (btalloc_0(size, bits));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/src/btalloc_0.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nbtalloc_n_gen(0)\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/src/btalloc_1.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nbtalloc_n_gen(1)\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/src/math.c",
    "content": "#define\tMATH_C_\n#include \"test/jemalloc_test.h\"\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/src/mq.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n/*\n * Sleep for approximately ns nanoseconds.  No lower *nor* upper bound on sleep\n * time is guaranteed.\n */\nvoid\nmq_nanosleep(unsigned ns)\n{\n\n\tassert(ns <= 1000*1000*1000);\n\n#ifdef _WIN32\n\tSleep(ns / 1000);\n#else\n\t{\n\t\tstruct timespec timeout;\n\n\t\tif (ns < 1000*1000*1000) {\n\t\t\ttimeout.tv_sec = 0;\n\t\t\ttimeout.tv_nsec = ns;\n\t\t} else {\n\t\t\ttimeout.tv_sec = 1;\n\t\t\ttimeout.tv_nsec = 0;\n\t\t}\n\t\tnanosleep(&timeout, NULL);\n\t}\n#endif\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/src/mtx.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#ifndef _CRT_SPINCOUNT\n#define\t_CRT_SPINCOUNT 4000\n#endif\n\nbool\nmtx_init(mtx_t *mtx)\n{\n\n#ifdef _WIN32\n\tif (!InitializeCriticalSectionAndSpinCount(&mtx->lock, _CRT_SPINCOUNT))\n\t\treturn (true);\n#elif (defined(JEMALLOC_OSSPIN))\n\tmtx->lock = 0;\n#else\n\tpthread_mutexattr_t attr;\n\n\tif (pthread_mutexattr_init(&attr) != 0)\n\t\treturn (true);\n\tpthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT);\n\tif (pthread_mutex_init(&mtx->lock, &attr) != 0) {\n\t\tpthread_mutexattr_destroy(&attr);\n\t\treturn (true);\n\t}\n\tpthread_mutexattr_destroy(&attr);\n#endif\n\treturn (false);\n}\n\nvoid\nmtx_fini(mtx_t *mtx)\n{\n\n#ifdef _WIN32\n#elif (defined(JEMALLOC_OSSPIN))\n#else\n\tpthread_mutex_destroy(&mtx->lock);\n#endif\n}\n\nvoid\nmtx_lock(mtx_t *mtx)\n{\n\n#ifdef _WIN32\n\tEnterCriticalSection(&mtx->lock);\n#elif (defined(JEMALLOC_OSSPIN))\n\tOSSpinLockLock(&mtx->lock);\n#else\n\tpthread_mutex_lock(&mtx->lock);\n#endif\n}\n\nvoid\nmtx_unlock(mtx_t *mtx)\n{\n\n#ifdef _WIN32\n\tLeaveCriticalSection(&mtx->lock);\n#elif (defined(JEMALLOC_OSSPIN))\n\tOSSpinLockUnlock(&mtx->lock);\n#else\n\tpthread_mutex_unlock(&mtx->lock);\n#endif\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/src/test.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nstatic unsigned\t\ttest_count = 0;\nstatic test_status_t\ttest_counts[test_status_count] = {0, 0, 0};\nstatic test_status_t\ttest_status = test_status_pass;\nstatic const char *\ttest_name = \"\";\n\nJEMALLOC_FORMAT_PRINTF(1, 2)\nvoid\ntest_skip(const char *format, ...)\n{\n\tva_list ap;\n\n\tva_start(ap, format);\n\tmalloc_vcprintf(NULL, NULL, format, ap);\n\tva_end(ap);\n\tmalloc_printf(\"\\n\");\n\ttest_status = test_status_skip;\n}\n\nJEMALLOC_FORMAT_PRINTF(1, 2)\nvoid\ntest_fail(const char *format, ...)\n{\n\tva_list ap;\n\n\tva_start(ap, format);\n\tmalloc_vcprintf(NULL, NULL, format, ap);\n\tva_end(ap);\n\tmalloc_printf(\"\\n\");\n\ttest_status = test_status_fail;\n}\n\nstatic const char *\ntest_status_string(test_status_t test_status)\n{\n\n\tswitch (test_status) {\n\tcase test_status_pass: return \"pass\";\n\tcase test_status_skip: return \"skip\";\n\tcase test_status_fail: return \"fail\";\n\tdefault: not_reached();\n\t}\n}\n\nvoid\np_test_init(const char *name)\n{\n\n\ttest_count++;\n\ttest_status = test_status_pass;\n\ttest_name = name;\n}\n\nvoid\np_test_fini(void)\n{\n\n\ttest_counts[test_status]++;\n\tmalloc_printf(\"%s: %s\\n\", test_name, test_status_string(test_status));\n}\n\ntest_status_t\np_test(test_t *t, ...)\n{\n\ttest_status_t ret;\n\tva_list ap;\n\n\t/*\n\t * Make sure initialization occurs prior to running tests.  Tests are\n\t * special because they may use internal facilities prior to triggering\n\t * initialization as a side effect of calling into the public API.  This\n\t * is a final safety that works even if jemalloc_constructor() doesn't\n\t * run, as for MSVC builds.\n\t */\n\tif (nallocx(1, 0) == 0) {\n\t\tmalloc_printf(\"Initialization error\");\n\t\treturn (test_status_fail);\n\t}\n\n\tret = test_status_pass;\n\tva_start(ap, t);\n\tfor (; t != NULL; t = va_arg(ap, test_t *)) {\n\t\tt();\n\t\tif (test_status > ret)\n\t\t\tret = test_status;\n\t}\n\tva_end(ap);\n\n\tmalloc_printf(\"--- %s: %u/%u, %s: %u/%u, %s: %u/%u ---\\n\",\n\t    test_status_string(test_status_pass),\n\t    test_counts[test_status_pass], test_count,\n\t    test_status_string(test_status_skip),\n\t    test_counts[test_status_skip], test_count,\n\t    test_status_string(test_status_fail),\n\t    test_counts[test_status_fail], test_count);\n\n\treturn (ret);\n}\n\nvoid\np_test_fail(const char *prefix, const char *message)\n{\n\n\tmalloc_cprintf(NULL, NULL, \"%s%s\\n\", prefix, message);\n\ttest_status = test_status_fail;\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/src/thd.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#ifdef _WIN32\nvoid\nthd_create(thd_t *thd, void *(*proc)(void *), void *arg)\n{\n\tLPTHREAD_START_ROUTINE routine = (LPTHREAD_START_ROUTINE)proc;\n\t*thd = CreateThread(NULL, 0, routine, arg, 0, NULL);\n\tif (*thd == NULL)\n\t\ttest_fail(\"Error in CreateThread()\\n\");\n}\n\nvoid\nthd_join(thd_t thd, void **ret)\n{\n\n\tif (WaitForSingleObject(thd, INFINITE) == WAIT_OBJECT_0 && ret) {\n\t\tDWORD exit_code;\n\t\tGetExitCodeThread(thd, (LPDWORD) &exit_code);\n\t\t*ret = (void *)(uintptr_t)exit_code;\n\t}\n}\n\n#else\nvoid\nthd_create(thd_t *thd, void *(*proc)(void *), void *arg)\n{\n\n\tif (pthread_create(thd, NULL, proc, arg) != 0)\n\t\ttest_fail(\"Error in pthread_create()\\n\");\n}\n\nvoid\nthd_join(thd_t thd, void **ret)\n{\n\n\tpthread_join(thd, ret);\n}\n#endif\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/src/timer.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nvoid\ntimer_start(timedelta_t *timer)\n{\n\n\tnstime_init(&timer->t0, 0);\n\tnstime_update(&timer->t0);\n}\n\nvoid\ntimer_stop(timedelta_t *timer)\n{\n\n\tnstime_copy(&timer->t1, &timer->t0);\n\tnstime_update(&timer->t1);\n}\n\nuint64_t\ntimer_usec(const timedelta_t *timer)\n{\n\tnstime_t delta;\n\n\tnstime_copy(&delta, &timer->t1);\n\tnstime_subtract(&delta, &timer->t0);\n\treturn (nstime_ns(&delta) / 1000);\n}\n\nvoid\ntimer_ratio(timedelta_t *a, timedelta_t *b, char *buf, size_t buflen)\n{\n\tuint64_t t0 = timer_usec(a);\n\tuint64_t t1 = timer_usec(b);\n\tuint64_t mult;\n\tunsigned i = 0;\n\tunsigned j;\n\tint n;\n\n\t/* Whole. */\n\tn = malloc_snprintf(&buf[i], buflen-i, \"%\"FMTu64, t0 / t1);\n\ti += n;\n\tif (i >= buflen)\n\t\treturn;\n\tmult = 1;\n\tfor (j = 0; j < n; j++)\n\t\tmult *= 10;\n\n\t/* Decimal. */\n\tn = malloc_snprintf(&buf[i], buflen-i, \".\");\n\ti += n;\n\n\t/* Fraction. */\n\twhile (i < buflen-1) {\n\t\tuint64_t round = (i+1 == buflen-1 && ((t0 * mult * 10 / t1) % 10\n\t\t    >= 5)) ? 1 : 0;\n\t\tn = malloc_snprintf(&buf[i], buflen-i,\n\t\t    \"%\"FMTu64, (t0 * mult / t1) % 10 + round);\n\t\ti += n;\n\t\tmult *= 10;\n\t}\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/stress/microbench.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nJEMALLOC_INLINE_C void\ntime_func(timedelta_t *timer, uint64_t nwarmup, uint64_t niter, void (*func)(void))\n{\n\tuint64_t i;\n\n\tfor (i = 0; i < nwarmup; i++)\n\t\tfunc();\n\ttimer_start(timer);\n\tfor (i = 0; i < niter; i++)\n\t\tfunc();\n\ttimer_stop(timer);\n}\n\nvoid\ncompare_funcs(uint64_t nwarmup, uint64_t niter, const char *name_a,\n    void (*func_a), const char *name_b, void (*func_b))\n{\n\ttimedelta_t timer_a, timer_b;\n\tchar ratio_buf[6];\n\tvoid *p;\n\n\tp = mallocx(1, 0);\n\tif (p == NULL) {\n\t\ttest_fail(\"Unexpected mallocx() failure\");\n\t\treturn;\n\t}\n\n\ttime_func(&timer_a, nwarmup, niter, func_a);\n\ttime_func(&timer_b, nwarmup, niter, func_b);\n\n\ttimer_ratio(&timer_a, &timer_b, ratio_buf, sizeof(ratio_buf));\n\tmalloc_printf(\"%\"FMTu64\" iterations, %s=%\"FMTu64\"us, \"\n\t    \"%s=%\"FMTu64\"us, ratio=1:%s\\n\",\n\t    niter, name_a, timer_usec(&timer_a), name_b, timer_usec(&timer_b),\n\t    ratio_buf);\n\n\tdallocx(p, 0);\n}\n\nstatic void\nmalloc_free(void)\n{\n\t/* The compiler can optimize away free(malloc(1))! */\n\tvoid *p = malloc(1);\n\tif (p == NULL) {\n\t\ttest_fail(\"Unexpected malloc() failure\");\n\t\treturn;\n\t}\n\tfree(p);\n}\n\nstatic void\nmallocx_free(void)\n{\n\tvoid *p = mallocx(1, 0);\n\tif (p == NULL) {\n\t\ttest_fail(\"Unexpected mallocx() failure\");\n\t\treturn;\n\t}\n\tfree(p);\n}\n\nTEST_BEGIN(test_malloc_vs_mallocx)\n{\n\n\tcompare_funcs(10*1000*1000, 100*1000*1000, \"malloc\",\n\t    malloc_free, \"mallocx\", mallocx_free);\n}\nTEST_END\n\nstatic void\nmalloc_dallocx(void)\n{\n\tvoid *p = malloc(1);\n\tif (p == NULL) {\n\t\ttest_fail(\"Unexpected malloc() failure\");\n\t\treturn;\n\t}\n\tdallocx(p, 0);\n}\n\nstatic void\nmalloc_sdallocx(void)\n{\n\tvoid *p = malloc(1);\n\tif (p == NULL) {\n\t\ttest_fail(\"Unexpected malloc() failure\");\n\t\treturn;\n\t}\n\tsdallocx(p, 1, 0);\n}\n\nTEST_BEGIN(test_free_vs_dallocx)\n{\n\n\tcompare_funcs(10*1000*1000, 100*1000*1000, \"free\", malloc_free,\n\t    \"dallocx\", malloc_dallocx);\n}\nTEST_END\n\nTEST_BEGIN(test_dallocx_vs_sdallocx)\n{\n\n\tcompare_funcs(10*1000*1000, 100*1000*1000, \"dallocx\", malloc_dallocx,\n\t    \"sdallocx\", malloc_sdallocx);\n}\nTEST_END\n\nstatic void\nmalloc_mus_free(void)\n{\n\tvoid *p;\n\n\tp = malloc(1);\n\tif (p == NULL) {\n\t\ttest_fail(\"Unexpected malloc() failure\");\n\t\treturn;\n\t}\n\tmalloc_usable_size(p);\n\tfree(p);\n}\n\nstatic void\nmalloc_sallocx_free(void)\n{\n\tvoid *p;\n\n\tp = malloc(1);\n\tif (p == NULL) {\n\t\ttest_fail(\"Unexpected malloc() failure\");\n\t\treturn;\n\t}\n\tif (sallocx(p, 0) < 1)\n\t\ttest_fail(\"Unexpected sallocx() failure\");\n\tfree(p);\n}\n\nTEST_BEGIN(test_mus_vs_sallocx)\n{\n\n\tcompare_funcs(10*1000*1000, 100*1000*1000, \"malloc_usable_size\",\n\t    malloc_mus_free, \"sallocx\", malloc_sallocx_free);\n}\nTEST_END\n\nstatic void\nmalloc_nallocx_free(void)\n{\n\tvoid *p;\n\n\tp = malloc(1);\n\tif (p == NULL) {\n\t\ttest_fail(\"Unexpected malloc() failure\");\n\t\treturn;\n\t}\n\tif (nallocx(1, 0) < 1)\n\t\ttest_fail(\"Unexpected nallocx() failure\");\n\tfree(p);\n}\n\nTEST_BEGIN(test_sallocx_vs_nallocx)\n{\n\n\tcompare_funcs(10*1000*1000, 100*1000*1000, \"sallocx\",\n\t    malloc_sallocx_free, \"nallocx\", malloc_nallocx_free);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_malloc_vs_mallocx,\n\t    test_free_vs_dallocx,\n\t    test_dallocx_vs_sdallocx,\n\t    test_mus_vs_sallocx,\n\t    test_sallocx_vs_nallocx));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/test.sh.in",
    "content": "#!/bin/sh\n\ncase @abi@ in\n  macho)\n    export DYLD_FALLBACK_LIBRARY_PATH=\"@objroot@lib\"\n    ;;\n  pecoff)\n    export PATH=\"${PATH}:@objroot@lib\"\n    ;;\n  *)\n    ;;\nesac\n\n# Corresponds to test_status_t.\npass_code=0\nskip_code=1\nfail_code=2\n\npass_count=0\nskip_count=0\nfail_count=0\nfor t in $@; do\n  if [ $pass_count -ne 0 -o $skip_count -ne 0 -o $fail_count != 0 ] ; then\n    echo\n  fi\n  echo \"=== ${t} ===\"\n  ${t}@exe@ @abs_srcroot@ @abs_objroot@\n  result_code=$?\n  case ${result_code} in\n    ${pass_code})\n      pass_count=$((pass_count+1))\n      ;;\n    ${skip_code})\n      skip_count=$((skip_count+1))\n      ;;\n    ${fail_code})\n      fail_count=$((fail_count+1))\n      ;;\n    *)\n      echo \"Test harness error\" 1>&2\n      exit 1\n  esac\ndone\n\ntotal_count=`expr ${pass_count} + ${skip_count} + ${fail_count}`\necho\necho \"Test suite summary: pass: ${pass_count}/${total_count}, skip: ${skip_count}/${total_count}, fail: ${fail_count}/${total_count}\"\n\nif [ ${fail_count} -eq 0 ] ; then\n  exit 0\nelse\n  exit 1\nfi\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/SFMT.c",
    "content": "/*\n * This file derives from SFMT 1.3.3\n * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was\n * released under the terms of the following license:\n *\n *   Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima\n *   University. 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\n *         disclaimer in the documentation and/or other materials provided\n *         with the distribution.\n *       * Neither the name of the Hiroshima University nor the names of\n *         its contributors may be used to endorse or promote products\n *         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\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 \"test/jemalloc_test.h\"\n\n#define\tBLOCK_SIZE 10000\n#define\tBLOCK_SIZE64 (BLOCK_SIZE / 2)\n#define\tCOUNT_1 1000\n#define\tCOUNT_2 700\n\nstatic const uint32_t init_gen_rand_32_expected[] = {\n\t3440181298U, 1564997079U, 1510669302U, 2930277156U, 1452439940U,\n\t3796268453U,  423124208U, 2143818589U, 3827219408U, 2987036003U,\n\t2674978610U, 1536842514U, 2027035537U, 2534897563U, 1686527725U,\n\t 545368292U, 1489013321U, 1370534252U, 4231012796U, 3994803019U,\n\t1764869045U,  824597505U,  862581900U, 2469764249U,  812862514U,\n\t 359318673U,  116957936U, 3367389672U, 2327178354U, 1898245200U,\n\t3206507879U, 2378925033U, 1040214787U, 2524778605U, 3088428700U,\n\t1417665896U,  964324147U, 2282797708U, 2456269299U,  313400376U,\n\t2245093271U, 1015729427U, 2694465011U, 3246975184U, 1992793635U,\n\t 463679346U, 3721104591U, 3475064196U,  856141236U, 1499559719U,\n\t3522818941U, 3721533109U, 1954826617U, 1282044024U, 1543279136U,\n\t1301863085U, 2669145051U, 4221477354U, 3896016841U, 3392740262U,\n\t 462466863U, 1037679449U, 1228140306U,  922298197U, 1205109853U,\n\t1872938061U, 3102547608U, 2742766808U, 1888626088U, 4028039414U,\n\t 157593879U, 1136901695U, 4038377686U, 3572517236U, 4231706728U,\n\t2997311961U, 1189931652U, 3981543765U, 2826166703U,   87159245U,\n\t1721379072U, 3897926942U, 1790395498U, 2569178939U, 1047368729U,\n\t2340259131U, 3144212906U, 2301169789U, 2442885464U, 3034046771U,\n\t3667880593U, 3935928400U, 2372805237U, 1666397115U, 2460584504U,\n\t 513866770U, 3810869743U, 2147400037U, 2792078025U, 2941761810U,\n\t3212265810U,  984692259U,  346590253U, 1804179199U, 3298543443U,\n\t 750108141U, 2880257022U,  243310542U, 1869036465U, 1588062513U,\n\t2983949551U, 1931450364U, 4034505847U, 2735030199U, 1628461061U,\n\t2539522841U,  127965585U, 3992448871U,  913388237U,  559130076U,\n\t1202933193U, 4087643167U, 2590021067U, 2256240196U, 1746697293U,\n\t1013913783U, 1155864921U, 2715773730U,  915061862U, 1948766573U,\n\t2322882854U, 3761119102U, 1343405684U, 3078711943U, 3067431651U,\n\t3245156316U, 3588354584U, 3484623306U, 3899621563U, 4156689741U,\n\t3237090058U, 3880063844U,  862416318U, 4039923869U, 2303788317U,\n\t3073590536U,  701653667U, 2131530884U, 3169309950U, 2028486980U,\n\t 747196777U, 3620218225U,  432016035U, 1449580595U, 2772266392U,\n\t 444224948U, 1662832057U, 3184055582U, 3028331792U, 1861686254U,\n\t1104864179U,  342430307U, 1350510923U, 3024656237U, 1028417492U,\n\t2870772950U,  290847558U, 3675663500U,  508431529U, 4264340390U,\n\t2263569913U, 1669302976U,  519511383U, 2706411211U, 3764615828U,\n\t3883162495U, 4051445305U, 2412729798U, 3299405164U, 3991911166U,\n\t2348767304U, 2664054906U, 3763609282U,  593943581U, 3757090046U,\n\t2075338894U, 2020550814U, 4287452920U, 4290140003U, 1422957317U,\n\t2512716667U, 2003485045U, 2307520103U, 2288472169U, 3940751663U,\n\t4204638664U, 2892583423U, 1710068300U, 3904755993U, 2363243951U,\n\t3038334120U,  547099465U,  771105860U, 3199983734U, 4282046461U,\n\t2298388363U,  934810218U, 2837827901U, 3952500708U, 2095130248U,\n\t3083335297U,   26885281U, 3932155283U, 1531751116U, 1425227133U,\n\t 495654159U, 3279634176U, 3855562207U, 3957195338U, 4159985527U,\n\t 893375062U, 1875515536U, 1327247422U, 3754140693U, 1028923197U,\n\t1729880440U,  805571298U,  448971099U, 2726757106U, 2749436461U,\n\t2485987104U,  175337042U, 3235477922U, 3882114302U, 2020970972U,\n\t 943926109U, 2762587195U, 1904195558U, 3452650564U,  108432281U,\n\t3893463573U, 3977583081U, 2636504348U, 1110673525U, 3548479841U,\n\t4258854744U,  980047703U, 4057175418U, 3890008292U,  145653646U,\n\t3141868989U, 3293216228U, 1194331837U, 1254570642U, 3049934521U,\n\t2868313360U, 2886032750U, 1110873820U,  279553524U, 3007258565U,\n\t1104807822U, 3186961098U,  315764646U, 2163680838U, 3574508994U,\n\t3099755655U,  191957684U, 3642656737U, 3317946149U, 3522087636U,\n\t 444526410U,  779157624U, 1088229627U, 1092460223U, 1856013765U,\n\t3659877367U,  368270451U,  503570716U, 3000984671U, 2742789647U,\n\t 928097709U, 2914109539U,  308843566U, 2816161253U, 3667192079U,\n\t2762679057U, 3395240989U, 2928925038U, 1491465914U, 3458702834U,\n\t3787782576U, 2894104823U, 1296880455U, 1253636503U,  989959407U,\n\t2291560361U, 2776790436U, 1913178042U, 1584677829U,  689637520U,\n\t1898406878U,  688391508U, 3385234998U,  845493284U, 1943591856U,\n\t2720472050U,  222695101U, 1653320868U, 2904632120U, 4084936008U,\n\t1080720688U, 3938032556U,  387896427U, 2650839632U,   99042991U,\n\t1720913794U, 1047186003U, 1877048040U, 2090457659U,  517087501U,\n\t4172014665U, 2129713163U, 2413533132U, 2760285054U, 4129272496U,\n\t1317737175U, 2309566414U, 2228873332U, 3889671280U, 1110864630U,\n\t3576797776U, 2074552772U,  832002644U, 3097122623U, 2464859298U,\n\t2679603822U, 1667489885U, 3237652716U, 1478413938U, 1719340335U,\n\t2306631119U,  639727358U, 3369698270U,  226902796U, 2099920751U,\n\t1892289957U, 2201594097U, 3508197013U, 3495811856U, 3900381493U,\n\t 841660320U, 3974501451U, 3360949056U, 1676829340U,  728899254U,\n\t2047809627U, 2390948962U,  670165943U, 3412951831U, 4189320049U,\n\t1911595255U, 2055363086U,  507170575U,  418219594U, 4141495280U,\n\t2692088692U, 4203630654U, 3540093932U,  791986533U, 2237921051U,\n\t2526864324U, 2956616642U, 1394958700U, 1983768223U, 1893373266U,\n\t 591653646U,  228432437U, 1611046598U, 3007736357U, 1040040725U,\n\t2726180733U, 2789804360U, 4263568405U,  829098158U, 3847722805U,\n\t1123578029U, 1804276347U,  997971319U, 4203797076U, 4185199713U,\n\t2811733626U, 2343642194U, 2985262313U, 1417930827U, 3759587724U,\n\t1967077982U, 1585223204U, 1097475516U, 1903944948U,  740382444U,\n\t1114142065U, 1541796065U, 1718384172U, 1544076191U, 1134682254U,\n\t3519754455U, 2866243923U,  341865437U,  645498576U, 2690735853U,\n\t1046963033U, 2493178460U, 1187604696U, 1619577821U,  488503634U,\n\t3255768161U, 2306666149U, 1630514044U, 2377698367U, 2751503746U,\n\t3794467088U, 1796415981U, 3657173746U,  409136296U, 1387122342U,\n\t1297726519U,  219544855U, 4270285558U,  437578827U, 1444698679U,\n\t2258519491U,  963109892U, 3982244073U, 3351535275U,  385328496U,\n\t1804784013U,  698059346U, 3920535147U,  708331212U,  784338163U,\n\t 785678147U, 1238376158U, 1557298846U, 2037809321U,  271576218U,\n\t4145155269U, 1913481602U, 2763691931U,  588981080U, 1201098051U,\n\t3717640232U, 1509206239U,  662536967U, 3180523616U, 1133105435U,\n\t2963500837U, 2253971215U, 3153642623U, 1066925709U, 2582781958U,\n\t3034720222U, 1090798544U, 2942170004U, 4036187520U,  686972531U,\n\t2610990302U, 2641437026U, 1837562420U,  722096247U, 1315333033U,\n\t2102231203U, 3402389208U, 3403698140U, 1312402831U, 2898426558U,\n\t 814384596U,  385649582U, 1916643285U, 1924625106U, 2512905582U,\n\t2501170304U, 4275223366U, 2841225246U, 1467663688U, 3563567847U,\n\t2969208552U,  884750901U,  102992576U,  227844301U, 3681442994U,\n\t3502881894U, 4034693299U, 1166727018U, 1697460687U, 1737778332U,\n\t1787161139U, 1053003655U, 1215024478U, 2791616766U, 2525841204U,\n\t1629323443U,    3233815U, 2003823032U, 3083834263U, 2379264872U,\n\t3752392312U, 1287475550U, 3770904171U, 3004244617U, 1502117784U,\n\t 918698423U, 2419857538U, 3864502062U, 1751322107U, 2188775056U,\n\t4018728324U,  983712955U,  440071928U, 3710838677U, 2001027698U,\n\t3994702151U,   22493119U, 3584400918U, 3446253670U, 4254789085U,\n\t1405447860U, 1240245579U, 1800644159U, 1661363424U, 3278326132U,\n\t3403623451U,   67092802U, 2609352193U, 3914150340U, 1814842761U,\n\t3610830847U,  591531412U, 3880232807U, 1673505890U, 2585326991U,\n\t1678544474U, 3148435887U, 3457217359U, 1193226330U, 2816576908U,\n\t 154025329U,  121678860U, 1164915738U,  973873761U,  269116100U,\n\t  52087970U,  744015362U,  498556057U,   94298882U, 1563271621U,\n\t2383059628U, 4197367290U, 3958472990U, 2592083636U, 2906408439U,\n\t1097742433U, 3924840517U,  264557272U, 2292287003U, 3203307984U,\n\t4047038857U, 3820609705U, 2333416067U, 1839206046U, 3600944252U,\n\t3412254904U,  583538222U, 2390557166U, 4140459427U, 2810357445U,\n\t 226777499U, 2496151295U, 2207301712U, 3283683112U,  611630281U,\n\t1933218215U, 3315610954U, 3889441987U, 3719454256U, 3957190521U,\n\t1313998161U, 2365383016U, 3146941060U, 1801206260U,  796124080U,\n\t2076248581U, 1747472464U, 3254365145U,  595543130U, 3573909503U,\n\t3758250204U, 2020768540U, 2439254210U,   93368951U, 3155792250U,\n\t2600232980U, 3709198295U, 3894900440U, 2971850836U, 1578909644U,\n\t1443493395U, 2581621665U, 3086506297U, 2443465861U,  558107211U,\n\t1519367835U,  249149686U,  908102264U, 2588765675U, 1232743965U,\n\t1001330373U, 3561331654U, 2259301289U, 1564977624U, 3835077093U,\n\t 727244906U, 4255738067U, 1214133513U, 2570786021U, 3899704621U,\n\t1633861986U, 1636979509U, 1438500431U,   58463278U, 2823485629U,\n\t2297430187U, 2926781924U, 3371352948U, 1864009023U, 2722267973U,\n\t1444292075U,  437703973U, 1060414512U,  189705863U,  910018135U,\n\t4077357964U,  884213423U, 2644986052U, 3973488374U, 1187906116U,\n\t2331207875U,  780463700U, 3713351662U, 3854611290U,  412805574U,\n\t2978462572U, 2176222820U,  829424696U, 2790788332U, 2750819108U,\n\t1594611657U, 3899878394U, 3032870364U, 1702887682U, 1948167778U,\n\t  14130042U,  192292500U,  947227076U,   90719497U, 3854230320U,\n\t 784028434U, 2142399787U, 1563449646U, 2844400217U,  819143172U,\n\t2883302356U, 2328055304U, 1328532246U, 2603885363U, 3375188924U,\n\t 933941291U, 3627039714U, 2129697284U, 2167253953U, 2506905438U,\n\t1412424497U, 2981395985U, 1418359660U, 2925902456U,   52752784U,\n\t3713667988U, 3924669405U,  648975707U, 1145520213U, 4018650664U,\n\t3805915440U, 2380542088U, 2013260958U, 3262572197U, 2465078101U,\n\t1114540067U, 3728768081U, 2396958768U,  590672271U,  904818725U,\n\t4263660715U,  700754408U, 1042601829U, 4094111823U, 4274838909U,\n\t2512692617U, 2774300207U, 2057306915U, 3470942453U,   99333088U,\n\t1142661026U, 2889931380U,   14316674U, 2201179167U,  415289459U,\n\t 448265759U, 3515142743U, 3254903683U,  246633281U, 1184307224U,\n\t2418347830U, 2092967314U, 2682072314U, 2558750234U, 2000352263U,\n\t1544150531U,  399010405U, 1513946097U,  499682937U,  461167460U,\n\t3045570638U, 1633669705U,  851492362U, 4052801922U, 2055266765U,\n\t 635556996U,  368266356U, 2385737383U, 3218202352U, 2603772408U,\n\t 349178792U,  226482567U, 3102426060U, 3575998268U, 2103001871U,\n\t3243137071U,  225500688U, 1634718593U, 4283311431U, 4292122923U,\n\t3842802787U,  811735523U,  105712518U,  663434053U, 1855889273U,\n\t2847972595U, 1196355421U, 2552150115U, 4254510614U, 3752181265U,\n\t3430721819U, 3828705396U, 3436287905U, 3441964937U, 4123670631U,\n\t 353001539U,  459496439U, 3799690868U, 1293777660U, 2761079737U,\n\t 498096339U, 3398433374U, 4080378380U, 2304691596U, 2995729055U,\n\t4134660419U, 3903444024U, 3576494993U,  203682175U, 3321164857U,\n\t2747963611U,   79749085U, 2992890370U, 1240278549U, 1772175713U,\n\t2111331972U, 2655023449U, 1683896345U, 2836027212U, 3482868021U,\n\t2489884874U,  756853961U, 2298874501U, 4013448667U, 4143996022U,\n\t2948306858U, 4132920035U, 1283299272U,  995592228U, 3450508595U,\n\t1027845759U, 1766942720U, 3861411826U, 1446861231U,   95974993U,\n\t3502263554U, 1487532194U,  601502472U, 4129619129U,  250131773U,\n\t2050079547U, 3198903947U, 3105589778U, 4066481316U, 3026383978U,\n\t2276901713U,  365637751U, 2260718426U, 1394775634U, 1791172338U,\n\t2690503163U, 2952737846U, 1568710462U,  732623190U, 2980358000U,\n\t1053631832U, 1432426951U, 3229149635U, 1854113985U, 3719733532U,\n\t3204031934U,  735775531U,  107468620U, 3734611984U,  631009402U,\n\t3083622457U, 4109580626U,  159373458U, 1301970201U, 4132389302U,\n\t1293255004U,  847182752U, 4170022737U,   96712900U, 2641406755U,\n\t1381727755U,  405608287U, 4287919625U, 1703554290U, 3589580244U,\n\t2911403488U,    2166565U, 2647306451U, 2330535117U, 1200815358U,\n\t1165916754U,  245060911U, 4040679071U, 3684908771U, 2452834126U,\n\t2486872773U, 2318678365U, 2940627908U, 1837837240U, 3447897409U,\n\t4270484676U, 1495388728U, 3754288477U, 4204167884U, 1386977705U,\n\t2692224733U, 3076249689U, 4109568048U, 4170955115U, 4167531356U,\n\t4020189950U, 4261855038U, 3036907575U, 3410399885U, 3076395737U,\n\t1046178638U,  144496770U,  230725846U, 3349637149U,   17065717U,\n\t2809932048U, 2054581785U, 3608424964U, 3259628808U,  134897388U,\n\t3743067463U,  257685904U, 3795656590U, 1562468719U, 3589103904U,\n\t3120404710U,  254684547U, 2653661580U, 3663904795U, 2631942758U,\n\t1063234347U, 2609732900U, 2332080715U, 3521125233U, 1180599599U,\n\t1935868586U, 4110970440U,  296706371U, 2128666368U, 1319875791U,\n\t1570900197U, 3096025483U, 1799882517U, 1928302007U, 1163707758U,\n\t1244491489U, 3533770203U,  567496053U, 2757924305U, 2781639343U,\n\t2818420107U,  560404889U, 2619609724U, 4176035430U, 2511289753U,\n\t2521842019U, 3910553502U, 2926149387U, 3302078172U, 4237118867U,\n\t 330725126U,  367400677U,  888239854U,  545570454U, 4259590525U,\n\t 134343617U, 1102169784U, 1647463719U, 3260979784U, 1518840883U,\n\t3631537963U, 3342671457U, 1301549147U, 2083739356U,  146593792U,\n\t3217959080U,  652755743U, 2032187193U, 3898758414U, 1021358093U,\n\t4037409230U, 2176407931U, 3427391950U, 2883553603U,  985613827U,\n\t3105265092U, 3423168427U, 3387507672U,  467170288U, 2141266163U,\n\t3723870208U,  916410914U, 1293987799U, 2652584950U,  769160137U,\n\t3205292896U, 1561287359U, 1684510084U, 3136055621U, 3765171391U,\n\t 639683232U, 2639569327U, 1218546948U, 4263586685U, 3058215773U,\n\t2352279820U,  401870217U, 2625822463U, 1529125296U, 2981801895U,\n\t1191285226U, 4027725437U, 3432700217U, 4098835661U,  971182783U,\n\t2443861173U, 3881457123U, 3874386651U,  457276199U, 2638294160U,\n\t4002809368U,  421169044U, 1112642589U, 3076213779U, 3387033971U,\n\t2499610950U, 3057240914U, 1662679783U,  461224431U, 1168395933U\n};\nstatic const uint32_t init_by_array_32_expected[] = {\n\t2920711183U, 3885745737U, 3501893680U,  856470934U, 1421864068U,\n\t 277361036U, 1518638004U, 2328404353U, 3355513634U,   64329189U,\n\t1624587673U, 3508467182U, 2481792141U, 3706480799U, 1925859037U,\n\t2913275699U,  882658412U,  384641219U,  422202002U, 1873384891U,\n\t2006084383U, 3924929912U, 1636718106U, 3108838742U, 1245465724U,\n\t4195470535U,  779207191U, 1577721373U, 1390469554U, 2928648150U,\n\t 121399709U, 3170839019U, 4044347501U,  953953814U, 3821710850U,\n\t3085591323U, 3666535579U, 3577837737U, 2012008410U, 3565417471U,\n\t4044408017U,  433600965U, 1637785608U, 1798509764U,  860770589U,\n\t3081466273U, 3982393409U, 2451928325U, 3437124742U, 4093828739U,\n\t3357389386U, 2154596123U,  496568176U, 2650035164U, 2472361850U,\n\t   3438299U, 2150366101U, 1577256676U, 3802546413U, 1787774626U,\n\t4078331588U, 3706103141U,  170391138U, 3806085154U, 1680970100U,\n\t1961637521U, 3316029766U,  890610272U, 1453751581U, 1430283664U,\n\t3051057411U, 3597003186U,  542563954U, 3796490244U, 1690016688U,\n\t3448752238U,  440702173U,  347290497U, 1121336647U, 2540588620U,\n\t 280881896U, 2495136428U,  213707396U,   15104824U, 2946180358U,\n\t 659000016U,  566379385U, 2614030979U, 2855760170U,  334526548U,\n\t2315569495U, 2729518615U,  564745877U, 1263517638U, 3157185798U,\n\t1604852056U, 1011639885U, 2950579535U, 2524219188U,  312951012U,\n\t1528896652U, 1327861054U, 2846910138U, 3966855905U, 2536721582U,\n\t 855353911U, 1685434729U, 3303978929U, 1624872055U, 4020329649U,\n\t3164802143U, 1642802700U, 1957727869U, 1792352426U, 3334618929U,\n\t2631577923U, 3027156164U,  842334259U, 3353446843U, 1226432104U,\n\t1742801369U, 3552852535U, 3471698828U, 1653910186U, 3380330939U,\n\t2313782701U, 3351007196U, 2129839995U, 1800682418U, 4085884420U,\n\t1625156629U, 3669701987U,  615211810U, 3294791649U, 4131143784U,\n\t2590843588U, 3207422808U, 3275066464U,  561592872U, 3957205738U,\n\t3396578098U,   48410678U, 3505556445U, 1005764855U, 3920606528U,\n\t2936980473U, 2378918600U, 2404449845U, 1649515163U,  701203563U,\n\t3705256349U,   83714199U, 3586854132U,  922978446U, 2863406304U,\n\t3523398907U, 2606864832U, 2385399361U, 3171757816U, 4262841009U,\n\t3645837721U, 1169579486U, 3666433897U, 3174689479U, 1457866976U,\n\t3803895110U, 3346639145U, 1907224409U, 1978473712U, 1036712794U,\n\t 980754888U, 1302782359U, 1765252468U,  459245755U, 3728923860U,\n\t1512894209U, 2046491914U,  207860527U,  514188684U, 2288713615U,\n\t1597354672U, 3349636117U, 2357291114U, 3995796221U,  945364213U,\n\t1893326518U, 3770814016U, 1691552714U, 2397527410U,  967486361U,\n\t 776416472U, 4197661421U,  951150819U, 1852770983U, 4044624181U,\n\t1399439738U, 4194455275U, 2284037669U, 1550734958U, 3321078108U,\n\t1865235926U, 2912129961U, 2664980877U, 1357572033U, 2600196436U,\n\t2486728200U, 2372668724U, 1567316966U, 2374111491U, 1839843570U,\n\t  20815612U, 3727008608U, 3871996229U,  824061249U, 1932503978U,\n\t3404541726U,  758428924U, 2609331364U, 1223966026U, 1299179808U,\n\t 648499352U, 2180134401U,  880821170U, 3781130950U,  113491270U,\n\t1032413764U, 4185884695U, 2490396037U, 1201932817U, 4060951446U,\n\t4165586898U, 1629813212U, 2887821158U,  415045333U,  628926856U,\n\t2193466079U, 3391843445U, 2227540681U, 1907099846U, 2848448395U,\n\t1717828221U, 1372704537U, 1707549841U, 2294058813U, 2101214437U,\n\t2052479531U, 1695809164U, 3176587306U, 2632770465U,   81634404U,\n\t1603220563U,  644238487U,  302857763U,  897352968U, 2613146653U,\n\t1391730149U, 4245717312U, 4191828749U, 1948492526U, 2618174230U,\n\t3992984522U, 2178852787U, 3596044509U, 3445573503U, 2026614616U,\n\t 915763564U, 3415689334U, 2532153403U, 3879661562U, 2215027417U,\n\t3111154986U, 2929478371U,  668346391U, 1152241381U, 2632029711U,\n\t3004150659U, 2135025926U,  948690501U, 2799119116U, 4228829406U,\n\t1981197489U, 4209064138U,  684318751U, 3459397845U,  201790843U,\n\t4022541136U, 3043635877U,  492509624U, 3263466772U, 1509148086U,\n\t 921459029U, 3198857146U,  705479721U, 3835966910U, 3603356465U,\n\t 576159741U, 1742849431U,  594214882U, 2055294343U, 3634861861U,\n\t 449571793U, 3246390646U, 3868232151U, 1479156585U, 2900125656U,\n\t2464815318U, 3960178104U, 1784261920U,   18311476U, 3627135050U,\n\t 644609697U,  424968996U,  919890700U, 2986824110U,  816423214U,\n\t4003562844U, 1392714305U, 1757384428U, 2569030598U,  995949559U,\n\t3875659880U, 2933807823U, 2752536860U, 2993858466U, 4030558899U,\n\t2770783427U, 2775406005U, 2777781742U, 1931292655U,  472147933U,\n\t3865853827U, 2726470545U, 2668412860U, 2887008249U,  408979190U,\n\t3578063323U, 3242082049U, 1778193530U,   27981909U, 2362826515U,\n\t 389875677U, 1043878156U,  581653903U, 3830568952U,  389535942U,\n\t3713523185U, 2768373359U, 2526101582U, 1998618197U, 1160859704U,\n\t3951172488U, 1098005003U,  906275699U, 3446228002U, 2220677963U,\n\t2059306445U,  132199571U,  476838790U, 1868039399U, 3097344807U,\n\t 857300945U,  396345050U, 2835919916U, 1782168828U, 1419519470U,\n\t4288137521U,  819087232U,  596301494U,  872823172U, 1526888217U,\n\t 805161465U, 1116186205U, 2829002754U, 2352620120U,  620121516U,\n\t 354159268U, 3601949785U,  209568138U, 1352371732U, 2145977349U,\n\t4236871834U, 1539414078U, 3558126206U, 3224857093U, 4164166682U,\n\t3817553440U, 3301780278U, 2682696837U, 3734994768U, 1370950260U,\n\t1477421202U, 2521315749U, 1330148125U, 1261554731U, 2769143688U,\n\t3554756293U, 4235882678U, 3254686059U, 3530579953U, 1215452615U,\n\t3574970923U, 4057131421U,  589224178U, 1000098193U,  171190718U,\n\t2521852045U, 2351447494U, 2284441580U, 2646685513U, 3486933563U,\n\t3789864960U, 1190528160U, 1702536782U, 1534105589U, 4262946827U,\n\t2726686826U, 3584544841U, 2348270128U, 2145092281U, 2502718509U,\n\t1027832411U, 3571171153U, 1287361161U, 4011474411U, 3241215351U,\n\t2419700818U,  971242709U, 1361975763U, 1096842482U, 3271045537U,\n\t  81165449U,  612438025U, 3912966678U, 1356929810U,  733545735U,\n\t 537003843U, 1282953084U,  884458241U,  588930090U, 3930269801U,\n\t2961472450U, 1219535534U, 3632251943U,  268183903U, 1441240533U,\n\t3653903360U, 3854473319U, 2259087390U, 2548293048U, 2022641195U,\n\t2105543911U, 1764085217U, 3246183186U,  482438805U,  888317895U,\n\t2628314765U, 2466219854U,  717546004U, 2322237039U,  416725234U,\n\t1544049923U, 1797944973U, 3398652364U, 3111909456U,  485742908U,\n\t2277491072U, 1056355088U, 3181001278U,  129695079U, 2693624550U,\n\t1764438564U, 3797785470U,  195503713U, 3266519725U, 2053389444U,\n\t1961527818U, 3400226523U, 3777903038U, 2597274307U, 4235851091U,\n\t4094406648U, 2171410785U, 1781151386U, 1378577117U,  654643266U,\n\t3424024173U, 3385813322U,  679385799U,  479380913U,  681715441U,\n\t3096225905U,  276813409U, 3854398070U, 2721105350U,  831263315U,\n\t3276280337U, 2628301522U, 3984868494U, 1466099834U, 2104922114U,\n\t1412672743U,  820330404U, 3491501010U,  942735832U,  710652807U,\n\t3972652090U,  679881088U,   40577009U, 3705286397U, 2815423480U,\n\t3566262429U,  663396513U, 3777887429U, 4016670678U,  404539370U,\n\t1142712925U, 1140173408U, 2913248352U, 2872321286U,  263751841U,\n\t3175196073U, 3162557581U, 2878996619U,   75498548U, 3836833140U,\n\t3284664959U, 1157523805U,  112847376U,  207855609U, 1337979698U,\n\t1222578451U,  157107174U,  901174378U, 3883717063U, 1618632639U,\n\t1767889440U, 4264698824U, 1582999313U,  884471997U, 2508825098U,\n\t3756370771U, 2457213553U, 3565776881U, 3709583214U,  915609601U,\n\t 460833524U, 1091049576U,   85522880U,    2553251U,  132102809U,\n\t2429882442U, 2562084610U, 1386507633U, 4112471229U,   21965213U,\n\t1981516006U, 2418435617U, 3054872091U, 4251511224U, 2025783543U,\n\t1916911512U, 2454491136U, 3938440891U, 3825869115U, 1121698605U,\n\t3463052265U,  802340101U, 1912886800U, 4031997367U, 3550640406U,\n\t1596096923U,  610150600U,  431464457U, 2541325046U,  486478003U,\n\t 739704936U, 2862696430U, 3037903166U, 1129749694U, 2611481261U,\n\t1228993498U,  510075548U, 3424962587U, 2458689681U,  818934833U,\n\t4233309125U, 1608196251U, 3419476016U, 1858543939U, 2682166524U,\n\t3317854285U,  631986188U, 3008214764U,  613826412U, 3567358221U,\n\t3512343882U, 1552467474U, 3316162670U, 1275841024U, 4142173454U,\n\t 565267881U,  768644821U,  198310105U, 2396688616U, 1837659011U,\n\t 203429334U,  854539004U, 4235811518U, 3338304926U, 3730418692U,\n\t3852254981U, 3032046452U, 2329811860U, 2303590566U, 2696092212U,\n\t3894665932U,  145835667U,  249563655U, 1932210840U, 2431696407U,\n\t3312636759U,  214962629U, 2092026914U, 3020145527U, 4073039873U,\n\t2739105705U, 1308336752U,  855104522U, 2391715321U,   67448785U,\n\t 547989482U,  854411802U, 3608633740U,  431731530U,  537375589U,\n\t3888005760U,  696099141U,  397343236U, 1864511780U,   44029739U,\n\t1729526891U, 1993398655U, 2010173426U, 2591546756U,  275223291U,\n\t1503900299U, 4217765081U, 2185635252U, 1122436015U, 3550155364U,\n\t 681707194U, 3260479338U,  933579397U, 2983029282U, 2505504587U,\n\t2667410393U, 2962684490U, 4139721708U, 2658172284U, 2452602383U,\n\t2607631612U, 1344296217U, 3075398709U, 2949785295U, 1049956168U,\n\t3917185129U, 2155660174U, 3280524475U, 1503827867U,  674380765U,\n\t1918468193U, 3843983676U,  634358221U, 2538335643U, 1873351298U,\n\t3368723763U, 2129144130U, 3203528633U, 3087174986U, 2691698871U,\n\t2516284287U,   24437745U, 1118381474U, 2816314867U, 2448576035U,\n\t4281989654U,  217287825U,  165872888U, 2628995722U, 3533525116U,\n\t2721669106U,  872340568U, 3429930655U, 3309047304U, 3916704967U,\n\t3270160355U, 1348884255U, 1634797670U,  881214967U, 4259633554U,\n\t 174613027U, 1103974314U, 1625224232U, 2678368291U, 1133866707U,\n\t3853082619U, 4073196549U, 1189620777U,  637238656U,  930241537U,\n\t4042750792U, 3842136042U, 2417007212U, 2524907510U, 1243036827U,\n\t1282059441U, 3764588774U, 1394459615U, 2323620015U, 1166152231U,\n\t3307479609U, 3849322257U, 3507445699U, 4247696636U,  758393720U,\n\t 967665141U, 1095244571U, 1319812152U,  407678762U, 2640605208U,\n\t2170766134U, 3663594275U, 4039329364U, 2512175520U,  725523154U,\n\t2249807004U, 3312617979U, 2414634172U, 1278482215U,  349206484U,\n\t1573063308U, 1196429124U, 3873264116U, 2400067801U,  268795167U,\n\t 226175489U, 2961367263U, 1968719665U,   42656370U, 1010790699U,\n\t 561600615U, 2422453992U, 3082197735U, 1636700484U, 3977715296U,\n\t3125350482U, 3478021514U, 2227819446U, 1540868045U, 3061908980U,\n\t1087362407U, 3625200291U,  361937537U,  580441897U, 1520043666U,\n\t2270875402U, 1009161260U, 2502355842U, 4278769785U,  473902412U,\n\t1057239083U, 1905829039U, 1483781177U, 2080011417U, 1207494246U,\n\t1806991954U, 2194674403U, 3455972205U,  807207678U, 3655655687U,\n\t 674112918U,  195425752U, 3917890095U, 1874364234U, 1837892715U,\n\t3663478166U, 1548892014U, 2570748714U, 2049929836U, 2167029704U,\n\t 697543767U, 3499545023U, 3342496315U, 1725251190U, 3561387469U,\n\t2905606616U, 1580182447U, 3934525927U, 4103172792U, 1365672522U,\n\t1534795737U, 3308667416U, 2841911405U, 3943182730U, 4072020313U,\n\t3494770452U, 3332626671U,   55327267U,  478030603U,  411080625U,\n\t3419529010U, 1604767823U, 3513468014U,  570668510U,  913790824U,\n\t2283967995U,  695159462U, 3825542932U, 4150698144U, 1829758699U,\n\t 202895590U, 1609122645U, 1267651008U, 2910315509U, 2511475445U,\n\t2477423819U, 3932081579U,  900879979U, 2145588390U, 2670007504U,\n\t 580819444U, 1864996828U, 2526325979U, 1019124258U,  815508628U,\n\t2765933989U, 1277301341U, 3006021786U,  855540956U,  288025710U,\n\t1919594237U, 2331223864U,  177452412U, 2475870369U, 2689291749U,\n\t 865194284U,  253432152U, 2628531804U, 2861208555U, 2361597573U,\n\t1653952120U, 1039661024U, 2159959078U, 3709040440U, 3564718533U,\n\t2596878672U, 2041442161U,   31164696U, 2662962485U, 3665637339U,\n\t1678115244U, 2699839832U, 3651968520U, 3521595541U,  458433303U,\n\t2423096824U,   21831741U,  380011703U, 2498168716U,  861806087U,\n\t1673574843U, 4188794405U, 2520563651U, 2632279153U, 2170465525U,\n\t4171949898U, 3886039621U, 1661344005U, 3424285243U,  992588372U,\n\t2500984144U, 2993248497U, 3590193895U, 1535327365U,  515645636U,\n\t 131633450U, 3729760261U, 1613045101U, 3254194278U,   15889678U,\n\t1493590689U,  244148718U, 2991472662U, 1401629333U,  777349878U,\n\t2501401703U, 4285518317U, 3794656178U,  955526526U, 3442142820U,\n\t3970298374U,  736025417U, 2737370764U, 1271509744U,  440570731U,\n\t 136141826U, 1596189518U,  923399175U,  257541519U, 3505774281U,\n\t2194358432U, 2518162991U, 1379893637U, 2667767062U, 3748146247U,\n\t1821712620U, 3923161384U, 1947811444U, 2392527197U, 4127419685U,\n\t1423694998U, 4156576871U, 1382885582U, 3420127279U, 3617499534U,\n\t2994377493U, 4038063986U, 1918458672U, 2983166794U, 4200449033U,\n\t 353294540U, 1609232588U,  243926648U, 2332803291U,  507996832U,\n\t2392838793U, 4075145196U, 2060984340U, 4287475136U,   88232602U,\n\t2491531140U, 4159725633U, 2272075455U,  759298618U,  201384554U,\n\t 838356250U, 1416268324U,  674476934U,   90795364U,  141672229U,\n\t3660399588U, 4196417251U, 3249270244U, 3774530247U,   59587265U,\n\t3683164208U,   19392575U, 1463123697U, 1882205379U,  293780489U,\n\t2553160622U, 2933904694U,  675638239U, 2851336944U, 1435238743U,\n\t2448730183U,  804436302U, 2119845972U,  322560608U, 4097732704U,\n\t2987802540U,  641492617U, 2575442710U, 4217822703U, 3271835300U,\n\t2836418300U, 3739921620U, 2138378768U, 2879771855U, 4294903423U,\n\t3121097946U, 2603440486U, 2560820391U, 1012930944U, 2313499967U,\n\t 584489368U, 3431165766U,  897384869U, 2062537737U, 2847889234U,\n\t3742362450U, 2951174585U, 4204621084U, 1109373893U, 3668075775U,\n\t2750138839U, 3518055702U,  733072558U, 4169325400U,  788493625U\n};\nstatic const uint64_t init_gen_rand_64_expected[] = {\n\tKQU(16924766246869039260), KQU( 8201438687333352714),\n\tKQU( 2265290287015001750), KQU(18397264611805473832),\n\tKQU( 3375255223302384358), KQU( 6345559975416828796),\n\tKQU(18229739242790328073), KQU( 7596792742098800905),\n\tKQU(  255338647169685981), KQU( 2052747240048610300),\n\tKQU(18328151576097299343), KQU(12472905421133796567),\n\tKQU(11315245349717600863), KQU(16594110197775871209),\n\tKQU(15708751964632456450), KQU(10452031272054632535),\n\tKQU(11097646720811454386), KQU( 4556090668445745441),\n\tKQU(17116187693090663106), KQU(14931526836144510645),\n\tKQU( 9190752218020552591), KQU( 9625800285771901401),\n\tKQU(13995141077659972832), KQU( 5194209094927829625),\n\tKQU( 4156788379151063303), KQU( 8523452593770139494),\n\tKQU(14082382103049296727), KQU( 2462601863986088483),\n\tKQU( 3030583461592840678), KQU( 5221622077872827681),\n\tKQU( 3084210671228981236), KQU(13956758381389953823),\n\tKQU(13503889856213423831), KQU(15696904024189836170),\n\tKQU( 4612584152877036206), KQU( 6231135538447867881),\n\tKQU(10172457294158869468), KQU( 6452258628466708150),\n\tKQU(14044432824917330221), KQU(  370168364480044279),\n\tKQU(10102144686427193359), KQU(  667870489994776076),\n\tKQU( 2732271956925885858), KQU(18027788905977284151),\n\tKQU(15009842788582923859), KQU( 7136357960180199542),\n\tKQU(15901736243475578127), KQU(16951293785352615701),\n\tKQU(10551492125243691632), KQU(17668869969146434804),\n\tKQU(13646002971174390445), KQU( 9804471050759613248),\n\tKQU( 5511670439655935493), KQU(18103342091070400926),\n\tKQU(17224512747665137533), KQU(15534627482992618168),\n\tKQU( 1423813266186582647), KQU(15821176807932930024),\n\tKQU(   30323369733607156), KQU(11599382494723479403),\n\tKQU(  653856076586810062), KQU( 3176437395144899659),\n\tKQU(14028076268147963917), KQU(16156398271809666195),\n\tKQU( 3166955484848201676), KQU( 5746805620136919390),\n\tKQU(17297845208891256593), KQU(11691653183226428483),\n\tKQU(17900026146506981577), KQU(15387382115755971042),\n\tKQU(16923567681040845943), KQU( 8039057517199388606),\n\tKQU(11748409241468629263), KQU(  794358245539076095),\n\tKQU(13438501964693401242), KQU(14036803236515618962),\n\tKQU( 5252311215205424721), KQU(17806589612915509081),\n\tKQU( 6802767092397596006), KQU(14212120431184557140),\n\tKQU( 1072951366761385712), KQU(13098491780722836296),\n\tKQU( 9466676828710797353), KQU(12673056849042830081),\n\tKQU(12763726623645357580), KQU(16468961652999309493),\n\tKQU(15305979875636438926), KQU(17444713151223449734),\n\tKQU( 5692214267627883674), KQU(13049589139196151505),\n\tKQU(  880115207831670745), KQU( 1776529075789695498),\n\tKQU(16695225897801466485), KQU(10666901778795346845),\n\tKQU( 6164389346722833869), KQU( 2863817793264300475),\n\tKQU( 9464049921886304754), KQU( 3993566636740015468),\n\tKQU( 9983749692528514136), KQU(16375286075057755211),\n\tKQU(16042643417005440820), KQU(11445419662923489877),\n\tKQU( 7999038846885158836), KQU( 6721913661721511535),\n\tKQU( 5363052654139357320), KQU( 1817788761173584205),\n\tKQU(13290974386445856444), KQU( 4650350818937984680),\n\tKQU( 8219183528102484836), KQU( 1569862923500819899),\n\tKQU( 4189359732136641860), KQU(14202822961683148583),\n\tKQU( 4457498315309429058), KQU(13089067387019074834),\n\tKQU(11075517153328927293), KQU(10277016248336668389),\n\tKQU( 7070509725324401122), KQU(17808892017780289380),\n\tKQU(13143367339909287349), KQU( 1377743745360085151),\n\tKQU( 5749341807421286485), KQU(14832814616770931325),\n\tKQU( 7688820635324359492), KQU(10960474011539770045),\n\tKQU(   81970066653179790), KQU(12619476072607878022),\n\tKQU( 4419566616271201744), KQU(15147917311750568503),\n\tKQU( 5549739182852706345), KQU( 7308198397975204770),\n\tKQU(13580425496671289278), KQU(17070764785210130301),\n\tKQU( 8202832846285604405), KQU( 6873046287640887249),\n\tKQU( 6927424434308206114), KQU( 6139014645937224874),\n\tKQU(10290373645978487639), KQU(15904261291701523804),\n\tKQU( 9628743442057826883), KQU(18383429096255546714),\n\tKQU( 4977413265753686967), KQU( 7714317492425012869),\n\tKQU( 9025232586309926193), KQU(14627338359776709107),\n\tKQU(14759849896467790763), KQU(10931129435864423252),\n\tKQU( 4588456988775014359), KQU(10699388531797056724),\n\tKQU(  468652268869238792), KQU( 5755943035328078086),\n\tKQU( 2102437379988580216), KQU( 9986312786506674028),\n\tKQU( 2654207180040945604), KQU( 8726634790559960062),\n\tKQU(  100497234871808137), KQU( 2800137176951425819),\n\tKQU( 6076627612918553487), KQU( 5780186919186152796),\n\tKQU( 8179183595769929098), KQU( 6009426283716221169),\n\tKQU( 2796662551397449358), KQU( 1756961367041986764),\n\tKQU( 6972897917355606205), KQU(14524774345368968243),\n\tKQU( 2773529684745706940), KQU( 4853632376213075959),\n\tKQU( 4198177923731358102), KQU( 8271224913084139776),\n\tKQU( 2741753121611092226), KQU(16782366145996731181),\n\tKQU(15426125238972640790), KQU(13595497100671260342),\n\tKQU( 3173531022836259898), KQU( 6573264560319511662),\n\tKQU(18041111951511157441), KQU( 2351433581833135952),\n\tKQU( 3113255578908173487), KQU( 1739371330877858784),\n\tKQU(16046126562789165480), KQU( 8072101652214192925),\n\tKQU(15267091584090664910), KQU( 9309579200403648940),\n\tKQU( 5218892439752408722), KQU(14492477246004337115),\n\tKQU(17431037586679770619), KQU( 7385248135963250480),\n\tKQU( 9580144956565560660), KQU( 4919546228040008720),\n\tKQU(15261542469145035584), KQU(18233297270822253102),\n\tKQU( 5453248417992302857), KQU( 9309519155931460285),\n\tKQU(10342813012345291756), KQU(15676085186784762381),\n\tKQU(15912092950691300645), KQU( 9371053121499003195),\n\tKQU( 9897186478226866746), KQU(14061858287188196327),\n\tKQU(  122575971620788119), KQU(12146750969116317754),\n\tKQU( 4438317272813245201), KQU( 8332576791009527119),\n\tKQU(13907785691786542057), KQU(10374194887283287467),\n\tKQU( 2098798755649059566), KQU( 3416235197748288894),\n\tKQU( 8688269957320773484), KQU( 7503964602397371571),\n\tKQU(16724977015147478236), KQU( 9461512855439858184),\n\tKQU(13259049744534534727), KQU( 3583094952542899294),\n\tKQU( 8764245731305528292), KQU(13240823595462088985),\n\tKQU(13716141617617910448), KQU(18114969519935960955),\n\tKQU( 2297553615798302206), KQU( 4585521442944663362),\n\tKQU(17776858680630198686), KQU( 4685873229192163363),\n\tKQU(  152558080671135627), KQU(15424900540842670088),\n\tKQU(13229630297130024108), KQU(17530268788245718717),\n\tKQU(16675633913065714144), KQU( 3158912717897568068),\n\tKQU(15399132185380087288), KQU( 7401418744515677872),\n\tKQU(13135412922344398535), KQU( 6385314346100509511),\n\tKQU(13962867001134161139), KQU(10272780155442671999),\n\tKQU(12894856086597769142), KQU(13340877795287554994),\n\tKQU(12913630602094607396), KQU(12543167911119793857),\n\tKQU(17343570372251873096), KQU(10959487764494150545),\n\tKQU( 6966737953093821128), KQU(13780699135496988601),\n\tKQU( 4405070719380142046), KQU(14923788365607284982),\n\tKQU( 2869487678905148380), KQU( 6416272754197188403),\n\tKQU(15017380475943612591), KQU( 1995636220918429487),\n\tKQU( 3402016804620122716), KQU(15800188663407057080),\n\tKQU(11362369990390932882), KQU(15262183501637986147),\n\tKQU(10239175385387371494), KQU( 9352042420365748334),\n\tKQU( 1682457034285119875), KQU( 1724710651376289644),\n\tKQU( 2038157098893817966), KQU( 9897825558324608773),\n\tKQU( 1477666236519164736), KQU(16835397314511233640),\n\tKQU(10370866327005346508), KQU(10157504370660621982),\n\tKQU(12113904045335882069), KQU(13326444439742783008),\n\tKQU(11302769043000765804), KQU(13594979923955228484),\n\tKQU(11779351762613475968), KQU( 3786101619539298383),\n\tKQU( 8021122969180846063), KQU(15745904401162500495),\n\tKQU(10762168465993897267), KQU(13552058957896319026),\n\tKQU(11200228655252462013), KQU( 5035370357337441226),\n\tKQU( 7593918984545500013), KQU( 5418554918361528700),\n\tKQU( 4858270799405446371), KQU( 9974659566876282544),\n\tKQU(18227595922273957859), KQU( 2772778443635656220),\n\tKQU(14285143053182085385), KQU( 9939700992429600469),\n\tKQU(12756185904545598068), KQU( 2020783375367345262),\n\tKQU(   57026775058331227), KQU(  950827867930065454),\n\tKQU( 6602279670145371217), KQU( 2291171535443566929),\n\tKQU( 5832380724425010313), KQU( 1220343904715982285),\n\tKQU(17045542598598037633), KQU(15460481779702820971),\n\tKQU(13948388779949365130), KQU(13975040175430829518),\n\tKQU(17477538238425541763), KQU(11104663041851745725),\n\tKQU(15860992957141157587), KQU(14529434633012950138),\n\tKQU( 2504838019075394203), KQU( 7512113882611121886),\n\tKQU( 4859973559980886617), KQU( 1258601555703250219),\n\tKQU(15594548157514316394), KQU( 4516730171963773048),\n\tKQU(11380103193905031983), KQU( 6809282239982353344),\n\tKQU(18045256930420065002), KQU( 2453702683108791859),\n\tKQU(  977214582986981460), KQU( 2006410402232713466),\n\tKQU( 6192236267216378358), KQU( 3429468402195675253),\n\tKQU(18146933153017348921), KQU(17369978576367231139),\n\tKQU( 1246940717230386603), KQU(11335758870083327110),\n\tKQU(14166488801730353682), KQU( 9008573127269635732),\n\tKQU(10776025389820643815), KQU(15087605441903942962),\n\tKQU( 1359542462712147922), KQU(13898874411226454206),\n\tKQU(17911176066536804411), KQU( 9435590428600085274),\n\tKQU(  294488509967864007), KQU( 8890111397567922046),\n\tKQU( 7987823476034328778), KQU(13263827582440967651),\n\tKQU( 7503774813106751573), KQU(14974747296185646837),\n\tKQU( 8504765037032103375), KQU(17340303357444536213),\n\tKQU( 7704610912964485743), KQU( 8107533670327205061),\n\tKQU( 9062969835083315985), KQU(16968963142126734184),\n\tKQU(12958041214190810180), KQU( 2720170147759570200),\n\tKQU( 2986358963942189566), KQU(14884226322219356580),\n\tKQU(  286224325144368520), KQU(11313800433154279797),\n\tKQU(18366849528439673248), KQU(17899725929482368789),\n\tKQU( 3730004284609106799), KQU( 1654474302052767205),\n\tKQU( 5006698007047077032), KQU( 8196893913601182838),\n\tKQU(15214541774425211640), KQU(17391346045606626073),\n\tKQU( 8369003584076969089), KQU( 3939046733368550293),\n\tKQU(10178639720308707785), KQU( 2180248669304388697),\n\tKQU(   62894391300126322), KQU( 9205708961736223191),\n\tKQU( 6837431058165360438), KQU( 3150743890848308214),\n\tKQU(17849330658111464583), KQU(12214815643135450865),\n\tKQU(13410713840519603402), KQU( 3200778126692046802),\n\tKQU(13354780043041779313), KQU(  800850022756886036),\n\tKQU(15660052933953067433), KQU( 6572823544154375676),\n\tKQU(11030281857015819266), KQU(12682241941471433835),\n\tKQU(11654136407300274693), KQU( 4517795492388641109),\n\tKQU( 9757017371504524244), KQU(17833043400781889277),\n\tKQU(12685085201747792227), KQU(10408057728835019573),\n\tKQU(   98370418513455221), KQU( 6732663555696848598),\n\tKQU(13248530959948529780), KQU( 3530441401230622826),\n\tKQU(18188251992895660615), KQU( 1847918354186383756),\n\tKQU( 1127392190402660921), KQU(11293734643143819463),\n\tKQU( 3015506344578682982), KQU(13852645444071153329),\n\tKQU( 2121359659091349142), KQU( 1294604376116677694),\n\tKQU( 5616576231286352318), KQU( 7112502442954235625),\n\tKQU(11676228199551561689), KQU(12925182803007305359),\n\tKQU( 7852375518160493082), KQU( 1136513130539296154),\n\tKQU( 5636923900916593195), KQU( 3221077517612607747),\n\tKQU(17784790465798152513), KQU( 3554210049056995938),\n\tKQU(17476839685878225874), KQU( 3206836372585575732),\n\tKQU( 2765333945644823430), KQU(10080070903718799528),\n\tKQU( 5412370818878286353), KQU( 9689685887726257728),\n\tKQU( 8236117509123533998), KQU( 1951139137165040214),\n\tKQU( 4492205209227980349), KQU(16541291230861602967),\n\tKQU( 1424371548301437940), KQU( 9117562079669206794),\n\tKQU(14374681563251691625), KQU(13873164030199921303),\n\tKQU( 6680317946770936731), KQU(15586334026918276214),\n\tKQU(10896213950976109802), KQU( 9506261949596413689),\n\tKQU( 9903949574308040616), KQU( 6038397344557204470),\n\tKQU(  174601465422373648), KQU(15946141191338238030),\n\tKQU(17142225620992044937), KQU( 7552030283784477064),\n\tKQU( 2947372384532947997), KQU(  510797021688197711),\n\tKQU( 4962499439249363461), KQU(   23770320158385357),\n\tKQU(  959774499105138124), KQU( 1468396011518788276),\n\tKQU( 2015698006852312308), KQU( 4149400718489980136),\n\tKQU( 5992916099522371188), KQU(10819182935265531076),\n\tKQU(16189787999192351131), KQU(  342833961790261950),\n\tKQU(12470830319550495336), KQU(18128495041912812501),\n\tKQU( 1193600899723524337), KQU( 9056793666590079770),\n\tKQU( 2154021227041669041), KQU( 4963570213951235735),\n\tKQU( 4865075960209211409), KQU( 2097724599039942963),\n\tKQU( 2024080278583179845), KQU(11527054549196576736),\n\tKQU(10650256084182390252), KQU( 4808408648695766755),\n\tKQU( 1642839215013788844), KQU(10607187948250398390),\n\tKQU( 7076868166085913508), KQU(  730522571106887032),\n\tKQU(12500579240208524895), KQU( 4484390097311355324),\n\tKQU(15145801330700623870), KQU( 8055827661392944028),\n\tKQU( 5865092976832712268), KQU(15159212508053625143),\n\tKQU( 3560964582876483341), KQU( 4070052741344438280),\n\tKQU( 6032585709886855634), KQU(15643262320904604873),\n\tKQU( 2565119772293371111), KQU(  318314293065348260),\n\tKQU(15047458749141511872), KQU( 7772788389811528730),\n\tKQU( 7081187494343801976), KQU( 6465136009467253947),\n\tKQU(10425940692543362069), KQU(  554608190318339115),\n\tKQU(14796699860302125214), KQU( 1638153134431111443),\n\tKQU(10336967447052276248), KQU( 8412308070396592958),\n\tKQU( 4004557277152051226), KQU( 8143598997278774834),\n\tKQU(16413323996508783221), KQU(13139418758033994949),\n\tKQU( 9772709138335006667), KQU( 2818167159287157659),\n\tKQU(17091740573832523669), KQU(14629199013130751608),\n\tKQU(18268322711500338185), KQU( 8290963415675493063),\n\tKQU( 8830864907452542588), KQU( 1614839084637494849),\n\tKQU(14855358500870422231), KQU( 3472996748392519937),\n\tKQU(15317151166268877716), KQU( 5825895018698400362),\n\tKQU(16730208429367544129), KQU(10481156578141202800),\n\tKQU( 4746166512382823750), KQU(12720876014472464998),\n\tKQU( 8825177124486735972), KQU(13733447296837467838),\n\tKQU( 6412293741681359625), KQU( 8313213138756135033),\n\tKQU(11421481194803712517), KQU( 7997007691544174032),\n\tKQU( 6812963847917605930), KQU( 9683091901227558641),\n\tKQU(14703594165860324713), KQU( 1775476144519618309),\n\tKQU( 2724283288516469519), KQU(  717642555185856868),\n\tKQU( 8736402192215092346), KQU(11878800336431381021),\n\tKQU( 4348816066017061293), KQU( 6115112756583631307),\n\tKQU( 9176597239667142976), KQU(12615622714894259204),\n\tKQU(10283406711301385987), KQU( 5111762509485379420),\n\tKQU( 3118290051198688449), KQU( 7345123071632232145),\n\tKQU( 9176423451688682359), KQU( 4843865456157868971),\n\tKQU(12008036363752566088), KQU(12058837181919397720),\n\tKQU( 2145073958457347366), KQU( 1526504881672818067),\n\tKQU( 3488830105567134848), KQU(13208362960674805143),\n\tKQU( 4077549672899572192), KQU( 7770995684693818365),\n\tKQU( 1398532341546313593), KQU(12711859908703927840),\n\tKQU( 1417561172594446813), KQU(17045191024194170604),\n\tKQU( 4101933177604931713), KQU(14708428834203480320),\n\tKQU(17447509264469407724), KQU(14314821973983434255),\n\tKQU(17990472271061617265), KQU( 5087756685841673942),\n\tKQU(12797820586893859939), KQU( 1778128952671092879),\n\tKQU( 3535918530508665898), KQU( 9035729701042481301),\n\tKQU(14808661568277079962), KQU(14587345077537747914),\n\tKQU(11920080002323122708), KQU( 6426515805197278753),\n\tKQU( 3295612216725984831), KQU(11040722532100876120),\n\tKQU(12305952936387598754), KQU(16097391899742004253),\n\tKQU( 4908537335606182208), KQU(12446674552196795504),\n\tKQU(16010497855816895177), KQU( 9194378874788615551),\n\tKQU( 3382957529567613384), KQU( 5154647600754974077),\n\tKQU( 9801822865328396141), KQU( 9023662173919288143),\n\tKQU(17623115353825147868), KQU( 8238115767443015816),\n\tKQU(15811444159859002560), KQU( 9085612528904059661),\n\tKQU( 6888601089398614254), KQU(  258252992894160189),\n\tKQU( 6704363880792428622), KQU( 6114966032147235763),\n\tKQU(11075393882690261875), KQU( 8797664238933620407),\n\tKQU( 5901892006476726920), KQU( 5309780159285518958),\n\tKQU(14940808387240817367), KQU(14642032021449656698),\n\tKQU( 9808256672068504139), KQU( 3670135111380607658),\n\tKQU(11211211097845960152), KQU( 1474304506716695808),\n\tKQU(15843166204506876239), KQU( 7661051252471780561),\n\tKQU(10170905502249418476), KQU( 7801416045582028589),\n\tKQU( 2763981484737053050), KQU( 9491377905499253054),\n\tKQU(16201395896336915095), KQU( 9256513756442782198),\n\tKQU( 5411283157972456034), KQU( 5059433122288321676),\n\tKQU( 4327408006721123357), KQU( 9278544078834433377),\n\tKQU( 7601527110882281612), KQU(11848295896975505251),\n\tKQU(12096998801094735560), KQU(14773480339823506413),\n\tKQU(15586227433895802149), KQU(12786541257830242872),\n\tKQU( 6904692985140503067), KQU( 5309011515263103959),\n\tKQU(12105257191179371066), KQU(14654380212442225037),\n\tKQU( 2556774974190695009), KQU( 4461297399927600261),\n\tKQU(14888225660915118646), KQU(14915459341148291824),\n\tKQU( 2738802166252327631), KQU( 6047155789239131512),\n\tKQU(12920545353217010338), KQU(10697617257007840205),\n\tKQU( 2751585253158203504), KQU(13252729159780047496),\n\tKQU(14700326134672815469), KQU(14082527904374600529),\n\tKQU(16852962273496542070), KQU(17446675504235853907),\n\tKQU(15019600398527572311), KQU(12312781346344081551),\n\tKQU(14524667935039810450), KQU( 5634005663377195738),\n\tKQU(11375574739525000569), KQU( 2423665396433260040),\n\tKQU( 5222836914796015410), KQU( 4397666386492647387),\n\tKQU( 4619294441691707638), KQU(  665088602354770716),\n\tKQU(13246495665281593610), KQU( 6564144270549729409),\n\tKQU(10223216188145661688), KQU( 3961556907299230585),\n\tKQU(11543262515492439914), KQU(16118031437285993790),\n\tKQU( 7143417964520166465), KQU(13295053515909486772),\n\tKQU(   40434666004899675), KQU(17127804194038347164),\n\tKQU( 8599165966560586269), KQU( 8214016749011284903),\n\tKQU(13725130352140465239), KQU( 5467254474431726291),\n\tKQU( 7748584297438219877), KQU(16933551114829772472),\n\tKQU( 2169618439506799400), KQU( 2169787627665113463),\n\tKQU(17314493571267943764), KQU(18053575102911354912),\n\tKQU(11928303275378476973), KQU(11593850925061715550),\n\tKQU(17782269923473589362), KQU( 3280235307704747039),\n\tKQU( 6145343578598685149), KQU(17080117031114086090),\n\tKQU(18066839902983594755), KQU( 6517508430331020706),\n\tKQU( 8092908893950411541), KQU(12558378233386153732),\n\tKQU( 4476532167973132976), KQU(16081642430367025016),\n\tKQU( 4233154094369139361), KQU( 8693630486693161027),\n\tKQU(11244959343027742285), KQU(12273503967768513508),\n\tKQU(14108978636385284876), KQU( 7242414665378826984),\n\tKQU( 6561316938846562432), KQU( 8601038474994665795),\n\tKQU(17532942353612365904), KQU(17940076637020912186),\n\tKQU( 7340260368823171304), KQU( 7061807613916067905),\n\tKQU(10561734935039519326), KQU(17990796503724650862),\n\tKQU( 6208732943911827159), KQU(  359077562804090617),\n\tKQU(14177751537784403113), KQU(10659599444915362902),\n\tKQU(15081727220615085833), KQU(13417573895659757486),\n\tKQU(15513842342017811524), KQU(11814141516204288231),\n\tKQU( 1827312513875101814), KQU( 2804611699894603103),\n\tKQU(17116500469975602763), KQU(12270191815211952087),\n\tKQU(12256358467786024988), KQU(18435021722453971267),\n\tKQU(  671330264390865618), KQU(  476504300460286050),\n\tKQU(16465470901027093441), KQU( 4047724406247136402),\n\tKQU( 1322305451411883346), KQU( 1388308688834322280),\n\tKQU( 7303989085269758176), KQU( 9323792664765233642),\n\tKQU( 4542762575316368936), KQU(17342696132794337618),\n\tKQU( 4588025054768498379), KQU(13415475057390330804),\n\tKQU(17880279491733405570), KQU(10610553400618620353),\n\tKQU( 3180842072658960139), KQU(13002966655454270120),\n\tKQU( 1665301181064982826), KQU( 7083673946791258979),\n\tKQU(  190522247122496820), KQU(17388280237250677740),\n\tKQU( 8430770379923642945), KQU(12987180971921668584),\n\tKQU( 2311086108365390642), KQU( 2870984383579822345),\n\tKQU(14014682609164653318), KQU(14467187293062251484),\n\tKQU(  192186361147413298), KQU(15171951713531796524),\n\tKQU( 9900305495015948728), KQU(17958004775615466344),\n\tKQU(14346380954498606514), KQU(18040047357617407096),\n\tKQU( 5035237584833424532), KQU(15089555460613972287),\n\tKQU( 4131411873749729831), KQU( 1329013581168250330),\n\tKQU(10095353333051193949), KQU(10749518561022462716),\n\tKQU( 9050611429810755847), KQU(15022028840236655649),\n\tKQU( 8775554279239748298), KQU(13105754025489230502),\n\tKQU(15471300118574167585), KQU(   89864764002355628),\n\tKQU( 8776416323420466637), KQU( 5280258630612040891),\n\tKQU( 2719174488591862912), KQU( 7599309137399661994),\n\tKQU(15012887256778039979), KQU(14062981725630928925),\n\tKQU(12038536286991689603), KQU( 7089756544681775245),\n\tKQU(10376661532744718039), KQU( 1265198725901533130),\n\tKQU(13807996727081142408), KQU( 2935019626765036403),\n\tKQU( 7651672460680700141), KQU( 3644093016200370795),\n\tKQU( 2840982578090080674), KQU(17956262740157449201),\n\tKQU(18267979450492880548), KQU(11799503659796848070),\n\tKQU( 9942537025669672388), KQU(11886606816406990297),\n\tKQU( 5488594946437447576), KQU( 7226714353282744302),\n\tKQU( 3784851653123877043), KQU(  878018453244803041),\n\tKQU(12110022586268616085), KQU(  734072179404675123),\n\tKQU(11869573627998248542), KQU(  469150421297783998),\n\tKQU(  260151124912803804), KQU(11639179410120968649),\n\tKQU( 9318165193840846253), KQU(12795671722734758075),\n\tKQU(15318410297267253933), KQU(  691524703570062620),\n\tKQU( 5837129010576994601), KQU(15045963859726941052),\n\tKQU( 5850056944932238169), KQU(12017434144750943807),\n\tKQU( 7447139064928956574), KQU( 3101711812658245019),\n\tKQU(16052940704474982954), KQU(18195745945986994042),\n\tKQU( 8932252132785575659), KQU(13390817488106794834),\n\tKQU(11582771836502517453), KQU( 4964411326683611686),\n\tKQU( 2195093981702694011), KQU(14145229538389675669),\n\tKQU(16459605532062271798), KQU(  866316924816482864),\n\tKQU( 4593041209937286377), KQU( 8415491391910972138),\n\tKQU( 4171236715600528969), KQU(16637569303336782889),\n\tKQU( 2002011073439212680), KQU(17695124661097601411),\n\tKQU( 4627687053598611702), KQU( 7895831936020190403),\n\tKQU( 8455951300917267802), KQU( 2923861649108534854),\n\tKQU( 8344557563927786255), KQU( 6408671940373352556),\n\tKQU(12210227354536675772), KQU(14294804157294222295),\n\tKQU(10103022425071085127), KQU(10092959489504123771),\n\tKQU( 6554774405376736268), KQU(12629917718410641774),\n\tKQU( 6260933257596067126), KQU( 2460827021439369673),\n\tKQU( 2541962996717103668), KQU(  597377203127351475),\n\tKQU( 5316984203117315309), KQU( 4811211393563241961),\n\tKQU(13119698597255811641), KQU( 8048691512862388981),\n\tKQU(10216818971194073842), KQU( 4612229970165291764),\n\tKQU(10000980798419974770), KQU( 6877640812402540687),\n\tKQU( 1488727563290436992), KQU( 2227774069895697318),\n\tKQU(11237754507523316593), KQU(13478948605382290972),\n\tKQU( 1963583846976858124), KQU( 5512309205269276457),\n\tKQU( 3972770164717652347), KQU( 3841751276198975037),\n\tKQU(10283343042181903117), KQU( 8564001259792872199),\n\tKQU(16472187244722489221), KQU( 8953493499268945921),\n\tKQU( 3518747340357279580), KQU( 4003157546223963073),\n\tKQU( 3270305958289814590), KQU( 3966704458129482496),\n\tKQU( 8122141865926661939), KQU(14627734748099506653),\n\tKQU(13064426990862560568), KQU( 2414079187889870829),\n\tKQU( 5378461209354225306), KQU(10841985740128255566),\n\tKQU(  538582442885401738), KQU( 7535089183482905946),\n\tKQU(16117559957598879095), KQU( 8477890721414539741),\n\tKQU( 1459127491209533386), KQU(17035126360733620462),\n\tKQU( 8517668552872379126), KQU(10292151468337355014),\n\tKQU(17081267732745344157), KQU(13751455337946087178),\n\tKQU(14026945459523832966), KQU( 6653278775061723516),\n\tKQU(10619085543856390441), KQU( 2196343631481122885),\n\tKQU(10045966074702826136), KQU(10082317330452718282),\n\tKQU( 5920859259504831242), KQU( 9951879073426540617),\n\tKQU( 7074696649151414158), KQU(15808193543879464318),\n\tKQU( 7385247772746953374), KQU( 3192003544283864292),\n\tKQU(18153684490917593847), KQU(12423498260668568905),\n\tKQU(10957758099756378169), KQU(11488762179911016040),\n\tKQU( 2099931186465333782), KQU(11180979581250294432),\n\tKQU( 8098916250668367933), KQU( 3529200436790763465),\n\tKQU(12988418908674681745), KQU( 6147567275954808580),\n\tKQU( 3207503344604030989), KQU(10761592604898615360),\n\tKQU(  229854861031893504), KQU( 8809853962667144291),\n\tKQU(13957364469005693860), KQU( 7634287665224495886),\n\tKQU(12353487366976556874), KQU( 1134423796317152034),\n\tKQU( 2088992471334107068), KQU( 7393372127190799698),\n\tKQU( 1845367839871058391), KQU(  207922563987322884),\n\tKQU(11960870813159944976), KQU(12182120053317317363),\n\tKQU(17307358132571709283), KQU(13871081155552824936),\n\tKQU(18304446751741566262), KQU( 7178705220184302849),\n\tKQU(10929605677758824425), KQU(16446976977835806844),\n\tKQU(13723874412159769044), KQU( 6942854352100915216),\n\tKQU( 1726308474365729390), KQU( 2150078766445323155),\n\tKQU(15345558947919656626), KQU(12145453828874527201),\n\tKQU( 2054448620739726849), KQU( 2740102003352628137),\n\tKQU(11294462163577610655), KQU(  756164283387413743),\n\tKQU(17841144758438810880), KQU(10802406021185415861),\n\tKQU( 8716455530476737846), KQU( 6321788834517649606),\n\tKQU(14681322910577468426), KQU(17330043563884336387),\n\tKQU(12701802180050071614), KQU(14695105111079727151),\n\tKQU( 5112098511654172830), KQU( 4957505496794139973),\n\tKQU( 8270979451952045982), KQU(12307685939199120969),\n\tKQU(12425799408953443032), KQU( 8376410143634796588),\n\tKQU(16621778679680060464), KQU( 3580497854566660073),\n\tKQU( 1122515747803382416), KQU(  857664980960597599),\n\tKQU( 6343640119895925918), KQU(12878473260854462891),\n\tKQU(10036813920765722626), KQU(14451335468363173812),\n\tKQU( 5476809692401102807), KQU(16442255173514366342),\n\tKQU(13060203194757167104), KQU(14354124071243177715),\n\tKQU(15961249405696125227), KQU(13703893649690872584),\n\tKQU(  363907326340340064), KQU( 6247455540491754842),\n\tKQU(12242249332757832361), KQU(  156065475679796717),\n\tKQU( 9351116235749732355), KQU( 4590350628677701405),\n\tKQU( 1671195940982350389), KQU(13501398458898451905),\n\tKQU( 6526341991225002255), KQU( 1689782913778157592),\n\tKQU( 7439222350869010334), KQU(13975150263226478308),\n\tKQU(11411961169932682710), KQU(17204271834833847277),\n\tKQU(  541534742544435367), KQU( 6591191931218949684),\n\tKQU( 2645454775478232486), KQU( 4322857481256485321),\n\tKQU( 8477416487553065110), KQU(12902505428548435048),\n\tKQU(  971445777981341415), KQU(14995104682744976712),\n\tKQU( 4243341648807158063), KQU( 8695061252721927661),\n\tKQU( 5028202003270177222), KQU( 2289257340915567840),\n\tKQU(13870416345121866007), KQU(13994481698072092233),\n\tKQU( 6912785400753196481), KQU( 2278309315841980139),\n\tKQU( 4329765449648304839), KQU( 5963108095785485298),\n\tKQU( 4880024847478722478), KQU(16015608779890240947),\n\tKQU( 1866679034261393544), KQU(  914821179919731519),\n\tKQU( 9643404035648760131), KQU( 2418114953615593915),\n\tKQU(  944756836073702374), KQU(15186388048737296834),\n\tKQU( 7723355336128442206), KQU( 7500747479679599691),\n\tKQU(18013961306453293634), KQU( 2315274808095756456),\n\tKQU(13655308255424029566), KQU(17203800273561677098),\n\tKQU( 1382158694422087756), KQU( 5090390250309588976),\n\tKQU(  517170818384213989), KQU( 1612709252627729621),\n\tKQU( 1330118955572449606), KQU(  300922478056709885),\n\tKQU(18115693291289091987), KQU(13491407109725238321),\n\tKQU(15293714633593827320), KQU( 5151539373053314504),\n\tKQU( 5951523243743139207), KQU(14459112015249527975),\n\tKQU( 5456113959000700739), KQU( 3877918438464873016),\n\tKQU(12534071654260163555), KQU(15871678376893555041),\n\tKQU(11005484805712025549), KQU(16353066973143374252),\n\tKQU( 4358331472063256685), KQU( 8268349332210859288),\n\tKQU(12485161590939658075), KQU(13955993592854471343),\n\tKQU( 5911446886848367039), KQU(14925834086813706974),\n\tKQU( 6590362597857994805), KQU( 1280544923533661875),\n\tKQU( 1637756018947988164), KQU( 4734090064512686329),\n\tKQU(16693705263131485912), KQU( 6834882340494360958),\n\tKQU( 8120732176159658505), KQU( 2244371958905329346),\n\tKQU(10447499707729734021), KQU( 7318742361446942194),\n\tKQU( 8032857516355555296), KQU(14023605983059313116),\n\tKQU( 1032336061815461376), KQU( 9840995337876562612),\n\tKQU( 9869256223029203587), KQU(12227975697177267636),\n\tKQU(12728115115844186033), KQU( 7752058479783205470),\n\tKQU(  729733219713393087), KQU(12954017801239007622)\n};\nstatic const uint64_t init_by_array_64_expected[] = {\n\tKQU( 2100341266307895239), KQU( 8344256300489757943),\n\tKQU(15687933285484243894), KQU( 8268620370277076319),\n\tKQU(12371852309826545459), KQU( 8800491541730110238),\n\tKQU(18113268950100835773), KQU( 2886823658884438119),\n\tKQU( 3293667307248180724), KQU( 9307928143300172731),\n\tKQU( 7688082017574293629), KQU(  900986224735166665),\n\tKQU( 9977972710722265039), KQU( 6008205004994830552),\n\tKQU(  546909104521689292), KQU( 7428471521869107594),\n\tKQU(14777563419314721179), KQU(16116143076567350053),\n\tKQU( 5322685342003142329), KQU( 4200427048445863473),\n\tKQU( 4693092150132559146), KQU(13671425863759338582),\n\tKQU( 6747117460737639916), KQU( 4732666080236551150),\n\tKQU( 5912839950611941263), KQU( 3903717554504704909),\n\tKQU( 2615667650256786818), KQU(10844129913887006352),\n\tKQU(13786467861810997820), KQU(14267853002994021570),\n\tKQU(13767807302847237439), KQU(16407963253707224617),\n\tKQU( 4802498363698583497), KQU( 2523802839317209764),\n\tKQU( 3822579397797475589), KQU( 8950320572212130610),\n\tKQU( 3745623504978342534), KQU(16092609066068482806),\n\tKQU( 9817016950274642398), KQU(10591660660323829098),\n\tKQU(11751606650792815920), KQU( 5122873818577122211),\n\tKQU(17209553764913936624), KQU( 6249057709284380343),\n\tKQU(15088791264695071830), KQU(15344673071709851930),\n\tKQU( 4345751415293646084), KQU( 2542865750703067928),\n\tKQU(13520525127852368784), KQU(18294188662880997241),\n\tKQU( 3871781938044881523), KQU( 2873487268122812184),\n\tKQU(15099676759482679005), KQU(15442599127239350490),\n\tKQU( 6311893274367710888), KQU( 3286118760484672933),\n\tKQU( 4146067961333542189), KQU(13303942567897208770),\n\tKQU( 8196013722255630418), KQU( 4437815439340979989),\n\tKQU(15433791533450605135), KQU( 4254828956815687049),\n\tKQU( 1310903207708286015), KQU(10529182764462398549),\n\tKQU(14900231311660638810), KQU( 9727017277104609793),\n\tKQU( 1821308310948199033), KQU(11628861435066772084),\n\tKQU( 9469019138491546924), KQU( 3145812670532604988),\n\tKQU( 9938468915045491919), KQU( 1562447430672662142),\n\tKQU(13963995266697989134), KQU( 3356884357625028695),\n\tKQU( 4499850304584309747), KQU( 8456825817023658122),\n\tKQU(10859039922814285279), KQU( 8099512337972526555),\n\tKQU(  348006375109672149), KQU(11919893998241688603),\n\tKQU( 1104199577402948826), KQU(16689191854356060289),\n\tKQU(10992552041730168078), KQU( 7243733172705465836),\n\tKQU( 5668075606180319560), KQU(18182847037333286970),\n\tKQU( 4290215357664631322), KQU( 4061414220791828613),\n\tKQU(13006291061652989604), KQU( 7140491178917128798),\n\tKQU(12703446217663283481), KQU( 5500220597564558267),\n\tKQU(10330551509971296358), KQU(15958554768648714492),\n\tKQU( 5174555954515360045), KQU( 1731318837687577735),\n\tKQU( 3557700801048354857), KQU(13764012341928616198),\n\tKQU(13115166194379119043), KQU( 7989321021560255519),\n\tKQU( 2103584280905877040), KQU( 9230788662155228488),\n\tKQU(16396629323325547654), KQU(  657926409811318051),\n\tKQU(15046700264391400727), KQU( 5120132858771880830),\n\tKQU( 7934160097989028561), KQU( 6963121488531976245),\n\tKQU(17412329602621742089), KQU(15144843053931774092),\n\tKQU(17204176651763054532), KQU(13166595387554065870),\n\tKQU( 8590377810513960213), KQU( 5834365135373991938),\n\tKQU( 7640913007182226243), KQU( 3479394703859418425),\n\tKQU(16402784452644521040), KQU( 4993979809687083980),\n\tKQU(13254522168097688865), KQU(15643659095244365219),\n\tKQU( 5881437660538424982), KQU(11174892200618987379),\n\tKQU(  254409966159711077), KQU(17158413043140549909),\n\tKQU( 3638048789290376272), KQU( 1376816930299489190),\n\tKQU( 4622462095217761923), KQU(15086407973010263515),\n\tKQU(13253971772784692238), KQU( 5270549043541649236),\n\tKQU(11182714186805411604), KQU(12283846437495577140),\n\tKQU( 5297647149908953219), KQU(10047451738316836654),\n\tKQU( 4938228100367874746), KQU(12328523025304077923),\n\tKQU( 3601049438595312361), KQU( 9313624118352733770),\n\tKQU(13322966086117661798), KQU(16660005705644029394),\n\tKQU(11337677526988872373), KQU(13869299102574417795),\n\tKQU(15642043183045645437), KQU( 3021755569085880019),\n\tKQU( 4979741767761188161), KQU(13679979092079279587),\n\tKQU( 3344685842861071743), KQU(13947960059899588104),\n\tKQU(  305806934293368007), KQU( 5749173929201650029),\n\tKQU(11123724852118844098), KQU(15128987688788879802),\n\tKQU(15251651211024665009), KQU( 7689925933816577776),\n\tKQU(16732804392695859449), KQU(17087345401014078468),\n\tKQU(14315108589159048871), KQU( 4820700266619778917),\n\tKQU(16709637539357958441), KQU( 4936227875177351374),\n\tKQU( 2137907697912987247), KQU(11628565601408395420),\n\tKQU( 2333250549241556786), KQU( 5711200379577778637),\n\tKQU( 5170680131529031729), KQU(12620392043061335164),\n\tKQU(   95363390101096078), KQU( 5487981914081709462),\n\tKQU( 1763109823981838620), KQU( 3395861271473224396),\n\tKQU( 1300496844282213595), KQU( 6894316212820232902),\n\tKQU(10673859651135576674), KQU( 5911839658857903252),\n\tKQU(17407110743387299102), KQU( 8257427154623140385),\n\tKQU(11389003026741800267), KQU( 4070043211095013717),\n\tKQU(11663806997145259025), KQU(15265598950648798210),\n\tKQU(  630585789434030934), KQU( 3524446529213587334),\n\tKQU( 7186424168495184211), KQU(10806585451386379021),\n\tKQU(11120017753500499273), KQU( 1586837651387701301),\n\tKQU(17530454400954415544), KQU( 9991670045077880430),\n\tKQU( 7550997268990730180), KQU( 8640249196597379304),\n\tKQU( 3522203892786893823), KQU(10401116549878854788),\n\tKQU(13690285544733124852), KQU( 8295785675455774586),\n\tKQU(15535716172155117603), KQU( 3112108583723722511),\n\tKQU(17633179955339271113), KQU(18154208056063759375),\n\tKQU( 1866409236285815666), KQU(13326075895396412882),\n\tKQU( 8756261842948020025), KQU( 6281852999868439131),\n\tKQU(15087653361275292858), KQU(10333923911152949397),\n\tKQU( 5265567645757408500), KQU(12728041843210352184),\n\tKQU( 6347959327507828759), KQU(  154112802625564758),\n\tKQU(18235228308679780218), KQU( 3253805274673352418),\n\tKQU( 4849171610689031197), KQU(17948529398340432518),\n\tKQU(13803510475637409167), KQU(13506570190409883095),\n\tKQU(15870801273282960805), KQU( 8451286481299170773),\n\tKQU( 9562190620034457541), KQU( 8518905387449138364),\n\tKQU(12681306401363385655), KQU( 3788073690559762558),\n\tKQU( 5256820289573487769), KQU( 2752021372314875467),\n\tKQU( 6354035166862520716), KQU( 4328956378309739069),\n\tKQU(  449087441228269600), KQU( 5533508742653090868),\n\tKQU( 1260389420404746988), KQU(18175394473289055097),\n\tKQU( 1535467109660399420), KQU( 8818894282874061442),\n\tKQU(12140873243824811213), KQU(15031386653823014946),\n\tKQU( 1286028221456149232), KQU( 6329608889367858784),\n\tKQU( 9419654354945132725), KQU( 6094576547061672379),\n\tKQU(17706217251847450255), KQU( 1733495073065878126),\n\tKQU(16918923754607552663), KQU( 8881949849954945044),\n\tKQU(12938977706896313891), KQU(14043628638299793407),\n\tKQU(18393874581723718233), KQU( 6886318534846892044),\n\tKQU(14577870878038334081), KQU(13541558383439414119),\n\tKQU(13570472158807588273), KQU(18300760537910283361),\n\tKQU(  818368572800609205), KQU( 1417000585112573219),\n\tKQU(12337533143867683655), KQU(12433180994702314480),\n\tKQU(  778190005829189083), KQU(13667356216206524711),\n\tKQU( 9866149895295225230), KQU(11043240490417111999),\n\tKQU( 1123933826541378598), KQU( 6469631933605123610),\n\tKQU(14508554074431980040), KQU(13918931242962026714),\n\tKQU( 2870785929342348285), KQU(14786362626740736974),\n\tKQU(13176680060902695786), KQU( 9591778613541679456),\n\tKQU( 9097662885117436706), KQU(  749262234240924947),\n\tKQU( 1944844067793307093), KQU( 4339214904577487742),\n\tKQU( 8009584152961946551), KQU(16073159501225501777),\n\tKQU( 3335870590499306217), KQU(17088312653151202847),\n\tKQU( 3108893142681931848), KQU(16636841767202792021),\n\tKQU(10423316431118400637), KQU( 8008357368674443506),\n\tKQU(11340015231914677875), KQU(17687896501594936090),\n\tKQU(15173627921763199958), KQU(  542569482243721959),\n\tKQU(15071714982769812975), KQU( 4466624872151386956),\n\tKQU( 1901780715602332461), KQU( 9822227742154351098),\n\tKQU( 1479332892928648780), KQU( 6981611948382474400),\n\tKQU( 7620824924456077376), KQU(14095973329429406782),\n\tKQU( 7902744005696185404), KQU(15830577219375036920),\n\tKQU(10287076667317764416), KQU(12334872764071724025),\n\tKQU( 4419302088133544331), KQU(14455842851266090520),\n\tKQU(12488077416504654222), KQU( 7953892017701886766),\n\tKQU( 6331484925529519007), KQU( 4902145853785030022),\n\tKQU(17010159216096443073), KQU(11945354668653886087),\n\tKQU(15112022728645230829), KQU(17363484484522986742),\n\tKQU( 4423497825896692887), KQU( 8155489510809067471),\n\tKQU(  258966605622576285), KQU( 5462958075742020534),\n\tKQU( 6763710214913276228), KQU( 2368935183451109054),\n\tKQU(14209506165246453811), KQU( 2646257040978514881),\n\tKQU( 3776001911922207672), KQU( 1419304601390147631),\n\tKQU(14987366598022458284), KQU( 3977770701065815721),\n\tKQU(  730820417451838898), KQU( 3982991703612885327),\n\tKQU( 2803544519671388477), KQU(17067667221114424649),\n\tKQU( 2922555119737867166), KQU( 1989477584121460932),\n\tKQU(15020387605892337354), KQU( 9293277796427533547),\n\tKQU(10722181424063557247), KQU(16704542332047511651),\n\tKQU( 5008286236142089514), KQU(16174732308747382540),\n\tKQU(17597019485798338402), KQU(13081745199110622093),\n\tKQU( 8850305883842258115), KQU(12723629125624589005),\n\tKQU( 8140566453402805978), KQU(15356684607680935061),\n\tKQU(14222190387342648650), KQU(11134610460665975178),\n\tKQU( 1259799058620984266), KQU(13281656268025610041),\n\tKQU(  298262561068153992), KQU(12277871700239212922),\n\tKQU(13911297774719779438), KQU(16556727962761474934),\n\tKQU(17903010316654728010), KQU( 9682617699648434744),\n\tKQU(14757681836838592850), KQU( 1327242446558524473),\n\tKQU(11126645098780572792), KQU( 1883602329313221774),\n\tKQU( 2543897783922776873), KQU(15029168513767772842),\n\tKQU(12710270651039129878), KQU(16118202956069604504),\n\tKQU(15010759372168680524), KQU( 2296827082251923948),\n\tKQU(10793729742623518101), KQU(13829764151845413046),\n\tKQU(17769301223184451213), KQU( 3118268169210783372),\n\tKQU(17626204544105123127), KQU( 7416718488974352644),\n\tKQU(10450751996212925994), KQU( 9352529519128770586),\n\tKQU(  259347569641110140), KQU( 8048588892269692697),\n\tKQU( 1774414152306494058), KQU(10669548347214355622),\n\tKQU(13061992253816795081), KQU(18432677803063861659),\n\tKQU( 8879191055593984333), KQU(12433753195199268041),\n\tKQU(14919392415439730602), KQU( 6612848378595332963),\n\tKQU( 6320986812036143628), KQU(10465592420226092859),\n\tKQU( 4196009278962570808), KQU( 3747816564473572224),\n\tKQU(17941203486133732898), KQU( 2350310037040505198),\n\tKQU( 5811779859134370113), KQU(10492109599506195126),\n\tKQU( 7699650690179541274), KQU( 1954338494306022961),\n\tKQU(14095816969027231152), KQU( 5841346919964852061),\n\tKQU(14945969510148214735), KQU( 3680200305887550992),\n\tKQU( 6218047466131695792), KQU( 8242165745175775096),\n\tKQU(11021371934053307357), KQU( 1265099502753169797),\n\tKQU( 4644347436111321718), KQU( 3609296916782832859),\n\tKQU( 8109807992218521571), KQU(18387884215648662020),\n\tKQU(14656324896296392902), KQU(17386819091238216751),\n\tKQU(17788300878582317152), KQU( 7919446259742399591),\n\tKQU( 4466613134576358004), KQU(12928181023667938509),\n\tKQU(13147446154454932030), KQU(16552129038252734620),\n\tKQU( 8395299403738822450), KQU(11313817655275361164),\n\tKQU(  434258809499511718), KQU( 2074882104954788676),\n\tKQU( 7929892178759395518), KQU( 9006461629105745388),\n\tKQU( 5176475650000323086), KQU(11128357033468341069),\n\tKQU(12026158851559118955), KQU(14699716249471156500),\n\tKQU(  448982497120206757), KQU( 4156475356685519900),\n\tKQU( 6063816103417215727), KQU(10073289387954971479),\n\tKQU( 8174466846138590962), KQU( 2675777452363449006),\n\tKQU( 9090685420572474281), KQU( 6659652652765562060),\n\tKQU(12923120304018106621), KQU(11117480560334526775),\n\tKQU(  937910473424587511), KQU( 1838692113502346645),\n\tKQU(11133914074648726180), KQU( 7922600945143884053),\n\tKQU(13435287702700959550), KQU( 5287964921251123332),\n\tKQU(11354875374575318947), KQU(17955724760748238133),\n\tKQU(13728617396297106512), KQU( 4107449660118101255),\n\tKQU( 1210269794886589623), KQU(11408687205733456282),\n\tKQU( 4538354710392677887), KQU(13566803319341319267),\n\tKQU(17870798107734050771), KQU( 3354318982568089135),\n\tKQU( 9034450839405133651), KQU(13087431795753424314),\n\tKQU(  950333102820688239), KQU( 1968360654535604116),\n\tKQU(16840551645563314995), KQU( 8867501803892924995),\n\tKQU(11395388644490626845), KQU( 1529815836300732204),\n\tKQU(13330848522996608842), KQU( 1813432878817504265),\n\tKQU( 2336867432693429560), KQU(15192805445973385902),\n\tKQU( 2528593071076407877), KQU(  128459777936689248),\n\tKQU( 9976345382867214866), KQU( 6208885766767996043),\n\tKQU(14982349522273141706), KQU( 3099654362410737822),\n\tKQU(13776700761947297661), KQU( 8806185470684925550),\n\tKQU( 8151717890410585321), KQU(  640860591588072925),\n\tKQU(14592096303937307465), KQU( 9056472419613564846),\n\tKQU(14861544647742266352), KQU(12703771500398470216),\n\tKQU( 3142372800384138465), KQU( 6201105606917248196),\n\tKQU(18337516409359270184), KQU(15042268695665115339),\n\tKQU(15188246541383283846), KQU(12800028693090114519),\n\tKQU( 5992859621101493472), KQU(18278043971816803521),\n\tKQU( 9002773075219424560), KQU( 7325707116943598353),\n\tKQU( 7930571931248040822), KQU( 5645275869617023448),\n\tKQU( 7266107455295958487), KQU( 4363664528273524411),\n\tKQU(14313875763787479809), KQU(17059695613553486802),\n\tKQU( 9247761425889940932), KQU(13704726459237593128),\n\tKQU( 2701312427328909832), KQU(17235532008287243115),\n\tKQU(14093147761491729538), KQU( 6247352273768386516),\n\tKQU( 8268710048153268415), KQU( 7985295214477182083),\n\tKQU(15624495190888896807), KQU( 3772753430045262788),\n\tKQU( 9133991620474991698), KQU( 5665791943316256028),\n\tKQU( 7551996832462193473), KQU(13163729206798953877),\n\tKQU( 9263532074153846374), KQU( 1015460703698618353),\n\tKQU(17929874696989519390), KQU(18257884721466153847),\n\tKQU(16271867543011222991), KQU( 3905971519021791941),\n\tKQU(16814488397137052085), KQU( 1321197685504621613),\n\tKQU( 2870359191894002181), KQU(14317282970323395450),\n\tKQU(13663920845511074366), KQU( 2052463995796539594),\n\tKQU(14126345686431444337), KQU( 1727572121947022534),\n\tKQU(17793552254485594241), KQU( 6738857418849205750),\n\tKQU( 1282987123157442952), KQU(16655480021581159251),\n\tKQU( 6784587032080183866), KQU(14726758805359965162),\n\tKQU( 7577995933961987349), KQU(12539609320311114036),\n\tKQU(10789773033385439494), KQU( 8517001497411158227),\n\tKQU(10075543932136339710), KQU(14838152340938811081),\n\tKQU( 9560840631794044194), KQU(17445736541454117475),\n\tKQU(10633026464336393186), KQU(15705729708242246293),\n\tKQU( 1117517596891411098), KQU( 4305657943415886942),\n\tKQU( 4948856840533979263), KQU(16071681989041789593),\n\tKQU(13723031429272486527), KQU( 7639567622306509462),\n\tKQU(12670424537483090390), KQU( 9715223453097197134),\n\tKQU( 5457173389992686394), KQU(  289857129276135145),\n\tKQU(17048610270521972512), KQU(  692768013309835485),\n\tKQU(14823232360546632057), KQU(18218002361317895936),\n\tKQU( 3281724260212650204), KQU(16453957266549513795),\n\tKQU( 8592711109774511881), KQU(  929825123473369579),\n\tKQU(15966784769764367791), KQU( 9627344291450607588),\n\tKQU(10849555504977813287), KQU( 9234566913936339275),\n\tKQU( 6413807690366911210), KQU(10862389016184219267),\n\tKQU(13842504799335374048), KQU( 1531994113376881174),\n\tKQU( 2081314867544364459), KQU(16430628791616959932),\n\tKQU( 8314714038654394368), KQU( 9155473892098431813),\n\tKQU(12577843786670475704), KQU( 4399161106452401017),\n\tKQU( 1668083091682623186), KQU( 1741383777203714216),\n\tKQU( 2162597285417794374), KQU(15841980159165218736),\n\tKQU( 1971354603551467079), KQU( 1206714764913205968),\n\tKQU( 4790860439591272330), KQU(14699375615594055799),\n\tKQU( 8374423871657449988), KQU(10950685736472937738),\n\tKQU(  697344331343267176), KQU(10084998763118059810),\n\tKQU(12897369539795983124), KQU(12351260292144383605),\n\tKQU( 1268810970176811234), KQU( 7406287800414582768),\n\tKQU(  516169557043807831), KQU( 5077568278710520380),\n\tKQU( 3828791738309039304), KQU( 7721974069946943610),\n\tKQU( 3534670260981096460), KQU( 4865792189600584891),\n\tKQU(16892578493734337298), KQU( 9161499464278042590),\n\tKQU(11976149624067055931), KQU(13219479887277343990),\n\tKQU(14161556738111500680), KQU(14670715255011223056),\n\tKQU( 4671205678403576558), KQU(12633022931454259781),\n\tKQU(14821376219869187646), KQU(  751181776484317028),\n\tKQU( 2192211308839047070), KQU(11787306362361245189),\n\tKQU(10672375120744095707), KQU( 4601972328345244467),\n\tKQU(15457217788831125879), KQU( 8464345256775460809),\n\tKQU(10191938789487159478), KQU( 6184348739615197613),\n\tKQU(11425436778806882100), KQU( 2739227089124319793),\n\tKQU(  461464518456000551), KQU( 4689850170029177442),\n\tKQU( 6120307814374078625), KQU(11153579230681708671),\n\tKQU( 7891721473905347926), KQU(10281646937824872400),\n\tKQU( 3026099648191332248), KQU( 8666750296953273818),\n\tKQU(14978499698844363232), KQU(13303395102890132065),\n\tKQU( 8182358205292864080), KQU(10560547713972971291),\n\tKQU(11981635489418959093), KQU( 3134621354935288409),\n\tKQU(11580681977404383968), KQU(14205530317404088650),\n\tKQU( 5997789011854923157), KQU(13659151593432238041),\n\tKQU(11664332114338865086), KQU( 7490351383220929386),\n\tKQU( 7189290499881530378), KQU(15039262734271020220),\n\tKQU( 2057217285976980055), KQU(  555570804905355739),\n\tKQU(11235311968348555110), KQU(13824557146269603217),\n\tKQU(16906788840653099693), KQU( 7222878245455661677),\n\tKQU( 5245139444332423756), KQU( 4723748462805674292),\n\tKQU(12216509815698568612), KQU(17402362976648951187),\n\tKQU(17389614836810366768), KQU( 4880936484146667711),\n\tKQU( 9085007839292639880), KQU(13837353458498535449),\n\tKQU(11914419854360366677), KQU(16595890135313864103),\n\tKQU( 6313969847197627222), KQU(18296909792163910431),\n\tKQU(10041780113382084042), KQU( 2499478551172884794),\n\tKQU(11057894246241189489), KQU( 9742243032389068555),\n\tKQU(12838934582673196228), KQU(13437023235248490367),\n\tKQU(13372420669446163240), KQU( 6752564244716909224),\n\tKQU( 7157333073400313737), KQU(12230281516370654308),\n\tKQU( 1182884552219419117), KQU( 2955125381312499218),\n\tKQU(10308827097079443249), KQU( 1337648572986534958),\n\tKQU(16378788590020343939), KQU(  108619126514420935),\n\tKQU( 3990981009621629188), KQU( 5460953070230946410),\n\tKQU( 9703328329366531883), KQU(13166631489188077236),\n\tKQU( 1104768831213675170), KQU( 3447930458553877908),\n\tKQU( 8067172487769945676), KQU( 5445802098190775347),\n\tKQU( 3244840981648973873), KQU(17314668322981950060),\n\tKQU( 5006812527827763807), KQU(18158695070225526260),\n\tKQU( 2824536478852417853), KQU(13974775809127519886),\n\tKQU( 9814362769074067392), KQU(17276205156374862128),\n\tKQU(11361680725379306967), KQU( 3422581970382012542),\n\tKQU(11003189603753241266), KQU(11194292945277862261),\n\tKQU( 6839623313908521348), KQU(11935326462707324634),\n\tKQU( 1611456788685878444), KQU(13112620989475558907),\n\tKQU(  517659108904450427), KQU(13558114318574407624),\n\tKQU(15699089742731633077), KQU( 4988979278862685458),\n\tKQU( 8111373583056521297), KQU( 3891258746615399627),\n\tKQU( 8137298251469718086), KQU(12748663295624701649),\n\tKQU( 4389835683495292062), KQU( 5775217872128831729),\n\tKQU( 9462091896405534927), KQU( 8498124108820263989),\n\tKQU( 8059131278842839525), KQU(10503167994254090892),\n\tKQU(11613153541070396656), KQU(18069248738504647790),\n\tKQU(  570657419109768508), KQU( 3950574167771159665),\n\tKQU( 5514655599604313077), KQU( 2908460854428484165),\n\tKQU(10777722615935663114), KQU(12007363304839279486),\n\tKQU( 9800646187569484767), KQU( 8795423564889864287),\n\tKQU(14257396680131028419), KQU( 6405465117315096498),\n\tKQU( 7939411072208774878), KQU(17577572378528990006),\n\tKQU(14785873806715994850), KQU(16770572680854747390),\n\tKQU(18127549474419396481), KQU(11637013449455757750),\n\tKQU(14371851933996761086), KQU( 3601181063650110280),\n\tKQU( 4126442845019316144), KQU(10198287239244320669),\n\tKQU(18000169628555379659), KQU(18392482400739978269),\n\tKQU( 6219919037686919957), KQU( 3610085377719446052),\n\tKQU( 2513925039981776336), KQU(16679413537926716955),\n\tKQU(12903302131714909434), KQU( 5581145789762985009),\n\tKQU(12325955044293303233), KQU(17216111180742141204),\n\tKQU( 6321919595276545740), KQU( 3507521147216174501),\n\tKQU( 9659194593319481840), KQU(11473976005975358326),\n\tKQU(14742730101435987026), KQU(  492845897709954780),\n\tKQU(16976371186162599676), KQU(17712703422837648655),\n\tKQU( 9881254778587061697), KQU( 8413223156302299551),\n\tKQU( 1563841828254089168), KQU( 9996032758786671975),\n\tKQU(  138877700583772667), KQU(13003043368574995989),\n\tKQU( 4390573668650456587), KQU( 8610287390568126755),\n\tKQU(15126904974266642199), KQU( 6703637238986057662),\n\tKQU( 2873075592956810157), KQU( 6035080933946049418),\n\tKQU(13382846581202353014), KQU( 7303971031814642463),\n\tKQU(18418024405307444267), KQU( 5847096731675404647),\n\tKQU( 4035880699639842500), KQU(11525348625112218478),\n\tKQU( 3041162365459574102), KQU( 2604734487727986558),\n\tKQU(15526341771636983145), KQU(14556052310697370254),\n\tKQU(12997787077930808155), KQU( 9601806501755554499),\n\tKQU(11349677952521423389), KQU(14956777807644899350),\n\tKQU(16559736957742852721), KQU(12360828274778140726),\n\tKQU( 6685373272009662513), KQU(16932258748055324130),\n\tKQU(15918051131954158508), KQU( 1692312913140790144),\n\tKQU(  546653826801637367), KQU( 5341587076045986652),\n\tKQU(14975057236342585662), KQU(12374976357340622412),\n\tKQU(10328833995181940552), KQU(12831807101710443149),\n\tKQU(10548514914382545716), KQU( 2217806727199715993),\n\tKQU(12627067369242845138), KQU( 4598965364035438158),\n\tKQU(  150923352751318171), KQU(14274109544442257283),\n\tKQU( 4696661475093863031), KQU( 1505764114384654516),\n\tKQU(10699185831891495147), KQU( 2392353847713620519),\n\tKQU( 3652870166711788383), KQU( 8640653276221911108),\n\tKQU( 3894077592275889704), KQU( 4918592872135964845),\n\tKQU(16379121273281400789), KQU(12058465483591683656),\n\tKQU(11250106829302924945), KQU( 1147537556296983005),\n\tKQU( 6376342756004613268), KQU(14967128191709280506),\n\tKQU(18007449949790627628), KQU( 9497178279316537841),\n\tKQU( 7920174844809394893), KQU(10037752595255719907),\n\tKQU(15875342784985217697), KQU(15311615921712850696),\n\tKQU( 9552902652110992950), KQU(14054979450099721140),\n\tKQU( 5998709773566417349), KQU(18027910339276320187),\n\tKQU( 8223099053868585554), KQU( 7842270354824999767),\n\tKQU( 4896315688770080292), KQU(12969320296569787895),\n\tKQU( 2674321489185759961), KQU( 4053615936864718439),\n\tKQU(11349775270588617578), KQU( 4743019256284553975),\n\tKQU( 5602100217469723769), KQU(14398995691411527813),\n\tKQU( 7412170493796825470), KQU(  836262406131744846),\n\tKQU( 8231086633845153022), KQU( 5161377920438552287),\n\tKQU( 8828731196169924949), KQU(16211142246465502680),\n\tKQU( 3307990879253687818), KQU( 5193405406899782022),\n\tKQU( 8510842117467566693), KQU( 6070955181022405365),\n\tKQU(14482950231361409799), KQU(12585159371331138077),\n\tKQU( 3511537678933588148), KQU( 2041849474531116417),\n\tKQU(10944936685095345792), KQU(18303116923079107729),\n\tKQU( 2720566371239725320), KQU( 4958672473562397622),\n\tKQU( 3032326668253243412), KQU(13689418691726908338),\n\tKQU( 1895205511728843996), KQU( 8146303515271990527),\n\tKQU(16507343500056113480), KQU(  473996939105902919),\n\tKQU( 9897686885246881481), KQU(14606433762712790575),\n\tKQU( 6732796251605566368), KQU( 1399778120855368916),\n\tKQU(  935023885182833777), KQU(16066282816186753477),\n\tKQU( 7291270991820612055), KQU(17530230393129853844),\n\tKQU(10223493623477451366), KQU(15841725630495676683),\n\tKQU(17379567246435515824), KQU( 8588251429375561971),\n\tKQU(18339511210887206423), KQU(17349587430725976100),\n\tKQU(12244876521394838088), KQU( 6382187714147161259),\n\tKQU(12335807181848950831), KQU(16948885622305460665),\n\tKQU(13755097796371520506), KQU(14806740373324947801),\n\tKQU( 4828699633859287703), KQU( 8209879281452301604),\n\tKQU(12435716669553736437), KQU(13970976859588452131),\n\tKQU( 6233960842566773148), KQU(12507096267900505759),\n\tKQU( 1198713114381279421), KQU(14989862731124149015),\n\tKQU(15932189508707978949), KQU( 2526406641432708722),\n\tKQU(   29187427817271982), KQU( 1499802773054556353),\n\tKQU(10816638187021897173), KQU( 5436139270839738132),\n\tKQU( 6659882287036010082), KQU( 2154048955317173697),\n\tKQU(10887317019333757642), KQU(16281091802634424955),\n\tKQU(10754549879915384901), KQU(10760611745769249815),\n\tKQU( 2161505946972504002), KQU( 5243132808986265107),\n\tKQU(10129852179873415416), KQU(  710339480008649081),\n\tKQU( 7802129453068808528), KQU(17967213567178907213),\n\tKQU(15730859124668605599), KQU(13058356168962376502),\n\tKQU( 3701224985413645909), KQU(14464065869149109264),\n\tKQU( 9959272418844311646), KQU(10157426099515958752),\n\tKQU(14013736814538268528), KQU(17797456992065653951),\n\tKQU(17418878140257344806), KQU(15457429073540561521),\n\tKQU( 2184426881360949378), KQU( 2062193041154712416),\n\tKQU( 8553463347406931661), KQU( 4913057625202871854),\n\tKQU( 2668943682126618425), KQU(17064444737891172288),\n\tKQU( 4997115903913298637), KQU(12019402608892327416),\n\tKQU(17603584559765897352), KQU(11367529582073647975),\n\tKQU( 8211476043518436050), KQU( 8676849804070323674),\n\tKQU(18431829230394475730), KQU(10490177861361247904),\n\tKQU( 9508720602025651349), KQU( 7409627448555722700),\n\tKQU( 5804047018862729008), KQU(11943858176893142594),\n\tKQU(11908095418933847092), KQU( 5415449345715887652),\n\tKQU( 1554022699166156407), KQU( 9073322106406017161),\n\tKQU( 7080630967969047082), KQU(18049736940860732943),\n\tKQU(12748714242594196794), KQU( 1226992415735156741),\n\tKQU(17900981019609531193), KQU(11720739744008710999),\n\tKQU( 3006400683394775434), KQU(11347974011751996028),\n\tKQU( 3316999628257954608), KQU( 8384484563557639101),\n\tKQU(18117794685961729767), KQU( 1900145025596618194),\n\tKQU(17459527840632892676), KQU( 5634784101865710994),\n\tKQU( 7918619300292897158), KQU( 3146577625026301350),\n\tKQU( 9955212856499068767), KQU( 1873995843681746975),\n\tKQU( 1561487759967972194), KQU( 8322718804375878474),\n\tKQU(11300284215327028366), KQU( 4667391032508998982),\n\tKQU( 9820104494306625580), KQU(17922397968599970610),\n\tKQU( 1784690461886786712), KQU(14940365084341346821),\n\tKQU( 5348719575594186181), KQU(10720419084507855261),\n\tKQU(14210394354145143274), KQU( 2426468692164000131),\n\tKQU(16271062114607059202), KQU(14851904092357070247),\n\tKQU( 6524493015693121897), KQU( 9825473835127138531),\n\tKQU(14222500616268569578), KQU(15521484052007487468),\n\tKQU(14462579404124614699), KQU(11012375590820665520),\n\tKQU(11625327350536084927), KQU(14452017765243785417),\n\tKQU( 9989342263518766305), KQU( 3640105471101803790),\n\tKQU( 4749866455897513242), KQU(13963064946736312044),\n\tKQU(10007416591973223791), KQU(18314132234717431115),\n\tKQU( 3286596588617483450), KQU( 7726163455370818765),\n\tKQU( 7575454721115379328), KQU( 5308331576437663422),\n\tKQU(18288821894903530934), KQU( 8028405805410554106),\n\tKQU(15744019832103296628), KQU(  149765559630932100),\n\tKQU( 6137705557200071977), KQU(14513416315434803615),\n\tKQU(11665702820128984473), KQU(  218926670505601386),\n\tKQU( 6868675028717769519), KQU(15282016569441512302),\n\tKQU( 5707000497782960236), KQU( 6671120586555079567),\n\tKQU( 2194098052618985448), KQU(16849577895477330978),\n\tKQU(12957148471017466283), KQU( 1997805535404859393),\n\tKQU( 1180721060263860490), KQU(13206391310193756958),\n\tKQU(12980208674461861797), KQU( 3825967775058875366),\n\tKQU(17543433670782042631), KQU( 1518339070120322730),\n\tKQU(16344584340890991669), KQU( 2611327165318529819),\n\tKQU(11265022723283422529), KQU( 4001552800373196817),\n\tKQU(14509595890079346161), KQU( 3528717165416234562),\n\tKQU(18153222571501914072), KQU( 9387182977209744425),\n\tKQU(10064342315985580021), KQU(11373678413215253977),\n\tKQU( 2308457853228798099), KQU( 9729042942839545302),\n\tKQU( 7833785471140127746), KQU( 6351049900319844436),\n\tKQU(14454610627133496067), KQU(12533175683634819111),\n\tKQU(15570163926716513029), KQU(13356980519185762498)\n};\n\nTEST_BEGIN(test_gen_rand_32)\n{\n\tuint32_t array32[BLOCK_SIZE] JEMALLOC_ATTR(aligned(16));\n\tuint32_t array32_2[BLOCK_SIZE] JEMALLOC_ATTR(aligned(16));\n\tint i;\n\tuint32_t r32;\n\tsfmt_t *ctx;\n\n\tassert_d_le(get_min_array_size32(), BLOCK_SIZE,\n\t    \"Array size too small\");\n\tctx = init_gen_rand(1234);\n\tfill_array32(ctx, array32, BLOCK_SIZE);\n\tfill_array32(ctx, array32_2, BLOCK_SIZE);\n\tfini_gen_rand(ctx);\n\n\tctx = init_gen_rand(1234);\n\tfor (i = 0; i < BLOCK_SIZE; i++) {\n\t\tif (i < COUNT_1) {\n\t\t\tassert_u32_eq(array32[i], init_gen_rand_32_expected[i],\n\t\t\t    \"Output mismatch for i=%d\", i);\n\t\t}\n\t\tr32 = gen_rand32(ctx);\n\t\tassert_u32_eq(r32, array32[i],\n\t\t    \"Mismatch at array32[%d]=%x, gen=%x\", i, array32[i], r32);\n\t}\n\tfor (i = 0; i < COUNT_2; i++) {\n\t\tr32 = gen_rand32(ctx);\n\t\tassert_u32_eq(r32, array32_2[i],\n\t\t    \"Mismatch at array32_2[%d]=%x, gen=%x\", i, array32_2[i],\n\t\t    r32);\n\t}\n\tfini_gen_rand(ctx);\n}\nTEST_END\n\nTEST_BEGIN(test_by_array_32)\n{\n\tuint32_t array32[BLOCK_SIZE] JEMALLOC_ATTR(aligned(16));\n\tuint32_t array32_2[BLOCK_SIZE] JEMALLOC_ATTR(aligned(16));\n\tint i;\n\tuint32_t ini[4] = {0x1234, 0x5678, 0x9abc, 0xdef0};\n\tuint32_t r32;\n\tsfmt_t *ctx;\n\n\tassert_d_le(get_min_array_size32(), BLOCK_SIZE,\n\t    \"Array size too small\");\n\tctx = init_by_array(ini, 4);\n\tfill_array32(ctx, array32, BLOCK_SIZE);\n\tfill_array32(ctx, array32_2, BLOCK_SIZE);\n\tfini_gen_rand(ctx);\n\n\tctx = init_by_array(ini, 4);\n\tfor (i = 0; i < BLOCK_SIZE; i++) {\n\t\tif (i < COUNT_1) {\n\t\t\tassert_u32_eq(array32[i], init_by_array_32_expected[i],\n\t\t\t    \"Output mismatch for i=%d\", i);\n\t\t}\n\t\tr32 = gen_rand32(ctx);\n\t\tassert_u32_eq(r32, array32[i],\n\t\t    \"Mismatch at array32[%d]=%x, gen=%x\", i, array32[i], r32);\n\t}\n\tfor (i = 0; i < COUNT_2; i++) {\n\t\tr32 = gen_rand32(ctx);\n\t\tassert_u32_eq(r32, array32_2[i],\n\t\t    \"Mismatch at array32_2[%d]=%x, gen=%x\", i, array32_2[i],\n\t\t    r32);\n\t}\n\tfini_gen_rand(ctx);\n}\nTEST_END\n\nTEST_BEGIN(test_gen_rand_64)\n{\n\tuint64_t array64[BLOCK_SIZE64] JEMALLOC_ATTR(aligned(16));\n\tuint64_t array64_2[BLOCK_SIZE64] JEMALLOC_ATTR(aligned(16));\n\tint i;\n\tuint64_t r;\n\tsfmt_t *ctx;\n\n\tassert_d_le(get_min_array_size64(), BLOCK_SIZE64,\n\t    \"Array size too small\");\n\tctx = init_gen_rand(4321);\n\tfill_array64(ctx, array64, BLOCK_SIZE64);\n\tfill_array64(ctx, array64_2, BLOCK_SIZE64);\n\tfini_gen_rand(ctx);\n\n\tctx = init_gen_rand(4321);\n\tfor (i = 0; i < BLOCK_SIZE64; i++) {\n\t\tif (i < COUNT_1) {\n\t\t\tassert_u64_eq(array64[i], init_gen_rand_64_expected[i],\n\t\t\t    \"Output mismatch for i=%d\", i);\n\t\t}\n\t\tr = gen_rand64(ctx);\n\t\tassert_u64_eq(r, array64[i],\n\t\t    \"Mismatch at array64[%d]=%\"FMTx64\", gen=%\"FMTx64, i,\n\t\t    array64[i], r);\n\t}\n\tfor (i = 0; i < COUNT_2; i++) {\n\t\tr = gen_rand64(ctx);\n\t\tassert_u64_eq(r, array64_2[i],\n\t\t    \"Mismatch at array64_2[%d]=%\"FMTx64\" gen=%\"FMTx64\"\", i,\n\t\t    array64_2[i], r);\n\t}\n\tfini_gen_rand(ctx);\n}\nTEST_END\n\nTEST_BEGIN(test_by_array_64)\n{\n\tuint64_t array64[BLOCK_SIZE64] JEMALLOC_ATTR(aligned(16));\n\tuint64_t array64_2[BLOCK_SIZE64] JEMALLOC_ATTR(aligned(16));\n\tint i;\n\tuint64_t r;\n\tuint32_t ini[] = {5, 4, 3, 2, 1};\n\tsfmt_t *ctx;\n\n\tassert_d_le(get_min_array_size64(), BLOCK_SIZE64,\n\t    \"Array size too small\");\n\tctx = init_by_array(ini, 5);\n\tfill_array64(ctx, array64, BLOCK_SIZE64);\n\tfill_array64(ctx, array64_2, BLOCK_SIZE64);\n\tfini_gen_rand(ctx);\n\n\tctx = init_by_array(ini, 5);\n\tfor (i = 0; i < BLOCK_SIZE64; i++) {\n\t\tif (i < COUNT_1) {\n\t\t\tassert_u64_eq(array64[i], init_by_array_64_expected[i],\n\t\t\t    \"Output mismatch for i=%d\", i);\n\t\t}\n\t\tr = gen_rand64(ctx);\n\t\tassert_u64_eq(r, array64[i],\n\t\t    \"Mismatch at array64[%d]=%\"FMTx64\" gen=%\"FMTx64, i,\n\t\t    array64[i], r);\n\t}\n\tfor (i = 0; i < COUNT_2; i++) {\n\t\tr = gen_rand64(ctx);\n\t\tassert_u64_eq(r, array64_2[i],\n\t\t    \"Mismatch at array64_2[%d]=%\"FMTx64\" gen=%\"FMTx64, i,\n\t\t    array64_2[i], r);\n\t}\n\tfini_gen_rand(ctx);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_gen_rand_32,\n\t    test_by_array_32,\n\t    test_gen_rand_64,\n\t    test_by_array_64));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/atomic.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#define\tTEST_STRUCT(p, t)\t\t\t\t\t\t\\\nstruct p##_test_s {\t\t\t\t\t\t\t\\\n\tt\taccum0;\t\t\t\t\t\t\t\\\n\tt\tx;\t\t\t\t\t\t\t\\\n\tt\ts;\t\t\t\t\t\t\t\\\n};\t\t\t\t\t\t\t\t\t\\\ntypedef struct p##_test_s p##_test_t;\n\n#define\tTEST_BODY(p, t, tc, ta, FMT) do {\t\t\t\t\\\n\tconst p##_test_t tests[] = {\t\t\t\t\t\\\n\t\t{(t)-1, (t)-1, (t)-2},\t\t\t\t\t\\\n\t\t{(t)-1, (t) 0, (t)-2},\t\t\t\t\t\\\n\t\t{(t)-1, (t) 1, (t)-2},\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\t{(t) 0, (t)-1, (t)-2},\t\t\t\t\t\\\n\t\t{(t) 0, (t) 0, (t)-2},\t\t\t\t\t\\\n\t\t{(t) 0, (t) 1, (t)-2},\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\t{(t) 1, (t)-1, (t)-2},\t\t\t\t\t\\\n\t\t{(t) 1, (t) 0, (t)-2},\t\t\t\t\t\\\n\t\t{(t) 1, (t) 1, (t)-2},\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\t{(t)0, (t)-(1 << 22), (t)-2},\t\t\t\t\\\n\t\t{(t)0, (t)(1 << 22), (t)-2},\t\t\t\t\\\n\t\t{(t)(1 << 22), (t)-(1 << 22), (t)-2},\t\t\t\\\n\t\t{(t)(1 << 22), (t)(1 << 22), (t)-2}\t\t\t\\\n\t};\t\t\t\t\t\t\t\t\\\n\tunsigned i;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tfor (i = 0; i < sizeof(tests)/sizeof(p##_test_t); i++) {\t\\\n\t\tbool err;\t\t\t\t\t\t\\\n\t\tt accum = tests[i].accum0;\t\t\t\t\\\n\t\tassert_##ta##_eq(atomic_read_##p(&accum),\t\t\\\n\t\t    tests[i].accum0,\t\t\t\t\t\\\n\t\t    \"Erroneous read, i=%u\", i);\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\tassert_##ta##_eq(atomic_add_##p(&accum, tests[i].x),\t\\\n\t\t    (t)((tc)tests[i].accum0 + (tc)tests[i].x),\t\t\\\n\t\t    \"i=%u, accum=%\"FMT\", x=%\"FMT,\t\t\t\\\n\t\t    i, tests[i].accum0, tests[i].x);\t\t\t\\\n\t\tassert_##ta##_eq(atomic_read_##p(&accum), accum,\t\\\n\t\t    \"Erroneous add, i=%u\", i);\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\taccum = tests[i].accum0;\t\t\t\t\\\n\t\tassert_##ta##_eq(atomic_sub_##p(&accum, tests[i].x),\t\\\n\t\t    (t)((tc)tests[i].accum0 - (tc)tests[i].x),\t\t\\\n\t\t    \"i=%u, accum=%\"FMT\", x=%\"FMT,\t\t\t\\\n\t\t    i, tests[i].accum0, tests[i].x);\t\t\t\\\n\t\tassert_##ta##_eq(atomic_read_##p(&accum), accum,\t\\\n\t\t    \"Erroneous sub, i=%u\", i);\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\taccum = tests[i].accum0;\t\t\t\t\\\n\t\terr = atomic_cas_##p(&accum, tests[i].x, tests[i].s);\t\\\n\t\tassert_b_eq(err, tests[i].accum0 != tests[i].x,\t\t\\\n\t\t    \"Erroneous cas success/failure result\");\t\t\\\n\t\tassert_##ta##_eq(accum, err ? tests[i].accum0 :\t\t\\\n\t\t    tests[i].s, \"Erroneous cas effect, i=%u\", i);\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\taccum = tests[i].accum0;\t\t\t\t\\\n\t\tatomic_write_##p(&accum, tests[i].s);\t\t\t\\\n\t\tassert_##ta##_eq(accum, tests[i].s,\t\t\t\\\n\t\t    \"Erroneous write, i=%u\", i);\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\nTEST_STRUCT(uint64, uint64_t)\nTEST_BEGIN(test_atomic_uint64)\n{\n\n#if !(LG_SIZEOF_PTR == 3 || LG_SIZEOF_INT == 3)\n\ttest_skip(\"64-bit atomic operations not supported\");\n#else\n\tTEST_BODY(uint64, uint64_t, uint64_t, u64, FMTx64);\n#endif\n}\nTEST_END\n\nTEST_STRUCT(uint32, uint32_t)\nTEST_BEGIN(test_atomic_uint32)\n{\n\n\tTEST_BODY(uint32, uint32_t, uint32_t, u32, \"#\"FMTx32);\n}\nTEST_END\n\nTEST_STRUCT(p, void *)\nTEST_BEGIN(test_atomic_p)\n{\n\n\tTEST_BODY(p, void *, uintptr_t, ptr, \"p\");\n}\nTEST_END\n\nTEST_STRUCT(z, size_t)\nTEST_BEGIN(test_atomic_z)\n{\n\n\tTEST_BODY(z, size_t, size_t, zu, \"#zx\");\n}\nTEST_END\n\nTEST_STRUCT(u, unsigned)\nTEST_BEGIN(test_atomic_u)\n{\n\n\tTEST_BODY(u, unsigned, unsigned, u, \"#x\");\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_atomic_uint64,\n\t    test_atomic_uint32,\n\t    test_atomic_p,\n\t    test_atomic_z,\n\t    test_atomic_u));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/bitmap.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nTEST_BEGIN(test_bitmap_size)\n{\n\tsize_t i, prev_size;\n\n\tprev_size = 0;\n\tfor (i = 1; i <= BITMAP_MAXBITS; i++) {\n\t\tbitmap_info_t binfo;\n\t\tsize_t size;\n\n\t\tbitmap_info_init(&binfo, i);\n\t\tsize = bitmap_size(&binfo);\n\t\tassert_true(size >= prev_size,\n\t\t    \"Bitmap size is smaller than expected\");\n\t\tprev_size = size;\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_bitmap_init)\n{\n\tsize_t i;\n\n\tfor (i = 1; i <= BITMAP_MAXBITS; i++) {\n\t\tbitmap_info_t binfo;\n\t\tbitmap_info_init(&binfo, i);\n\t\t{\n\t\t\tsize_t j;\n\t\t\tbitmap_t *bitmap = (bitmap_t *)malloc(\n\t\t\t    bitmap_size(&binfo));\n\t\t\tbitmap_init(bitmap, &binfo);\n\n\t\t\tfor (j = 0; j < i; j++) {\n\t\t\t\tassert_false(bitmap_get(bitmap, &binfo, j),\n\t\t\t\t    \"Bit should be unset\");\n\t\t\t}\n\t\t\tfree(bitmap);\n\t\t}\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_bitmap_set)\n{\n\tsize_t i;\n\n\tfor (i = 1; i <= BITMAP_MAXBITS; i++) {\n\t\tbitmap_info_t binfo;\n\t\tbitmap_info_init(&binfo, i);\n\t\t{\n\t\t\tsize_t j;\n\t\t\tbitmap_t *bitmap = (bitmap_t *)malloc(\n\t\t\t    bitmap_size(&binfo));\n\t\t\tbitmap_init(bitmap, &binfo);\n\n\t\t\tfor (j = 0; j < i; j++)\n\t\t\t\tbitmap_set(bitmap, &binfo, j);\n\t\t\tassert_true(bitmap_full(bitmap, &binfo),\n\t\t\t    \"All bits should be set\");\n\t\t\tfree(bitmap);\n\t\t}\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_bitmap_unset)\n{\n\tsize_t i;\n\n\tfor (i = 1; i <= BITMAP_MAXBITS; i++) {\n\t\tbitmap_info_t binfo;\n\t\tbitmap_info_init(&binfo, i);\n\t\t{\n\t\t\tsize_t j;\n\t\t\tbitmap_t *bitmap = (bitmap_t *)malloc(\n\t\t\t    bitmap_size(&binfo));\n\t\t\tbitmap_init(bitmap, &binfo);\n\n\t\t\tfor (j = 0; j < i; j++)\n\t\t\t\tbitmap_set(bitmap, &binfo, j);\n\t\t\tassert_true(bitmap_full(bitmap, &binfo),\n\t\t\t    \"All bits should be set\");\n\t\t\tfor (j = 0; j < i; j++)\n\t\t\t\tbitmap_unset(bitmap, &binfo, j);\n\t\t\tfor (j = 0; j < i; j++)\n\t\t\t\tbitmap_set(bitmap, &binfo, j);\n\t\t\tassert_true(bitmap_full(bitmap, &binfo),\n\t\t\t    \"All bits should be set\");\n\t\t\tfree(bitmap);\n\t\t}\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_bitmap_sfu)\n{\n\tsize_t i;\n\n\tfor (i = 1; i <= BITMAP_MAXBITS; i++) {\n\t\tbitmap_info_t binfo;\n\t\tbitmap_info_init(&binfo, i);\n\t\t{\n\t\t\tssize_t j;\n\t\t\tbitmap_t *bitmap = (bitmap_t *)malloc(\n\t\t\t    bitmap_size(&binfo));\n\t\t\tbitmap_init(bitmap, &binfo);\n\n\t\t\t/* Iteratively set bits starting at the beginning. */\n\t\t\tfor (j = 0; j < i; j++) {\n\t\t\t\tassert_zd_eq(bitmap_sfu(bitmap, &binfo), j,\n\t\t\t\t    \"First unset bit should be just after \"\n\t\t\t\t    \"previous first unset bit\");\n\t\t\t}\n\t\t\tassert_true(bitmap_full(bitmap, &binfo),\n\t\t\t    \"All bits should be set\");\n\n\t\t\t/*\n\t\t\t * Iteratively unset bits starting at the end, and\n\t\t\t * verify that bitmap_sfu() reaches the unset bits.\n\t\t\t */\n\t\t\tfor (j = i - 1; j >= 0; j--) {\n\t\t\t\tbitmap_unset(bitmap, &binfo, j);\n\t\t\t\tassert_zd_eq(bitmap_sfu(bitmap, &binfo), j,\n\t\t\t\t    \"First unset bit should the bit previously \"\n\t\t\t\t    \"unset\");\n\t\t\t\tbitmap_unset(bitmap, &binfo, j);\n\t\t\t}\n\t\t\tassert_false(bitmap_get(bitmap, &binfo, 0),\n\t\t\t    \"Bit should be unset\");\n\n\t\t\t/*\n\t\t\t * Iteratively set bits starting at the beginning, and\n\t\t\t * verify that bitmap_sfu() looks past them.\n\t\t\t */\n\t\t\tfor (j = 1; j < i; j++) {\n\t\t\t\tbitmap_set(bitmap, &binfo, j - 1);\n\t\t\t\tassert_zd_eq(bitmap_sfu(bitmap, &binfo), j,\n\t\t\t\t    \"First unset bit should be just after the \"\n\t\t\t\t    \"bit previously set\");\n\t\t\t\tbitmap_unset(bitmap, &binfo, j);\n\t\t\t}\n\t\t\tassert_zd_eq(bitmap_sfu(bitmap, &binfo), i - 1,\n\t\t\t    \"First unset bit should be the last bit\");\n\t\t\tassert_true(bitmap_full(bitmap, &binfo),\n\t\t\t    \"All bits should be set\");\n\t\t\tfree(bitmap);\n\t\t}\n\t}\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_bitmap_size,\n\t    test_bitmap_init,\n\t    test_bitmap_set,\n\t    test_bitmap_unset,\n\t    test_bitmap_sfu));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/ckh.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nTEST_BEGIN(test_new_delete)\n{\n\ttsd_t *tsd;\n\tckh_t ckh;\n\n\ttsd = tsd_fetch();\n\n\tassert_false(ckh_new(tsd, &ckh, 2, ckh_string_hash, ckh_string_keycomp),\n\t    \"Unexpected ckh_new() error\");\n\tckh_delete(tsd, &ckh);\n\n\tassert_false(ckh_new(tsd, &ckh, 3, ckh_pointer_hash,\n\t    ckh_pointer_keycomp), \"Unexpected ckh_new() error\");\n\tckh_delete(tsd, &ckh);\n}\nTEST_END\n\nTEST_BEGIN(test_count_insert_search_remove)\n{\n\ttsd_t *tsd;\n\tckh_t ckh;\n\tconst char *strs[] = {\n\t    \"a string\",\n\t    \"A string\",\n\t    \"a string.\",\n\t    \"A string.\"\n\t};\n\tconst char *missing = \"A string not in the hash table.\";\n\tsize_t i;\n\n\ttsd = tsd_fetch();\n\n\tassert_false(ckh_new(tsd, &ckh, 2, ckh_string_hash, ckh_string_keycomp),\n\t    \"Unexpected ckh_new() error\");\n\tassert_zu_eq(ckh_count(&ckh), 0,\n\t    \"ckh_count() should return %zu, but it returned %zu\", ZU(0),\n\t    ckh_count(&ckh));\n\n\t/* Insert. */\n\tfor (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {\n\t\tckh_insert(tsd, &ckh, strs[i], strs[i]);\n\t\tassert_zu_eq(ckh_count(&ckh), i+1,\n\t\t    \"ckh_count() should return %zu, but it returned %zu\", i+1,\n\t\t    ckh_count(&ckh));\n\t}\n\n\t/* Search. */\n\tfor (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {\n\t\tunion {\n\t\t\tvoid *p;\n\t\t\tconst char *s;\n\t\t} k, v;\n\t\tvoid **kp, **vp;\n\t\tconst char *ks, *vs;\n\n\t\tkp = (i & 1) ? &k.p : NULL;\n\t\tvp = (i & 2) ? &v.p : NULL;\n\t\tk.p = NULL;\n\t\tv.p = NULL;\n\t\tassert_false(ckh_search(&ckh, strs[i], kp, vp),\n\t\t    \"Unexpected ckh_search() error\");\n\n\t\tks = (i & 1) ? strs[i] : (const char *)NULL;\n\t\tvs = (i & 2) ? strs[i] : (const char *)NULL;\n\t\tassert_ptr_eq((void *)ks, (void *)k.s, \"Key mismatch, i=%zu\",\n\t\t    i);\n\t\tassert_ptr_eq((void *)vs, (void *)v.s, \"Value mismatch, i=%zu\",\n\t\t    i);\n\t}\n\tassert_true(ckh_search(&ckh, missing, NULL, NULL),\n\t    \"Unexpected ckh_search() success\");\n\n\t/* Remove. */\n\tfor (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {\n\t\tunion {\n\t\t\tvoid *p;\n\t\t\tconst char *s;\n\t\t} k, v;\n\t\tvoid **kp, **vp;\n\t\tconst char *ks, *vs;\n\n\t\tkp = (i & 1) ? &k.p : NULL;\n\t\tvp = (i & 2) ? &v.p : NULL;\n\t\tk.p = NULL;\n\t\tv.p = NULL;\n\t\tassert_false(ckh_remove(tsd, &ckh, strs[i], kp, vp),\n\t\t    \"Unexpected ckh_remove() error\");\n\n\t\tks = (i & 1) ? strs[i] : (const char *)NULL;\n\t\tvs = (i & 2) ? strs[i] : (const char *)NULL;\n\t\tassert_ptr_eq((void *)ks, (void *)k.s, \"Key mismatch, i=%zu\",\n\t\t    i);\n\t\tassert_ptr_eq((void *)vs, (void *)v.s, \"Value mismatch, i=%zu\",\n\t\t    i);\n\t\tassert_zu_eq(ckh_count(&ckh),\n\t\t    sizeof(strs)/sizeof(const char *) - i - 1,\n\t\t    \"ckh_count() should return %zu, but it returned %zu\",\n\t\t        sizeof(strs)/sizeof(const char *) - i - 1,\n\t\t    ckh_count(&ckh));\n\t}\n\n\tckh_delete(tsd, &ckh);\n}\nTEST_END\n\nTEST_BEGIN(test_insert_iter_remove)\n{\n#define\tNITEMS ZU(1000)\n\ttsd_t *tsd;\n\tckh_t ckh;\n\tvoid **p[NITEMS];\n\tvoid *q, *r;\n\tsize_t i;\n\n\ttsd = tsd_fetch();\n\n\tassert_false(ckh_new(tsd, &ckh, 2, ckh_pointer_hash,\n\t    ckh_pointer_keycomp), \"Unexpected ckh_new() error\");\n\n\tfor (i = 0; i < NITEMS; i++) {\n\t\tp[i] = mallocx(i+1, 0);\n\t\tassert_ptr_not_null(p[i], \"Unexpected mallocx() failure\");\n\t}\n\n\tfor (i = 0; i < NITEMS; i++) {\n\t\tsize_t j;\n\n\t\tfor (j = i; j < NITEMS; j++) {\n\t\t\tassert_false(ckh_insert(tsd, &ckh, p[j], p[j]),\n\t\t\t    \"Unexpected ckh_insert() failure\");\n\t\t\tassert_false(ckh_search(&ckh, p[j], &q, &r),\n\t\t\t    \"Unexpected ckh_search() failure\");\n\t\t\tassert_ptr_eq(p[j], q, \"Key pointer mismatch\");\n\t\t\tassert_ptr_eq(p[j], r, \"Value pointer mismatch\");\n\t\t}\n\n\t\tassert_zu_eq(ckh_count(&ckh), NITEMS,\n\t\t    \"ckh_count() should return %zu, but it returned %zu\",\n\t\t    NITEMS, ckh_count(&ckh));\n\n\t\tfor (j = i + 1; j < NITEMS; j++) {\n\t\t\tassert_false(ckh_search(&ckh, p[j], NULL, NULL),\n\t\t\t    \"Unexpected ckh_search() failure\");\n\t\t\tassert_false(ckh_remove(tsd, &ckh, p[j], &q, &r),\n\t\t\t    \"Unexpected ckh_remove() failure\");\n\t\t\tassert_ptr_eq(p[j], q, \"Key pointer mismatch\");\n\t\t\tassert_ptr_eq(p[j], r, \"Value pointer mismatch\");\n\t\t\tassert_true(ckh_search(&ckh, p[j], NULL, NULL),\n\t\t\t    \"Unexpected ckh_search() success\");\n\t\t\tassert_true(ckh_remove(tsd, &ckh, p[j], &q, &r),\n\t\t\t    \"Unexpected ckh_remove() success\");\n\t\t}\n\n\t\t{\n\t\t\tbool seen[NITEMS];\n\t\t\tsize_t tabind;\n\n\t\t\tmemset(seen, 0, sizeof(seen));\n\n\t\t\tfor (tabind = 0; !ckh_iter(&ckh, &tabind, &q, &r);) {\n\t\t\t\tsize_t k;\n\n\t\t\t\tassert_ptr_eq(q, r, \"Key and val not equal\");\n\n\t\t\t\tfor (k = 0; k < NITEMS; k++) {\n\t\t\t\t\tif (p[k] == q) {\n\t\t\t\t\t\tassert_false(seen[k],\n\t\t\t\t\t\t    \"Item %zu already seen\", k);\n\t\t\t\t\t\tseen[k] = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (j = 0; j < i + 1; j++)\n\t\t\t\tassert_true(seen[j], \"Item %zu not seen\", j);\n\t\t\tfor (; j < NITEMS; j++)\n\t\t\t\tassert_false(seen[j], \"Item %zu seen\", j);\n\t\t}\n\t}\n\n\tfor (i = 0; i < NITEMS; i++) {\n\t\tassert_false(ckh_search(&ckh, p[i], NULL, NULL),\n\t\t    \"Unexpected ckh_search() failure\");\n\t\tassert_false(ckh_remove(tsd, &ckh, p[i], &q, &r),\n\t\t    \"Unexpected ckh_remove() failure\");\n\t\tassert_ptr_eq(p[i], q, \"Key pointer mismatch\");\n\t\tassert_ptr_eq(p[i], r, \"Value pointer mismatch\");\n\t\tassert_true(ckh_search(&ckh, p[i], NULL, NULL),\n\t\t    \"Unexpected ckh_search() success\");\n\t\tassert_true(ckh_remove(tsd, &ckh, p[i], &q, &r),\n\t\t    \"Unexpected ckh_remove() success\");\n\t\tdallocx(p[i], 0);\n\t}\n\n\tassert_zu_eq(ckh_count(&ckh), 0,\n\t    \"ckh_count() should return %zu, but it returned %zu\",\n\t    ZU(0), ckh_count(&ckh));\n\tckh_delete(tsd, &ckh);\n#undef NITEMS\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_new_delete,\n\t    test_count_insert_search_remove,\n\t    test_insert_iter_remove));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/decay.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nconst char *malloc_conf = \"purge:decay,decay_time:1\";\n\nstatic nstime_update_t *nstime_update_orig;\n\nstatic unsigned nupdates_mock;\nstatic nstime_t time_mock;\nstatic bool nonmonotonic_mock;\n\nstatic bool\nnstime_update_mock(nstime_t *time)\n{\n\n\tnupdates_mock++;\n\tif (!nonmonotonic_mock)\n\t\tnstime_copy(time, &time_mock);\n\treturn (nonmonotonic_mock);\n}\n\nTEST_BEGIN(test_decay_ticks)\n{\n\tticker_t *decay_ticker;\n\tunsigned tick0, tick1;\n\tsize_t sz, huge0, large0;\n\tvoid *p;\n\n\ttest_skip_if(opt_purge != purge_mode_decay);\n\n\tdecay_ticker = decay_ticker_get(tsd_fetch(), 0);\n\tassert_ptr_not_null(decay_ticker,\n\t    \"Unexpected failure getting decay ticker\");\n\n\tsz = sizeof(size_t);\n\tassert_d_eq(mallctl(\"arenas.hchunk.0.size\", &huge0, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl failure\");\n\tassert_d_eq(mallctl(\"arenas.lrun.0.size\", &large0, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl failure\");\n\n\t/*\n\t * Test the standard APIs using a huge size class, since we can't\n\t * control tcache interactions (except by completely disabling tcache\n\t * for the entire test program).\n\t */\n\n\t/* malloc(). */\n\ttick0 = ticker_read(decay_ticker);\n\tp = malloc(huge0);\n\tassert_ptr_not_null(p, \"Unexpected malloc() failure\");\n\ttick1 = ticker_read(decay_ticker);\n\tassert_u32_ne(tick1, tick0, \"Expected ticker to tick during malloc()\");\n\t/* free(). */\n\ttick0 = ticker_read(decay_ticker);\n\tfree(p);\n\ttick1 = ticker_read(decay_ticker);\n\tassert_u32_ne(tick1, tick0, \"Expected ticker to tick during free()\");\n\n\t/* calloc(). */\n\ttick0 = ticker_read(decay_ticker);\n\tp = calloc(1, huge0);\n\tassert_ptr_not_null(p, \"Unexpected calloc() failure\");\n\ttick1 = ticker_read(decay_ticker);\n\tassert_u32_ne(tick1, tick0, \"Expected ticker to tick during calloc()\");\n\tfree(p);\n\n\t/* posix_memalign(). */\n\ttick0 = ticker_read(decay_ticker);\n\tassert_d_eq(posix_memalign(&p, sizeof(size_t), huge0), 0,\n\t    \"Unexpected posix_memalign() failure\");\n\ttick1 = ticker_read(decay_ticker);\n\tassert_u32_ne(tick1, tick0,\n\t    \"Expected ticker to tick during posix_memalign()\");\n\tfree(p);\n\n\t/* aligned_alloc(). */\n\ttick0 = ticker_read(decay_ticker);\n\tp = aligned_alloc(sizeof(size_t), huge0);\n\tassert_ptr_not_null(p, \"Unexpected aligned_alloc() failure\");\n\ttick1 = ticker_read(decay_ticker);\n\tassert_u32_ne(tick1, tick0,\n\t    \"Expected ticker to tick during aligned_alloc()\");\n\tfree(p);\n\n\t/* realloc(). */\n\t/* Allocate. */\n\ttick0 = ticker_read(decay_ticker);\n\tp = realloc(NULL, huge0);\n\tassert_ptr_not_null(p, \"Unexpected realloc() failure\");\n\ttick1 = ticker_read(decay_ticker);\n\tassert_u32_ne(tick1, tick0, \"Expected ticker to tick during realloc()\");\n\t/* Reallocate. */\n\ttick0 = ticker_read(decay_ticker);\n\tp = realloc(p, huge0);\n\tassert_ptr_not_null(p, \"Unexpected realloc() failure\");\n\ttick1 = ticker_read(decay_ticker);\n\tassert_u32_ne(tick1, tick0, \"Expected ticker to tick during realloc()\");\n\t/* Deallocate. */\n\ttick0 = ticker_read(decay_ticker);\n\trealloc(p, 0);\n\ttick1 = ticker_read(decay_ticker);\n\tassert_u32_ne(tick1, tick0, \"Expected ticker to tick during realloc()\");\n\n\t/*\n\t * Test the *allocx() APIs using huge, large, and small size classes,\n\t * with tcache explicitly disabled.\n\t */\n\t{\n\t\tunsigned i;\n\t\tsize_t allocx_sizes[3];\n\t\tallocx_sizes[0] = huge0;\n\t\tallocx_sizes[1] = large0;\n\t\tallocx_sizes[2] = 1;\n\n\t\tfor (i = 0; i < sizeof(allocx_sizes) / sizeof(size_t); i++) {\n\t\t\tsz = allocx_sizes[i];\n\n\t\t\t/* mallocx(). */\n\t\t\ttick0 = ticker_read(decay_ticker);\n\t\t\tp = mallocx(sz, MALLOCX_TCACHE_NONE);\n\t\t\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\t\t\ttick1 = ticker_read(decay_ticker);\n\t\t\tassert_u32_ne(tick1, tick0,\n\t\t\t    \"Expected ticker to tick during mallocx() (sz=%zu)\",\n\t\t\t    sz);\n\t\t\t/* rallocx(). */\n\t\t\ttick0 = ticker_read(decay_ticker);\n\t\t\tp = rallocx(p, sz, MALLOCX_TCACHE_NONE);\n\t\t\tassert_ptr_not_null(p, \"Unexpected rallocx() failure\");\n\t\t\ttick1 = ticker_read(decay_ticker);\n\t\t\tassert_u32_ne(tick1, tick0,\n\t\t\t    \"Expected ticker to tick during rallocx() (sz=%zu)\",\n\t\t\t    sz);\n\t\t\t/* xallocx(). */\n\t\t\ttick0 = ticker_read(decay_ticker);\n\t\t\txallocx(p, sz, 0, MALLOCX_TCACHE_NONE);\n\t\t\ttick1 = ticker_read(decay_ticker);\n\t\t\tassert_u32_ne(tick1, tick0,\n\t\t\t    \"Expected ticker to tick during xallocx() (sz=%zu)\",\n\t\t\t    sz);\n\t\t\t/* dallocx(). */\n\t\t\ttick0 = ticker_read(decay_ticker);\n\t\t\tdallocx(p, MALLOCX_TCACHE_NONE);\n\t\t\ttick1 = ticker_read(decay_ticker);\n\t\t\tassert_u32_ne(tick1, tick0,\n\t\t\t    \"Expected ticker to tick during dallocx() (sz=%zu)\",\n\t\t\t    sz);\n\t\t\t/* sdallocx(). */\n\t\t\tp = mallocx(sz, MALLOCX_TCACHE_NONE);\n\t\t\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\t\t\ttick0 = ticker_read(decay_ticker);\n\t\t\tsdallocx(p, sz, MALLOCX_TCACHE_NONE);\n\t\t\ttick1 = ticker_read(decay_ticker);\n\t\t\tassert_u32_ne(tick1, tick0,\n\t\t\t    \"Expected ticker to tick during sdallocx() \"\n\t\t\t    \"(sz=%zu)\", sz);\n\t\t}\n\t}\n\n\t/*\n\t * Test tcache fill/flush interactions for large and small size classes,\n\t * using an explicit tcache.\n\t */\n\tif (config_tcache) {\n\t\tunsigned tcache_ind, i;\n\t\tsize_t tcache_sizes[2];\n\t\ttcache_sizes[0] = large0;\n\t\ttcache_sizes[1] = 1;\n\n\t\tsz = sizeof(unsigned);\n\t\tassert_d_eq(mallctl(\"tcache.create\", &tcache_ind, &sz, NULL, 0),\n\t\t    0, \"Unexpected mallctl failure\");\n\n\t\tfor (i = 0; i < sizeof(tcache_sizes) / sizeof(size_t); i++) {\n\t\t\tsz = tcache_sizes[i];\n\n\t\t\t/* tcache fill. */\n\t\t\ttick0 = ticker_read(decay_ticker);\n\t\t\tp = mallocx(sz, MALLOCX_TCACHE(tcache_ind));\n\t\t\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\t\t\ttick1 = ticker_read(decay_ticker);\n\t\t\tassert_u32_ne(tick1, tick0,\n\t\t\t    \"Expected ticker to tick during tcache fill \"\n\t\t\t    \"(sz=%zu)\", sz);\n\t\t\t/* tcache flush. */\n\t\t\tdallocx(p, MALLOCX_TCACHE(tcache_ind));\n\t\t\ttick0 = ticker_read(decay_ticker);\n\t\t\tassert_d_eq(mallctl(\"tcache.flush\", NULL, NULL,\n\t\t\t    &tcache_ind, sizeof(unsigned)), 0,\n\t\t\t    \"Unexpected mallctl failure\");\n\t\t\ttick1 = ticker_read(decay_ticker);\n\t\t\tassert_u32_ne(tick1, tick0,\n\t\t\t    \"Expected ticker to tick during tcache flush \"\n\t\t\t    \"(sz=%zu)\", sz);\n\t\t}\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_decay_ticker)\n{\n#define\tNPS 1024\n\tint flags = (MALLOCX_ARENA(0) | MALLOCX_TCACHE_NONE);\n\tvoid *ps[NPS];\n\tuint64_t epoch;\n\tuint64_t npurge0 = 0;\n\tuint64_t npurge1 = 0;\n\tsize_t sz, large;\n\tunsigned i, nupdates0;\n\tnstime_t time, decay_time, deadline;\n\n\ttest_skip_if(opt_purge != purge_mode_decay);\n\n\t/*\n\t * Allocate a bunch of large objects, pause the clock, deallocate the\n\t * objects, restore the clock, then [md]allocx() in a tight loop to\n\t * verify the ticker triggers purging.\n\t */\n\n\tif (config_tcache) {\n\t\tsize_t tcache_max;\n\n\t\tsz = sizeof(size_t);\n\t\tassert_d_eq(mallctl(\"arenas.tcache_max\", &tcache_max, &sz, NULL,\n\t\t    0), 0, \"Unexpected mallctl failure\");\n\t\tlarge = nallocx(tcache_max + 1, flags);\n\t}  else {\n\t\tsz = sizeof(size_t);\n\t\tassert_d_eq(mallctl(\"arenas.lrun.0.size\", &large, &sz, NULL, 0),\n\t\t    0, \"Unexpected mallctl failure\");\n\t}\n\n\tassert_d_eq(mallctl(\"arena.0.purge\", NULL, NULL, NULL, 0), 0,\n\t    \"Unexpected mallctl failure\");\n\tassert_d_eq(mallctl(\"epoch\", NULL, NULL, &epoch, sizeof(uint64_t)), 0,\n\t    \"Unexpected mallctl failure\");\n\tsz = sizeof(uint64_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.npurge\", &npurge0, &sz, NULL, 0),\n\t    config_stats ? 0 : ENOENT, \"Unexpected mallctl result\");\n\n\tfor (i = 0; i < NPS; i++) {\n\t\tps[i] = mallocx(large, flags);\n\t\tassert_ptr_not_null(ps[i], \"Unexpected mallocx() failure\");\n\t}\n\n\tnupdates_mock = 0;\n\tnstime_init(&time_mock, 0);\n\tnstime_update(&time_mock);\n\tnonmonotonic_mock = false;\n\n\tnstime_update_orig = nstime_update;\n\tnstime_update = nstime_update_mock;\n\n\tfor (i = 0; i < NPS; i++) {\n\t\tdallocx(ps[i], flags);\n\t\tnupdates0 = nupdates_mock;\n\t\tassert_d_eq(mallctl(\"arena.0.decay\", NULL, NULL, NULL, 0), 0,\n\t\t    \"Unexpected arena.0.decay failure\");\n\t\tassert_u_gt(nupdates_mock, nupdates0,\n\t\t    \"Expected nstime_update() to be called\");\n\t}\n\n\tnstime_update = nstime_update_orig;\n\n\tnstime_init(&time, 0);\n\tnstime_update(&time);\n\tnstime_init2(&decay_time, opt_decay_time, 0);\n\tnstime_copy(&deadline, &time);\n\tnstime_add(&deadline, &decay_time);\n\tdo {\n\t\tfor (i = 0; i < DECAY_NTICKS_PER_UPDATE / 2; i++) {\n\t\t\tvoid *p = mallocx(1, flags);\n\t\t\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\t\t\tdallocx(p, flags);\n\t\t}\n\t\tassert_d_eq(mallctl(\"epoch\", NULL, NULL, &epoch,\n\t\t    sizeof(uint64_t)), 0, \"Unexpected mallctl failure\");\n\t\tsz = sizeof(uint64_t);\n\t\tassert_d_eq(mallctl(\"stats.arenas.0.npurge\", &npurge1, &sz,\n\t\t    NULL, 0), config_stats ? 0 : ENOENT,\n\t\t    \"Unexpected mallctl result\");\n\n\t\tnstime_update(&time);\n\t} while (nstime_compare(&time, &deadline) <= 0 && npurge1 == npurge0);\n\n\tif (config_stats)\n\t\tassert_u64_gt(npurge1, npurge0, \"Expected purging to occur\");\n#undef NPS\n}\nTEST_END\n\nTEST_BEGIN(test_decay_nonmonotonic)\n{\n#define\tNPS (SMOOTHSTEP_NSTEPS + 1)\n\tint flags = (MALLOCX_ARENA(0) | MALLOCX_TCACHE_NONE);\n\tvoid *ps[NPS];\n\tuint64_t epoch;\n\tuint64_t npurge0 = 0;\n\tuint64_t npurge1 = 0;\n\tsize_t sz, large0;\n\tunsigned i, nupdates0;\n\n\ttest_skip_if(opt_purge != purge_mode_decay);\n\n\tsz = sizeof(size_t);\n\tassert_d_eq(mallctl(\"arenas.lrun.0.size\", &large0, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl failure\");\n\n\tassert_d_eq(mallctl(\"arena.0.purge\", NULL, NULL, NULL, 0), 0,\n\t    \"Unexpected mallctl failure\");\n\tassert_d_eq(mallctl(\"epoch\", NULL, NULL, &epoch, sizeof(uint64_t)), 0,\n\t    \"Unexpected mallctl failure\");\n\tsz = sizeof(uint64_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.npurge\", &npurge0, &sz, NULL, 0),\n\t    config_stats ? 0 : ENOENT, \"Unexpected mallctl result\");\n\n\tnupdates_mock = 0;\n\tnstime_init(&time_mock, 0);\n\tnstime_update(&time_mock);\n\tnonmonotonic_mock = true;\n\n\tnstime_update_orig = nstime_update;\n\tnstime_update = nstime_update_mock;\n\n\tfor (i = 0; i < NPS; i++) {\n\t\tps[i] = mallocx(large0, flags);\n\t\tassert_ptr_not_null(ps[i], \"Unexpected mallocx() failure\");\n\t}\n\n\tfor (i = 0; i < NPS; i++) {\n\t\tdallocx(ps[i], flags);\n\t\tnupdates0 = nupdates_mock;\n\t\tassert_d_eq(mallctl(\"arena.0.decay\", NULL, NULL, NULL, 0), 0,\n\t\t    \"Unexpected arena.0.decay failure\");\n\t\tassert_u_gt(nupdates_mock, nupdates0,\n\t\t    \"Expected nstime_update() to be called\");\n\t}\n\n\tassert_d_eq(mallctl(\"epoch\", NULL, NULL, &epoch, sizeof(uint64_t)), 0,\n\t    \"Unexpected mallctl failure\");\n\tsz = sizeof(uint64_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.npurge\", &npurge1, &sz, NULL, 0),\n\t    config_stats ? 0 : ENOENT, \"Unexpected mallctl result\");\n\n\tif (config_stats)\n\t\tassert_u64_gt(npurge1, npurge0, \"Expected purging to occur\");\n\n\tnstime_update = nstime_update_orig;\n#undef NPS\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_decay_ticks,\n\t    test_decay_ticker,\n\t    test_decay_nonmonotonic));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/hash.c",
    "content": "/*\n * This file is based on code that is part of SMHasher\n * (https://code.google.com/p/smhasher/), and is subject to the MIT license\n * (http://www.opensource.org/licenses/mit-license.php).  Both email addresses\n * associated with the source code's revision history belong to Austin Appleby,\n * and the revision history ranges from 2010 to 2012.  Therefore the copyright\n * and license are here taken to be:\n *\n * Copyright (c) 2010-2012 Austin Appleby\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 deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * 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 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n#include \"test/jemalloc_test.h\"\n\ntypedef enum {\n\thash_variant_x86_32,\n\thash_variant_x86_128,\n\thash_variant_x64_128\n} hash_variant_t;\n\nstatic int\nhash_variant_bits(hash_variant_t variant)\n{\n\n\tswitch (variant) {\n\tcase hash_variant_x86_32: return (32);\n\tcase hash_variant_x86_128: return (128);\n\tcase hash_variant_x64_128: return (128);\n\tdefault: not_reached();\n\t}\n}\n\nstatic const char *\nhash_variant_string(hash_variant_t variant)\n{\n\n\tswitch (variant) {\n\tcase hash_variant_x86_32: return (\"hash_x86_32\");\n\tcase hash_variant_x86_128: return (\"hash_x86_128\");\n\tcase hash_variant_x64_128: return (\"hash_x64_128\");\n\tdefault: not_reached();\n\t}\n}\n\n#define\tKEY_SIZE\t256\nstatic void\nhash_variant_verify_key(hash_variant_t variant, uint8_t *key)\n{\n\tconst int hashbytes = hash_variant_bits(variant) / 8;\n\tVARIABLE_ARRAY(uint8_t, hashes, hashbytes * 256);\n\tVARIABLE_ARRAY(uint8_t, final, hashbytes);\n\tunsigned i;\n\tuint32_t computed, expected;\n\n\tmemset(key, 0, KEY_SIZE);\n\tmemset(hashes, 0, sizeof(hashes));\n\tmemset(final, 0, sizeof(final));\n\n\t/*\n\t * Hash keys of the form {0}, {0,1}, {0,1,2}, ..., {0,1,...,255} as the\n\t * seed.\n\t */\n\tfor (i = 0; i < 256; i++) {\n\t\tkey[i] = (uint8_t)i;\n\t\tswitch (variant) {\n\t\tcase hash_variant_x86_32: {\n\t\t\tuint32_t out;\n\t\t\tout = hash_x86_32(key, i, 256-i);\n\t\t\tmemcpy(&hashes[i*hashbytes], &out, hashbytes);\n\t\t\tbreak;\n\t\t} case hash_variant_x86_128: {\n\t\t\tuint64_t out[2];\n\t\t\thash_x86_128(key, i, 256-i, out);\n\t\t\tmemcpy(&hashes[i*hashbytes], out, hashbytes);\n\t\t\tbreak;\n\t\t} case hash_variant_x64_128: {\n\t\t\tuint64_t out[2];\n\t\t\thash_x64_128(key, i, 256-i, out);\n\t\t\tmemcpy(&hashes[i*hashbytes], out, hashbytes);\n\t\t\tbreak;\n\t\t} default: not_reached();\n\t\t}\n\t}\n\n\t/* Hash the result array. */\n\tswitch (variant) {\n\tcase hash_variant_x86_32: {\n\t\tuint32_t out = hash_x86_32(hashes, hashbytes*256, 0);\n\t\tmemcpy(final, &out, sizeof(out));\n\t\tbreak;\n\t} case hash_variant_x86_128: {\n\t\tuint64_t out[2];\n\t\thash_x86_128(hashes, hashbytes*256, 0, out);\n\t\tmemcpy(final, out, sizeof(out));\n\t\tbreak;\n\t} case hash_variant_x64_128: {\n\t\tuint64_t out[2];\n\t\thash_x64_128(hashes, hashbytes*256, 0, out);\n\t\tmemcpy(final, out, sizeof(out));\n\t\tbreak;\n\t} default: not_reached();\n\t}\n\n\tcomputed = (final[0] << 0) | (final[1] << 8) | (final[2] << 16) |\n\t    (final[3] << 24);\n\n\tswitch (variant) {\n#ifdef JEMALLOC_BIG_ENDIAN\n\tcase hash_variant_x86_32: expected = 0x6213303eU; break;\n\tcase hash_variant_x86_128: expected = 0x266820caU; break;\n\tcase hash_variant_x64_128: expected = 0xcc622b6fU; break;\n#else\n\tcase hash_variant_x86_32: expected = 0xb0f57ee3U; break;\n\tcase hash_variant_x86_128: expected = 0xb3ece62aU; break;\n\tcase hash_variant_x64_128: expected = 0x6384ba69U; break;\n#endif\n\tdefault: not_reached();\n\t}\n\n\tassert_u32_eq(computed, expected,\n\t    \"Hash mismatch for %s(): expected %#x but got %#x\",\n\t    hash_variant_string(variant), expected, computed);\n}\n\nstatic void\nhash_variant_verify(hash_variant_t variant)\n{\n#define\tMAX_ALIGN\t16\n\tuint8_t key[KEY_SIZE + (MAX_ALIGN - 1)];\n\tunsigned i;\n\n\tfor (i = 0; i < MAX_ALIGN; i++)\n\t\thash_variant_verify_key(variant, &key[i]);\n#undef MAX_ALIGN\n}\n#undef KEY_SIZE\n\nTEST_BEGIN(test_hash_x86_32)\n{\n\n\thash_variant_verify(hash_variant_x86_32);\n}\nTEST_END\n\nTEST_BEGIN(test_hash_x86_128)\n{\n\n\thash_variant_verify(hash_variant_x86_128);\n}\nTEST_END\n\nTEST_BEGIN(test_hash_x64_128)\n{\n\n\thash_variant_verify(hash_variant_x64_128);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_hash_x86_32,\n\t    test_hash_x86_128,\n\t    test_hash_x64_128));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/junk.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#ifdef JEMALLOC_FILL\n#  ifndef JEMALLOC_TEST_JUNK_OPT\n#    define JEMALLOC_TEST_JUNK_OPT \"junk:true\"\n#  endif\nconst char *malloc_conf =\n    \"abort:false,zero:false,redzone:true,quarantine:0,\" JEMALLOC_TEST_JUNK_OPT;\n#endif\n\nstatic arena_dalloc_junk_small_t *arena_dalloc_junk_small_orig;\nstatic arena_dalloc_junk_large_t *arena_dalloc_junk_large_orig;\nstatic huge_dalloc_junk_t *huge_dalloc_junk_orig;\nstatic void *watch_for_junking;\nstatic bool saw_junking;\n\nstatic void\nwatch_junking(void *p)\n{\n\n\twatch_for_junking = p;\n\tsaw_junking = false;\n}\n\nstatic void\narena_dalloc_junk_small_intercept(void *ptr, arena_bin_info_t *bin_info)\n{\n\tsize_t i;\n\n\tarena_dalloc_junk_small_orig(ptr, bin_info);\n\tfor (i = 0; i < bin_info->reg_size; i++) {\n\t\tassert_c_eq(((char *)ptr)[i], 0x5a,\n\t\t    \"Missing junk fill for byte %zu/%zu of deallocated region\",\n\t\t    i, bin_info->reg_size);\n\t}\n\tif (ptr == watch_for_junking)\n\t\tsaw_junking = true;\n}\n\nstatic void\narena_dalloc_junk_large_intercept(void *ptr, size_t usize)\n{\n\tsize_t i;\n\n\tarena_dalloc_junk_large_orig(ptr, usize);\n\tfor (i = 0; i < usize; i++) {\n\t\tassert_c_eq(((char *)ptr)[i], 0x5a,\n\t\t    \"Missing junk fill for byte %zu/%zu of deallocated region\",\n\t\t    i, usize);\n\t}\n\tif (ptr == watch_for_junking)\n\t\tsaw_junking = true;\n}\n\nstatic void\nhuge_dalloc_junk_intercept(void *ptr, size_t usize)\n{\n\n\thuge_dalloc_junk_orig(ptr, usize);\n\t/*\n\t * The conditions under which junk filling actually occurs are nuanced\n\t * enough that it doesn't make sense to duplicate the decision logic in\n\t * test code, so don't actually check that the region is junk-filled.\n\t */\n\tif (ptr == watch_for_junking)\n\t\tsaw_junking = true;\n}\n\nstatic void\ntest_junk(size_t sz_min, size_t sz_max)\n{\n\tchar *s;\n\tsize_t sz_prev, sz, i;\n\n\tif (opt_junk_free) {\n\t\tarena_dalloc_junk_small_orig = arena_dalloc_junk_small;\n\t\tarena_dalloc_junk_small = arena_dalloc_junk_small_intercept;\n\t\tarena_dalloc_junk_large_orig = arena_dalloc_junk_large;\n\t\tarena_dalloc_junk_large = arena_dalloc_junk_large_intercept;\n\t\thuge_dalloc_junk_orig = huge_dalloc_junk;\n\t\thuge_dalloc_junk = huge_dalloc_junk_intercept;\n\t}\n\n\tsz_prev = 0;\n\ts = (char *)mallocx(sz_min, 0);\n\tassert_ptr_not_null((void *)s, \"Unexpected mallocx() failure\");\n\n\tfor (sz = sallocx(s, 0); sz <= sz_max;\n\t    sz_prev = sz, sz = sallocx(s, 0)) {\n\t\tif (sz_prev > 0) {\n\t\t\tassert_c_eq(s[0], 'a',\n\t\t\t    \"Previously allocated byte %zu/%zu is corrupted\",\n\t\t\t    ZU(0), sz_prev);\n\t\t\tassert_c_eq(s[sz_prev-1], 'a',\n\t\t\t    \"Previously allocated byte %zu/%zu is corrupted\",\n\t\t\t    sz_prev-1, sz_prev);\n\t\t}\n\n\t\tfor (i = sz_prev; i < sz; i++) {\n\t\t\tif (opt_junk_alloc) {\n\t\t\t\tassert_c_eq(s[i], 0xa5,\n\t\t\t\t    \"Newly allocated byte %zu/%zu isn't \"\n\t\t\t\t    \"junk-filled\", i, sz);\n\t\t\t}\n\t\t\ts[i] = 'a';\n\t\t}\n\n\t\tif (xallocx(s, sz+1, 0, 0) == sz) {\n\t\t\twatch_junking(s);\n\t\t\ts = (char *)rallocx(s, sz+1, 0);\n\t\t\tassert_ptr_not_null((void *)s,\n\t\t\t    \"Unexpected rallocx() failure\");\n\t\t\tassert_true(!opt_junk_free || saw_junking,\n\t\t\t    \"Expected region of size %zu to be junk-filled\",\n\t\t\t    sz);\n\t\t}\n\t}\n\n\twatch_junking(s);\n\tdallocx(s, 0);\n\tassert_true(!opt_junk_free || saw_junking,\n\t    \"Expected region of size %zu to be junk-filled\", sz);\n\n\tif (opt_junk_free) {\n\t\tarena_dalloc_junk_small = arena_dalloc_junk_small_orig;\n\t\tarena_dalloc_junk_large = arena_dalloc_junk_large_orig;\n\t\thuge_dalloc_junk = huge_dalloc_junk_orig;\n\t}\n}\n\nTEST_BEGIN(test_junk_small)\n{\n\n\ttest_skip_if(!config_fill);\n\ttest_junk(1, SMALL_MAXCLASS-1);\n}\nTEST_END\n\nTEST_BEGIN(test_junk_large)\n{\n\n\ttest_skip_if(!config_fill);\n\ttest_junk(SMALL_MAXCLASS+1, large_maxclass);\n}\nTEST_END\n\nTEST_BEGIN(test_junk_huge)\n{\n\n\ttest_skip_if(!config_fill);\n\ttest_junk(large_maxclass+1, chunksize*2);\n}\nTEST_END\n\narena_ralloc_junk_large_t *arena_ralloc_junk_large_orig;\nstatic void *most_recently_trimmed;\n\nstatic size_t\nshrink_size(size_t size)\n{\n\tsize_t shrink_size;\n\n\tfor (shrink_size = size - 1; nallocx(shrink_size, 0) == size;\n\t    shrink_size--)\n\t\t; /* Do nothing. */\n\n\treturn (shrink_size);\n}\n\nstatic void\narena_ralloc_junk_large_intercept(void *ptr, size_t old_usize, size_t usize)\n{\n\n\tarena_ralloc_junk_large_orig(ptr, old_usize, usize);\n\tassert_zu_eq(old_usize, large_maxclass, \"Unexpected old_usize\");\n\tassert_zu_eq(usize, shrink_size(large_maxclass), \"Unexpected usize\");\n\tmost_recently_trimmed = ptr;\n}\n\nTEST_BEGIN(test_junk_large_ralloc_shrink)\n{\n\tvoid *p1, *p2;\n\n\tp1 = mallocx(large_maxclass, 0);\n\tassert_ptr_not_null(p1, \"Unexpected mallocx() failure\");\n\n\tarena_ralloc_junk_large_orig = arena_ralloc_junk_large;\n\tarena_ralloc_junk_large = arena_ralloc_junk_large_intercept;\n\n\tp2 = rallocx(p1, shrink_size(large_maxclass), 0);\n\tassert_ptr_eq(p1, p2, \"Unexpected move during shrink\");\n\n\tarena_ralloc_junk_large = arena_ralloc_junk_large_orig;\n\n\tassert_ptr_eq(most_recently_trimmed, p1,\n\t    \"Expected trimmed portion of region to be junk-filled\");\n}\nTEST_END\n\nstatic bool detected_redzone_corruption;\n\nstatic void\narena_redzone_corruption_replacement(void *ptr, size_t usize, bool after,\n    size_t offset, uint8_t byte)\n{\n\n\tdetected_redzone_corruption = true;\n}\n\nTEST_BEGIN(test_junk_redzone)\n{\n\tchar *s;\n\tarena_redzone_corruption_t *arena_redzone_corruption_orig;\n\n\ttest_skip_if(!config_fill);\n\ttest_skip_if(!opt_junk_alloc || !opt_junk_free);\n\n\tarena_redzone_corruption_orig = arena_redzone_corruption;\n\tarena_redzone_corruption = arena_redzone_corruption_replacement;\n\n\t/* Test underflow. */\n\tdetected_redzone_corruption = false;\n\ts = (char *)mallocx(1, 0);\n\tassert_ptr_not_null((void *)s, \"Unexpected mallocx() failure\");\n\ts[-1] = 0xbb;\n\tdallocx(s, 0);\n\tassert_true(detected_redzone_corruption,\n\t    \"Did not detect redzone corruption\");\n\n\t/* Test overflow. */\n\tdetected_redzone_corruption = false;\n\ts = (char *)mallocx(1, 0);\n\tassert_ptr_not_null((void *)s, \"Unexpected mallocx() failure\");\n\ts[sallocx(s, 0)] = 0xbb;\n\tdallocx(s, 0);\n\tassert_true(detected_redzone_corruption,\n\t    \"Did not detect redzone corruption\");\n\n\tarena_redzone_corruption = arena_redzone_corruption_orig;\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\tassert(!config_fill || opt_junk_alloc || opt_junk_free);\n\treturn (test(\n\t    test_junk_small,\n\t    test_junk_large,\n\t    test_junk_huge,\n\t    test_junk_large_ralloc_shrink,\n\t    test_junk_redzone));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/junk_alloc.c",
    "content": "#define JEMALLOC_TEST_JUNK_OPT \"junk:alloc\"\n#include \"junk.c\"\n#undef JEMALLOC_TEST_JUNK_OPT\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/junk_free.c",
    "content": "#define JEMALLOC_TEST_JUNK_OPT \"junk:free\"\n#include \"junk.c\"\n#undef JEMALLOC_TEST_JUNK_OPT\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/lg_chunk.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n/*\n * Make sure that opt.lg_chunk clamping is sufficient.  In practice, this test\n * program will fail a debug assertion during initialization and abort (rather\n * than the test soft-failing) if clamping is insufficient.\n */\nconst char *malloc_conf = \"lg_chunk:0\";\n\nTEST_BEGIN(test_lg_chunk_clamp)\n{\n\tvoid *p;\n\n\tp = mallocx(1, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\tdallocx(p, 0);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_lg_chunk_clamp));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/mallctl.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nTEST_BEGIN(test_mallctl_errors)\n{\n\tuint64_t epoch;\n\tsize_t sz;\n\n\tassert_d_eq(mallctl(\"no_such_name\", NULL, NULL, NULL, 0), ENOENT,\n\t    \"mallctl() should return ENOENT for non-existent names\");\n\n\tassert_d_eq(mallctl(\"version\", NULL, NULL, \"0.0.0\", strlen(\"0.0.0\")),\n\t    EPERM, \"mallctl() should return EPERM on attempt to write \"\n\t    \"read-only value\");\n\n\tassert_d_eq(mallctl(\"epoch\", NULL, NULL, &epoch, sizeof(epoch)-1),\n\t    EINVAL, \"mallctl() should return EINVAL for input size mismatch\");\n\tassert_d_eq(mallctl(\"epoch\", NULL, NULL, &epoch, sizeof(epoch)+1),\n\t    EINVAL, \"mallctl() should return EINVAL for input size mismatch\");\n\n\tsz = sizeof(epoch)-1;\n\tassert_d_eq(mallctl(\"epoch\", &epoch, &sz, NULL, 0), EINVAL,\n\t    \"mallctl() should return EINVAL for output size mismatch\");\n\tsz = sizeof(epoch)+1;\n\tassert_d_eq(mallctl(\"epoch\", &epoch, &sz, NULL, 0), EINVAL,\n\t    \"mallctl() should return EINVAL for output size mismatch\");\n}\nTEST_END\n\nTEST_BEGIN(test_mallctlnametomib_errors)\n{\n\tsize_t mib[1];\n\tsize_t miblen;\n\n\tmiblen = sizeof(mib)/sizeof(size_t);\n\tassert_d_eq(mallctlnametomib(\"no_such_name\", mib, &miblen), ENOENT,\n\t    \"mallctlnametomib() should return ENOENT for non-existent names\");\n}\nTEST_END\n\nTEST_BEGIN(test_mallctlbymib_errors)\n{\n\tuint64_t epoch;\n\tsize_t sz;\n\tsize_t mib[1];\n\tsize_t miblen;\n\n\tmiblen = sizeof(mib)/sizeof(size_t);\n\tassert_d_eq(mallctlnametomib(\"version\", mib, &miblen), 0,\n\t    \"Unexpected mallctlnametomib() failure\");\n\n\tassert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, \"0.0.0\",\n\t    strlen(\"0.0.0\")), EPERM, \"mallctl() should return EPERM on \"\n\t    \"attempt to write read-only value\");\n\n\tmiblen = sizeof(mib)/sizeof(size_t);\n\tassert_d_eq(mallctlnametomib(\"epoch\", mib, &miblen), 0,\n\t    \"Unexpected mallctlnametomib() failure\");\n\n\tassert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, &epoch,\n\t    sizeof(epoch)-1), EINVAL,\n\t    \"mallctlbymib() should return EINVAL for input size mismatch\");\n\tassert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, &epoch,\n\t    sizeof(epoch)+1), EINVAL,\n\t    \"mallctlbymib() should return EINVAL for input size mismatch\");\n\n\tsz = sizeof(epoch)-1;\n\tassert_d_eq(mallctlbymib(mib, miblen, &epoch, &sz, NULL, 0), EINVAL,\n\t    \"mallctlbymib() should return EINVAL for output size mismatch\");\n\tsz = sizeof(epoch)+1;\n\tassert_d_eq(mallctlbymib(mib, miblen, &epoch, &sz, NULL, 0), EINVAL,\n\t    \"mallctlbymib() should return EINVAL for output size mismatch\");\n}\nTEST_END\n\nTEST_BEGIN(test_mallctl_read_write)\n{\n\tuint64_t old_epoch, new_epoch;\n\tsize_t sz = sizeof(old_epoch);\n\n\t/* Blind. */\n\tassert_d_eq(mallctl(\"epoch\", NULL, NULL, NULL, 0), 0,\n\t    \"Unexpected mallctl() failure\");\n\tassert_zu_eq(sz, sizeof(old_epoch), \"Unexpected output size\");\n\n\t/* Read. */\n\tassert_d_eq(mallctl(\"epoch\", &old_epoch, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl() failure\");\n\tassert_zu_eq(sz, sizeof(old_epoch), \"Unexpected output size\");\n\n\t/* Write. */\n\tassert_d_eq(mallctl(\"epoch\", NULL, NULL, &new_epoch, sizeof(new_epoch)),\n\t    0, \"Unexpected mallctl() failure\");\n\tassert_zu_eq(sz, sizeof(old_epoch), \"Unexpected output size\");\n\n\t/* Read+write. */\n\tassert_d_eq(mallctl(\"epoch\", &old_epoch, &sz, &new_epoch,\n\t    sizeof(new_epoch)), 0, \"Unexpected mallctl() failure\");\n\tassert_zu_eq(sz, sizeof(old_epoch), \"Unexpected output size\");\n}\nTEST_END\n\nTEST_BEGIN(test_mallctlnametomib_short_mib)\n{\n\tsize_t mib[4];\n\tsize_t miblen;\n\n\tmiblen = 3;\n\tmib[3] = 42;\n\tassert_d_eq(mallctlnametomib(\"arenas.bin.0.nregs\", mib, &miblen), 0,\n\t    \"Unexpected mallctlnametomib() failure\");\n\tassert_zu_eq(miblen, 3, \"Unexpected mib output length\");\n\tassert_zu_eq(mib[3], 42,\n\t    \"mallctlnametomib() wrote past the end of the input mib\");\n}\nTEST_END\n\nTEST_BEGIN(test_mallctl_config)\n{\n\n#define\tTEST_MALLCTL_CONFIG(config, t) do {\t\t\t\t\\\n\tt oldval;\t\t\t\t\t\t\t\\\n\tsize_t sz = sizeof(oldval);\t\t\t\t\t\\\n\tassert_d_eq(mallctl(\"config.\"#config, &oldval, &sz, NULL, 0),\t\\\n\t    0, \"Unexpected mallctl() failure\");\t\t\t\t\\\n\tassert_b_eq(oldval, config_##config, \"Incorrect config value\");\t\\\n\tassert_zu_eq(sz, sizeof(oldval), \"Unexpected output size\");\t\\\n} while (0)\n\n\tTEST_MALLCTL_CONFIG(cache_oblivious, bool);\n\tTEST_MALLCTL_CONFIG(debug, bool);\n\tTEST_MALLCTL_CONFIG(fill, bool);\n\tTEST_MALLCTL_CONFIG(lazy_lock, bool);\n\tTEST_MALLCTL_CONFIG(malloc_conf, const char *);\n\tTEST_MALLCTL_CONFIG(munmap, bool);\n\tTEST_MALLCTL_CONFIG(prof, bool);\n\tTEST_MALLCTL_CONFIG(prof_libgcc, bool);\n\tTEST_MALLCTL_CONFIG(prof_libunwind, bool);\n\tTEST_MALLCTL_CONFIG(stats, bool);\n\tTEST_MALLCTL_CONFIG(tcache, bool);\n\tTEST_MALLCTL_CONFIG(tls, bool);\n\tTEST_MALLCTL_CONFIG(utrace, bool);\n\tTEST_MALLCTL_CONFIG(valgrind, bool);\n\tTEST_MALLCTL_CONFIG(xmalloc, bool);\n\n#undef TEST_MALLCTL_CONFIG\n}\nTEST_END\n\nTEST_BEGIN(test_mallctl_opt)\n{\n\tbool config_always = true;\n\n#define\tTEST_MALLCTL_OPT(t, opt, config) do {\t\t\t\t\\\n\tt oldval;\t\t\t\t\t\t\t\\\n\tsize_t sz = sizeof(oldval);\t\t\t\t\t\\\n\tint expected = config_##config ? 0 : ENOENT;\t\t\t\\\n\tint result = mallctl(\"opt.\"#opt, &oldval, &sz, NULL, 0);\t\\\n\tassert_d_eq(result, expected,\t\t\t\t\t\\\n\t    \"Unexpected mallctl() result for opt.\"#opt);\t\t\\\n\tassert_zu_eq(sz, sizeof(oldval), \"Unexpected output size\");\t\\\n} while (0)\n\n\tTEST_MALLCTL_OPT(bool, abort, always);\n\tTEST_MALLCTL_OPT(size_t, lg_chunk, always);\n\tTEST_MALLCTL_OPT(const char *, dss, always);\n\tTEST_MALLCTL_OPT(unsigned, narenas, always);\n\tTEST_MALLCTL_OPT(const char *, purge, always);\n\tTEST_MALLCTL_OPT(ssize_t, lg_dirty_mult, always);\n\tTEST_MALLCTL_OPT(ssize_t, decay_time, always);\n\tTEST_MALLCTL_OPT(bool, stats_print, always);\n\tTEST_MALLCTL_OPT(const char *, junk, fill);\n\tTEST_MALLCTL_OPT(size_t, quarantine, fill);\n\tTEST_MALLCTL_OPT(bool, redzone, fill);\n\tTEST_MALLCTL_OPT(bool, zero, fill);\n\tTEST_MALLCTL_OPT(bool, utrace, utrace);\n\tTEST_MALLCTL_OPT(bool, xmalloc, xmalloc);\n\tTEST_MALLCTL_OPT(bool, tcache, tcache);\n\tTEST_MALLCTL_OPT(size_t, lg_tcache_max, tcache);\n\tTEST_MALLCTL_OPT(bool, prof, prof);\n\tTEST_MALLCTL_OPT(const char *, prof_prefix, prof);\n\tTEST_MALLCTL_OPT(bool, prof_active, prof);\n\tTEST_MALLCTL_OPT(ssize_t, lg_prof_sample, prof);\n\tTEST_MALLCTL_OPT(bool, prof_accum, prof);\n\tTEST_MALLCTL_OPT(ssize_t, lg_prof_interval, prof);\n\tTEST_MALLCTL_OPT(bool, prof_gdump, prof);\n\tTEST_MALLCTL_OPT(bool, prof_final, prof);\n\tTEST_MALLCTL_OPT(bool, prof_leak, prof);\n\n#undef TEST_MALLCTL_OPT\n}\nTEST_END\n\nTEST_BEGIN(test_manpage_example)\n{\n\tunsigned nbins, i;\n\tsize_t mib[4];\n\tsize_t len, miblen;\n\n\tlen = sizeof(nbins);\n\tassert_d_eq(mallctl(\"arenas.nbins\", &nbins, &len, NULL, 0), 0,\n\t    \"Unexpected mallctl() failure\");\n\n\tmiblen = 4;\n\tassert_d_eq(mallctlnametomib(\"arenas.bin.0.size\", mib, &miblen), 0,\n\t    \"Unexpected mallctlnametomib() failure\");\n\tfor (i = 0; i < nbins; i++) {\n\t\tsize_t bin_size;\n\n\t\tmib[2] = i;\n\t\tlen = sizeof(bin_size);\n\t\tassert_d_eq(mallctlbymib(mib, miblen, &bin_size, &len, NULL, 0),\n\t\t    0, \"Unexpected mallctlbymib() failure\");\n\t\t/* Do something with bin_size... */\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_tcache_none)\n{\n\tvoid *p0, *q, *p1;\n\n\ttest_skip_if(!config_tcache);\n\n\t/* Allocate p and q. */\n\tp0 = mallocx(42, 0);\n\tassert_ptr_not_null(p0, \"Unexpected mallocx() failure\");\n\tq = mallocx(42, 0);\n\tassert_ptr_not_null(q, \"Unexpected mallocx() failure\");\n\n\t/* Deallocate p and q, but bypass the tcache for q. */\n\tdallocx(p0, 0);\n\tdallocx(q, MALLOCX_TCACHE_NONE);\n\n\t/* Make sure that tcache-based allocation returns p, not q. */\n\tp1 = mallocx(42, 0);\n\tassert_ptr_not_null(p1, \"Unexpected mallocx() failure\");\n\tassert_ptr_eq(p0, p1, \"Expected tcache to allocate cached region\");\n\n\t/* Clean up. */\n\tdallocx(p1, MALLOCX_TCACHE_NONE);\n}\nTEST_END\n\nTEST_BEGIN(test_tcache)\n{\n#define\tNTCACHES\t10\n\tunsigned tis[NTCACHES];\n\tvoid *ps[NTCACHES];\n\tvoid *qs[NTCACHES];\n\tunsigned i;\n\tsize_t sz, psz, qsz;\n\n\ttest_skip_if(!config_tcache);\n\n\tpsz = 42;\n\tqsz = nallocx(psz, 0) + 1;\n\n\t/* Create tcaches. */\n\tfor (i = 0; i < NTCACHES; i++) {\n\t\tsz = sizeof(unsigned);\n\t\tassert_d_eq(mallctl(\"tcache.create\", &tis[i], &sz, NULL, 0), 0,\n\t\t    \"Unexpected mallctl() failure, i=%u\", i);\n\t}\n\n\t/* Exercise tcache ID recycling. */\n\tfor (i = 0; i < NTCACHES; i++) {\n\t\tassert_d_eq(mallctl(\"tcache.destroy\", NULL, NULL, &tis[i],\n\t\t    sizeof(unsigned)), 0, \"Unexpected mallctl() failure, i=%u\",\n\t\t    i);\n\t}\n\tfor (i = 0; i < NTCACHES; i++) {\n\t\tsz = sizeof(unsigned);\n\t\tassert_d_eq(mallctl(\"tcache.create\", &tis[i], &sz, NULL, 0), 0,\n\t\t    \"Unexpected mallctl() failure, i=%u\", i);\n\t}\n\n\t/* Flush empty tcaches. */\n\tfor (i = 0; i < NTCACHES; i++) {\n\t\tassert_d_eq(mallctl(\"tcache.flush\", NULL, NULL, &tis[i],\n\t\t    sizeof(unsigned)), 0, \"Unexpected mallctl() failure, i=%u\",\n\t\t    i);\n\t}\n\n\t/* Cache some allocations. */\n\tfor (i = 0; i < NTCACHES; i++) {\n\t\tps[i] = mallocx(psz, MALLOCX_TCACHE(tis[i]));\n\t\tassert_ptr_not_null(ps[i], \"Unexpected mallocx() failure, i=%u\",\n\t\t    i);\n\t\tdallocx(ps[i], MALLOCX_TCACHE(tis[i]));\n\n\t\tqs[i] = mallocx(qsz, MALLOCX_TCACHE(tis[i]));\n\t\tassert_ptr_not_null(qs[i], \"Unexpected mallocx() failure, i=%u\",\n\t\t    i);\n\t\tdallocx(qs[i], MALLOCX_TCACHE(tis[i]));\n\t}\n\n\t/* Verify that tcaches allocate cached regions. */\n\tfor (i = 0; i < NTCACHES; i++) {\n\t\tvoid *p0 = ps[i];\n\t\tps[i] = mallocx(psz, MALLOCX_TCACHE(tis[i]));\n\t\tassert_ptr_not_null(ps[i], \"Unexpected mallocx() failure, i=%u\",\n\t\t    i);\n\t\tassert_ptr_eq(ps[i], p0,\n\t\t    \"Expected mallocx() to allocate cached region, i=%u\", i);\n\t}\n\n\t/* Verify that reallocation uses cached regions. */\n\tfor (i = 0; i < NTCACHES; i++) {\n\t\tvoid *q0 = qs[i];\n\t\tqs[i] = rallocx(ps[i], qsz, MALLOCX_TCACHE(tis[i]));\n\t\tassert_ptr_not_null(qs[i], \"Unexpected rallocx() failure, i=%u\",\n\t\t    i);\n\t\tassert_ptr_eq(qs[i], q0,\n\t\t    \"Expected rallocx() to allocate cached region, i=%u\", i);\n\t\t/* Avoid undefined behavior in case of test failure. */\n\t\tif (qs[i] == NULL)\n\t\t\tqs[i] = ps[i];\n\t}\n\tfor (i = 0; i < NTCACHES; i++)\n\t\tdallocx(qs[i], MALLOCX_TCACHE(tis[i]));\n\n\t/* Flush some non-empty tcaches. */\n\tfor (i = 0; i < NTCACHES/2; i++) {\n\t\tassert_d_eq(mallctl(\"tcache.flush\", NULL, NULL, &tis[i],\n\t\t    sizeof(unsigned)), 0, \"Unexpected mallctl() failure, i=%u\",\n\t\t    i);\n\t}\n\n\t/* Destroy tcaches. */\n\tfor (i = 0; i < NTCACHES; i++) {\n\t\tassert_d_eq(mallctl(\"tcache.destroy\", NULL, NULL, &tis[i],\n\t\t    sizeof(unsigned)), 0, \"Unexpected mallctl() failure, i=%u\",\n\t\t    i);\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_thread_arena)\n{\n\tunsigned arena_old, arena_new, narenas;\n\tsize_t sz = sizeof(unsigned);\n\n\tassert_d_eq(mallctl(\"arenas.narenas\", &narenas, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl() failure\");\n\tassert_u_eq(narenas, opt_narenas, \"Number of arenas incorrect\");\n\tarena_new = narenas - 1;\n\tassert_d_eq(mallctl(\"thread.arena\", &arena_old, &sz, &arena_new,\n\t    sizeof(unsigned)), 0, \"Unexpected mallctl() failure\");\n\tarena_new = 0;\n\tassert_d_eq(mallctl(\"thread.arena\", &arena_old, &sz, &arena_new,\n\t    sizeof(unsigned)), 0, \"Unexpected mallctl() failure\");\n}\nTEST_END\n\nTEST_BEGIN(test_arena_i_lg_dirty_mult)\n{\n\tssize_t lg_dirty_mult, orig_lg_dirty_mult, prev_lg_dirty_mult;\n\tsize_t sz = sizeof(ssize_t);\n\n\ttest_skip_if(opt_purge != purge_mode_ratio);\n\n\tassert_d_eq(mallctl(\"arena.0.lg_dirty_mult\", &orig_lg_dirty_mult, &sz,\n\t    NULL, 0), 0, \"Unexpected mallctl() failure\");\n\n\tlg_dirty_mult = -2;\n\tassert_d_eq(mallctl(\"arena.0.lg_dirty_mult\", NULL, NULL,\n\t    &lg_dirty_mult, sizeof(ssize_t)), EFAULT,\n\t    \"Unexpected mallctl() success\");\n\n\tlg_dirty_mult = (sizeof(size_t) << 3);\n\tassert_d_eq(mallctl(\"arena.0.lg_dirty_mult\", NULL, NULL,\n\t    &lg_dirty_mult, sizeof(ssize_t)), EFAULT,\n\t    \"Unexpected mallctl() success\");\n\n\tfor (prev_lg_dirty_mult = orig_lg_dirty_mult, lg_dirty_mult = -1;\n\t    lg_dirty_mult < (ssize_t)(sizeof(size_t) << 3); prev_lg_dirty_mult\n\t    = lg_dirty_mult, lg_dirty_mult++) {\n\t\tssize_t old_lg_dirty_mult;\n\n\t\tassert_d_eq(mallctl(\"arena.0.lg_dirty_mult\", &old_lg_dirty_mult,\n\t\t    &sz, &lg_dirty_mult, sizeof(ssize_t)), 0,\n\t\t    \"Unexpected mallctl() failure\");\n\t\tassert_zd_eq(old_lg_dirty_mult, prev_lg_dirty_mult,\n\t\t    \"Unexpected old arena.0.lg_dirty_mult\");\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_arena_i_decay_time)\n{\n\tssize_t decay_time, orig_decay_time, prev_decay_time;\n\tsize_t sz = sizeof(ssize_t);\n\n\ttest_skip_if(opt_purge != purge_mode_decay);\n\n\tassert_d_eq(mallctl(\"arena.0.decay_time\", &orig_decay_time, &sz,\n\t    NULL, 0), 0, \"Unexpected mallctl() failure\");\n\n\tdecay_time = -2;\n\tassert_d_eq(mallctl(\"arena.0.decay_time\", NULL, NULL,\n\t    &decay_time, sizeof(ssize_t)), EFAULT,\n\t    \"Unexpected mallctl() success\");\n\n\tdecay_time = 0x7fffffff;\n\tassert_d_eq(mallctl(\"arena.0.decay_time\", NULL, NULL,\n\t    &decay_time, sizeof(ssize_t)), 0,\n\t    \"Unexpected mallctl() failure\");\n\n\tfor (prev_decay_time = decay_time, decay_time = -1;\n\t    decay_time < 20; prev_decay_time = decay_time, decay_time++) {\n\t\tssize_t old_decay_time;\n\n\t\tassert_d_eq(mallctl(\"arena.0.decay_time\", &old_decay_time,\n\t\t    &sz, &decay_time, sizeof(ssize_t)), 0,\n\t\t    \"Unexpected mallctl() failure\");\n\t\tassert_zd_eq(old_decay_time, prev_decay_time,\n\t\t    \"Unexpected old arena.0.decay_time\");\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_arena_i_purge)\n{\n\tunsigned narenas;\n\tsize_t sz = sizeof(unsigned);\n\tsize_t mib[3];\n\tsize_t miblen = 3;\n\n\tassert_d_eq(mallctl(\"arena.0.purge\", NULL, NULL, NULL, 0), 0,\n\t    \"Unexpected mallctl() failure\");\n\n\tassert_d_eq(mallctl(\"arenas.narenas\", &narenas, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl() failure\");\n\tassert_d_eq(mallctlnametomib(\"arena.0.purge\", mib, &miblen), 0,\n\t    \"Unexpected mallctlnametomib() failure\");\n\tmib[1] = narenas;\n\tassert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0,\n\t    \"Unexpected mallctlbymib() failure\");\n}\nTEST_END\n\nTEST_BEGIN(test_arena_i_decay)\n{\n\tunsigned narenas;\n\tsize_t sz = sizeof(unsigned);\n\tsize_t mib[3];\n\tsize_t miblen = 3;\n\n\tassert_d_eq(mallctl(\"arena.0.decay\", NULL, NULL, NULL, 0), 0,\n\t    \"Unexpected mallctl() failure\");\n\n\tassert_d_eq(mallctl(\"arenas.narenas\", &narenas, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl() failure\");\n\tassert_d_eq(mallctlnametomib(\"arena.0.decay\", mib, &miblen), 0,\n\t    \"Unexpected mallctlnametomib() failure\");\n\tmib[1] = narenas;\n\tassert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0,\n\t    \"Unexpected mallctlbymib() failure\");\n}\nTEST_END\n\nTEST_BEGIN(test_arena_i_dss)\n{\n\tconst char *dss_prec_old, *dss_prec_new;\n\tsize_t sz = sizeof(dss_prec_old);\n\tsize_t mib[3];\n\tsize_t miblen;\n\n\tmiblen = sizeof(mib)/sizeof(size_t);\n\tassert_d_eq(mallctlnametomib(\"arena.0.dss\", mib, &miblen), 0,\n\t    \"Unexpected mallctlnametomib() error\");\n\n\tdss_prec_new = \"disabled\";\n\tassert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, &dss_prec_new,\n\t    sizeof(dss_prec_new)), 0, \"Unexpected mallctl() failure\");\n\tassert_str_ne(dss_prec_old, \"primary\",\n\t    \"Unexpected default for dss precedence\");\n\n\tassert_d_eq(mallctlbymib(mib, miblen, &dss_prec_new, &sz, &dss_prec_old,\n\t    sizeof(dss_prec_old)), 0, \"Unexpected mallctl() failure\");\n\n\tassert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl() failure\");\n\tassert_str_ne(dss_prec_old, \"primary\",\n\t    \"Unexpected value for dss precedence\");\n\n\tmib[1] = narenas_total_get();\n\tdss_prec_new = \"disabled\";\n\tassert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, &dss_prec_new,\n\t    sizeof(dss_prec_new)), 0, \"Unexpected mallctl() failure\");\n\tassert_str_ne(dss_prec_old, \"primary\",\n\t    \"Unexpected default for dss precedence\");\n\n\tassert_d_eq(mallctlbymib(mib, miblen, &dss_prec_new, &sz, &dss_prec_old,\n\t    sizeof(dss_prec_new)), 0, \"Unexpected mallctl() failure\");\n\n\tassert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl() failure\");\n\tassert_str_ne(dss_prec_old, \"primary\",\n\t    \"Unexpected value for dss precedence\");\n}\nTEST_END\n\nTEST_BEGIN(test_arenas_initialized)\n{\n\tunsigned narenas;\n\tsize_t sz = sizeof(narenas);\n\n\tassert_d_eq(mallctl(\"arenas.narenas\", &narenas, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl() failure\");\n\t{\n\t\tVARIABLE_ARRAY(bool, initialized, narenas);\n\n\t\tsz = narenas * sizeof(bool);\n\t\tassert_d_eq(mallctl(\"arenas.initialized\", initialized, &sz,\n\t\t    NULL, 0), 0, \"Unexpected mallctl() failure\");\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_arenas_lg_dirty_mult)\n{\n\tssize_t lg_dirty_mult, orig_lg_dirty_mult, prev_lg_dirty_mult;\n\tsize_t sz = sizeof(ssize_t);\n\n\ttest_skip_if(opt_purge != purge_mode_ratio);\n\n\tassert_d_eq(mallctl(\"arenas.lg_dirty_mult\", &orig_lg_dirty_mult, &sz,\n\t    NULL, 0), 0, \"Unexpected mallctl() failure\");\n\n\tlg_dirty_mult = -2;\n\tassert_d_eq(mallctl(\"arenas.lg_dirty_mult\", NULL, NULL,\n\t    &lg_dirty_mult, sizeof(ssize_t)), EFAULT,\n\t    \"Unexpected mallctl() success\");\n\n\tlg_dirty_mult = (sizeof(size_t) << 3);\n\tassert_d_eq(mallctl(\"arenas.lg_dirty_mult\", NULL, NULL,\n\t    &lg_dirty_mult, sizeof(ssize_t)), EFAULT,\n\t    \"Unexpected mallctl() success\");\n\n\tfor (prev_lg_dirty_mult = orig_lg_dirty_mult, lg_dirty_mult = -1;\n\t    lg_dirty_mult < (ssize_t)(sizeof(size_t) << 3); prev_lg_dirty_mult =\n\t    lg_dirty_mult, lg_dirty_mult++) {\n\t\tssize_t old_lg_dirty_mult;\n\n\t\tassert_d_eq(mallctl(\"arenas.lg_dirty_mult\", &old_lg_dirty_mult,\n\t\t    &sz, &lg_dirty_mult, sizeof(ssize_t)), 0,\n\t\t    \"Unexpected mallctl() failure\");\n\t\tassert_zd_eq(old_lg_dirty_mult, prev_lg_dirty_mult,\n\t\t    \"Unexpected old arenas.lg_dirty_mult\");\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_arenas_decay_time)\n{\n\tssize_t decay_time, orig_decay_time, prev_decay_time;\n\tsize_t sz = sizeof(ssize_t);\n\n\ttest_skip_if(opt_purge != purge_mode_decay);\n\n\tassert_d_eq(mallctl(\"arenas.decay_time\", &orig_decay_time, &sz,\n\t    NULL, 0), 0, \"Unexpected mallctl() failure\");\n\n\tdecay_time = -2;\n\tassert_d_eq(mallctl(\"arenas.decay_time\", NULL, NULL,\n\t    &decay_time, sizeof(ssize_t)), EFAULT,\n\t    \"Unexpected mallctl() success\");\n\n\tdecay_time = 0x7fffffff;\n\tassert_d_eq(mallctl(\"arenas.decay_time\", NULL, NULL,\n\t    &decay_time, sizeof(ssize_t)), 0,\n\t    \"Expected mallctl() failure\");\n\n\tfor (prev_decay_time = decay_time, decay_time = -1;\n\t    decay_time < 20; prev_decay_time = decay_time, decay_time++) {\n\t\tssize_t old_decay_time;\n\n\t\tassert_d_eq(mallctl(\"arenas.decay_time\", &old_decay_time,\n\t\t    &sz, &decay_time, sizeof(ssize_t)), 0,\n\t\t    \"Unexpected mallctl() failure\");\n\t\tassert_zd_eq(old_decay_time, prev_decay_time,\n\t\t    \"Unexpected old arenas.decay_time\");\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_arenas_constants)\n{\n\n#define\tTEST_ARENAS_CONSTANT(t, name, expected) do {\t\t\t\\\n\tt name;\t\t\t\t\t\t\t\t\\\n\tsize_t sz = sizeof(t);\t\t\t\t\t\t\\\n\tassert_d_eq(mallctl(\"arenas.\"#name, &name, &sz, NULL, 0), 0,\t\\\n\t    \"Unexpected mallctl() failure\");\t\t\t\t\\\n\tassert_zu_eq(name, expected, \"Incorrect \"#name\" size\");\t\t\\\n} while (0)\n\n\tTEST_ARENAS_CONSTANT(size_t, quantum, QUANTUM);\n\tTEST_ARENAS_CONSTANT(size_t, page, PAGE);\n\tTEST_ARENAS_CONSTANT(unsigned, nbins, NBINS);\n\tTEST_ARENAS_CONSTANT(unsigned, nlruns, nlclasses);\n\tTEST_ARENAS_CONSTANT(unsigned, nhchunks, nhclasses);\n\n#undef TEST_ARENAS_CONSTANT\n}\nTEST_END\n\nTEST_BEGIN(test_arenas_bin_constants)\n{\n\n#define\tTEST_ARENAS_BIN_CONSTANT(t, name, expected) do {\t\t\\\n\tt name;\t\t\t\t\t\t\t\t\\\n\tsize_t sz = sizeof(t);\t\t\t\t\t\t\\\n\tassert_d_eq(mallctl(\"arenas.bin.0.\"#name, &name, &sz, NULL, 0),\t\\\n\t    0, \"Unexpected mallctl() failure\");\t\t\t\t\\\n\tassert_zu_eq(name, expected, \"Incorrect \"#name\" size\");\t\t\\\n} while (0)\n\n\tTEST_ARENAS_BIN_CONSTANT(size_t, size, arena_bin_info[0].reg_size);\n\tTEST_ARENAS_BIN_CONSTANT(uint32_t, nregs, arena_bin_info[0].nregs);\n\tTEST_ARENAS_BIN_CONSTANT(size_t, run_size, arena_bin_info[0].run_size);\n\n#undef TEST_ARENAS_BIN_CONSTANT\n}\nTEST_END\n\nTEST_BEGIN(test_arenas_lrun_constants)\n{\n\n#define\tTEST_ARENAS_LRUN_CONSTANT(t, name, expected) do {\t\t\\\n\tt name;\t\t\t\t\t\t\t\t\\\n\tsize_t sz = sizeof(t);\t\t\t\t\t\t\\\n\tassert_d_eq(mallctl(\"arenas.lrun.0.\"#name, &name, &sz, NULL,\t\\\n\t    0), 0, \"Unexpected mallctl() failure\");\t\t\t\\\n\tassert_zu_eq(name, expected, \"Incorrect \"#name\" size\");\t\t\\\n} while (0)\n\n\tTEST_ARENAS_LRUN_CONSTANT(size_t, size, LARGE_MINCLASS);\n\n#undef TEST_ARENAS_LRUN_CONSTANT\n}\nTEST_END\n\nTEST_BEGIN(test_arenas_hchunk_constants)\n{\n\n#define\tTEST_ARENAS_HCHUNK_CONSTANT(t, name, expected) do {\t\t\\\n\tt name;\t\t\t\t\t\t\t\t\\\n\tsize_t sz = sizeof(t);\t\t\t\t\t\t\\\n\tassert_d_eq(mallctl(\"arenas.hchunk.0.\"#name, &name, &sz, NULL,\t\\\n\t    0), 0, \"Unexpected mallctl() failure\");\t\t\t\\\n\tassert_zu_eq(name, expected, \"Incorrect \"#name\" size\");\t\t\\\n} while (0)\n\n\tTEST_ARENAS_HCHUNK_CONSTANT(size_t, size, chunksize);\n\n#undef TEST_ARENAS_HCHUNK_CONSTANT\n}\nTEST_END\n\nTEST_BEGIN(test_arenas_extend)\n{\n\tunsigned narenas_before, arena, narenas_after;\n\tsize_t sz = sizeof(unsigned);\n\n\tassert_d_eq(mallctl(\"arenas.narenas\", &narenas_before, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl() failure\");\n\tassert_d_eq(mallctl(\"arenas.extend\", &arena, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl() failure\");\n\tassert_d_eq(mallctl(\"arenas.narenas\", &narenas_after, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl() failure\");\n\n\tassert_u_eq(narenas_before+1, narenas_after,\n\t    \"Unexpected number of arenas before versus after extension\");\n\tassert_u_eq(arena, narenas_after-1, \"Unexpected arena index\");\n}\nTEST_END\n\nTEST_BEGIN(test_stats_arenas)\n{\n\n#define\tTEST_STATS_ARENAS(t, name) do {\t\t\t\t\t\\\n\tt name;\t\t\t\t\t\t\t\t\\\n\tsize_t sz = sizeof(t);\t\t\t\t\t\t\\\n\tassert_d_eq(mallctl(\"stats.arenas.0.\"#name, &name, &sz, NULL,\t\\\n\t    0), 0, \"Unexpected mallctl() failure\");\t\t\t\\\n} while (0)\n\n\tTEST_STATS_ARENAS(unsigned, nthreads);\n\tTEST_STATS_ARENAS(const char *, dss);\n\tTEST_STATS_ARENAS(ssize_t, lg_dirty_mult);\n\tTEST_STATS_ARENAS(ssize_t, decay_time);\n\tTEST_STATS_ARENAS(size_t, pactive);\n\tTEST_STATS_ARENAS(size_t, pdirty);\n\n#undef TEST_STATS_ARENAS\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_mallctl_errors,\n\t    test_mallctlnametomib_errors,\n\t    test_mallctlbymib_errors,\n\t    test_mallctl_read_write,\n\t    test_mallctlnametomib_short_mib,\n\t    test_mallctl_config,\n\t    test_mallctl_opt,\n\t    test_manpage_example,\n\t    test_tcache_none,\n\t    test_tcache,\n\t    test_thread_arena,\n\t    test_arena_i_lg_dirty_mult,\n\t    test_arena_i_decay_time,\n\t    test_arena_i_purge,\n\t    test_arena_i_decay,\n\t    test_arena_i_dss,\n\t    test_arenas_initialized,\n\t    test_arenas_lg_dirty_mult,\n\t    test_arenas_decay_time,\n\t    test_arenas_constants,\n\t    test_arenas_bin_constants,\n\t    test_arenas_lrun_constants,\n\t    test_arenas_hchunk_constants,\n\t    test_arenas_extend,\n\t    test_stats_arenas));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/math.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#define\tMAX_REL_ERR 1.0e-9\n#define\tMAX_ABS_ERR 1.0e-9\n\n#include <float.h>\n\n#ifndef INFINITY\n#define\tINFINITY (DBL_MAX + DBL_MAX)\n#endif\n\nstatic bool\ndouble_eq_rel(double a, double b, double max_rel_err, double max_abs_err)\n{\n\tdouble rel_err;\n\n\tif (fabs(a - b) < max_abs_err)\n\t\treturn (true);\n\trel_err = (fabs(b) > fabs(a)) ? fabs((a-b)/b) : fabs((a-b)/a);\n\treturn (rel_err < max_rel_err);\n}\n\nstatic uint64_t\nfactorial(unsigned x)\n{\n\tuint64_t ret = 1;\n\tunsigned i;\n\n\tfor (i = 2; i <= x; i++)\n\t\tret *= (uint64_t)i;\n\n\treturn (ret);\n}\n\nTEST_BEGIN(test_ln_gamma_factorial)\n{\n\tunsigned x;\n\n\t/* exp(ln_gamma(x)) == (x-1)! for integer x. */\n\tfor (x = 1; x <= 21; x++) {\n\t\tassert_true(double_eq_rel(exp(ln_gamma(x)),\n\t\t    (double)factorial(x-1), MAX_REL_ERR, MAX_ABS_ERR),\n\t\t    \"Incorrect factorial result for x=%u\", x);\n\t}\n}\nTEST_END\n\n/* Expected ln_gamma([0.0..100.0] increment=0.25). */\nstatic const double ln_gamma_misc_expected[] = {\n\tINFINITY,\n\t1.28802252469807743, 0.57236494292470008, 0.20328095143129538,\n\t0.00000000000000000, -0.09827183642181320, -0.12078223763524518,\n\t-0.08440112102048555, 0.00000000000000000, 0.12487171489239651,\n\t0.28468287047291918, 0.47521466691493719, 0.69314718055994529,\n\t0.93580193110872523, 1.20097360234707429, 1.48681557859341718,\n\t1.79175946922805496, 2.11445692745037128, 2.45373657084244234,\n\t2.80857141857573644, 3.17805383034794575, 3.56137591038669710,\n\t3.95781396761871651, 4.36671603662228680, 4.78749174278204581,\n\t5.21960398699022932, 5.66256205985714178, 6.11591589143154568,\n\t6.57925121201010121, 7.05218545073853953, 7.53436423675873268,\n\t8.02545839631598312, 8.52516136106541467, 9.03318691960512332,\n\t9.54926725730099690, 10.07315123968123949, 10.60460290274525086,\n\t11.14340011995171231, 11.68933342079726856, 12.24220494005076176,\n\t12.80182748008146909, 13.36802367147604720, 13.94062521940376342,\n\t14.51947222506051816, 15.10441257307551943, 15.69530137706046524,\n\t16.29200047656724237, 16.89437797963419285, 17.50230784587389010,\n\t18.11566950571089407, 18.73434751193644843, 19.35823122022435427,\n\t19.98721449566188468, 20.62119544270163018, 21.26007615624470048,\n\t21.90376249182879320, 22.55216385312342098, 23.20519299513386002,\n\t23.86276584168908954, 24.52480131594137802, 25.19122118273868338,\n\t25.86194990184851861, 26.53691449111561340, 27.21604439872720604,\n\t27.89927138384089389, 28.58652940490193828, 29.27775451504081516,\n\t29.97288476399884871, 30.67186010608067548, 31.37462231367769050,\n\t32.08111489594735843, 32.79128302226991565, 33.50507345013689076,\n\t34.22243445715505317, 34.94331577687681545, 35.66766853819134298,\n\t36.39544520803305261, 37.12659953718355865, 37.86108650896109395,\n\t38.59886229060776230, 39.33988418719949465, 40.08411059791735198,\n\t40.83150097453079752, 41.58201578195490100, 42.33561646075348506,\n\t43.09226539146988699, 43.85192586067515208, 44.61456202863158893,\n\t45.38013889847690052, 46.14862228684032885, 46.91997879580877395,\n\t47.69417578616628361, 48.47118135183522014, 49.25096429545256882,\n\t50.03349410501914463, 50.81874093156324790, 51.60667556776436982,\n\t52.39726942748592364, 53.19049452616926743, 53.98632346204390586,\n\t54.78472939811231157, 55.58568604486942633, 56.38916764371992940,\n\t57.19514895105859864, 58.00360522298051080, 58.81451220059079787,\n\t59.62784609588432261, 60.44358357816834371, 61.26170176100199427,\n\t62.08217818962842927, 62.90499082887649962, 63.73011805151035958,\n\t64.55753862700632340, 65.38723171073768015, 66.21917683354901385,\n\t67.05335389170279825, 67.88974313718154008, 68.72832516833013017,\n\t69.56908092082363737, 70.41199165894616385, 71.25703896716800045,\n\t72.10420474200799390, 72.95347118416940191, 73.80482079093779646,\n\t74.65823634883015814, 75.51370092648485866, 76.37119786778275454,\n\t77.23071078519033961, 78.09222355331530707, 78.95572030266725960,\n\t79.82118541361435859, 80.68860351052903468, 81.55795945611502873,\n\t82.42923834590904164, 83.30242550295004378, 84.17750647261028973,\n\t85.05446701758152983, 85.93329311301090456, 86.81397094178107920,\n\t87.69648688992882057, 88.58082754219766741, 89.46697967771913795,\n\t90.35493026581838194, 91.24466646193963015, 92.13617560368709292,\n\t93.02944520697742803, 93.92446296229978486, 94.82121673107967297,\n\t95.71969454214321615, 96.61988458827809723, 97.52177522288820910,\n\t98.42535495673848800, 99.33061245478741341, 100.23753653310367895,\n\t101.14611615586458981, 102.05634043243354370, 102.96819861451382394,\n\t103.88168009337621811, 104.79677439715833032, 105.71347118823287303,\n\t106.63176026064346047, 107.55163153760463501, 108.47307506906540198,\n\t109.39608102933323153, 110.32063971475740516, 111.24674154146920557,\n\t112.17437704317786995, 113.10353686902013237, 114.03421178146170689,\n\t114.96639265424990128, 115.90007047041454769, 116.83523632031698014,\n\t117.77188139974506953, 118.70999700805310795, 119.64957454634490830,\n\t120.59060551569974962, 121.53308151543865279, 122.47699424143097247,\n\t123.42233548443955726, 124.36909712850338394, 125.31727114935689826,\n\t126.26684961288492559, 127.21782467361175861, 128.17018857322420899,\n\t129.12393363912724453, 130.07905228303084755, 131.03553699956862033,\n\t131.99338036494577864, 132.95257503561629164, 133.91311374698926784,\n\t134.87498931216194364, 135.83819462068046846, 136.80272263732638294,\n\t137.76856640092901785, 138.73571902320256299, 139.70417368760718091,\n\t140.67392364823425055, 141.64496222871400732, 142.61728282114600574,\n\t143.59087888505104047, 144.56574394634486680, 145.54187159633210058,\n\t146.51925549072063859, 147.49788934865566148, 148.47776695177302031,\n\t149.45888214327129617, 150.44122882700193600, 151.42480096657754984,\n\t152.40959258449737490, 153.39559776128982094, 154.38281063467164245,\n\t155.37122539872302696, 156.36083630307879844, 157.35163765213474107,\n\t158.34362380426921391, 159.33678917107920370, 160.33112821663092973,\n\t161.32663545672428995, 162.32330545817117695, 163.32113283808695314,\n\t164.32011226319519892, 165.32023844914485267, 166.32150615984036790,\n\t167.32391020678358018, 168.32744544842768164, 169.33210678954270634,\n\t170.33788918059275375, 171.34478761712384198, 172.35279713916281707,\n\t173.36191283062726143, 174.37212981874515094, 175.38344327348534080,\n\t176.39584840699734514, 177.40934047306160437, 178.42391476654847793,\n\t179.43956662288721304, 180.45629141754378111, 181.47408456550741107,\n\t182.49294152078630304, 183.51285777591152737, 184.53382886144947861,\n\t185.55585034552262869, 186.57891783333786861, 187.60302696672312095,\n\t188.62817342367162610, 189.65435291789341932, 190.68156119837468054,\n\t191.70979404894376330, 192.73904728784492590, 193.76931676731820176,\n\t194.80059837318714244, 195.83288802445184729, 196.86618167288995096,\n\t197.90047530266301123, 198.93576492992946214, 199.97204660246373464,\n\t201.00931639928148797, 202.04757043027063901, 203.08680483582807597,\n\t204.12701578650228385, 205.16819948264117102, 206.21035215404597807,\n\t207.25347005962987623, 208.29754948708190909, 209.34258675253678916,\n\t210.38857820024875878, 211.43552020227099320, 212.48340915813977858,\n\t213.53224149456323744, 214.58201366511514152, 215.63272214993284592,\n\t216.68436345542014010, 217.73693411395422004, 218.79043068359703739,\n\t219.84484974781133815, 220.90018791517996988, 221.95644181913033322,\n\t223.01360811766215875, 224.07168349307951871, 225.13066465172661879,\n\t226.19054832372759734, 227.25133126272962159, 228.31301024565024704,\n\t229.37558207242807384, 230.43904356577689896, 231.50339157094342113,\n\t232.56862295546847008, 233.63473460895144740, 234.70172344281823484,\n\t235.76958639009222907, 236.83832040516844586, 237.90792246359117712,\n\t238.97838956183431947, 240.04971871708477238, 241.12190696702904802,\n\t242.19495136964280846, 243.26884900298270509, 244.34359696498191283,\n\t245.41919237324782443, 246.49563236486270057, 247.57291409618682110,\n\t248.65103474266476269, 249.72999149863338175, 250.80978157713354904,\n\t251.89040220972316320, 252.97185064629374551, 254.05412415488834199,\n\t255.13722002152300661, 256.22113555000953511, 257.30586806178126835,\n\t258.39141489572085675, 259.47777340799029844, 260.56494097186322279,\n\t261.65291497755913497, 262.74169283208021852, 263.83127195904967266,\n\t264.92164979855277807, 266.01282380697938379, 267.10479145686849733,\n\t268.19755023675537586, 269.29109765101975427, 270.38543121973674488,\n\t271.48054847852881721, 272.57644697842033565, 273.67312428569374561,\n\t274.77057798174683967, 275.86880566295326389, 276.96780494052313770,\n\t278.06757344036617496, 279.16810880295668085, 280.26940868320008349,\n\t281.37147075030043197, 282.47429268763045229, 283.57787219260217171,\n\t284.68220697654078322, 285.78729476455760050, 286.89313329542699194,\n\t287.99972032146268930, 289.10705360839756395, 290.21513093526289140,\n\t291.32395009427028754, 292.43350889069523646, 293.54380514276073200,\n\t294.65483668152336350, 295.76660135076059532, 296.87909700685889902,\n\t297.99232151870342022, 299.10627276756946458, 300.22094864701409733,\n\t301.33634706277030091, 302.45246593264130297, 303.56930318639643929,\n\t304.68685676566872189, 305.80512462385280514, 306.92410472600477078,\n\t308.04379504874236773, 309.16419358014690033, 310.28529831966631036,\n\t311.40710727801865687, 312.52961847709792664, 313.65282994987899201,\n\t314.77673974032603610, 315.90134590329950015, 317.02664650446632777,\n\t318.15263962020929966, 319.27932333753892635, 320.40669575400545455,\n\t321.53475497761127144, 322.66349912672620803, 323.79292633000159185,\n\t324.92303472628691452, 326.05382246454587403, 327.18528770377525916,\n\t328.31742861292224234, 329.45024337080525356, 330.58373016603343331,\n\t331.71788719692847280, 332.85271267144611329, 333.98820480709991898,\n\t335.12436183088397001, 336.26118197919845443, 337.39866349777429377,\n\t338.53680464159958774, 339.67560367484657036, 340.81505887079896411,\n\t341.95516851178109619, 343.09593088908627578, 344.23734430290727460,\n\t345.37940706226686416, 346.52211748494903532, 347.66547389743118401,\n\t348.80947463481720661, 349.95411804077025408, 351.09940246744753267,\n\t352.24532627543504759, 353.39188783368263103, 354.53908551944078908,\n\t355.68691771819692349, 356.83538282361303118, 357.98447923746385868,\n\t359.13420536957539753\n};\n\nTEST_BEGIN(test_ln_gamma_misc)\n{\n\tunsigned i;\n\n\tfor (i = 1; i < sizeof(ln_gamma_misc_expected)/sizeof(double); i++) {\n\t\tdouble x = (double)i * 0.25;\n\t\tassert_true(double_eq_rel(ln_gamma(x),\n\t\t    ln_gamma_misc_expected[i], MAX_REL_ERR, MAX_ABS_ERR),\n\t\t    \"Incorrect ln_gamma result for i=%u\", i);\n\t}\n}\nTEST_END\n\n/* Expected pt_norm([0.01..0.99] increment=0.01). */\nstatic const double pt_norm_expected[] = {\n\t-INFINITY,\n\t-2.32634787404084076, -2.05374891063182252, -1.88079360815125085,\n\t-1.75068607125216946, -1.64485362695147264, -1.55477359459685305,\n\t-1.47579102817917063, -1.40507156030963221, -1.34075503369021654,\n\t-1.28155156554460081, -1.22652812003661049, -1.17498679206608991,\n\t-1.12639112903880045, -1.08031934081495606, -1.03643338949378938,\n\t-0.99445788320975281, -0.95416525314619416, -0.91536508784281390,\n\t-0.87789629505122846, -0.84162123357291418, -0.80642124701824025,\n\t-0.77219321418868492, -0.73884684918521371, -0.70630256284008752,\n\t-0.67448975019608171, -0.64334540539291685, -0.61281299101662701,\n\t-0.58284150727121620, -0.55338471955567281, -0.52440051270804067,\n\t-0.49585034734745320, -0.46769879911450812, -0.43991316567323380,\n\t-0.41246312944140462, -0.38532046640756751, -0.35845879325119373,\n\t-0.33185334643681652, -0.30548078809939738, -0.27931903444745404,\n\t-0.25334710313579978, -0.22754497664114931, -0.20189347914185077,\n\t-0.17637416478086135, -0.15096921549677725, -0.12566134685507399,\n\t-0.10043372051146975, -0.07526986209982976, -0.05015358346473352,\n\t-0.02506890825871106, 0.00000000000000000, 0.02506890825871106,\n\t0.05015358346473366, 0.07526986209982990, 0.10043372051146990,\n\t0.12566134685507413, 0.15096921549677739, 0.17637416478086146,\n\t0.20189347914185105, 0.22754497664114931, 0.25334710313579978,\n\t0.27931903444745404, 0.30548078809939738, 0.33185334643681652,\n\t0.35845879325119373, 0.38532046640756762, 0.41246312944140484,\n\t0.43991316567323391, 0.46769879911450835, 0.49585034734745348,\n\t0.52440051270804111, 0.55338471955567303, 0.58284150727121620,\n\t0.61281299101662701, 0.64334540539291685, 0.67448975019608171,\n\t0.70630256284008752, 0.73884684918521371, 0.77219321418868492,\n\t0.80642124701824036, 0.84162123357291441, 0.87789629505122879,\n\t0.91536508784281423, 0.95416525314619460, 0.99445788320975348,\n\t1.03643338949378938, 1.08031934081495606, 1.12639112903880045,\n\t1.17498679206608991, 1.22652812003661049, 1.28155156554460081,\n\t1.34075503369021654, 1.40507156030963265, 1.47579102817917085,\n\t1.55477359459685394, 1.64485362695147308, 1.75068607125217102,\n\t1.88079360815125041, 2.05374891063182208, 2.32634787404084076\n};\n\nTEST_BEGIN(test_pt_norm)\n{\n\tunsigned i;\n\n\tfor (i = 1; i < sizeof(pt_norm_expected)/sizeof(double); i++) {\n\t\tdouble p = (double)i * 0.01;\n\t\tassert_true(double_eq_rel(pt_norm(p), pt_norm_expected[i],\n\t\t    MAX_REL_ERR, MAX_ABS_ERR),\n\t\t    \"Incorrect pt_norm result for i=%u\", i);\n\t}\n}\nTEST_END\n\n/*\n * Expected pt_chi2(p=[0.01..0.99] increment=0.07,\n *                  df={0.1, 1.1, 10.1, 100.1, 1000.1}).\n */\nstatic const double pt_chi2_df[] = {0.1, 1.1, 10.1, 100.1, 1000.1};\nstatic const double pt_chi2_expected[] = {\n\t1.168926411457320e-40, 1.347680397072034e-22, 3.886980416666260e-17,\n\t8.245951724356564e-14, 2.068936347497604e-11, 1.562561743309233e-09,\n\t5.459543043426564e-08, 1.114775688149252e-06, 1.532101202364371e-05,\n\t1.553884683726585e-04, 1.239396954915939e-03, 8.153872320255721e-03,\n\t4.631183739647523e-02, 2.473187311701327e-01, 2.175254800183617e+00,\n\n\t0.0003729887888876379, 0.0164409238228929513, 0.0521523015190650113,\n\t0.1064701372271216612, 0.1800913735793082115, 0.2748704281195626931,\n\t0.3939246282787986497, 0.5420727552260817816, 0.7267265822221973259,\n\t0.9596554296000253670, 1.2607440376386165326, 1.6671185084541604304,\n\t2.2604828984738705167, 3.2868613342148607082, 6.9298574921692139839,\n\n\t2.606673548632508, 4.602913725294877, 5.646152813924212,\n\t6.488971315540869, 7.249823275816285, 7.977314231410841,\n\t8.700354939944047, 9.441728024225892, 10.224338321374127,\n\t11.076435368801061, 12.039320937038386, 13.183878752697167,\n\t14.657791935084575, 16.885728216339373, 23.361991680031817,\n\n\t70.14844087392152, 80.92379498849355, 85.53325420085891,\n\t88.94433120715347, 91.83732712857017, 94.46719943606301,\n\t96.96896479994635, 99.43412843510363, 101.94074719829733,\n\t104.57228644307247, 107.43900093448734, 110.71844673417287,\n\t114.76616819871325, 120.57422505959563, 135.92318818757556,\n\n\t899.0072447849649, 937.9271278858220, 953.8117189560207,\n\t965.3079371501154, 974.8974061207954, 983.4936235182347,\n\t991.5691170518946, 999.4334123954690, 1007.3391826856553,\n\t1015.5445154999951, 1024.3777075619569, 1034.3538789836223,\n\t1046.4872561869577, 1063.5717461999654, 1107.0741966053859\n};\n\nTEST_BEGIN(test_pt_chi2)\n{\n\tunsigned i, j;\n\tunsigned e = 0;\n\n\tfor (i = 0; i < sizeof(pt_chi2_df)/sizeof(double); i++) {\n\t\tdouble df = pt_chi2_df[i];\n\t\tdouble ln_gamma_df = ln_gamma(df * 0.5);\n\t\tfor (j = 1; j < 100; j += 7) {\n\t\t\tdouble p = (double)j * 0.01;\n\t\t\tassert_true(double_eq_rel(pt_chi2(p, df, ln_gamma_df),\n\t\t\t    pt_chi2_expected[e], MAX_REL_ERR, MAX_ABS_ERR),\n\t\t\t    \"Incorrect pt_chi2 result for i=%u, j=%u\", i, j);\n\t\t\te++;\n\t\t}\n\t}\n}\nTEST_END\n\n/*\n * Expected pt_gamma(p=[0.1..0.99] increment=0.07,\n *                   shape=[0.5..3.0] increment=0.5).\n */\nstatic const double pt_gamma_shape[] = {0.5, 1.0, 1.5, 2.0, 2.5, 3.0};\nstatic const double pt_gamma_expected[] = {\n\t7.854392895485103e-05, 5.043466107888016e-03, 1.788288957794883e-02,\n\t3.900956150232906e-02, 6.913847560638034e-02, 1.093710833465766e-01,\n\t1.613412523825817e-01, 2.274682115597864e-01, 3.114117323127083e-01,\n\t4.189466220207417e-01, 5.598106789059246e-01, 7.521856146202706e-01,\n\t1.036125427911119e+00, 1.532450860038180e+00, 3.317448300510606e+00,\n\n\t0.01005033585350144, 0.08338160893905107, 0.16251892949777497,\n\t0.24846135929849966, 0.34249030894677596, 0.44628710262841947,\n\t0.56211891815354142, 0.69314718055994529, 0.84397007029452920,\n\t1.02165124753198167, 1.23787435600161766, 1.51412773262977574,\n\t1.89711998488588196, 2.52572864430825783, 4.60517018598809091,\n\n\t0.05741590094955853, 0.24747378084860744, 0.39888572212236084,\n\t0.54394139997444901, 0.69048812513915159, 0.84311389861296104,\n\t1.00580622221479898, 1.18298694218766931, 1.38038096305861213,\n\t1.60627736383027453, 1.87396970522337947, 2.20749220408081070,\n\t2.65852391865854942, 3.37934630984842244, 5.67243336507218476,\n\n\t0.1485547402532659, 0.4657458011640391, 0.6832386130709406,\n\t0.8794297834672100, 1.0700752852474524, 1.2629614217350744,\n\t1.4638400448580779, 1.6783469900166610, 1.9132338090606940,\n\t2.1778589228618777, 2.4868823970010991, 2.8664695666264195,\n\t3.3724415436062114, 4.1682658512758071, 6.6383520679938108,\n\n\t0.2771490383641385, 0.7195001279643727, 0.9969081732265243,\n\t1.2383497880608061, 1.4675206597269927, 1.6953064251816552,\n\t1.9291243435606809, 2.1757300955477641, 2.4428032131216391,\n\t2.7406534569230616, 3.0851445039665513, 3.5043101122033367,\n\t4.0575997065264637, 4.9182956424675286, 7.5431362346944937,\n\n\t0.4360451650782932, 0.9983600902486267, 1.3306365880734528,\n\t1.6129750834753802, 1.8767241606994294, 2.1357032436097660,\n\t2.3988853336865565, 2.6740603137235603, 2.9697561737517959,\n\t3.2971457713883265, 3.6731795898504660, 4.1275751617770631,\n\t4.7230515633946677, 5.6417477865306020, 8.4059469148854635\n};\n\nTEST_BEGIN(test_pt_gamma_shape)\n{\n\tunsigned i, j;\n\tunsigned e = 0;\n\n\tfor (i = 0; i < sizeof(pt_gamma_shape)/sizeof(double); i++) {\n\t\tdouble shape = pt_gamma_shape[i];\n\t\tdouble ln_gamma_shape = ln_gamma(shape);\n\t\tfor (j = 1; j < 100; j += 7) {\n\t\t\tdouble p = (double)j * 0.01;\n\t\t\tassert_true(double_eq_rel(pt_gamma(p, shape, 1.0,\n\t\t\t    ln_gamma_shape), pt_gamma_expected[e], MAX_REL_ERR,\n\t\t\t    MAX_ABS_ERR),\n\t\t\t    \"Incorrect pt_gamma result for i=%u, j=%u\", i, j);\n\t\t\te++;\n\t\t}\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_pt_gamma_scale)\n{\n\tdouble shape = 1.0;\n\tdouble ln_gamma_shape = ln_gamma(shape);\n\n\tassert_true(double_eq_rel(\n\t    pt_gamma(0.5, shape, 1.0, ln_gamma_shape) * 10.0,\n\t    pt_gamma(0.5, shape, 10.0, ln_gamma_shape), MAX_REL_ERR,\n\t    MAX_ABS_ERR),\n\t    \"Scale should be trivially equivalent to external multiplication\");\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_ln_gamma_factorial,\n\t    test_ln_gamma_misc,\n\t    test_pt_norm,\n\t    test_pt_chi2,\n\t    test_pt_gamma_shape,\n\t    test_pt_gamma_scale));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/mq.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#define\tNSENDERS\t3\n#define\tNMSGS\t\t100000\n\ntypedef struct mq_msg_s mq_msg_t;\nstruct mq_msg_s {\n\tmq_msg(mq_msg_t)\tlink;\n};\nmq_gen(static, mq_, mq_t, mq_msg_t, link)\n\nTEST_BEGIN(test_mq_basic)\n{\n\tmq_t mq;\n\tmq_msg_t msg;\n\n\tassert_false(mq_init(&mq), \"Unexpected mq_init() failure\");\n\tassert_u_eq(mq_count(&mq), 0, \"mq should be empty\");\n\tassert_ptr_null(mq_tryget(&mq),\n\t    \"mq_tryget() should fail when the queue is empty\");\n\n\tmq_put(&mq, &msg);\n\tassert_u_eq(mq_count(&mq), 1, \"mq should contain one message\");\n\tassert_ptr_eq(mq_tryget(&mq), &msg, \"mq_tryget() should return msg\");\n\n\tmq_put(&mq, &msg);\n\tassert_ptr_eq(mq_get(&mq), &msg, \"mq_get() should return msg\");\n\n\tmq_fini(&mq);\n}\nTEST_END\n\nstatic void *\nthd_receiver_start(void *arg)\n{\n\tmq_t *mq = (mq_t *)arg;\n\tunsigned i;\n\n\tfor (i = 0; i < (NSENDERS * NMSGS); i++) {\n\t\tmq_msg_t *msg = mq_get(mq);\n\t\tassert_ptr_not_null(msg, \"mq_get() should never return NULL\");\n\t\tdallocx(msg, 0);\n\t}\n\treturn (NULL);\n}\n\nstatic void *\nthd_sender_start(void *arg)\n{\n\tmq_t *mq = (mq_t *)arg;\n\tunsigned i;\n\n\tfor (i = 0; i < NMSGS; i++) {\n\t\tmq_msg_t *msg;\n\t\tvoid *p;\n\t\tp = mallocx(sizeof(mq_msg_t), 0);\n\t\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\t\tmsg = (mq_msg_t *)p;\n\t\tmq_put(mq, msg);\n\t}\n\treturn (NULL);\n}\n\nTEST_BEGIN(test_mq_threaded)\n{\n\tmq_t mq;\n\tthd_t receiver;\n\tthd_t senders[NSENDERS];\n\tunsigned i;\n\n\tassert_false(mq_init(&mq), \"Unexpected mq_init() failure\");\n\n\tthd_create(&receiver, thd_receiver_start, (void *)&mq);\n\tfor (i = 0; i < NSENDERS; i++)\n\t\tthd_create(&senders[i], thd_sender_start, (void *)&mq);\n\n\tthd_join(receiver, NULL);\n\tfor (i = 0; i < NSENDERS; i++)\n\t\tthd_join(senders[i], NULL);\n\n\tmq_fini(&mq);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_mq_basic,\n\t    test_mq_threaded));\n}\n\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/mtx.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#define\tNTHREADS\t2\n#define\tNINCRS\t\t2000000\n\nTEST_BEGIN(test_mtx_basic)\n{\n\tmtx_t mtx;\n\n\tassert_false(mtx_init(&mtx), \"Unexpected mtx_init() failure\");\n\tmtx_lock(&mtx);\n\tmtx_unlock(&mtx);\n\tmtx_fini(&mtx);\n}\nTEST_END\n\ntypedef struct {\n\tmtx_t\t\tmtx;\n\tunsigned\tx;\n} thd_start_arg_t;\n\nstatic void *\nthd_start(void *varg)\n{\n\tthd_start_arg_t *arg = (thd_start_arg_t *)varg;\n\tunsigned i;\n\n\tfor (i = 0; i < NINCRS; i++) {\n\t\tmtx_lock(&arg->mtx);\n\t\targ->x++;\n\t\tmtx_unlock(&arg->mtx);\n\t}\n\treturn (NULL);\n}\n\nTEST_BEGIN(test_mtx_race)\n{\n\tthd_start_arg_t arg;\n\tthd_t thds[NTHREADS];\n\tunsigned i;\n\n\tassert_false(mtx_init(&arg.mtx), \"Unexpected mtx_init() failure\");\n\targ.x = 0;\n\tfor (i = 0; i < NTHREADS; i++)\n\t\tthd_create(&thds[i], thd_start, (void *)&arg);\n\tfor (i = 0; i < NTHREADS; i++)\n\t\tthd_join(thds[i], NULL);\n\tassert_u_eq(arg.x, NTHREADS * NINCRS,\n\t    \"Race-related counter corruption\");\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_mtx_basic,\n\t    test_mtx_race));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/nstime.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#define\tBILLION\tUINT64_C(1000000000)\n\nTEST_BEGIN(test_nstime_init)\n{\n\tnstime_t nst;\n\n\tnstime_init(&nst, 42000000043);\n\tassert_u64_eq(nstime_ns(&nst), 42000000043, \"ns incorrectly read\");\n\tassert_u64_eq(nstime_sec(&nst), 42, \"sec incorrectly read\");\n\tassert_u64_eq(nstime_nsec(&nst), 43, \"nsec incorrectly read\");\n}\nTEST_END\n\nTEST_BEGIN(test_nstime_init2)\n{\n\tnstime_t nst;\n\n\tnstime_init2(&nst, 42, 43);\n\tassert_u64_eq(nstime_sec(&nst), 42, \"sec incorrectly read\");\n\tassert_u64_eq(nstime_nsec(&nst), 43, \"nsec incorrectly read\");\n}\nTEST_END\n\nTEST_BEGIN(test_nstime_copy)\n{\n\tnstime_t nsta, nstb;\n\n\tnstime_init2(&nsta, 42, 43);\n\tnstime_init(&nstb, 0);\n\tnstime_copy(&nstb, &nsta);\n\tassert_u64_eq(nstime_sec(&nstb), 42, \"sec incorrectly copied\");\n\tassert_u64_eq(nstime_nsec(&nstb), 43, \"nsec incorrectly copied\");\n}\nTEST_END\n\nTEST_BEGIN(test_nstime_compare)\n{\n\tnstime_t nsta, nstb;\n\n\tnstime_init2(&nsta, 42, 43);\n\tnstime_copy(&nstb, &nsta);\n\tassert_d_eq(nstime_compare(&nsta, &nstb), 0, \"Times should be equal\");\n\tassert_d_eq(nstime_compare(&nstb, &nsta), 0, \"Times should be equal\");\n\n\tnstime_init2(&nstb, 42, 42);\n\tassert_d_eq(nstime_compare(&nsta, &nstb), 1,\n\t    \"nsta should be greater than nstb\");\n\tassert_d_eq(nstime_compare(&nstb, &nsta), -1,\n\t    \"nstb should be less than nsta\");\n\n\tnstime_init2(&nstb, 42, 44);\n\tassert_d_eq(nstime_compare(&nsta, &nstb), -1,\n\t    \"nsta should be less than nstb\");\n\tassert_d_eq(nstime_compare(&nstb, &nsta), 1,\n\t    \"nstb should be greater than nsta\");\n\n\tnstime_init2(&nstb, 41, BILLION - 1);\n\tassert_d_eq(nstime_compare(&nsta, &nstb), 1,\n\t    \"nsta should be greater than nstb\");\n\tassert_d_eq(nstime_compare(&nstb, &nsta), -1,\n\t    \"nstb should be less than nsta\");\n\n\tnstime_init2(&nstb, 43, 0);\n\tassert_d_eq(nstime_compare(&nsta, &nstb), -1,\n\t    \"nsta should be less than nstb\");\n\tassert_d_eq(nstime_compare(&nstb, &nsta), 1,\n\t    \"nstb should be greater than nsta\");\n}\nTEST_END\n\nTEST_BEGIN(test_nstime_add)\n{\n\tnstime_t nsta, nstb;\n\n\tnstime_init2(&nsta, 42, 43);\n\tnstime_copy(&nstb, &nsta);\n\tnstime_add(&nsta, &nstb);\n\tnstime_init2(&nstb, 84, 86);\n\tassert_d_eq(nstime_compare(&nsta, &nstb), 0,\n\t    \"Incorrect addition result\");\n\n\tnstime_init2(&nsta, 42, BILLION - 1);\n\tnstime_copy(&nstb, &nsta);\n\tnstime_add(&nsta, &nstb);\n\tnstime_init2(&nstb, 85, BILLION - 2);\n\tassert_d_eq(nstime_compare(&nsta, &nstb), 0,\n\t    \"Incorrect addition result\");\n}\nTEST_END\n\nTEST_BEGIN(test_nstime_subtract)\n{\n\tnstime_t nsta, nstb;\n\n\tnstime_init2(&nsta, 42, 43);\n\tnstime_copy(&nstb, &nsta);\n\tnstime_subtract(&nsta, &nstb);\n\tnstime_init(&nstb, 0);\n\tassert_d_eq(nstime_compare(&nsta, &nstb), 0,\n\t    \"Incorrect subtraction result\");\n\n\tnstime_init2(&nsta, 42, 43);\n\tnstime_init2(&nstb, 41, 44);\n\tnstime_subtract(&nsta, &nstb);\n\tnstime_init2(&nstb, 0, BILLION - 1);\n\tassert_d_eq(nstime_compare(&nsta, &nstb), 0,\n\t    \"Incorrect subtraction result\");\n}\nTEST_END\n\nTEST_BEGIN(test_nstime_imultiply)\n{\n\tnstime_t nsta, nstb;\n\n\tnstime_init2(&nsta, 42, 43);\n\tnstime_imultiply(&nsta, 10);\n\tnstime_init2(&nstb, 420, 430);\n\tassert_d_eq(nstime_compare(&nsta, &nstb), 0,\n\t    \"Incorrect multiplication result\");\n\n\tnstime_init2(&nsta, 42, 666666666);\n\tnstime_imultiply(&nsta, 3);\n\tnstime_init2(&nstb, 127, 999999998);\n\tassert_d_eq(nstime_compare(&nsta, &nstb), 0,\n\t    \"Incorrect multiplication result\");\n}\nTEST_END\n\nTEST_BEGIN(test_nstime_idivide)\n{\n\tnstime_t nsta, nstb;\n\n\tnstime_init2(&nsta, 42, 43);\n\tnstime_copy(&nstb, &nsta);\n\tnstime_imultiply(&nsta, 10);\n\tnstime_idivide(&nsta, 10);\n\tassert_d_eq(nstime_compare(&nsta, &nstb), 0,\n\t    \"Incorrect division result\");\n\n\tnstime_init2(&nsta, 42, 666666666);\n\tnstime_copy(&nstb, &nsta);\n\tnstime_imultiply(&nsta, 3);\n\tnstime_idivide(&nsta, 3);\n\tassert_d_eq(nstime_compare(&nsta, &nstb), 0,\n\t    \"Incorrect division result\");\n}\nTEST_END\n\nTEST_BEGIN(test_nstime_divide)\n{\n\tnstime_t nsta, nstb, nstc;\n\n\tnstime_init2(&nsta, 42, 43);\n\tnstime_copy(&nstb, &nsta);\n\tnstime_imultiply(&nsta, 10);\n\tassert_u64_eq(nstime_divide(&nsta, &nstb), 10,\n\t    \"Incorrect division result\");\n\n\tnstime_init2(&nsta, 42, 43);\n\tnstime_copy(&nstb, &nsta);\n\tnstime_imultiply(&nsta, 10);\n\tnstime_init(&nstc, 1);\n\tnstime_add(&nsta, &nstc);\n\tassert_u64_eq(nstime_divide(&nsta, &nstb), 10,\n\t    \"Incorrect division result\");\n\n\tnstime_init2(&nsta, 42, 43);\n\tnstime_copy(&nstb, &nsta);\n\tnstime_imultiply(&nsta, 10);\n\tnstime_init(&nstc, 1);\n\tnstime_subtract(&nsta, &nstc);\n\tassert_u64_eq(nstime_divide(&nsta, &nstb), 9,\n\t    \"Incorrect division result\");\n}\nTEST_END\n\nTEST_BEGIN(test_nstime_update)\n{\n\tnstime_t nst;\n\n\tnstime_init(&nst, 0);\n\n\tassert_false(nstime_update(&nst), \"Basic time update failed.\");\n\n\t/* Only Rip Van Winkle sleeps this long. */\n\t{\n\t\tnstime_t addend;\n\t\tnstime_init2(&addend, 631152000, 0);\n\t\tnstime_add(&nst, &addend);\n\t}\n\t{\n\t\tnstime_t nst0;\n\t\tnstime_copy(&nst0, &nst);\n\t\tassert_true(nstime_update(&nst),\n\t\t    \"Update should detect time roll-back.\");\n\t\tassert_d_eq(nstime_compare(&nst, &nst0), 0,\n\t\t    \"Time should not have been modified\");\n\t}\n\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_nstime_init,\n\t    test_nstime_init2,\n\t    test_nstime_copy,\n\t    test_nstime_compare,\n\t    test_nstime_add,\n\t    test_nstime_subtract,\n\t    test_nstime_imultiply,\n\t    test_nstime_idivide,\n\t    test_nstime_divide,\n\t    test_nstime_update));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/prng.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nTEST_BEGIN(test_prng_lg_range)\n{\n\tuint64_t sa, sb, ra, rb;\n\tunsigned lg_range;\n\n\tsa = 42;\n\tra = prng_lg_range(&sa, 64);\n\tsa = 42;\n\trb = prng_lg_range(&sa, 64);\n\tassert_u64_eq(ra, rb,\n\t    \"Repeated generation should produce repeated results\");\n\n\tsb = 42;\n\trb = prng_lg_range(&sb, 64);\n\tassert_u64_eq(ra, rb,\n\t    \"Equivalent generation should produce equivalent results\");\n\n\tsa = 42;\n\tra = prng_lg_range(&sa, 64);\n\trb = prng_lg_range(&sa, 64);\n\tassert_u64_ne(ra, rb,\n\t    \"Full-width results must not immediately repeat\");\n\n\tsa = 42;\n\tra = prng_lg_range(&sa, 64);\n\tfor (lg_range = 63; lg_range > 0; lg_range--) {\n\t\tsb = 42;\n\t\trb = prng_lg_range(&sb, lg_range);\n\t\tassert_u64_eq((rb & (UINT64_C(0xffffffffffffffff) << lg_range)),\n\t\t    0, \"High order bits should be 0, lg_range=%u\", lg_range);\n\t\tassert_u64_eq(rb, (ra >> (64 - lg_range)),\n\t\t    \"Expected high order bits of full-width result, \"\n\t\t    \"lg_range=%u\", lg_range);\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_prng_range)\n{\n\tuint64_t range;\n#define\tMAX_RANGE\t10000000\n#define\tRANGE_STEP\t97\n#define\tNREPS\t\t10\n\n\tfor (range = 2; range < MAX_RANGE; range += RANGE_STEP) {\n\t\tuint64_t s;\n\t\tunsigned rep;\n\n\t\ts = range;\n\t\tfor (rep = 0; rep < NREPS; rep++) {\n\t\t\tuint64_t r = prng_range(&s, range);\n\n\t\t\tassert_u64_lt(r, range, \"Out of range\");\n\t\t}\n\t}\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_prng_lg_range,\n\t    test_prng_range));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/prof_accum.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#define\tNTHREADS\t\t4\n#define\tNALLOCS_PER_THREAD\t50\n#define\tDUMP_INTERVAL\t\t1\n#define\tBT_COUNT_CHECK_INTERVAL\t5\n\n#ifdef JEMALLOC_PROF\nconst char *malloc_conf =\n    \"prof:true,prof_accum:true,prof_active:false,lg_prof_sample:0\";\n#endif\n\nstatic int\nprof_dump_open_intercept(bool propagate_err, const char *filename)\n{\n\tint fd;\n\n\tfd = open(\"/dev/null\", O_WRONLY);\n\tassert_d_ne(fd, -1, \"Unexpected open() failure\");\n\n\treturn (fd);\n}\n\nstatic void *\nalloc_from_permuted_backtrace(unsigned thd_ind, unsigned iteration)\n{\n\n\treturn (btalloc(1, thd_ind*NALLOCS_PER_THREAD + iteration));\n}\n\nstatic void *\nthd_start(void *varg)\n{\n\tunsigned thd_ind = *(unsigned *)varg;\n\tsize_t bt_count_prev, bt_count;\n\tunsigned i_prev, i;\n\n\ti_prev = 0;\n\tbt_count_prev = 0;\n\tfor (i = 0; i < NALLOCS_PER_THREAD; i++) {\n\t\tvoid *p = alloc_from_permuted_backtrace(thd_ind, i);\n\t\tdallocx(p, 0);\n\t\tif (i % DUMP_INTERVAL == 0) {\n\t\t\tassert_d_eq(mallctl(\"prof.dump\", NULL, NULL, NULL, 0),\n\t\t\t    0, \"Unexpected error while dumping heap profile\");\n\t\t}\n\n\t\tif (i % BT_COUNT_CHECK_INTERVAL == 0 ||\n\t\t    i+1 == NALLOCS_PER_THREAD) {\n\t\t\tbt_count = prof_bt_count();\n\t\t\tassert_zu_le(bt_count_prev+(i-i_prev), bt_count,\n\t\t\t    \"Expected larger backtrace count increase\");\n\t\t\ti_prev = i;\n\t\t\tbt_count_prev = bt_count;\n\t\t}\n\t}\n\n\treturn (NULL);\n}\n\nTEST_BEGIN(test_idump)\n{\n\tbool active;\n\tthd_t thds[NTHREADS];\n\tunsigned thd_args[NTHREADS];\n\tunsigned i;\n\n\ttest_skip_if(!config_prof);\n\n\tactive = true;\n\tassert_d_eq(mallctl(\"prof.active\", NULL, NULL, &active, sizeof(active)),\n\t    0, \"Unexpected mallctl failure while activating profiling\");\n\n\tprof_dump_open = prof_dump_open_intercept;\n\n\tfor (i = 0; i < NTHREADS; i++) {\n\t\tthd_args[i] = i;\n\t\tthd_create(&thds[i], thd_start, (void *)&thd_args[i]);\n\t}\n\tfor (i = 0; i < NTHREADS; i++)\n\t\tthd_join(thds[i], NULL);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_idump));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/prof_active.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#ifdef JEMALLOC_PROF\nconst char *malloc_conf =\n    \"prof:true,prof_thread_active_init:false,lg_prof_sample:0\";\n#endif\n\nstatic void\nmallctl_bool_get(const char *name, bool expected, const char *func, int line)\n{\n\tbool old;\n\tsize_t sz;\n\n\tsz = sizeof(old);\n\tassert_d_eq(mallctl(name, &old, &sz, NULL, 0), 0,\n\t    \"%s():%d: Unexpected mallctl failure reading %s\", func, line, name);\n\tassert_b_eq(old, expected, \"%s():%d: Unexpected %s value\", func, line,\n\t    name);\n}\n\nstatic void\nmallctl_bool_set(const char *name, bool old_expected, bool val_new,\n    const char *func, int line)\n{\n\tbool old;\n\tsize_t sz;\n\n\tsz = sizeof(old);\n\tassert_d_eq(mallctl(name, &old, &sz, &val_new, sizeof(val_new)), 0,\n\t    \"%s():%d: Unexpected mallctl failure reading/writing %s\", func,\n\t    line, name);\n\tassert_b_eq(old, old_expected, \"%s():%d: Unexpected %s value\", func,\n\t    line, name);\n}\n\nstatic void\nmallctl_prof_active_get_impl(bool prof_active_old_expected, const char *func,\n    int line)\n{\n\n\tmallctl_bool_get(\"prof.active\", prof_active_old_expected, func, line);\n}\n#define\tmallctl_prof_active_get(a)\t\t\t\t\t\\\n\tmallctl_prof_active_get_impl(a, __func__, __LINE__)\n\nstatic void\nmallctl_prof_active_set_impl(bool prof_active_old_expected,\n    bool prof_active_new, const char *func, int line)\n{\n\n\tmallctl_bool_set(\"prof.active\", prof_active_old_expected,\n\t    prof_active_new, func, line);\n}\n#define\tmallctl_prof_active_set(a, b)\t\t\t\t\t\\\n\tmallctl_prof_active_set_impl(a, b, __func__, __LINE__)\n\nstatic void\nmallctl_thread_prof_active_get_impl(bool thread_prof_active_old_expected,\n    const char *func, int line)\n{\n\n\tmallctl_bool_get(\"thread.prof.active\", thread_prof_active_old_expected,\n\t    func, line);\n}\n#define\tmallctl_thread_prof_active_get(a)\t\t\t\t\\\n\tmallctl_thread_prof_active_get_impl(a, __func__, __LINE__)\n\nstatic void\nmallctl_thread_prof_active_set_impl(bool thread_prof_active_old_expected,\n    bool thread_prof_active_new, const char *func, int line)\n{\n\n\tmallctl_bool_set(\"thread.prof.active\", thread_prof_active_old_expected,\n\t    thread_prof_active_new, func, line);\n}\n#define\tmallctl_thread_prof_active_set(a, b)\t\t\t\t\\\n\tmallctl_thread_prof_active_set_impl(a, b, __func__, __LINE__)\n\nstatic void\nprof_sampling_probe_impl(bool expect_sample, const char *func, int line)\n{\n\tvoid *p;\n\tsize_t expected_backtraces = expect_sample ? 1 : 0;\n\n\tassert_zu_eq(prof_bt_count(), 0, \"%s():%d: Expected 0 backtraces\", func,\n\t    line);\n\tp = mallocx(1, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\tassert_zu_eq(prof_bt_count(), expected_backtraces,\n\t    \"%s():%d: Unexpected backtrace count\", func, line);\n\tdallocx(p, 0);\n}\n#define\tprof_sampling_probe(a)\t\t\t\t\t\t\\\n\tprof_sampling_probe_impl(a, __func__, __LINE__)\n\nTEST_BEGIN(test_prof_active)\n{\n\n\ttest_skip_if(!config_prof);\n\n\tmallctl_prof_active_get(true);\n\tmallctl_thread_prof_active_get(false);\n\n\tmallctl_prof_active_set(true, true);\n\tmallctl_thread_prof_active_set(false, false);\n\t/* prof.active, !thread.prof.active. */\n\tprof_sampling_probe(false);\n\n\tmallctl_prof_active_set(true, false);\n\tmallctl_thread_prof_active_set(false, false);\n\t/* !prof.active, !thread.prof.active. */\n\tprof_sampling_probe(false);\n\n\tmallctl_prof_active_set(false, false);\n\tmallctl_thread_prof_active_set(false, true);\n\t/* !prof.active, thread.prof.active. */\n\tprof_sampling_probe(false);\n\n\tmallctl_prof_active_set(false, true);\n\tmallctl_thread_prof_active_set(true, true);\n\t/* prof.active, thread.prof.active. */\n\tprof_sampling_probe(true);\n\n\t/* Restore settings. */\n\tmallctl_prof_active_set(true, true);\n\tmallctl_thread_prof_active_set(true, false);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_prof_active));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/prof_gdump.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#ifdef JEMALLOC_PROF\nconst char *malloc_conf = \"prof:true,prof_active:false,prof_gdump:true\";\n#endif\n\nstatic bool did_prof_dump_open;\n\nstatic int\nprof_dump_open_intercept(bool propagate_err, const char *filename)\n{\n\tint fd;\n\n\tdid_prof_dump_open = true;\n\n\tfd = open(\"/dev/null\", O_WRONLY);\n\tassert_d_ne(fd, -1, \"Unexpected open() failure\");\n\n\treturn (fd);\n}\n\nTEST_BEGIN(test_gdump)\n{\n\tbool active, gdump, gdump_old;\n\tvoid *p, *q, *r, *s;\n\tsize_t sz;\n\n\ttest_skip_if(!config_prof);\n\n\tactive = true;\n\tassert_d_eq(mallctl(\"prof.active\", NULL, NULL, &active, sizeof(active)),\n\t    0, \"Unexpected mallctl failure while activating profiling\");\n\n\tprof_dump_open = prof_dump_open_intercept;\n\n\tdid_prof_dump_open = false;\n\tp = mallocx(chunksize, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\tassert_true(did_prof_dump_open, \"Expected a profile dump\");\n\n\tdid_prof_dump_open = false;\n\tq = mallocx(chunksize, 0);\n\tassert_ptr_not_null(q, \"Unexpected mallocx() failure\");\n\tassert_true(did_prof_dump_open, \"Expected a profile dump\");\n\n\tgdump = false;\n\tsz = sizeof(gdump_old);\n\tassert_d_eq(mallctl(\"prof.gdump\", &gdump_old, &sz, &gdump,\n\t    sizeof(gdump)), 0,\n\t    \"Unexpected mallctl failure while disabling prof.gdump\");\n\tassert(gdump_old);\n\tdid_prof_dump_open = false;\n\tr = mallocx(chunksize, 0);\n\tassert_ptr_not_null(q, \"Unexpected mallocx() failure\");\n\tassert_false(did_prof_dump_open, \"Unexpected profile dump\");\n\n\tgdump = true;\n\tsz = sizeof(gdump_old);\n\tassert_d_eq(mallctl(\"prof.gdump\", &gdump_old, &sz, &gdump,\n\t    sizeof(gdump)), 0,\n\t    \"Unexpected mallctl failure while enabling prof.gdump\");\n\tassert(!gdump_old);\n\tdid_prof_dump_open = false;\n\ts = mallocx(chunksize, 0);\n\tassert_ptr_not_null(q, \"Unexpected mallocx() failure\");\n\tassert_true(did_prof_dump_open, \"Expected a profile dump\");\n\n\tdallocx(p, 0);\n\tdallocx(q, 0);\n\tdallocx(r, 0);\n\tdallocx(s, 0);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_gdump));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/prof_idump.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#ifdef JEMALLOC_PROF\nconst char *malloc_conf =\n    \"prof:true,prof_accum:true,prof_active:false,lg_prof_sample:0,\"\n    \"lg_prof_interval:0\";\n#endif\n\nstatic bool did_prof_dump_open;\n\nstatic int\nprof_dump_open_intercept(bool propagate_err, const char *filename)\n{\n\tint fd;\n\n\tdid_prof_dump_open = true;\n\n\tfd = open(\"/dev/null\", O_WRONLY);\n\tassert_d_ne(fd, -1, \"Unexpected open() failure\");\n\n\treturn (fd);\n}\n\nTEST_BEGIN(test_idump)\n{\n\tbool active;\n\tvoid *p;\n\n\ttest_skip_if(!config_prof);\n\n\tactive = true;\n\tassert_d_eq(mallctl(\"prof.active\", NULL, NULL, &active, sizeof(active)),\n\t    0, \"Unexpected mallctl failure while activating profiling\");\n\n\tprof_dump_open = prof_dump_open_intercept;\n\n\tdid_prof_dump_open = false;\n\tp = mallocx(1, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\tdallocx(p, 0);\n\tassert_true(did_prof_dump_open, \"Expected a profile dump\");\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_idump));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/prof_reset.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#ifdef JEMALLOC_PROF\nconst char *malloc_conf =\n    \"prof:true,prof_active:false,lg_prof_sample:0\";\n#endif\n\nstatic int\nprof_dump_open_intercept(bool propagate_err, const char *filename)\n{\n\tint fd;\n\n\tfd = open(\"/dev/null\", O_WRONLY);\n\tassert_d_ne(fd, -1, \"Unexpected open() failure\");\n\n\treturn (fd);\n}\n\nstatic void\nset_prof_active(bool active)\n{\n\n\tassert_d_eq(mallctl(\"prof.active\", NULL, NULL, &active, sizeof(active)),\n\t    0, \"Unexpected mallctl failure\");\n}\n\nstatic size_t\nget_lg_prof_sample(void)\n{\n\tsize_t lg_prof_sample;\n\tsize_t sz = sizeof(size_t);\n\n\tassert_d_eq(mallctl(\"prof.lg_sample\", &lg_prof_sample, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl failure while reading profiling sample rate\");\n\treturn (lg_prof_sample);\n}\n\nstatic void\ndo_prof_reset(size_t lg_prof_sample)\n{\n\tassert_d_eq(mallctl(\"prof.reset\", NULL, NULL,\n\t    &lg_prof_sample, sizeof(size_t)), 0,\n\t    \"Unexpected mallctl failure while resetting profile data\");\n\tassert_zu_eq(lg_prof_sample, get_lg_prof_sample(),\n\t    \"Expected profile sample rate change\");\n}\n\nTEST_BEGIN(test_prof_reset_basic)\n{\n\tsize_t lg_prof_sample_orig, lg_prof_sample, lg_prof_sample_next;\n\tsize_t sz;\n\tunsigned i;\n\n\ttest_skip_if(!config_prof);\n\n\tsz = sizeof(size_t);\n\tassert_d_eq(mallctl(\"opt.lg_prof_sample\", &lg_prof_sample_orig, &sz,\n\t    NULL, 0), 0,\n\t    \"Unexpected mallctl failure while reading profiling sample rate\");\n\tassert_zu_eq(lg_prof_sample_orig, 0,\n\t    \"Unexpected profiling sample rate\");\n\tlg_prof_sample = get_lg_prof_sample();\n\tassert_zu_eq(lg_prof_sample_orig, lg_prof_sample,\n\t    \"Unexpected disagreement between \\\"opt.lg_prof_sample\\\" and \"\n\t    \"\\\"prof.lg_sample\\\"\");\n\n\t/* Test simple resets. */\n\tfor (i = 0; i < 2; i++) {\n\t\tassert_d_eq(mallctl(\"prof.reset\", NULL, NULL, NULL, 0), 0,\n\t\t    \"Unexpected mallctl failure while resetting profile data\");\n\t\tlg_prof_sample = get_lg_prof_sample();\n\t\tassert_zu_eq(lg_prof_sample_orig, lg_prof_sample,\n\t\t    \"Unexpected profile sample rate change\");\n\t}\n\n\t/* Test resets with prof.lg_sample changes. */\n\tlg_prof_sample_next = 1;\n\tfor (i = 0; i < 2; i++) {\n\t\tdo_prof_reset(lg_prof_sample_next);\n\t\tlg_prof_sample = get_lg_prof_sample();\n\t\tassert_zu_eq(lg_prof_sample, lg_prof_sample_next,\n\t\t    \"Expected profile sample rate change\");\n\t\tlg_prof_sample_next = lg_prof_sample_orig;\n\t}\n\n\t/* Make sure the test code restored prof.lg_sample. */\n\tlg_prof_sample = get_lg_prof_sample();\n\tassert_zu_eq(lg_prof_sample_orig, lg_prof_sample,\n\t    \"Unexpected disagreement between \\\"opt.lg_prof_sample\\\" and \"\n\t    \"\\\"prof.lg_sample\\\"\");\n}\nTEST_END\n\nbool prof_dump_header_intercepted = false;\nprof_cnt_t cnt_all_copy = {0, 0, 0, 0};\nstatic bool\nprof_dump_header_intercept(bool propagate_err, const prof_cnt_t *cnt_all)\n{\n\n\tprof_dump_header_intercepted = true;\n\tmemcpy(&cnt_all_copy, cnt_all, sizeof(prof_cnt_t));\n\n\treturn (false);\n}\n\nTEST_BEGIN(test_prof_reset_cleanup)\n{\n\tvoid *p;\n\tprof_dump_header_t *prof_dump_header_orig;\n\n\ttest_skip_if(!config_prof);\n\n\tset_prof_active(true);\n\n\tassert_zu_eq(prof_bt_count(), 0, \"Expected 0 backtraces\");\n\tp = mallocx(1, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\tassert_zu_eq(prof_bt_count(), 1, \"Expected 1 backtrace\");\n\n\tprof_dump_header_orig = prof_dump_header;\n\tprof_dump_header = prof_dump_header_intercept;\n\tassert_false(prof_dump_header_intercepted, \"Unexpected intercept\");\n\n\tassert_d_eq(mallctl(\"prof.dump\", NULL, NULL, NULL, 0),\n\t    0, \"Unexpected error while dumping heap profile\");\n\tassert_true(prof_dump_header_intercepted, \"Expected intercept\");\n\tassert_u64_eq(cnt_all_copy.curobjs, 1, \"Expected 1 allocation\");\n\n\tassert_d_eq(mallctl(\"prof.reset\", NULL, NULL, NULL, 0), 0,\n\t    \"Unexpected error while resetting heap profile data\");\n\tassert_d_eq(mallctl(\"prof.dump\", NULL, NULL, NULL, 0),\n\t    0, \"Unexpected error while dumping heap profile\");\n\tassert_u64_eq(cnt_all_copy.curobjs, 0, \"Expected 0 allocations\");\n\tassert_zu_eq(prof_bt_count(), 1, \"Expected 1 backtrace\");\n\n\tprof_dump_header = prof_dump_header_orig;\n\n\tdallocx(p, 0);\n\tassert_zu_eq(prof_bt_count(), 0, \"Expected 0 backtraces\");\n\n\tset_prof_active(false);\n}\nTEST_END\n\n#define\tNTHREADS\t\t4\n#define\tNALLOCS_PER_THREAD\t(1U << 13)\n#define\tOBJ_RING_BUF_COUNT\t1531\n#define\tRESET_INTERVAL\t\t(1U << 10)\n#define\tDUMP_INTERVAL\t\t3677\nstatic void *\nthd_start(void *varg)\n{\n\tunsigned thd_ind = *(unsigned *)varg;\n\tunsigned i;\n\tvoid *objs[OBJ_RING_BUF_COUNT];\n\n\tmemset(objs, 0, sizeof(objs));\n\n\tfor (i = 0; i < NALLOCS_PER_THREAD; i++) {\n\t\tif (i % RESET_INTERVAL == 0) {\n\t\t\tassert_d_eq(mallctl(\"prof.reset\", NULL, NULL, NULL, 0),\n\t\t\t    0, \"Unexpected error while resetting heap profile \"\n\t\t\t    \"data\");\n\t\t}\n\n\t\tif (i % DUMP_INTERVAL == 0) {\n\t\t\tassert_d_eq(mallctl(\"prof.dump\", NULL, NULL, NULL, 0),\n\t\t\t    0, \"Unexpected error while dumping heap profile\");\n\t\t}\n\n\t\t{\n\t\t\tvoid **pp = &objs[i % OBJ_RING_BUF_COUNT];\n\t\t\tif (*pp != NULL) {\n\t\t\t\tdallocx(*pp, 0);\n\t\t\t\t*pp = NULL;\n\t\t\t}\n\t\t\t*pp = btalloc(1, thd_ind*NALLOCS_PER_THREAD + i);\n\t\t\tassert_ptr_not_null(*pp,\n\t\t\t    \"Unexpected btalloc() failure\");\n\t\t}\n\t}\n\n\t/* Clean up any remaining objects. */\n\tfor (i = 0; i < OBJ_RING_BUF_COUNT; i++) {\n\t\tvoid **pp = &objs[i % OBJ_RING_BUF_COUNT];\n\t\tif (*pp != NULL) {\n\t\t\tdallocx(*pp, 0);\n\t\t\t*pp = NULL;\n\t\t}\n\t}\n\n\treturn (NULL);\n}\n\nTEST_BEGIN(test_prof_reset)\n{\n\tsize_t lg_prof_sample_orig;\n\tthd_t thds[NTHREADS];\n\tunsigned thd_args[NTHREADS];\n\tunsigned i;\n\tsize_t bt_count, tdata_count;\n\n\ttest_skip_if(!config_prof);\n\n\tbt_count = prof_bt_count();\n\tassert_zu_eq(bt_count, 0,\n\t    \"Unexpected pre-existing tdata structures\");\n\ttdata_count = prof_tdata_count();\n\n\tlg_prof_sample_orig = get_lg_prof_sample();\n\tdo_prof_reset(5);\n\n\tset_prof_active(true);\n\n\tfor (i = 0; i < NTHREADS; i++) {\n\t\tthd_args[i] = i;\n\t\tthd_create(&thds[i], thd_start, (void *)&thd_args[i]);\n\t}\n\tfor (i = 0; i < NTHREADS; i++)\n\t\tthd_join(thds[i], NULL);\n\n\tassert_zu_eq(prof_bt_count(), bt_count,\n\t    \"Unexpected bactrace count change\");\n\tassert_zu_eq(prof_tdata_count(), tdata_count,\n\t    \"Unexpected remaining tdata structures\");\n\n\tset_prof_active(false);\n\n\tdo_prof_reset(lg_prof_sample_orig);\n}\nTEST_END\n#undef NTHREADS\n#undef NALLOCS_PER_THREAD\n#undef OBJ_RING_BUF_COUNT\n#undef RESET_INTERVAL\n#undef DUMP_INTERVAL\n\n/* Test sampling at the same allocation site across resets. */\n#define\tNITER 10\nTEST_BEGIN(test_xallocx)\n{\n\tsize_t lg_prof_sample_orig;\n\tunsigned i;\n\tvoid *ptrs[NITER];\n\n\ttest_skip_if(!config_prof);\n\n\tlg_prof_sample_orig = get_lg_prof_sample();\n\tset_prof_active(true);\n\n\t/* Reset profiling. */\n\tdo_prof_reset(0);\n\n\tfor (i = 0; i < NITER; i++) {\n\t\tvoid *p;\n\t\tsize_t sz, nsz;\n\n\t\t/* Reset profiling. */\n\t\tdo_prof_reset(0);\n\n\t\t/* Allocate small object (which will be promoted). */\n\t\tp = ptrs[i] = mallocx(1, 0);\n\t\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\n\t\t/* Reset profiling. */\n\t\tdo_prof_reset(0);\n\n\t\t/* Perform successful xallocx(). */\n\t\tsz = sallocx(p, 0);\n\t\tassert_zu_eq(xallocx(p, sz, 0, 0), sz,\n\t\t    \"Unexpected xallocx() failure\");\n\n\t\t/* Perform unsuccessful xallocx(). */\n\t\tnsz = nallocx(sz+1, 0);\n\t\tassert_zu_eq(xallocx(p, nsz, 0, 0), sz,\n\t\t    \"Unexpected xallocx() success\");\n\t}\n\n\tfor (i = 0; i < NITER; i++) {\n\t\t/* dallocx. */\n\t\tdallocx(ptrs[i], 0);\n\t}\n\n\tset_prof_active(false);\n\tdo_prof_reset(lg_prof_sample_orig);\n}\nTEST_END\n#undef NITER\n\nint\nmain(void)\n{\n\n\t/* Intercept dumping prior to running any tests. */\n\tprof_dump_open = prof_dump_open_intercept;\n\n\treturn (test(\n\t    test_prof_reset_basic,\n\t    test_prof_reset_cleanup,\n\t    test_prof_reset,\n\t    test_xallocx));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/prof_thread_name.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#ifdef JEMALLOC_PROF\nconst char *malloc_conf = \"prof:true,prof_active:false\";\n#endif\n\nstatic void\nmallctl_thread_name_get_impl(const char *thread_name_expected, const char *func,\n    int line)\n{\n\tconst char *thread_name_old;\n\tsize_t sz;\n\n\tsz = sizeof(thread_name_old);\n\tassert_d_eq(mallctl(\"thread.prof.name\", &thread_name_old, &sz, NULL, 0),\n\t    0, \"%s():%d: Unexpected mallctl failure reading thread.prof.name\",\n\t    func, line);\n\tassert_str_eq(thread_name_old, thread_name_expected,\n\t    \"%s():%d: Unexpected thread.prof.name value\", func, line);\n}\n#define\tmallctl_thread_name_get(a)\t\t\t\t\t\\\n\tmallctl_thread_name_get_impl(a, __func__, __LINE__)\n\nstatic void\nmallctl_thread_name_set_impl(const char *thread_name, const char *func,\n    int line)\n{\n\n\tassert_d_eq(mallctl(\"thread.prof.name\", NULL, NULL, &thread_name,\n\t    sizeof(thread_name)), 0,\n\t    \"%s():%d: Unexpected mallctl failure reading thread.prof.name\",\n\t    func, line);\n\tmallctl_thread_name_get_impl(thread_name, func, line);\n}\n#define\tmallctl_thread_name_set(a)\t\t\t\t\t\\\n\tmallctl_thread_name_set_impl(a, __func__, __LINE__)\n\nTEST_BEGIN(test_prof_thread_name_validation)\n{\n\tconst char *thread_name;\n\n\ttest_skip_if(!config_prof);\n\n\tmallctl_thread_name_get(\"\");\n\tmallctl_thread_name_set(\"hi there\");\n\n\t/* NULL input shouldn't be allowed. */\n\tthread_name = NULL;\n\tassert_d_eq(mallctl(\"thread.prof.name\", NULL, NULL, &thread_name,\n\t    sizeof(thread_name)), EFAULT,\n\t    \"Unexpected mallctl result writing \\\"%s\\\" to thread.prof.name\",\n\t    thread_name);\n\n\t/* '\\n' shouldn't be allowed. */\n\tthread_name = \"hi\\nthere\";\n\tassert_d_eq(mallctl(\"thread.prof.name\", NULL, NULL, &thread_name,\n\t    sizeof(thread_name)), EFAULT,\n\t    \"Unexpected mallctl result writing \\\"%s\\\" to thread.prof.name\",\n\t    thread_name);\n\n\t/* Simultaneous read/write shouldn't be allowed. */\n\t{\n\t\tconst char *thread_name_old;\n\t\tsize_t sz;\n\n\t\tsz = sizeof(thread_name_old);\n\t\tassert_d_eq(mallctl(\"thread.prof.name\", &thread_name_old, &sz,\n\t\t    &thread_name, sizeof(thread_name)), EPERM,\n\t\t    \"Unexpected mallctl result writing \\\"%s\\\" to \"\n\t\t    \"thread.prof.name\", thread_name);\n\t}\n\n\tmallctl_thread_name_set(\"\");\n}\nTEST_END\n\n#define\tNTHREADS\t4\n#define\tNRESET\t\t25\nstatic void *\nthd_start(void *varg)\n{\n\tunsigned thd_ind = *(unsigned *)varg;\n\tchar thread_name[16] = \"\";\n\tunsigned i;\n\n\tmalloc_snprintf(thread_name, sizeof(thread_name), \"thread %u\", thd_ind);\n\n\tmallctl_thread_name_get(\"\");\n\tmallctl_thread_name_set(thread_name);\n\n\tfor (i = 0; i < NRESET; i++) {\n\t\tassert_d_eq(mallctl(\"prof.reset\", NULL, NULL, NULL, 0), 0,\n\t\t    \"Unexpected error while resetting heap profile data\");\n\t\tmallctl_thread_name_get(thread_name);\n\t}\n\n\tmallctl_thread_name_set(thread_name);\n\tmallctl_thread_name_set(\"\");\n\n\treturn (NULL);\n}\n\nTEST_BEGIN(test_prof_thread_name_threaded)\n{\n\tthd_t thds[NTHREADS];\n\tunsigned thd_args[NTHREADS];\n\tunsigned i;\n\n\ttest_skip_if(!config_prof);\n\n\tfor (i = 0; i < NTHREADS; i++) {\n\t\tthd_args[i] = i;\n\t\tthd_create(&thds[i], thd_start, (void *)&thd_args[i]);\n\t}\n\tfor (i = 0; i < NTHREADS; i++)\n\t\tthd_join(thds[i], NULL);\n}\nTEST_END\n#undef NTHREADS\n#undef NRESET\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_prof_thread_name_validation,\n\t    test_prof_thread_name_threaded));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/ql.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n/* Number of ring entries, in [2..26]. */\n#define\tNENTRIES 9\n\ntypedef struct list_s list_t;\ntypedef ql_head(list_t) list_head_t;\n\nstruct list_s {\n\tql_elm(list_t) link;\n\tchar id;\n};\n\nstatic void\ntest_empty_list(list_head_t *head)\n{\n\tlist_t *t;\n\tunsigned i;\n\n\tassert_ptr_null(ql_first(head), \"Unexpected element for empty list\");\n\tassert_ptr_null(ql_last(head, link),\n\t    \"Unexpected element for empty list\");\n\n\ti = 0;\n\tql_foreach(t, head, link) {\n\t\ti++;\n\t}\n\tassert_u_eq(i, 0, \"Unexpected element for empty list\");\n\n\ti = 0;\n\tql_reverse_foreach(t, head, link) {\n\t\ti++;\n\t}\n\tassert_u_eq(i, 0, \"Unexpected element for empty list\");\n}\n\nTEST_BEGIN(test_ql_empty)\n{\n\tlist_head_t head;\n\n\tql_new(&head);\n\ttest_empty_list(&head);\n}\nTEST_END\n\nstatic void\ninit_entries(list_t *entries, unsigned nentries)\n{\n\tunsigned i;\n\n\tfor (i = 0; i < nentries; i++) {\n\t\tentries[i].id = 'a' + i;\n\t\tql_elm_new(&entries[i], link);\n\t}\n}\n\nstatic void\ntest_entries_list(list_head_t *head, list_t *entries, unsigned nentries)\n{\n\tlist_t *t;\n\tunsigned i;\n\n\tassert_c_eq(ql_first(head)->id, entries[0].id, \"Element id mismatch\");\n\tassert_c_eq(ql_last(head, link)->id, entries[nentries-1].id,\n\t    \"Element id mismatch\");\n\n\ti = 0;\n\tql_foreach(t, head, link) {\n\t\tassert_c_eq(t->id, entries[i].id, \"Element id mismatch\");\n\t\ti++;\n\t}\n\n\ti = 0;\n\tql_reverse_foreach(t, head, link) {\n\t\tassert_c_eq(t->id, entries[nentries-i-1].id,\n\t\t    \"Element id mismatch\");\n\t\ti++;\n\t}\n\n\tfor (i = 0; i < nentries-1; i++) {\n\t\tt = ql_next(head, &entries[i], link);\n\t\tassert_c_eq(t->id, entries[i+1].id, \"Element id mismatch\");\n\t}\n\tassert_ptr_null(ql_next(head, &entries[nentries-1], link),\n\t    \"Unexpected element\");\n\n\tassert_ptr_null(ql_prev(head, &entries[0], link), \"Unexpected element\");\n\tfor (i = 1; i < nentries; i++) {\n\t\tt = ql_prev(head, &entries[i], link);\n\t\tassert_c_eq(t->id, entries[i-1].id, \"Element id mismatch\");\n\t}\n}\n\nTEST_BEGIN(test_ql_tail_insert)\n{\n\tlist_head_t head;\n\tlist_t entries[NENTRIES];\n\tunsigned i;\n\n\tql_new(&head);\n\tinit_entries(entries, sizeof(entries)/sizeof(list_t));\n\tfor (i = 0; i < NENTRIES; i++)\n\t\tql_tail_insert(&head, &entries[i], link);\n\n\ttest_entries_list(&head, entries, NENTRIES);\n}\nTEST_END\n\nTEST_BEGIN(test_ql_tail_remove)\n{\n\tlist_head_t head;\n\tlist_t entries[NENTRIES];\n\tunsigned i;\n\n\tql_new(&head);\n\tinit_entries(entries, sizeof(entries)/sizeof(list_t));\n\tfor (i = 0; i < NENTRIES; i++)\n\t\tql_tail_insert(&head, &entries[i], link);\n\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\ttest_entries_list(&head, entries, NENTRIES-i);\n\t\tql_tail_remove(&head, list_t, link);\n\t}\n\ttest_empty_list(&head);\n}\nTEST_END\n\nTEST_BEGIN(test_ql_head_insert)\n{\n\tlist_head_t head;\n\tlist_t entries[NENTRIES];\n\tunsigned i;\n\n\tql_new(&head);\n\tinit_entries(entries, sizeof(entries)/sizeof(list_t));\n\tfor (i = 0; i < NENTRIES; i++)\n\t\tql_head_insert(&head, &entries[NENTRIES-i-1], link);\n\n\ttest_entries_list(&head, entries, NENTRIES);\n}\nTEST_END\n\nTEST_BEGIN(test_ql_head_remove)\n{\n\tlist_head_t head;\n\tlist_t entries[NENTRIES];\n\tunsigned i;\n\n\tql_new(&head);\n\tinit_entries(entries, sizeof(entries)/sizeof(list_t));\n\tfor (i = 0; i < NENTRIES; i++)\n\t\tql_head_insert(&head, &entries[NENTRIES-i-1], link);\n\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\ttest_entries_list(&head, &entries[i], NENTRIES-i);\n\t\tql_head_remove(&head, list_t, link);\n\t}\n\ttest_empty_list(&head);\n}\nTEST_END\n\nTEST_BEGIN(test_ql_insert)\n{\n\tlist_head_t head;\n\tlist_t entries[8];\n\tlist_t *a, *b, *c, *d, *e, *f, *g, *h;\n\n\tql_new(&head);\n\tinit_entries(entries, sizeof(entries)/sizeof(list_t));\n\ta = &entries[0];\n\tb = &entries[1];\n\tc = &entries[2];\n\td = &entries[3];\n\te = &entries[4];\n\tf = &entries[5];\n\tg = &entries[6];\n\th = &entries[7];\n\n\t/*\n\t * ql_remove(), ql_before_insert(), and ql_after_insert() are used\n\t * internally by other macros that are already tested, so there's no\n\t * need to test them completely.  However, insertion/deletion from the\n\t * middle of lists is not otherwise tested; do so here.\n\t */\n\tql_tail_insert(&head, f, link);\n\tql_before_insert(&head, f, b, link);\n\tql_before_insert(&head, f, c, link);\n\tql_after_insert(f, h, link);\n\tql_after_insert(f, g, link);\n\tql_before_insert(&head, b, a, link);\n\tql_after_insert(c, d, link);\n\tql_before_insert(&head, f, e, link);\n\n\ttest_entries_list(&head, entries, sizeof(entries)/sizeof(list_t));\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_ql_empty,\n\t    test_ql_tail_insert,\n\t    test_ql_tail_remove,\n\t    test_ql_head_insert,\n\t    test_ql_head_remove,\n\t    test_ql_insert));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/qr.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n/* Number of ring entries, in [2..26]. */\n#define\tNENTRIES 9\n/* Split index, in [1..NENTRIES). */\n#define\tSPLIT_INDEX 5\n\ntypedef struct ring_s ring_t;\n\nstruct ring_s {\n\tqr(ring_t) link;\n\tchar id;\n};\n\nstatic void\ninit_entries(ring_t *entries)\n{\n\tunsigned i;\n\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\tqr_new(&entries[i], link);\n\t\tentries[i].id = 'a' + i;\n\t}\n}\n\nstatic void\ntest_independent_entries(ring_t *entries)\n{\n\tring_t *t;\n\tunsigned i, j;\n\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\tj = 0;\n\t\tqr_foreach(t, &entries[i], link) {\n\t\t\tj++;\n\t\t}\n\t\tassert_u_eq(j, 1,\n\t\t    \"Iteration over single-element ring should visit precisely \"\n\t\t    \"one element\");\n\t}\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\tj = 0;\n\t\tqr_reverse_foreach(t, &entries[i], link) {\n\t\t\tj++;\n\t\t}\n\t\tassert_u_eq(j, 1,\n\t\t    \"Iteration over single-element ring should visit precisely \"\n\t\t    \"one element\");\n\t}\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\tt = qr_next(&entries[i], link);\n\t\tassert_ptr_eq(t, &entries[i],\n\t\t    \"Next element in single-element ring should be same as \"\n\t\t    \"current element\");\n\t}\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\tt = qr_prev(&entries[i], link);\n\t\tassert_ptr_eq(t, &entries[i],\n\t\t    \"Previous element in single-element ring should be same as \"\n\t\t    \"current element\");\n\t}\n}\n\nTEST_BEGIN(test_qr_one)\n{\n\tring_t entries[NENTRIES];\n\n\tinit_entries(entries);\n\ttest_independent_entries(entries);\n}\nTEST_END\n\nstatic void\ntest_entries_ring(ring_t *entries)\n{\n\tring_t *t;\n\tunsigned i, j;\n\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\tj = 0;\n\t\tqr_foreach(t, &entries[i], link) {\n\t\t\tassert_c_eq(t->id, entries[(i+j) % NENTRIES].id,\n\t\t\t    \"Element id mismatch\");\n\t\t\tj++;\n\t\t}\n\t}\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\tj = 0;\n\t\tqr_reverse_foreach(t, &entries[i], link) {\n\t\t\tassert_c_eq(t->id, entries[(NENTRIES+i-j-1) %\n\t\t\t    NENTRIES].id, \"Element id mismatch\");\n\t\t\tj++;\n\t\t}\n\t}\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\tt = qr_next(&entries[i], link);\n\t\tassert_c_eq(t->id, entries[(i+1) % NENTRIES].id,\n\t\t    \"Element id mismatch\");\n\t}\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\tt = qr_prev(&entries[i], link);\n\t\tassert_c_eq(t->id, entries[(NENTRIES+i-1) % NENTRIES].id,\n\t\t    \"Element id mismatch\");\n\t}\n}\n\nTEST_BEGIN(test_qr_after_insert)\n{\n\tring_t entries[NENTRIES];\n\tunsigned i;\n\n\tinit_entries(entries);\n\tfor (i = 1; i < NENTRIES; i++)\n\t\tqr_after_insert(&entries[i - 1], &entries[i], link);\n\ttest_entries_ring(entries);\n}\nTEST_END\n\nTEST_BEGIN(test_qr_remove)\n{\n\tring_t entries[NENTRIES];\n\tring_t *t;\n\tunsigned i, j;\n\n\tinit_entries(entries);\n\tfor (i = 1; i < NENTRIES; i++)\n\t\tqr_after_insert(&entries[i - 1], &entries[i], link);\n\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\tj = 0;\n\t\tqr_foreach(t, &entries[i], link) {\n\t\t\tassert_c_eq(t->id, entries[i+j].id,\n\t\t\t    \"Element id mismatch\");\n\t\t\tj++;\n\t\t}\n\t\tj = 0;\n\t\tqr_reverse_foreach(t, &entries[i], link) {\n\t\t\tassert_c_eq(t->id, entries[NENTRIES - 1 - j].id,\n\t\t\t\"Element id mismatch\");\n\t\t\tj++;\n\t\t}\n\t\tqr_remove(&entries[i], link);\n\t}\n\ttest_independent_entries(entries);\n}\nTEST_END\n\nTEST_BEGIN(test_qr_before_insert)\n{\n\tring_t entries[NENTRIES];\n\tring_t *t;\n\tunsigned i, j;\n\n\tinit_entries(entries);\n\tfor (i = 1; i < NENTRIES; i++)\n\t\tqr_before_insert(&entries[i - 1], &entries[i], link);\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\tj = 0;\n\t\tqr_foreach(t, &entries[i], link) {\n\t\t\tassert_c_eq(t->id, entries[(NENTRIES+i-j) %\n\t\t\t    NENTRIES].id, \"Element id mismatch\");\n\t\t\tj++;\n\t\t}\n\t}\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\tj = 0;\n\t\tqr_reverse_foreach(t, &entries[i], link) {\n\t\t\tassert_c_eq(t->id, entries[(i+j+1) % NENTRIES].id,\n\t\t\t    \"Element id mismatch\");\n\t\t\tj++;\n\t\t}\n\t}\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\tt = qr_next(&entries[i], link);\n\t\tassert_c_eq(t->id, entries[(NENTRIES+i-1) % NENTRIES].id,\n\t\t    \"Element id mismatch\");\n\t}\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\tt = qr_prev(&entries[i], link);\n\t\tassert_c_eq(t->id, entries[(i+1) % NENTRIES].id,\n\t\t    \"Element id mismatch\");\n\t}\n}\nTEST_END\n\nstatic void\ntest_split_entries(ring_t *entries)\n{\n\tring_t *t;\n\tunsigned i, j;\n\n\tfor (i = 0; i < NENTRIES; i++) {\n\t\tj = 0;\n\t\tqr_foreach(t, &entries[i], link) {\n\t\t\tif (i < SPLIT_INDEX) {\n\t\t\t\tassert_c_eq(t->id,\n\t\t\t\t    entries[(i+j) % SPLIT_INDEX].id,\n\t\t\t\t    \"Element id mismatch\");\n\t\t\t} else {\n\t\t\t\tassert_c_eq(t->id, entries[(i+j-SPLIT_INDEX) %\n\t\t\t\t    (NENTRIES-SPLIT_INDEX) + SPLIT_INDEX].id,\n\t\t\t\t    \"Element id mismatch\");\n\t\t\t}\n\t\t\tj++;\n\t\t}\n\t}\n}\n\nTEST_BEGIN(test_qr_meld_split)\n{\n\tring_t entries[NENTRIES];\n\tunsigned i;\n\n\tinit_entries(entries);\n\tfor (i = 1; i < NENTRIES; i++)\n\t\tqr_after_insert(&entries[i - 1], &entries[i], link);\n\n\tqr_split(&entries[0], &entries[SPLIT_INDEX], link);\n\ttest_split_entries(entries);\n\n\tqr_meld(&entries[0], &entries[SPLIT_INDEX], link);\n\ttest_entries_ring(entries);\n\n\tqr_meld(&entries[0], &entries[SPLIT_INDEX], link);\n\ttest_split_entries(entries);\n\n\tqr_split(&entries[0], &entries[SPLIT_INDEX], link);\n\ttest_entries_ring(entries);\n\n\tqr_split(&entries[0], &entries[0], link);\n\ttest_entries_ring(entries);\n\n\tqr_meld(&entries[0], &entries[0], link);\n\ttest_entries_ring(entries);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_qr_one,\n\t    test_qr_after_insert,\n\t    test_qr_remove,\n\t    test_qr_before_insert,\n\t    test_qr_meld_split));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/quarantine.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#define\tQUARANTINE_SIZE\t\t8192\n#define\tSTRINGIFY_HELPER(x)\t#x\n#define\tSTRINGIFY(x)\t\tSTRINGIFY_HELPER(x)\n\n#ifdef JEMALLOC_FILL\nconst char *malloc_conf = \"abort:false,junk:true,redzone:true,quarantine:\"\n    STRINGIFY(QUARANTINE_SIZE);\n#endif\n\nvoid\nquarantine_clear(void)\n{\n\tvoid *p;\n\n\tp = mallocx(QUARANTINE_SIZE*2, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\tdallocx(p, 0);\n}\n\nTEST_BEGIN(test_quarantine)\n{\n#define\tSZ\t\tZU(256)\n#define\tNQUARANTINED\t(QUARANTINE_SIZE/SZ)\n\tvoid *quarantined[NQUARANTINED+1];\n\tsize_t i, j;\n\n\ttest_skip_if(!config_fill);\n\n\tassert_zu_eq(nallocx(SZ, 0), SZ,\n\t    \"SZ=%zu does not precisely equal a size class\", SZ);\n\n\tquarantine_clear();\n\n\t/*\n\t * Allocate enough regions to completely fill the quarantine, plus one\n\t * more.  The last iteration occurs with a completely full quarantine,\n\t * but no regions should be drained from the quarantine until the last\n\t * deallocation occurs.  Therefore no region recycling should occur\n\t * until after this loop completes.\n\t */\n\tfor (i = 0; i < NQUARANTINED+1; i++) {\n\t\tvoid *p = mallocx(SZ, 0);\n\t\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\t\tquarantined[i] = p;\n\t\tdallocx(p, 0);\n\t\tfor (j = 0; j < i; j++) {\n\t\t\tassert_ptr_ne(p, quarantined[j],\n\t\t\t    \"Quarantined region recycled too early; \"\n\t\t\t    \"i=%zu, j=%zu\", i, j);\n\t\t}\n\t}\n#undef NQUARANTINED\n#undef SZ\n}\nTEST_END\n\nstatic bool detected_redzone_corruption;\n\nstatic void\narena_redzone_corruption_replacement(void *ptr, size_t usize, bool after,\n    size_t offset, uint8_t byte)\n{\n\n\tdetected_redzone_corruption = true;\n}\n\nTEST_BEGIN(test_quarantine_redzone)\n{\n\tchar *s;\n\tarena_redzone_corruption_t *arena_redzone_corruption_orig;\n\n\ttest_skip_if(!config_fill);\n\n\tarena_redzone_corruption_orig = arena_redzone_corruption;\n\tarena_redzone_corruption = arena_redzone_corruption_replacement;\n\n\t/* Test underflow. */\n\tdetected_redzone_corruption = false;\n\ts = (char *)mallocx(1, 0);\n\tassert_ptr_not_null((void *)s, \"Unexpected mallocx() failure\");\n\ts[-1] = 0xbb;\n\tdallocx(s, 0);\n\tassert_true(detected_redzone_corruption,\n\t    \"Did not detect redzone corruption\");\n\n\t/* Test overflow. */\n\tdetected_redzone_corruption = false;\n\ts = (char *)mallocx(1, 0);\n\tassert_ptr_not_null((void *)s, \"Unexpected mallocx() failure\");\n\ts[sallocx(s, 0)] = 0xbb;\n\tdallocx(s, 0);\n\tassert_true(detected_redzone_corruption,\n\t    \"Did not detect redzone corruption\");\n\n\tarena_redzone_corruption = arena_redzone_corruption_orig;\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_quarantine,\n\t    test_quarantine_redzone));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/rb.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#define\trbtn_black_height(a_type, a_field, a_rbt, r_height) do {\t\\\n    a_type *rbp_bh_t;\t\t\t\t\t\t\t\\\n    for (rbp_bh_t = (a_rbt)->rbt_root, (r_height) = 0;\t\t\t\\\n\t rbp_bh_t != NULL;\t\t\t\t\t\t\\\n      rbp_bh_t = rbtn_left_get(a_type, a_field, rbp_bh_t)) {\t\t\\\n\tif (!rbtn_red_get(a_type, a_field, rbp_bh_t)) {\t\t\t\\\n\t    (r_height)++;\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\ntypedef struct node_s node_t;\n\nstruct node_s {\n#define\tNODE_MAGIC 0x9823af7e\n\tuint32_t magic;\n\trb_node(node_t) link;\n\tuint64_t key;\n};\n\nstatic int\nnode_cmp(const node_t *a, const node_t *b) {\n\tint ret;\n\n\tassert_u32_eq(a->magic, NODE_MAGIC, \"Bad magic\");\n\tassert_u32_eq(b->magic, NODE_MAGIC, \"Bad magic\");\n\n\tret = (a->key > b->key) - (a->key < b->key);\n\tif (ret == 0) {\n\t\t/*\n\t\t * Duplicates are not allowed in the tree, so force an\n\t\t * arbitrary ordering for non-identical items with equal keys.\n\t\t */\n\t\tret = (((uintptr_t)a) > ((uintptr_t)b))\n\t\t    - (((uintptr_t)a) < ((uintptr_t)b));\n\t}\n\treturn (ret);\n}\n\ntypedef rb_tree(node_t) tree_t;\nrb_gen(static, tree_, tree_t, node_t, link, node_cmp);\n\nTEST_BEGIN(test_rb_empty)\n{\n\ttree_t tree;\n\tnode_t key;\n\n\ttree_new(&tree);\n\n\tassert_true(tree_empty(&tree), \"Tree should be empty\");\n\tassert_ptr_null(tree_first(&tree), \"Unexpected node\");\n\tassert_ptr_null(tree_last(&tree), \"Unexpected node\");\n\n\tkey.key = 0;\n\tkey.magic = NODE_MAGIC;\n\tassert_ptr_null(tree_search(&tree, &key), \"Unexpected node\");\n\n\tkey.key = 0;\n\tkey.magic = NODE_MAGIC;\n\tassert_ptr_null(tree_nsearch(&tree, &key), \"Unexpected node\");\n\n\tkey.key = 0;\n\tkey.magic = NODE_MAGIC;\n\tassert_ptr_null(tree_psearch(&tree, &key), \"Unexpected node\");\n}\nTEST_END\n\nstatic unsigned\ntree_recurse(node_t *node, unsigned black_height, unsigned black_depth)\n{\n\tunsigned ret = 0;\n\tnode_t *left_node;\n\tnode_t *right_node;\n\n\tif (node == NULL)\n\t\treturn (ret);\n\n\tleft_node = rbtn_left_get(node_t, link, node);\n\tright_node = rbtn_right_get(node_t, link, node);\n\n\tif (!rbtn_red_get(node_t, link, node))\n\t\tblack_depth++;\n\n\t/* Red nodes must be interleaved with black nodes. */\n\tif (rbtn_red_get(node_t, link, node)) {\n\t\tif (left_node != NULL)\n\t\t\tassert_false(rbtn_red_get(node_t, link, left_node),\n\t\t\t\t\"Node should be black\");\n\t\tif (right_node != NULL)\n\t\t\tassert_false(rbtn_red_get(node_t, link, right_node),\n\t\t\t    \"Node should be black\");\n\t}\n\n\t/* Self. */\n\tassert_u32_eq(node->magic, NODE_MAGIC, \"Bad magic\");\n\n\t/* Left subtree. */\n\tif (left_node != NULL)\n\t\tret += tree_recurse(left_node, black_height, black_depth);\n\telse\n\t\tret += (black_depth != black_height);\n\n\t/* Right subtree. */\n\tif (right_node != NULL)\n\t\tret += tree_recurse(right_node, black_height, black_depth);\n\telse\n\t\tret += (black_depth != black_height);\n\n\treturn (ret);\n}\n\nstatic node_t *\ntree_iterate_cb(tree_t *tree, node_t *node, void *data)\n{\n\tunsigned *i = (unsigned *)data;\n\tnode_t *search_node;\n\n\tassert_u32_eq(node->magic, NODE_MAGIC, \"Bad magic\");\n\n\t/* Test rb_search(). */\n\tsearch_node = tree_search(tree, node);\n\tassert_ptr_eq(search_node, node,\n\t    \"tree_search() returned unexpected node\");\n\n\t/* Test rb_nsearch(). */\n\tsearch_node = tree_nsearch(tree, node);\n\tassert_ptr_eq(search_node, node,\n\t    \"tree_nsearch() returned unexpected node\");\n\n\t/* Test rb_psearch(). */\n\tsearch_node = tree_psearch(tree, node);\n\tassert_ptr_eq(search_node, node,\n\t    \"tree_psearch() returned unexpected node\");\n\n\t(*i)++;\n\n\treturn (NULL);\n}\n\nstatic unsigned\ntree_iterate(tree_t *tree)\n{\n\tunsigned i;\n\n\ti = 0;\n\ttree_iter(tree, NULL, tree_iterate_cb, (void *)&i);\n\n\treturn (i);\n}\n\nstatic unsigned\ntree_iterate_reverse(tree_t *tree)\n{\n\tunsigned i;\n\n\ti = 0;\n\ttree_reverse_iter(tree, NULL, tree_iterate_cb, (void *)&i);\n\n\treturn (i);\n}\n\nstatic void\nnode_remove(tree_t *tree, node_t *node, unsigned nnodes)\n{\n\tnode_t *search_node;\n\tunsigned black_height, imbalances;\n\n\ttree_remove(tree, node);\n\n\t/* Test rb_nsearch(). */\n\tsearch_node = tree_nsearch(tree, node);\n\tif (search_node != NULL) {\n\t\tassert_u64_ge(search_node->key, node->key,\n\t\t    \"Key ordering error\");\n\t}\n\n\t/* Test rb_psearch(). */\n\tsearch_node = tree_psearch(tree, node);\n\tif (search_node != NULL) {\n\t\tassert_u64_le(search_node->key, node->key,\n\t\t    \"Key ordering error\");\n\t}\n\n\tnode->magic = 0;\n\n\trbtn_black_height(node_t, link, tree, black_height);\n\timbalances = tree_recurse(tree->rbt_root, black_height, 0);\n\tassert_u_eq(imbalances, 0, \"Tree is unbalanced\");\n\tassert_u_eq(tree_iterate(tree), nnodes-1,\n\t    \"Unexpected node iteration count\");\n\tassert_u_eq(tree_iterate_reverse(tree), nnodes-1,\n\t    \"Unexpected node iteration count\");\n}\n\nstatic node_t *\nremove_iterate_cb(tree_t *tree, node_t *node, void *data)\n{\n\tunsigned *nnodes = (unsigned *)data;\n\tnode_t *ret = tree_next(tree, node);\n\n\tnode_remove(tree, node, *nnodes);\n\n\treturn (ret);\n}\n\nstatic node_t *\nremove_reverse_iterate_cb(tree_t *tree, node_t *node, void *data)\n{\n\tunsigned *nnodes = (unsigned *)data;\n\tnode_t *ret = tree_prev(tree, node);\n\n\tnode_remove(tree, node, *nnodes);\n\n\treturn (ret);\n}\n\nstatic void\ndestroy_cb(node_t *node, void *data)\n{\n\tunsigned *nnodes = (unsigned *)data;\n\n\tassert_u_gt(*nnodes, 0, \"Destruction removed too many nodes\");\n\t(*nnodes)--;\n}\n\nTEST_BEGIN(test_rb_random)\n{\n#define\tNNODES 25\n#define\tNBAGS 250\n#define\tSEED 42\n\tsfmt_t *sfmt;\n\tuint64_t bag[NNODES];\n\ttree_t tree;\n\tnode_t nodes[NNODES];\n\tunsigned i, j, k, black_height, imbalances;\n\n\tsfmt = init_gen_rand(SEED);\n\tfor (i = 0; i < NBAGS; i++) {\n\t\tswitch (i) {\n\t\tcase 0:\n\t\t\t/* Insert in order. */\n\t\t\tfor (j = 0; j < NNODES; j++)\n\t\t\t\tbag[j] = j;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\t/* Insert in reverse order. */\n\t\t\tfor (j = 0; j < NNODES; j++)\n\t\t\t\tbag[j] = NNODES - j - 1;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tfor (j = 0; j < NNODES; j++)\n\t\t\t\tbag[j] = gen_rand64_range(sfmt, NNODES);\n\t\t}\n\n\t\tfor (j = 1; j <= NNODES; j++) {\n\t\t\t/* Initialize tree and nodes. */\n\t\t\ttree_new(&tree);\n\t\t\tfor (k = 0; k < j; k++) {\n\t\t\t\tnodes[k].magic = NODE_MAGIC;\n\t\t\t\tnodes[k].key = bag[k];\n\t\t\t}\n\n\t\t\t/* Insert nodes. */\n\t\t\tfor (k = 0; k < j; k++) {\n\t\t\t\ttree_insert(&tree, &nodes[k]);\n\n\t\t\t\trbtn_black_height(node_t, link, &tree,\n\t\t\t\t    black_height);\n\t\t\t\timbalances = tree_recurse(tree.rbt_root,\n\t\t\t\t    black_height, 0);\n\t\t\t\tassert_u_eq(imbalances, 0,\n\t\t\t\t    \"Tree is unbalanced\");\n\n\t\t\t\tassert_u_eq(tree_iterate(&tree), k+1,\n\t\t\t\t    \"Unexpected node iteration count\");\n\t\t\t\tassert_u_eq(tree_iterate_reverse(&tree), k+1,\n\t\t\t\t    \"Unexpected node iteration count\");\n\n\t\t\t\tassert_false(tree_empty(&tree),\n\t\t\t\t    \"Tree should not be empty\");\n\t\t\t\tassert_ptr_not_null(tree_first(&tree),\n\t\t\t\t    \"Tree should not be empty\");\n\t\t\t\tassert_ptr_not_null(tree_last(&tree),\n\t\t\t\t    \"Tree should not be empty\");\n\n\t\t\t\ttree_next(&tree, &nodes[k]);\n\t\t\t\ttree_prev(&tree, &nodes[k]);\n\t\t\t}\n\n\t\t\t/* Remove nodes. */\n\t\t\tswitch (i % 5) {\n\t\t\tcase 0:\n\t\t\t\tfor (k = 0; k < j; k++)\n\t\t\t\t\tnode_remove(&tree, &nodes[k], j - k);\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tfor (k = j; k > 0; k--)\n\t\t\t\t\tnode_remove(&tree, &nodes[k-1], k);\n\t\t\t\tbreak;\n\t\t\tcase 2: {\n\t\t\t\tnode_t *start;\n\t\t\t\tunsigned nnodes = j;\n\n\t\t\t\tstart = NULL;\n\t\t\t\tdo {\n\t\t\t\t\tstart = tree_iter(&tree, start,\n\t\t\t\t\t    remove_iterate_cb, (void *)&nnodes);\n\t\t\t\t\tnnodes--;\n\t\t\t\t} while (start != NULL);\n\t\t\t\tassert_u_eq(nnodes, 0,\n\t\t\t\t    \"Removal terminated early\");\n\t\t\t\tbreak;\n\t\t\t} case 3: {\n\t\t\t\tnode_t *start;\n\t\t\t\tunsigned nnodes = j;\n\n\t\t\t\tstart = NULL;\n\t\t\t\tdo {\n\t\t\t\t\tstart = tree_reverse_iter(&tree, start,\n\t\t\t\t\t    remove_reverse_iterate_cb,\n\t\t\t\t\t    (void *)&nnodes);\n\t\t\t\t\tnnodes--;\n\t\t\t\t} while (start != NULL);\n\t\t\t\tassert_u_eq(nnodes, 0,\n\t\t\t\t    \"Removal terminated early\");\n\t\t\t\tbreak;\n\t\t\t} case 4: {\n\t\t\t\tunsigned nnodes = j;\n\t\t\t\ttree_destroy(&tree, destroy_cb, &nnodes);\n\t\t\t\tassert_u_eq(nnodes, 0,\n\t\t\t\t    \"Destruction terminated early\");\n\t\t\t\tbreak;\n\t\t\t} default:\n\t\t\t\tnot_reached();\n\t\t\t}\n\t\t}\n\t}\n\tfini_gen_rand(sfmt);\n#undef NNODES\n#undef NBAGS\n#undef SEED\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_rb_empty,\n\t    test_rb_random));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/rtree.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nstatic rtree_node_elm_t *\nnode_alloc(size_t nelms)\n{\n\n\treturn ((rtree_node_elm_t *)calloc(nelms, sizeof(rtree_node_elm_t)));\n}\n\nstatic void\nnode_dalloc(rtree_node_elm_t *node)\n{\n\n\tfree(node);\n}\n\nTEST_BEGIN(test_rtree_get_empty)\n{\n\tunsigned i;\n\n\tfor (i = 1; i <= (sizeof(uintptr_t) << 3); i++) {\n\t\trtree_t rtree;\n\t\tassert_false(rtree_new(&rtree, i, node_alloc, node_dalloc),\n\t\t    \"Unexpected rtree_new() failure\");\n\t\tassert_ptr_null(rtree_get(&rtree, 0, false),\n\t\t    \"rtree_get() should return NULL for empty tree\");\n\t\trtree_delete(&rtree);\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_rtree_extrema)\n{\n\tunsigned i;\n\textent_node_t node_a, node_b;\n\n\tfor (i = 1; i <= (sizeof(uintptr_t) << 3); i++) {\n\t\trtree_t rtree;\n\t\tassert_false(rtree_new(&rtree, i, node_alloc, node_dalloc),\n\t\t    \"Unexpected rtree_new() failure\");\n\n\t\tassert_false(rtree_set(&rtree, 0, &node_a),\n\t\t    \"Unexpected rtree_set() failure\");\n\t\tassert_ptr_eq(rtree_get(&rtree, 0, true), &node_a,\n\t\t    \"rtree_get() should return previously set value\");\n\n\t\tassert_false(rtree_set(&rtree, ~((uintptr_t)0), &node_b),\n\t\t    \"Unexpected rtree_set() failure\");\n\t\tassert_ptr_eq(rtree_get(&rtree, ~((uintptr_t)0), true), &node_b,\n\t\t    \"rtree_get() should return previously set value\");\n\n\t\trtree_delete(&rtree);\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_rtree_bits)\n{\n\tunsigned i, j, k;\n\n\tfor (i = 1; i < (sizeof(uintptr_t) << 3); i++) {\n\t\tuintptr_t keys[] = {0, 1,\n\t\t    (((uintptr_t)1) << (sizeof(uintptr_t)*8-i)) - 1};\n\t\textent_node_t node;\n\t\trtree_t rtree;\n\n\t\tassert_false(rtree_new(&rtree, i, node_alloc, node_dalloc),\n\t\t    \"Unexpected rtree_new() failure\");\n\n\t\tfor (j = 0; j < sizeof(keys)/sizeof(uintptr_t); j++) {\n\t\t\tassert_false(rtree_set(&rtree, keys[j], &node),\n\t\t\t    \"Unexpected rtree_set() failure\");\n\t\t\tfor (k = 0; k < sizeof(keys)/sizeof(uintptr_t); k++) {\n\t\t\t\tassert_ptr_eq(rtree_get(&rtree, keys[k], true),\n\t\t\t\t    &node, \"rtree_get() should return \"\n\t\t\t\t    \"previously set value and ignore \"\n\t\t\t\t    \"insignificant key bits; i=%u, j=%u, k=%u, \"\n\t\t\t\t    \"set key=%#\"FMTxPTR\", get key=%#\"FMTxPTR, i,\n\t\t\t\t    j, k, keys[j], keys[k]);\n\t\t\t}\n\t\t\tassert_ptr_null(rtree_get(&rtree,\n\t\t\t    (((uintptr_t)1) << (sizeof(uintptr_t)*8-i)), false),\n\t\t\t    \"Only leftmost rtree leaf should be set; \"\n\t\t\t    \"i=%u, j=%u\", i, j);\n\t\t\tassert_false(rtree_set(&rtree, keys[j], NULL),\n\t\t\t    \"Unexpected rtree_set() failure\");\n\t\t}\n\n\t\trtree_delete(&rtree);\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_rtree_random)\n{\n\tunsigned i;\n\tsfmt_t *sfmt;\n#define\tNSET 16\n#define\tSEED 42\n\n\tsfmt = init_gen_rand(SEED);\n\tfor (i = 1; i <= (sizeof(uintptr_t) << 3); i++) {\n\t\tuintptr_t keys[NSET];\n\t\textent_node_t node;\n\t\tunsigned j;\n\t\trtree_t rtree;\n\n\t\tassert_false(rtree_new(&rtree, i, node_alloc, node_dalloc),\n\t\t    \"Unexpected rtree_new() failure\");\n\n\t\tfor (j = 0; j < NSET; j++) {\n\t\t\tkeys[j] = (uintptr_t)gen_rand64(sfmt);\n\t\t\tassert_false(rtree_set(&rtree, keys[j], &node),\n\t\t\t    \"Unexpected rtree_set() failure\");\n\t\t\tassert_ptr_eq(rtree_get(&rtree, keys[j], true), &node,\n\t\t\t    \"rtree_get() should return previously set value\");\n\t\t}\n\t\tfor (j = 0; j < NSET; j++) {\n\t\t\tassert_ptr_eq(rtree_get(&rtree, keys[j], true), &node,\n\t\t\t    \"rtree_get() should return previously set value\");\n\t\t}\n\n\t\tfor (j = 0; j < NSET; j++) {\n\t\t\tassert_false(rtree_set(&rtree, keys[j], NULL),\n\t\t\t    \"Unexpected rtree_set() failure\");\n\t\t\tassert_ptr_null(rtree_get(&rtree, keys[j], true),\n\t\t\t    \"rtree_get() should return previously set value\");\n\t\t}\n\t\tfor (j = 0; j < NSET; j++) {\n\t\t\tassert_ptr_null(rtree_get(&rtree, keys[j], true),\n\t\t\t    \"rtree_get() should return previously set value\");\n\t\t}\n\n\t\trtree_delete(&rtree);\n\t}\n\tfini_gen_rand(sfmt);\n#undef NSET\n#undef SEED\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_rtree_get_empty,\n\t    test_rtree_extrema,\n\t    test_rtree_bits,\n\t    test_rtree_random));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/run_quantize.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nTEST_BEGIN(test_small_run_size)\n{\n\tunsigned nbins, i;\n\tsize_t sz, run_size;\n\tsize_t mib[4];\n\tsize_t miblen = sizeof(mib) / sizeof(size_t);\n\n\t/*\n\t * Iterate over all small size classes, get their run sizes, and verify\n\t * that the quantized size is the same as the run size.\n\t */\n\n\tsz = sizeof(unsigned);\n\tassert_d_eq(mallctl(\"arenas.nbins\", &nbins, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl failure\");\n\n\tassert_d_eq(mallctlnametomib(\"arenas.bin.0.run_size\", mib, &miblen), 0,\n\t    \"Unexpected mallctlnametomib failure\");\n\tfor (i = 0; i < nbins; i++) {\n\t\tmib[2] = i;\n\t\tsz = sizeof(size_t);\n\t\tassert_d_eq(mallctlbymib(mib, miblen, &run_size, &sz, NULL, 0),\n\t\t    0, \"Unexpected mallctlbymib failure\");\n\t\tassert_zu_eq(run_size, run_quantize_floor(run_size),\n\t\t    \"Small run quantization should be a no-op (run_size=%zu)\",\n\t\t    run_size);\n\t\tassert_zu_eq(run_size, run_quantize_ceil(run_size),\n\t\t    \"Small run quantization should be a no-op (run_size=%zu)\",\n\t\t    run_size);\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_large_run_size)\n{\n\tbool cache_oblivious;\n\tunsigned nlruns, i;\n\tsize_t sz, run_size_prev, ceil_prev;\n\tsize_t mib[4];\n\tsize_t miblen = sizeof(mib) / sizeof(size_t);\n\n\t/*\n\t * Iterate over all large size classes, get their run sizes, and verify\n\t * that the quantized size is the same as the run size.\n\t */\n\n\tsz = sizeof(bool);\n\tassert_d_eq(mallctl(\"config.cache_oblivious\", &cache_oblivious, &sz,\n\t    NULL, 0), 0, \"Unexpected mallctl failure\");\n\n\tsz = sizeof(unsigned);\n\tassert_d_eq(mallctl(\"arenas.nlruns\", &nlruns, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl failure\");\n\n\tassert_d_eq(mallctlnametomib(\"arenas.lrun.0.size\", mib, &miblen), 0,\n\t    \"Unexpected mallctlnametomib failure\");\n\tfor (i = 0; i < nlruns; i++) {\n\t\tsize_t lrun_size, run_size, floor, ceil;\n\n\t\tmib[2] = i;\n\t\tsz = sizeof(size_t);\n\t\tassert_d_eq(mallctlbymib(mib, miblen, &lrun_size, &sz, NULL, 0),\n\t\t    0, \"Unexpected mallctlbymib failure\");\n\t\trun_size = cache_oblivious ? lrun_size + PAGE : lrun_size;\n\t\tfloor = run_quantize_floor(run_size);\n\t\tceil = run_quantize_ceil(run_size);\n\n\t\tassert_zu_eq(run_size, floor,\n\t\t    \"Large run quantization should be a no-op for precise \"\n\t\t    \"size (lrun_size=%zu, run_size=%zu)\", lrun_size, run_size);\n\t\tassert_zu_eq(run_size, ceil,\n\t\t    \"Large run quantization should be a no-op for precise \"\n\t\t    \"size (lrun_size=%zu, run_size=%zu)\", lrun_size, run_size);\n\n\t\tif (i > 0) {\n\t\t\tassert_zu_eq(run_size_prev, run_quantize_floor(run_size\n\t\t\t    - PAGE), \"Floor should be a precise size\");\n\t\t\tif (run_size_prev < ceil_prev) {\n\t\t\t\tassert_zu_eq(ceil_prev, run_size,\n\t\t\t\t    \"Ceiling should be a precise size \"\n\t\t\t\t    \"(run_size_prev=%zu, ceil_prev=%zu, \"\n\t\t\t\t    \"run_size=%zu)\", run_size_prev, ceil_prev,\n\t\t\t\t    run_size);\n\t\t\t}\n\t\t}\n\t\trun_size_prev = floor;\n\t\tceil_prev = run_quantize_ceil(run_size + PAGE);\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_monotonic)\n{\n\tunsigned nbins, nlruns, i;\n\tsize_t sz, floor_prev, ceil_prev;\n\n\t/*\n\t * Iterate over all run sizes and verify that\n\t * run_quantize_{floor,ceil}() are monotonic.\n\t */\n\n\tsz = sizeof(unsigned);\n\tassert_d_eq(mallctl(\"arenas.nbins\", &nbins, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl failure\");\n\n\tsz = sizeof(unsigned);\n\tassert_d_eq(mallctl(\"arenas.nlruns\", &nlruns, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl failure\");\n\n\tfloor_prev = 0;\n\tceil_prev = 0;\n\tfor (i = 1; i < run_quantize_max >> LG_PAGE; i++) {\n\t\tsize_t run_size, floor, ceil;\n\n\t\trun_size = i << LG_PAGE;\n\t\tfloor = run_quantize_floor(run_size);\n\t\tceil = run_quantize_ceil(run_size);\n\n\t\tassert_zu_le(floor, run_size,\n\t\t    \"Floor should be <= (floor=%zu, run_size=%zu, ceil=%zu)\",\n\t\t    floor, run_size, ceil);\n\t\tassert_zu_ge(ceil, run_size,\n\t\t    \"Ceiling should be >= (floor=%zu, run_size=%zu, ceil=%zu)\",\n\t\t    floor, run_size, ceil);\n\n\t\tassert_zu_le(floor_prev, floor, \"Floor should be monotonic \"\n\t\t    \"(floor_prev=%zu, floor=%zu, run_size=%zu, ceil=%zu)\",\n\t\t    floor_prev, floor, run_size, ceil);\n\t\tassert_zu_le(ceil_prev, ceil, \"Ceiling should be monotonic \"\n\t\t    \"(floor=%zu, run_size=%zu, ceil_prev=%zu, ceil=%zu)\",\n\t\t    floor, run_size, ceil_prev, ceil);\n\n\t\tfloor_prev = floor;\n\t\tceil_prev = ceil;\n\t}\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_small_run_size,\n\t    test_large_run_size,\n\t    test_monotonic));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/size_classes.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nstatic size_t\nget_max_size_class(void)\n{\n\tunsigned nhchunks;\n\tsize_t mib[4];\n\tsize_t sz, miblen, max_size_class;\n\n\tsz = sizeof(unsigned);\n\tassert_d_eq(mallctl(\"arenas.nhchunks\", &nhchunks, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctl() error\");\n\n\tmiblen = sizeof(mib) / sizeof(size_t);\n\tassert_d_eq(mallctlnametomib(\"arenas.hchunk.0.size\", mib, &miblen), 0,\n\t    \"Unexpected mallctlnametomib() error\");\n\tmib[2] = nhchunks - 1;\n\n\tsz = sizeof(size_t);\n\tassert_d_eq(mallctlbymib(mib, miblen, &max_size_class, &sz, NULL, 0), 0,\n\t    \"Unexpected mallctlbymib() error\");\n\n\treturn (max_size_class);\n}\n\nTEST_BEGIN(test_size_classes)\n{\n\tsize_t size_class, max_size_class;\n\tszind_t index, max_index;\n\n\tmax_size_class = get_max_size_class();\n\tmax_index = size2index(max_size_class);\n\n\tfor (index = 0, size_class = index2size(index); index < max_index ||\n\t    size_class < max_size_class; index++, size_class =\n\t    index2size(index)) {\n\t\tassert_true(index < max_index,\n\t\t    \"Loop conditionals should be equivalent; index=%u, \"\n\t\t    \"size_class=%zu (%#zx)\", index, size_class, size_class);\n\t\tassert_true(size_class < max_size_class,\n\t\t    \"Loop conditionals should be equivalent; index=%u, \"\n\t\t    \"size_class=%zu (%#zx)\", index, size_class, size_class);\n\n\t\tassert_u_eq(index, size2index(size_class),\n\t\t    \"size2index() does not reverse index2size(): index=%u -->\"\n\t\t    \" size_class=%zu --> index=%u --> size_class=%zu\", index,\n\t\t    size_class, size2index(size_class),\n\t\t    index2size(size2index(size_class)));\n\t\tassert_zu_eq(size_class, index2size(size2index(size_class)),\n\t\t    \"index2size() does not reverse size2index(): index=%u -->\"\n\t\t    \" size_class=%zu --> index=%u --> size_class=%zu\", index,\n\t\t    size_class, size2index(size_class),\n\t\t    index2size(size2index(size_class)));\n\n\t\tassert_u_eq(index+1, size2index(size_class+1),\n\t\t    \"Next size_class does not round up properly\");\n\n\t\tassert_zu_eq(size_class, (index > 0) ?\n\t\t    s2u(index2size(index-1)+1) : s2u(1),\n\t\t    \"s2u() does not round up to size class\");\n\t\tassert_zu_eq(size_class, s2u(size_class-1),\n\t\t    \"s2u() does not round up to size class\");\n\t\tassert_zu_eq(size_class, s2u(size_class),\n\t\t    \"s2u() does not compute same size class\");\n\t\tassert_zu_eq(s2u(size_class+1), index2size(index+1),\n\t\t    \"s2u() does not round up to next size class\");\n\t}\n\n\tassert_u_eq(index, size2index(index2size(index)),\n\t    \"size2index() does not reverse index2size()\");\n\tassert_zu_eq(max_size_class, index2size(size2index(max_size_class)),\n\t    \"index2size() does not reverse size2index()\");\n\n\tassert_zu_eq(size_class, s2u(index2size(index-1)+1),\n\t    \"s2u() does not round up to size class\");\n\tassert_zu_eq(size_class, s2u(size_class-1),\n\t    \"s2u() does not round up to size class\");\n\tassert_zu_eq(size_class, s2u(size_class),\n\t    \"s2u() does not compute same size class\");\n}\nTEST_END\n\nTEST_BEGIN(test_overflow)\n{\n\tsize_t max_size_class;\n\n\tmax_size_class = get_max_size_class();\n\n\tassert_u_ge(size2index(max_size_class+1), NSIZES,\n\t    \"size2index() should return >= NSIZES on overflow\");\n\tassert_u_ge(size2index(ZU(PTRDIFF_MAX)+1), NSIZES,\n\t    \"size2index() should return >= NSIZES on overflow\");\n\tassert_u_ge(size2index(SIZE_T_MAX), NSIZES,\n\t    \"size2index() should return >= NSIZES on overflow\");\n\n\tassert_zu_gt(s2u(max_size_class+1), HUGE_MAXCLASS,\n\t    \"s2u() should return > HUGE_MAXCLASS for unsupported size\");\n\tassert_zu_gt(s2u(ZU(PTRDIFF_MAX)+1), HUGE_MAXCLASS,\n\t    \"s2u() should return > HUGE_MAXCLASS for unsupported size\");\n\tassert_zu_eq(s2u(SIZE_T_MAX), 0,\n\t    \"s2u() should return 0 on overflow\");\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_size_classes,\n\t    test_overflow));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/smoothstep.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nstatic const uint64_t smoothstep_tab[] = {\n#define\tSTEP(step, h, x, y) \\\n\th,\n\tSMOOTHSTEP\n#undef STEP\n};\n\nTEST_BEGIN(test_smoothstep_integral)\n{\n\tuint64_t sum, min, max;\n\tunsigned i;\n\n\t/*\n\t * The integral of smoothstep in the [0..1] range equals 1/2.  Verify\n\t * that the fixed point representation's integral is no more than\n\t * rounding error distant from 1/2.  Regarding rounding, each table\n\t * element is rounded down to the nearest fixed point value, so the\n\t * integral may be off by as much as SMOOTHSTEP_NSTEPS ulps.\n\t */\n\tsum = 0;\n\tfor (i = 0; i < SMOOTHSTEP_NSTEPS; i++)\n\t\tsum += smoothstep_tab[i];\n\n\tmax = (KQU(1) << (SMOOTHSTEP_BFP-1)) * (SMOOTHSTEP_NSTEPS+1);\n\tmin = max - SMOOTHSTEP_NSTEPS;\n\n\tassert_u64_ge(sum, min,\n\t    \"Integral too small, even accounting for truncation\");\n\tassert_u64_le(sum, max, \"Integral exceeds 1/2\");\n\tif (false) {\n\t\tmalloc_printf(\"%\"FMTu64\" ulps under 1/2 (limit %d)\\n\",\n\t\t    max - sum, SMOOTHSTEP_NSTEPS);\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_smoothstep_monotonic)\n{\n\tuint64_t prev_h;\n\tunsigned i;\n\n\t/*\n\t * The smoothstep function is monotonic in [0..1], i.e. its slope is\n\t * non-negative.  In practice we want to parametrize table generation\n\t * such that piecewise slope is greater than zero, but do not require\n\t * that here.\n\t */\n\tprev_h = 0;\n\tfor (i = 0; i < SMOOTHSTEP_NSTEPS; i++) {\n\t\tuint64_t h = smoothstep_tab[i];\n\t\tassert_u64_ge(h, prev_h, \"Piecewise non-monotonic, i=%u\", i);\n\t\tprev_h = h;\n\t}\n\tassert_u64_eq(smoothstep_tab[SMOOTHSTEP_NSTEPS-1],\n\t    (KQU(1) << SMOOTHSTEP_BFP), \"Last step must equal 1\");\n}\nTEST_END\n\nTEST_BEGIN(test_smoothstep_slope)\n{\n\tuint64_t prev_h, prev_delta;\n\tunsigned i;\n\n\t/*\n\t * The smoothstep slope strictly increases until x=0.5, and then\n\t * strictly decreases until x=1.0.  Verify the slightly weaker\n\t * requirement of monotonicity, so that inadequate table precision does\n\t * not cause false test failures.\n\t */\n\tprev_h = 0;\n\tprev_delta = 0;\n\tfor (i = 0; i < SMOOTHSTEP_NSTEPS / 2 + SMOOTHSTEP_NSTEPS % 2; i++) {\n\t\tuint64_t h = smoothstep_tab[i];\n\t\tuint64_t delta = h - prev_h;\n\t\tassert_u64_ge(delta, prev_delta,\n\t\t    \"Slope must monotonically increase in 0.0 <= x <= 0.5, \"\n\t\t    \"i=%u\", i);\n\t\tprev_h = h;\n\t\tprev_delta = delta;\n\t}\n\n\tprev_h = KQU(1) << SMOOTHSTEP_BFP;\n\tprev_delta = 0;\n\tfor (i = SMOOTHSTEP_NSTEPS-1; i >= SMOOTHSTEP_NSTEPS / 2; i--) {\n\t\tuint64_t h = smoothstep_tab[i];\n\t\tuint64_t delta = prev_h - h;\n\t\tassert_u64_ge(delta, prev_delta,\n\t\t    \"Slope must monotonically decrease in 0.5 <= x <= 1.0, \"\n\t\t    \"i=%u\", i);\n\t\tprev_h = h;\n\t\tprev_delta = delta;\n\t}\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_smoothstep_integral,\n\t    test_smoothstep_monotonic,\n\t    test_smoothstep_slope));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/stats.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nTEST_BEGIN(test_stats_summary)\n{\n\tsize_t *cactive;\n\tsize_t sz, allocated, active, resident, mapped;\n\tint expected = config_stats ? 0 : ENOENT;\n\n\tsz = sizeof(cactive);\n\tassert_d_eq(mallctl(\"stats.cactive\", &cactive, &sz, NULL, 0), expected,\n\t    \"Unexpected mallctl() result\");\n\n\tsz = sizeof(size_t);\n\tassert_d_eq(mallctl(\"stats.allocated\", &allocated, &sz, NULL, 0),\n\t    expected, \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.active\", &active, &sz, NULL, 0), expected,\n\t    \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.resident\", &resident, &sz, NULL, 0),\n\t    expected, \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.mapped\", &mapped, &sz, NULL, 0), expected,\n\t    \"Unexpected mallctl() result\");\n\n\tif (config_stats) {\n\t\tassert_zu_le(active, *cactive,\n\t\t    \"active should be no larger than cactive\");\n\t\tassert_zu_le(allocated, active,\n\t\t    \"allocated should be no larger than active\");\n\t\tassert_zu_lt(active, resident,\n\t\t    \"active should be less than resident\");\n\t\tassert_zu_lt(active, mapped,\n\t\t    \"active should be less than mapped\");\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_stats_huge)\n{\n\tvoid *p;\n\tuint64_t epoch;\n\tsize_t allocated;\n\tuint64_t nmalloc, ndalloc, nrequests;\n\tsize_t sz;\n\tint expected = config_stats ? 0 : ENOENT;\n\n\tp = mallocx(large_maxclass+1, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\n\tassert_d_eq(mallctl(\"epoch\", NULL, NULL, &epoch, sizeof(epoch)), 0,\n\t    \"Unexpected mallctl() failure\");\n\n\tsz = sizeof(size_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.huge.allocated\", &allocated, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tsz = sizeof(uint64_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.huge.nmalloc\", &nmalloc, &sz, NULL,\n\t    0), expected, \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.arenas.0.huge.ndalloc\", &ndalloc, &sz, NULL,\n\t    0), expected, \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.arenas.0.huge.nrequests\", &nrequests, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\n\tif (config_stats) {\n\t\tassert_zu_gt(allocated, 0,\n\t\t    \"allocated should be greater than zero\");\n\t\tassert_u64_ge(nmalloc, ndalloc,\n\t\t    \"nmalloc should be at least as large as ndalloc\");\n\t\tassert_u64_le(nmalloc, nrequests,\n\t\t    \"nmalloc should no larger than nrequests\");\n\t}\n\n\tdallocx(p, 0);\n}\nTEST_END\n\nTEST_BEGIN(test_stats_arenas_summary)\n{\n\tunsigned arena;\n\tvoid *little, *large, *huge;\n\tuint64_t epoch;\n\tsize_t sz;\n\tint expected = config_stats ? 0 : ENOENT;\n\tsize_t mapped;\n\tuint64_t npurge, nmadvise, purged;\n\n\tarena = 0;\n\tassert_d_eq(mallctl(\"thread.arena\", NULL, NULL, &arena, sizeof(arena)),\n\t    0, \"Unexpected mallctl() failure\");\n\n\tlittle = mallocx(SMALL_MAXCLASS, 0);\n\tassert_ptr_not_null(little, \"Unexpected mallocx() failure\");\n\tlarge = mallocx(large_maxclass, 0);\n\tassert_ptr_not_null(large, \"Unexpected mallocx() failure\");\n\thuge = mallocx(chunksize, 0);\n\tassert_ptr_not_null(huge, \"Unexpected mallocx() failure\");\n\n\tdallocx(little, 0);\n\tdallocx(large, 0);\n\tdallocx(huge, 0);\n\n\tassert_d_eq(mallctl(\"arena.0.purge\", NULL, NULL, NULL, 0), 0,\n\t    \"Unexpected mallctl() failure\");\n\n\tassert_d_eq(mallctl(\"epoch\", NULL, NULL, &epoch, sizeof(epoch)), 0,\n\t    \"Unexpected mallctl() failure\");\n\n\tsz = sizeof(size_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.mapped\", &mapped, &sz, NULL, 0),\n\t    expected, \"Unexepected mallctl() result\");\n\tsz = sizeof(uint64_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.npurge\", &npurge, &sz, NULL, 0),\n\t    expected, \"Unexepected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.arenas.0.nmadvise\", &nmadvise, &sz, NULL, 0),\n\t    expected, \"Unexepected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.arenas.0.purged\", &purged, &sz, NULL, 0),\n\t    expected, \"Unexepected mallctl() result\");\n\n\tif (config_stats) {\n\t\tassert_u64_gt(npurge, 0,\n\t\t    \"At least one purge should have occurred\");\n\t\tassert_u64_le(nmadvise, purged,\n\t\t    \"nmadvise should be no greater than purged\");\n\t}\n}\nTEST_END\n\nvoid *\nthd_start(void *arg)\n{\n\n\treturn (NULL);\n}\n\nstatic void\nno_lazy_lock(void)\n{\n\tthd_t thd;\n\n\tthd_create(&thd, thd_start, NULL);\n\tthd_join(thd, NULL);\n}\n\nTEST_BEGIN(test_stats_arenas_small)\n{\n\tunsigned arena;\n\tvoid *p;\n\tsize_t sz, allocated;\n\tuint64_t epoch, nmalloc, ndalloc, nrequests;\n\tint expected = config_stats ? 0 : ENOENT;\n\n\tno_lazy_lock(); /* Lazy locking would dodge tcache testing. */\n\n\tarena = 0;\n\tassert_d_eq(mallctl(\"thread.arena\", NULL, NULL, &arena, sizeof(arena)),\n\t    0, \"Unexpected mallctl() failure\");\n\n\tp = mallocx(SMALL_MAXCLASS, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\n\tassert_d_eq(mallctl(\"thread.tcache.flush\", NULL, NULL, NULL, 0),\n\t    config_tcache ? 0 : ENOENT, \"Unexpected mallctl() result\");\n\n\tassert_d_eq(mallctl(\"epoch\", NULL, NULL, &epoch, sizeof(epoch)), 0,\n\t    \"Unexpected mallctl() failure\");\n\n\tsz = sizeof(size_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.small.allocated\", &allocated, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tsz = sizeof(uint64_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.small.nmalloc\", &nmalloc, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.arenas.0.small.ndalloc\", &ndalloc, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.arenas.0.small.nrequests\", &nrequests, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\n\tif (config_stats) {\n\t\tassert_zu_gt(allocated, 0,\n\t\t    \"allocated should be greater than zero\");\n\t\tassert_u64_gt(nmalloc, 0,\n\t\t    \"nmalloc should be no greater than zero\");\n\t\tassert_u64_ge(nmalloc, ndalloc,\n\t\t    \"nmalloc should be at least as large as ndalloc\");\n\t\tassert_u64_gt(nrequests, 0,\n\t\t    \"nrequests should be greater than zero\");\n\t}\n\n\tdallocx(p, 0);\n}\nTEST_END\n\nTEST_BEGIN(test_stats_arenas_large)\n{\n\tunsigned arena;\n\tvoid *p;\n\tsize_t sz, allocated;\n\tuint64_t epoch, nmalloc, ndalloc, nrequests;\n\tint expected = config_stats ? 0 : ENOENT;\n\n\tarena = 0;\n\tassert_d_eq(mallctl(\"thread.arena\", NULL, NULL, &arena, sizeof(arena)),\n\t    0, \"Unexpected mallctl() failure\");\n\n\tp = mallocx(large_maxclass, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\n\tassert_d_eq(mallctl(\"epoch\", NULL, NULL, &epoch, sizeof(epoch)), 0,\n\t    \"Unexpected mallctl() failure\");\n\n\tsz = sizeof(size_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.large.allocated\", &allocated, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tsz = sizeof(uint64_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.large.nmalloc\", &nmalloc, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.arenas.0.large.ndalloc\", &ndalloc, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.arenas.0.large.nrequests\", &nrequests, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\n\tif (config_stats) {\n\t\tassert_zu_gt(allocated, 0,\n\t\t    \"allocated should be greater than zero\");\n\t\tassert_zu_gt(nmalloc, 0,\n\t\t    \"nmalloc should be greater than zero\");\n\t\tassert_zu_ge(nmalloc, ndalloc,\n\t\t    \"nmalloc should be at least as large as ndalloc\");\n\t\tassert_zu_gt(nrequests, 0,\n\t\t    \"nrequests should be greater than zero\");\n\t}\n\n\tdallocx(p, 0);\n}\nTEST_END\n\nTEST_BEGIN(test_stats_arenas_huge)\n{\n\tunsigned arena;\n\tvoid *p;\n\tsize_t sz, allocated;\n\tuint64_t epoch, nmalloc, ndalloc;\n\tint expected = config_stats ? 0 : ENOENT;\n\n\tarena = 0;\n\tassert_d_eq(mallctl(\"thread.arena\", NULL, NULL, &arena, sizeof(arena)),\n\t    0, \"Unexpected mallctl() failure\");\n\n\tp = mallocx(chunksize, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\n\tassert_d_eq(mallctl(\"epoch\", NULL, NULL, &epoch, sizeof(epoch)), 0,\n\t    \"Unexpected mallctl() failure\");\n\n\tsz = sizeof(size_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.huge.allocated\", &allocated, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tsz = sizeof(uint64_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.huge.nmalloc\", &nmalloc, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.arenas.0.huge.ndalloc\", &ndalloc, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\n\tif (config_stats) {\n\t\tassert_zu_gt(allocated, 0,\n\t\t    \"allocated should be greater than zero\");\n\t\tassert_zu_gt(nmalloc, 0,\n\t\t    \"nmalloc should be greater than zero\");\n\t\tassert_zu_ge(nmalloc, ndalloc,\n\t\t    \"nmalloc should be at least as large as ndalloc\");\n\t}\n\n\tdallocx(p, 0);\n}\nTEST_END\n\nTEST_BEGIN(test_stats_arenas_bins)\n{\n\tunsigned arena;\n\tvoid *p;\n\tsize_t sz, curruns, curregs;\n\tuint64_t epoch, nmalloc, ndalloc, nrequests, nfills, nflushes;\n\tuint64_t nruns, nreruns;\n\tint expected = config_stats ? 0 : ENOENT;\n\n\tarena = 0;\n\tassert_d_eq(mallctl(\"thread.arena\", NULL, NULL, &arena, sizeof(arena)),\n\t    0, \"Unexpected mallctl() failure\");\n\n\tp = mallocx(arena_bin_info[0].reg_size, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\n\tassert_d_eq(mallctl(\"thread.tcache.flush\", NULL, NULL, NULL, 0),\n\t    config_tcache ? 0 : ENOENT, \"Unexpected mallctl() result\");\n\n\tassert_d_eq(mallctl(\"epoch\", NULL, NULL, &epoch, sizeof(epoch)), 0,\n\t    \"Unexpected mallctl() failure\");\n\n\tsz = sizeof(uint64_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.bins.0.nmalloc\", &nmalloc, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.arenas.0.bins.0.ndalloc\", &ndalloc, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.arenas.0.bins.0.nrequests\", &nrequests, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tsz = sizeof(size_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.bins.0.curregs\", &curregs, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\n\tsz = sizeof(uint64_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.bins.0.nfills\", &nfills, &sz,\n\t    NULL, 0), config_tcache ? expected : ENOENT,\n\t    \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.arenas.0.bins.0.nflushes\", &nflushes, &sz,\n\t    NULL, 0), config_tcache ? expected : ENOENT,\n\t    \"Unexpected mallctl() result\");\n\n\tassert_d_eq(mallctl(\"stats.arenas.0.bins.0.nruns\", &nruns, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.arenas.0.bins.0.nreruns\", &nreruns, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tsz = sizeof(size_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.bins.0.curruns\", &curruns, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\n\tif (config_stats) {\n\t\tassert_u64_gt(nmalloc, 0,\n\t\t    \"nmalloc should be greater than zero\");\n\t\tassert_u64_ge(nmalloc, ndalloc,\n\t\t    \"nmalloc should be at least as large as ndalloc\");\n\t\tassert_u64_gt(nrequests, 0,\n\t\t    \"nrequests should be greater than zero\");\n\t\tassert_zu_gt(curregs, 0,\n\t\t    \"allocated should be greater than zero\");\n\t\tif (config_tcache) {\n\t\t\tassert_u64_gt(nfills, 0,\n\t\t\t    \"At least one fill should have occurred\");\n\t\t\tassert_u64_gt(nflushes, 0,\n\t\t\t    \"At least one flush should have occurred\");\n\t\t}\n\t\tassert_u64_gt(nruns, 0,\n\t\t    \"At least one run should have been allocated\");\n\t\tassert_zu_gt(curruns, 0,\n\t\t    \"At least one run should be currently allocated\");\n\t}\n\n\tdallocx(p, 0);\n}\nTEST_END\n\nTEST_BEGIN(test_stats_arenas_lruns)\n{\n\tunsigned arena;\n\tvoid *p;\n\tuint64_t epoch, nmalloc, ndalloc, nrequests;\n\tsize_t curruns, sz;\n\tint expected = config_stats ? 0 : ENOENT;\n\n\tarena = 0;\n\tassert_d_eq(mallctl(\"thread.arena\", NULL, NULL, &arena, sizeof(arena)),\n\t    0, \"Unexpected mallctl() failure\");\n\n\tp = mallocx(LARGE_MINCLASS, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\n\tassert_d_eq(mallctl(\"epoch\", NULL, NULL, &epoch, sizeof(epoch)), 0,\n\t    \"Unexpected mallctl() failure\");\n\n\tsz = sizeof(uint64_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.lruns.0.nmalloc\", &nmalloc, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.arenas.0.lruns.0.ndalloc\", &ndalloc, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.arenas.0.lruns.0.nrequests\", &nrequests, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tsz = sizeof(size_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.lruns.0.curruns\", &curruns, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\n\tif (config_stats) {\n\t\tassert_u64_gt(nmalloc, 0,\n\t\t    \"nmalloc should be greater than zero\");\n\t\tassert_u64_ge(nmalloc, ndalloc,\n\t\t    \"nmalloc should be at least as large as ndalloc\");\n\t\tassert_u64_gt(nrequests, 0,\n\t\t    \"nrequests should be greater than zero\");\n\t\tassert_u64_gt(curruns, 0,\n\t\t    \"At least one run should be currently allocated\");\n\t}\n\n\tdallocx(p, 0);\n}\nTEST_END\n\nTEST_BEGIN(test_stats_arenas_hchunks)\n{\n\tunsigned arena;\n\tvoid *p;\n\tuint64_t epoch, nmalloc, ndalloc;\n\tsize_t curhchunks, sz;\n\tint expected = config_stats ? 0 : ENOENT;\n\n\tarena = 0;\n\tassert_d_eq(mallctl(\"thread.arena\", NULL, NULL, &arena, sizeof(arena)),\n\t    0, \"Unexpected mallctl() failure\");\n\n\tp = mallocx(chunksize, 0);\n\tassert_ptr_not_null(p, \"Unexpected mallocx() failure\");\n\n\tassert_d_eq(mallctl(\"epoch\", NULL, NULL, &epoch, sizeof(epoch)), 0,\n\t    \"Unexpected mallctl() failure\");\n\n\tsz = sizeof(uint64_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.hchunks.0.nmalloc\", &nmalloc, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tassert_d_eq(mallctl(\"stats.arenas.0.hchunks.0.ndalloc\", &ndalloc, &sz,\n\t    NULL, 0), expected, \"Unexpected mallctl() result\");\n\tsz = sizeof(size_t);\n\tassert_d_eq(mallctl(\"stats.arenas.0.hchunks.0.curhchunks\", &curhchunks,\n\t    &sz, NULL, 0), expected, \"Unexpected mallctl() result\");\n\n\tif (config_stats) {\n\t\tassert_u64_gt(nmalloc, 0,\n\t\t    \"nmalloc should be greater than zero\");\n\t\tassert_u64_ge(nmalloc, ndalloc,\n\t\t    \"nmalloc should be at least as large as ndalloc\");\n\t\tassert_u64_gt(curhchunks, 0,\n\t\t    \"At least one chunk should be currently allocated\");\n\t}\n\n\tdallocx(p, 0);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_stats_summary,\n\t    test_stats_huge,\n\t    test_stats_arenas_summary,\n\t    test_stats_arenas_small,\n\t    test_stats_arenas_large,\n\t    test_stats_arenas_huge,\n\t    test_stats_arenas_bins,\n\t    test_stats_arenas_lruns,\n\t    test_stats_arenas_hchunks));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/ticker.c",
    "content": "#include \"test/jemalloc_test.h\"\n\nTEST_BEGIN(test_ticker_tick)\n{\n#define\tNREPS 2\n#define\tNTICKS 3\n\tticker_t ticker;\n\tint32_t i, j;\n\n\tticker_init(&ticker, NTICKS);\n\tfor (i = 0; i < NREPS; i++) {\n\t\tfor (j = 0; j < NTICKS; j++) {\n\t\t\tassert_u_eq(ticker_read(&ticker), NTICKS - j,\n\t\t\t    \"Unexpected ticker value (i=%d, j=%d)\", i, j);\n\t\t\tassert_false(ticker_tick(&ticker),\n\t\t\t    \"Unexpected ticker fire (i=%d, j=%d)\", i, j);\n\t\t}\n\t\tassert_u32_eq(ticker_read(&ticker), 0,\n\t\t    \"Expected ticker depletion\");\n\t\tassert_true(ticker_tick(&ticker),\n\t\t    \"Expected ticker fire (i=%d)\", i);\n\t\tassert_u32_eq(ticker_read(&ticker), NTICKS,\n\t\t    \"Expected ticker reset\");\n\t}\n#undef NTICKS\n}\nTEST_END\n\nTEST_BEGIN(test_ticker_ticks)\n{\n#define\tNTICKS 3\n\tticker_t ticker;\n\n\tticker_init(&ticker, NTICKS);\n\n\tassert_u_eq(ticker_read(&ticker), NTICKS, \"Unexpected ticker value\");\n\tassert_false(ticker_ticks(&ticker, NTICKS), \"Unexpected ticker fire\");\n\tassert_u_eq(ticker_read(&ticker), 0, \"Unexpected ticker value\");\n\tassert_true(ticker_ticks(&ticker, NTICKS), \"Expected ticker fire\");\n\tassert_u_eq(ticker_read(&ticker), NTICKS, \"Unexpected ticker value\");\n\n\tassert_true(ticker_ticks(&ticker, NTICKS + 1), \"Expected ticker fire\");\n\tassert_u_eq(ticker_read(&ticker), NTICKS, \"Unexpected ticker value\");\n#undef NTICKS\n}\nTEST_END\n\nTEST_BEGIN(test_ticker_copy)\n{\n#define\tNTICKS 3\n\tticker_t ta, tb;\n\n\tticker_init(&ta, NTICKS);\n\tticker_copy(&tb, &ta);\n\tassert_u_eq(ticker_read(&tb), NTICKS, \"Unexpected ticker value\");\n\tassert_true(ticker_ticks(&tb, NTICKS + 1), \"Expected ticker fire\");\n\tassert_u_eq(ticker_read(&tb), NTICKS, \"Unexpected ticker value\");\n\n\tticker_tick(&ta);\n\tticker_copy(&tb, &ta);\n\tassert_u_eq(ticker_read(&tb), NTICKS - 1, \"Unexpected ticker value\");\n\tassert_true(ticker_ticks(&tb, NTICKS), \"Expected ticker fire\");\n\tassert_u_eq(ticker_read(&tb), NTICKS, \"Unexpected ticker value\");\n#undef NTICKS\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_ticker_tick,\n\t    test_ticker_ticks,\n\t    test_ticker_copy));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/tsd.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#define\tTHREAD_DATA 0x72b65c10\n\ntypedef unsigned int data_t;\n\nstatic bool data_cleanup_executed;\n\nmalloc_tsd_types(data_, data_t)\nmalloc_tsd_protos(, data_, data_t)\n\nvoid\ndata_cleanup(void *arg)\n{\n\tdata_t *data = (data_t *)arg;\n\n\tif (!data_cleanup_executed) {\n\t\tassert_x_eq(*data, THREAD_DATA,\n\t\t    \"Argument passed into cleanup function should match tsd \"\n\t\t    \"value\");\n\t}\n\tdata_cleanup_executed = true;\n\n\t/*\n\t * Allocate during cleanup for two rounds, in order to assure that\n\t * jemalloc's internal tsd reinitialization happens.\n\t */\n\tswitch (*data) {\n\tcase THREAD_DATA:\n\t\t*data = 1;\n\t\tdata_tsd_set(data);\n\t\tbreak;\n\tcase 1:\n\t\t*data = 2;\n\t\tdata_tsd_set(data);\n\t\tbreak;\n\tcase 2:\n\t\treturn;\n\tdefault:\n\t\tnot_reached();\n\t}\n\n\t{\n\t\tvoid *p = mallocx(1, 0);\n\t\tassert_ptr_not_null(p, \"Unexpeced mallocx() failure\");\n\t\tdallocx(p, 0);\n\t}\n}\n\nmalloc_tsd_externs(data_, data_t)\n#define\tDATA_INIT 0x12345678\nmalloc_tsd_data(, data_, data_t, DATA_INIT)\nmalloc_tsd_funcs(, data_, data_t, DATA_INIT, data_cleanup)\n\nstatic void *\nthd_start(void *arg)\n{\n\tdata_t d = (data_t)(uintptr_t)arg;\n\tvoid *p;\n\n\tassert_x_eq(*data_tsd_get(), DATA_INIT,\n\t    \"Initial tsd get should return initialization value\");\n\n\tp = malloc(1);\n\tassert_ptr_not_null(p, \"Unexpected malloc() failure\");\n\n\tdata_tsd_set(&d);\n\tassert_x_eq(*data_tsd_get(), d,\n\t    \"After tsd set, tsd get should return value that was set\");\n\n\td = 0;\n\tassert_x_eq(*data_tsd_get(), (data_t)(uintptr_t)arg,\n\t    \"Resetting local data should have no effect on tsd\");\n\n\tfree(p);\n\treturn (NULL);\n}\n\nTEST_BEGIN(test_tsd_main_thread)\n{\n\n\tthd_start((void *) 0xa5f3e329);\n}\nTEST_END\n\nTEST_BEGIN(test_tsd_sub_thread)\n{\n\tthd_t thd;\n\n\tdata_cleanup_executed = false;\n\tthd_create(&thd, thd_start, (void *)THREAD_DATA);\n\tthd_join(thd, NULL);\n\tassert_true(data_cleanup_executed,\n\t    \"Cleanup function should have executed\");\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\tdata_tsd_boot();\n\n\treturn (test(\n\t    test_tsd_main_thread,\n\t    test_tsd_sub_thread));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/util.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#define\tTEST_POW2_CEIL(t, suf, pri) do {\t\t\t\t\\\n\tunsigned i, pow2;\t\t\t\t\t\t\\\n\tt x;\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tassert_zu_eq(pow2_ceil_##suf(0), 0, \"Unexpected result\");\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tfor (i = 0; i < sizeof(t) * 8; i++) {\t\t\t\t\\\n\t\tassert_zu_eq(pow2_ceil_##suf(((t)1) << i), ((t)1) << i,\t\\\n\t\t    \"Unexpected result\");\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\tfor (i = 2; i < sizeof(t) * 8; i++) {\t\t\t\t\\\n\t\tassert_zu_eq(pow2_ceil_##suf((((t)1) << i) - 1),\t\\\n\t\t    ((t)1) << i, \"Unexpected result\");\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tfor (i = 0; i < sizeof(t) * 8 - 1; i++) {\t\t\t\\\n\t\tassert_zu_eq(pow2_ceil_##suf((((t)1) << i) + 1),\t\\\n\t\t    ((t)1) << (i+1), \"Unexpected result\");\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tfor (pow2 = 1; pow2 < 25; pow2++) {\t\t\t\t\\\n\t\tfor (x = (((t)1) << (pow2-1)) + 1; x <= ((t)1) << pow2;\t\\\n\t\t    x++) {\t\t\t\t\t\t\\\n\t\t\tassert_zu_eq(pow2_ceil_##suf(x),\t\t\\\n\t\t\t    ((t)1) << pow2,\t\t\t\t\\\n\t\t\t    \"Unexpected result, x=%\"pri, x);\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\nTEST_BEGIN(test_pow2_ceil_u64)\n{\n\n\tTEST_POW2_CEIL(uint64_t, u64, FMTu64);\n}\nTEST_END\n\nTEST_BEGIN(test_pow2_ceil_u32)\n{\n\n\tTEST_POW2_CEIL(uint32_t, u32, FMTu32);\n}\nTEST_END\n\nTEST_BEGIN(test_pow2_ceil_zu)\n{\n\n\tTEST_POW2_CEIL(size_t, zu, \"zu\");\n}\nTEST_END\n\nTEST_BEGIN(test_malloc_strtoumax_no_endptr)\n{\n\tint err;\n\n\tset_errno(0);\n\tassert_ju_eq(malloc_strtoumax(\"0\", NULL, 0), 0, \"Unexpected result\");\n\terr = get_errno();\n\tassert_d_eq(err, 0, \"Unexpected failure\");\n}\nTEST_END\n\nTEST_BEGIN(test_malloc_strtoumax)\n{\n\tstruct test_s {\n\t\tconst char *input;\n\t\tconst char *expected_remainder;\n\t\tint base;\n\t\tint expected_errno;\n\t\tconst char *expected_errno_name;\n\t\tuintmax_t expected_x;\n\t};\n#define\tERR(e)\t\te, #e\n#define\tKUMAX(x)\t((uintmax_t)x##ULL)\n\tstruct test_s tests[] = {\n\t\t{\"0\",\t\t\"0\",\t-1,\tERR(EINVAL),\tUINTMAX_MAX},\n\t\t{\"0\",\t\t\"0\",\t1,\tERR(EINVAL),\tUINTMAX_MAX},\n\t\t{\"0\",\t\t\"0\",\t37,\tERR(EINVAL),\tUINTMAX_MAX},\n\n\t\t{\"\",\t\t\"\",\t0,\tERR(EINVAL),\tUINTMAX_MAX},\n\t\t{\"+\",\t\t\"+\",\t0,\tERR(EINVAL),\tUINTMAX_MAX},\n\t\t{\"++3\",\t\t\"++3\",\t0,\tERR(EINVAL),\tUINTMAX_MAX},\n\t\t{\"-\",\t\t\"-\",\t0,\tERR(EINVAL),\tUINTMAX_MAX},\n\n\t\t{\"42\",\t\t\"\",\t0,\tERR(0),\t\tKUMAX(42)},\n\t\t{\"+42\",\t\t\"\",\t0,\tERR(0),\t\tKUMAX(42)},\n\t\t{\"-42\",\t\t\"\",\t0,\tERR(0),\t\tKUMAX(-42)},\n\t\t{\"042\",\t\t\"\",\t0,\tERR(0),\t\tKUMAX(042)},\n\t\t{\"+042\",\t\"\",\t0,\tERR(0),\t\tKUMAX(042)},\n\t\t{\"-042\",\t\"\",\t0,\tERR(0),\t\tKUMAX(-042)},\n\t\t{\"0x42\",\t\"\",\t0,\tERR(0),\t\tKUMAX(0x42)},\n\t\t{\"+0x42\",\t\"\",\t0,\tERR(0),\t\tKUMAX(0x42)},\n\t\t{\"-0x42\",\t\"\",\t0,\tERR(0),\t\tKUMAX(-0x42)},\n\n\t\t{\"0\",\t\t\"\",\t0,\tERR(0),\t\tKUMAX(0)},\n\t\t{\"1\",\t\t\"\",\t0,\tERR(0),\t\tKUMAX(1)},\n\n\t\t{\"42\",\t\t\"\",\t0,\tERR(0),\t\tKUMAX(42)},\n\t\t{\" 42\",\t\t\"\",\t0,\tERR(0),\t\tKUMAX(42)},\n\t\t{\"42 \",\t\t\" \",\t0,\tERR(0),\t\tKUMAX(42)},\n\t\t{\"0x\",\t\t\"x\",\t0,\tERR(0),\t\tKUMAX(0)},\n\t\t{\"42x\",\t\t\"x\",\t0,\tERR(0),\t\tKUMAX(42)},\n\n\t\t{\"07\",\t\t\"\",\t0,\tERR(0),\t\tKUMAX(7)},\n\t\t{\"010\",\t\t\"\",\t0,\tERR(0),\t\tKUMAX(8)},\n\t\t{\"08\",\t\t\"8\",\t0,\tERR(0),\t\tKUMAX(0)},\n\t\t{\"0_\",\t\t\"_\",\t0,\tERR(0),\t\tKUMAX(0)},\n\n\t\t{\"0x\",\t\t\"x\",\t0,\tERR(0),\t\tKUMAX(0)},\n\t\t{\"0X\",\t\t\"X\",\t0,\tERR(0),\t\tKUMAX(0)},\n\t\t{\"0xg\",\t\t\"xg\",\t0,\tERR(0),\t\tKUMAX(0)},\n\t\t{\"0XA\",\t\t\"\",\t0,\tERR(0),\t\tKUMAX(10)},\n\n\t\t{\"010\",\t\t\"\",\t10,\tERR(0),\t\tKUMAX(10)},\n\t\t{\"0x3\",\t\t\"x3\",\t10,\tERR(0),\t\tKUMAX(0)},\n\n\t\t{\"12\",\t\t\"2\",\t2,\tERR(0),\t\tKUMAX(1)},\n\t\t{\"78\",\t\t\"8\",\t8,\tERR(0),\t\tKUMAX(7)},\n\t\t{\"9a\",\t\t\"a\",\t10,\tERR(0),\t\tKUMAX(9)},\n\t\t{\"9A\",\t\t\"A\",\t10,\tERR(0),\t\tKUMAX(9)},\n\t\t{\"fg\",\t\t\"g\",\t16,\tERR(0),\t\tKUMAX(15)},\n\t\t{\"FG\",\t\t\"G\",\t16,\tERR(0),\t\tKUMAX(15)},\n\t\t{\"0xfg\",\t\"g\",\t16,\tERR(0),\t\tKUMAX(15)},\n\t\t{\"0XFG\",\t\"G\",\t16,\tERR(0),\t\tKUMAX(15)},\n\t\t{\"z_\",\t\t\"_\",\t36,\tERR(0),\t\tKUMAX(35)},\n\t\t{\"Z_\",\t\t\"_\",\t36,\tERR(0),\t\tKUMAX(35)}\n\t};\n#undef ERR\n#undef KUMAX\n\tunsigned i;\n\n\tfor (i = 0; i < sizeof(tests)/sizeof(struct test_s); i++) {\n\t\tstruct test_s *test = &tests[i];\n\t\tint err;\n\t\tuintmax_t result;\n\t\tchar *remainder;\n\n\t\tset_errno(0);\n\t\tresult = malloc_strtoumax(test->input, &remainder, test->base);\n\t\terr = get_errno();\n\t\tassert_d_eq(err, test->expected_errno,\n\t\t    \"Expected errno %s for \\\"%s\\\", base %d\",\n\t\t    test->expected_errno_name, test->input, test->base);\n\t\tassert_str_eq(remainder, test->expected_remainder,\n\t\t    \"Unexpected remainder for \\\"%s\\\", base %d\",\n\t\t    test->input, test->base);\n\t\tif (err == 0) {\n\t\t\tassert_ju_eq(result, test->expected_x,\n\t\t\t    \"Unexpected result for \\\"%s\\\", base %d\",\n\t\t\t    test->input, test->base);\n\t\t}\n\t}\n}\nTEST_END\n\nTEST_BEGIN(test_malloc_snprintf_truncated)\n{\n#define\tBUFLEN\t15\n\tchar buf[BUFLEN];\n\tint result;\n\tsize_t len;\n#define TEST(expected_str_untruncated, ...) do {\t\t\t\\\n\tresult = malloc_snprintf(buf, len, __VA_ARGS__);\t\t\\\n\tassert_d_eq(strncmp(buf, expected_str_untruncated, len-1), 0,\t\\\n\t    \"Unexpected string inequality (\\\"%s\\\" vs \\\"%s\\\")\",\t\t\\\n\t    buf, expected_str_untruncated);\t\t\\\n\tassert_d_eq(result, strlen(expected_str_untruncated),\t\t\\\n\t    \"Unexpected result\");\t\t\t\t\t\\\n} while (0)\n\n\tfor (len = 1; len < BUFLEN; len++) {\n\t\tTEST(\"012346789\",\t\"012346789\");\n\t\tTEST(\"a0123b\",\t\t\"a%sb\", \"0123\");\n\t\tTEST(\"a01234567\",\t\"a%s%s\", \"0123\", \"4567\");\n\t\tTEST(\"a0123  \",\t\t\"a%-6s\", \"0123\");\n\t\tTEST(\"a  0123\",\t\t\"a%6s\", \"0123\");\n\t\tTEST(\"a   012\",\t\t\"a%6.3s\", \"0123\");\n\t\tTEST(\"a   012\",\t\t\"a%*.*s\", 6, 3, \"0123\");\n\t\tTEST(\"a 123b\",\t\t\"a% db\", 123);\n\t\tTEST(\"a123b\",\t\t\"a%-db\", 123);\n\t\tTEST(\"a-123b\",\t\t\"a%-db\", -123);\n\t\tTEST(\"a+123b\",\t\t\"a%+db\", 123);\n\t}\n#undef BUFLEN\n#undef TEST\n}\nTEST_END\n\nTEST_BEGIN(test_malloc_snprintf)\n{\n#define\tBUFLEN\t128\n\tchar buf[BUFLEN];\n\tint result;\n#define\tTEST(expected_str, ...) do {\t\t\t\t\t\\\n\tresult = malloc_snprintf(buf, sizeof(buf), __VA_ARGS__);\t\\\n\tassert_str_eq(buf, expected_str, \"Unexpected output\");\t\t\\\n\tassert_d_eq(result, strlen(expected_str), \"Unexpected result\");\t\\\n} while (0)\n\n\tTEST(\"hello\", \"hello\");\n\n\tTEST(\"50%, 100%\", \"50%%, %d%%\", 100);\n\n\tTEST(\"a0123b\", \"a%sb\", \"0123\");\n\n\tTEST(\"a 0123b\", \"a%5sb\", \"0123\");\n\tTEST(\"a 0123b\", \"a%*sb\", 5, \"0123\");\n\n\tTEST(\"a0123 b\", \"a%-5sb\", \"0123\");\n\tTEST(\"a0123b\", \"a%*sb\", -1, \"0123\");\n\tTEST(\"a0123 b\", \"a%*sb\", -5, \"0123\");\n\tTEST(\"a0123 b\", \"a%-*sb\", -5, \"0123\");\n\n\tTEST(\"a012b\", \"a%.3sb\", \"0123\");\n\tTEST(\"a012b\", \"a%.*sb\", 3, \"0123\");\n\tTEST(\"a0123b\", \"a%.*sb\", -3, \"0123\");\n\n\tTEST(\"a  012b\", \"a%5.3sb\", \"0123\");\n\tTEST(\"a  012b\", \"a%5.*sb\", 3, \"0123\");\n\tTEST(\"a  012b\", \"a%*.3sb\", 5, \"0123\");\n\tTEST(\"a  012b\", \"a%*.*sb\", 5, 3, \"0123\");\n\tTEST(\"a 0123b\", \"a%*.*sb\", 5, -3, \"0123\");\n\n\tTEST(\"_abcd_\", \"_%x_\", 0xabcd);\n\tTEST(\"_0xabcd_\", \"_%#x_\", 0xabcd);\n\tTEST(\"_1234_\", \"_%o_\", 01234);\n\tTEST(\"_01234_\", \"_%#o_\", 01234);\n\tTEST(\"_1234_\", \"_%u_\", 1234);\n\n\tTEST(\"_1234_\", \"_%d_\", 1234);\n\tTEST(\"_ 1234_\", \"_% d_\", 1234);\n\tTEST(\"_+1234_\", \"_%+d_\", 1234);\n\tTEST(\"_-1234_\", \"_%d_\", -1234);\n\tTEST(\"_-1234_\", \"_% d_\", -1234);\n\tTEST(\"_-1234_\", \"_%+d_\", -1234);\n\n\tTEST(\"_-1234_\", \"_%d_\", -1234);\n\tTEST(\"_1234_\", \"_%d_\", 1234);\n\tTEST(\"_-1234_\", \"_%i_\", -1234);\n\tTEST(\"_1234_\", \"_%i_\", 1234);\n\tTEST(\"_01234_\", \"_%#o_\", 01234);\n\tTEST(\"_1234_\", \"_%u_\", 1234);\n\tTEST(\"_0x1234abc_\", \"_%#x_\", 0x1234abc);\n\tTEST(\"_0X1234ABC_\", \"_%#X_\", 0x1234abc);\n\tTEST(\"_c_\", \"_%c_\", 'c');\n\tTEST(\"_string_\", \"_%s_\", \"string\");\n\tTEST(\"_0x42_\", \"_%p_\", ((void *)0x42));\n\n\tTEST(\"_-1234_\", \"_%ld_\", ((long)-1234));\n\tTEST(\"_1234_\", \"_%ld_\", ((long)1234));\n\tTEST(\"_-1234_\", \"_%li_\", ((long)-1234));\n\tTEST(\"_1234_\", \"_%li_\", ((long)1234));\n\tTEST(\"_01234_\", \"_%#lo_\", ((long)01234));\n\tTEST(\"_1234_\", \"_%lu_\", ((long)1234));\n\tTEST(\"_0x1234abc_\", \"_%#lx_\", ((long)0x1234abc));\n\tTEST(\"_0X1234ABC_\", \"_%#lX_\", ((long)0x1234ABC));\n\n\tTEST(\"_-1234_\", \"_%lld_\", ((long long)-1234));\n\tTEST(\"_1234_\", \"_%lld_\", ((long long)1234));\n\tTEST(\"_-1234_\", \"_%lli_\", ((long long)-1234));\n\tTEST(\"_1234_\", \"_%lli_\", ((long long)1234));\n\tTEST(\"_01234_\", \"_%#llo_\", ((long long)01234));\n\tTEST(\"_1234_\", \"_%llu_\", ((long long)1234));\n\tTEST(\"_0x1234abc_\", \"_%#llx_\", ((long long)0x1234abc));\n\tTEST(\"_0X1234ABC_\", \"_%#llX_\", ((long long)0x1234ABC));\n\n\tTEST(\"_-1234_\", \"_%qd_\", ((long long)-1234));\n\tTEST(\"_1234_\", \"_%qd_\", ((long long)1234));\n\tTEST(\"_-1234_\", \"_%qi_\", ((long long)-1234));\n\tTEST(\"_1234_\", \"_%qi_\", ((long long)1234));\n\tTEST(\"_01234_\", \"_%#qo_\", ((long long)01234));\n\tTEST(\"_1234_\", \"_%qu_\", ((long long)1234));\n\tTEST(\"_0x1234abc_\", \"_%#qx_\", ((long long)0x1234abc));\n\tTEST(\"_0X1234ABC_\", \"_%#qX_\", ((long long)0x1234ABC));\n\n\tTEST(\"_-1234_\", \"_%jd_\", ((intmax_t)-1234));\n\tTEST(\"_1234_\", \"_%jd_\", ((intmax_t)1234));\n\tTEST(\"_-1234_\", \"_%ji_\", ((intmax_t)-1234));\n\tTEST(\"_1234_\", \"_%ji_\", ((intmax_t)1234));\n\tTEST(\"_01234_\", \"_%#jo_\", ((intmax_t)01234));\n\tTEST(\"_1234_\", \"_%ju_\", ((intmax_t)1234));\n\tTEST(\"_0x1234abc_\", \"_%#jx_\", ((intmax_t)0x1234abc));\n\tTEST(\"_0X1234ABC_\", \"_%#jX_\", ((intmax_t)0x1234ABC));\n\n\tTEST(\"_1234_\", \"_%td_\", ((ptrdiff_t)1234));\n\tTEST(\"_-1234_\", \"_%td_\", ((ptrdiff_t)-1234));\n\tTEST(\"_1234_\", \"_%ti_\", ((ptrdiff_t)1234));\n\tTEST(\"_-1234_\", \"_%ti_\", ((ptrdiff_t)-1234));\n\n\tTEST(\"_-1234_\", \"_%zd_\", ((ssize_t)-1234));\n\tTEST(\"_1234_\", \"_%zd_\", ((ssize_t)1234));\n\tTEST(\"_-1234_\", \"_%zi_\", ((ssize_t)-1234));\n\tTEST(\"_1234_\", \"_%zi_\", ((ssize_t)1234));\n\tTEST(\"_01234_\", \"_%#zo_\", ((ssize_t)01234));\n\tTEST(\"_1234_\", \"_%zu_\", ((ssize_t)1234));\n\tTEST(\"_0x1234abc_\", \"_%#zx_\", ((ssize_t)0x1234abc));\n\tTEST(\"_0X1234ABC_\", \"_%#zX_\", ((ssize_t)0x1234ABC));\n#undef BUFLEN\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_pow2_ceil_u64,\n\t    test_pow2_ceil_u32,\n\t    test_pow2_ceil_zu,\n\t    test_malloc_strtoumax_no_endptr,\n\t    test_malloc_strtoumax,\n\t    test_malloc_snprintf_truncated,\n\t    test_malloc_snprintf));\n}\n"
  },
  {
    "path": "deps/jemalloc-4.1.0/test/unit/zero.c",
    "content": "#include \"test/jemalloc_test.h\"\n\n#ifdef JEMALLOC_FILL\nconst char *malloc_conf =\n    \"abort:false,junk:false,zero:true,redzone:false,quarantine:0\";\n#endif\n\nstatic void\ntest_zero(size_t sz_min, size_t sz_max)\n{\n\tchar *s;\n\tsize_t sz_prev, sz, i;\n\n\tsz_prev = 0;\n\ts = (char *)mallocx(sz_min, 0);\n\tassert_ptr_not_null((void *)s, \"Unexpected mallocx() failure\");\n\n\tfor (sz = sallocx(s, 0); sz <= sz_max;\n\t    sz_prev = sz, sz = sallocx(s, 0)) {\n\t\tif (sz_prev > 0) {\n\t\t\tassert_c_eq(s[0], 'a',\n\t\t\t    \"Previously allocated byte %zu/%zu is corrupted\",\n\t\t\t    ZU(0), sz_prev);\n\t\t\tassert_c_eq(s[sz_prev-1], 'a',\n\t\t\t    \"Previously allocated byte %zu/%zu is corrupted\",\n\t\t\t    sz_prev-1, sz_prev);\n\t\t}\n\n\t\tfor (i = sz_prev; i < sz; i++) {\n\t\t\tassert_c_eq(s[i], 0x0,\n\t\t\t    \"Newly allocated byte %zu/%zu isn't zero-filled\",\n\t\t\t    i, sz);\n\t\t\ts[i] = 'a';\n\t\t}\n\n\t\tif (xallocx(s, sz+1, 0, 0) == sz) {\n\t\t\ts = (char *)rallocx(s, sz+1, 0);\n\t\t\tassert_ptr_not_null((void *)s,\n\t\t\t    \"Unexpected rallocx() failure\");\n\t\t}\n\t}\n\n\tdallocx(s, 0);\n}\n\nTEST_BEGIN(test_zero_small)\n{\n\n\ttest_skip_if(!config_fill);\n\ttest_zero(1, SMALL_MAXCLASS-1);\n}\nTEST_END\n\nTEST_BEGIN(test_zero_large)\n{\n\n\ttest_skip_if(!config_fill);\n\ttest_zero(SMALL_MAXCLASS+1, large_maxclass);\n}\nTEST_END\n\nTEST_BEGIN(test_zero_huge)\n{\n\n\ttest_skip_if(!config_fill);\n\ttest_zero(large_maxclass+1, chunksize*2);\n}\nTEST_END\n\nint\nmain(void)\n{\n\n\treturn (test(\n\t    test_zero_small,\n\t    test_zero_large,\n\t    test_zero_huge));\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/.gitignore",
    "content": "build_config.mk\n*.a\n*.o\n*.dylib*\n*.so\n*.so.*\n*_test\ndb_bench\nleveldbutil\n"
  },
  {
    "path": "deps/leveldb-1.20/.travis.yml",
    "content": "language: cpp\ncompiler:\n- clang\n- gcc\nos:\n- linux\n- osx\nsudo: false\nbefore_install:\n- echo $LANG\n- echo $LC_ALL\nscript:\n- make -j 4 check\n"
  },
  {
    "path": "deps/leveldb-1.20/AUTHORS",
    "content": "# Names should be added to this file like so:\n# Name or Organization <email address>\n\nGoogle Inc.\n\n# Initial version authors:\nJeffrey Dean <jeff@google.com>\nSanjay Ghemawat <sanjay@google.com>\n\n# Partial list of contributors:\nKevin Regan <kevin.d.regan@gmail.com>\nJohan Bilien <jobi@litl.com>\n"
  },
  {
    "path": "deps/leveldb-1.20/CONTRIBUTING.md",
    "content": "# Contributing\n\nWe'd love to accept your code patches! However, before we can take them, we\nhave to jump a couple of legal hurdles.\n\n## Contributor License Agreements\n\nPlease fill out either the individual or corporate Contributor License\nAgreement as appropriate.\n\n* If you are an individual writing original source code and you're sure you\nown the intellectual property, then sign an [individual CLA](https://developers.google.com/open-source/cla/individual).\n* If you work for a company that wants to allow you to contribute your work,\nthen sign a [corporate CLA](https://developers.google.com/open-source/cla/corporate).\n\nFollow either of the two links above to access the appropriate CLA and\ninstructions for how to sign and return it.\n\n## Submitting a Patch\n\n1. Sign the contributors license agreement above.\n2. Decide which code you want to submit. A submission should be a set of changes\nthat addresses one issue in the [issue tracker](https://github.com/google/leveldb/issues).\nPlease don't mix more than one logical change per submission, because it makes\nthe history hard to follow. If you want to make a change\n(e.g. add a sample or feature) that doesn't have a corresponding issue in the\nissue tracker, please create one.\n3. **Submitting**: When you are ready to submit, send us a Pull Request. Be\nsure to include the issue number you fixed and the name you used to sign\nthe CLA.\n\n## Writing Code ##\n\nIf your contribution contains code, please make sure that it follows \n[the style guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml).\nOtherwise we will have to ask you to make changes, and that's no fun for anyone.\n"
  },
  {
    "path": "deps/leveldb-1.20/LICENSE",
    "content": "Copyright (c) 2011 The LevelDB Authors. All 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": "deps/leveldb-1.20/Makefile",
    "content": "# Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n# Use of this source code is governed by a BSD-style license that can be\n# found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#-----------------------------------------------\n# Uncomment exactly one of the lines labelled (A), (B), and (C) below\n# to switch between compilation modes.\n\n# (A) Production use (optimized mode)\nOPT ?= -O2 -DNDEBUG\n# (B) Debug mode, w/ full line-level debugging symbols\n# OPT ?= -g2\n# (C) Profiling mode: opt, but w/debugging symbols\n# OPT ?= -O2 -g2 -DNDEBUG\n#-----------------------------------------------\n\n# detect what platform we're building on\n$(shell CC=\"$(CC)\" CXX=\"$(CXX)\" TARGET_OS=\"$(TARGET_OS)\" \\\n    ./build_detect_platform build_config.mk ./)\n# this file is generated by the previous line to set build flags and sources\ninclude build_config.mk\n\nTESTS = \\\n\tdb/autocompact_test \\\n\tdb/c_test \\\n\tdb/corruption_test \\\n\tdb/db_test \\\n\tdb/dbformat_test \\\n\tdb/fault_injection_test \\\n\tdb/filename_test \\\n\tdb/log_test \\\n\tdb/recovery_test \\\n\tdb/skiplist_test \\\n\tdb/version_edit_test \\\n\tdb/version_set_test \\\n\tdb/write_batch_test \\\n\thelpers/memenv/memenv_test \\\n\tissues/issue178_test \\\n\tissues/issue200_test \\\n\ttable/filter_block_test \\\n\ttable/table_test \\\n\tutil/arena_test \\\n\tutil/bloom_test \\\n\tutil/cache_test \\\n\tutil/coding_test \\\n\tutil/crc32c_test \\\n\tutil/env_posix_test \\\n\tutil/env_test \\\n\tutil/hash_test\n\nUTILS = \\\n\tdb/db_bench \\\n\tdb/leveldbutil\n\n# Put the object files in a subdirectory, but the application at the top of the object dir.\nPROGNAMES := $(notdir $(TESTS) $(UTILS))\n\n# On Linux may need libkyotocabinet-dev for dependency.\nBENCHMARKS = \\\n\tdoc/bench/db_bench_sqlite3 \\\n\tdoc/bench/db_bench_tree_db\n\nCFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT)\nCXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT)\n\nLDFLAGS += $(PLATFORM_LDFLAGS)\nLIBS += $(PLATFORM_LIBS)\n\nSIMULATOR_OUTDIR=out-ios-x86\nDEVICE_OUTDIR=out-ios-arm\n\nifeq ($(PLATFORM), IOS)\n# Note: iOS should probably be using libtool, not ar.\nAR=xcrun ar\nSIMULATORSDK=$(shell xcrun -sdk iphonesimulator --show-sdk-path)\nDEVICESDK=$(shell xcrun -sdk iphoneos --show-sdk-path)\nDEVICE_CFLAGS = -isysroot \"$(DEVICESDK)\" -arch armv6 -arch armv7 -arch armv7s -arch arm64\nSIMULATOR_CFLAGS = -isysroot \"$(SIMULATORSDK)\" -arch i686 -arch x86_64\nSTATIC_OUTDIR=out-ios-universal\nelse\nSTATIC_OUTDIR=out-static\nSHARED_OUTDIR=out-shared\nSTATIC_PROGRAMS := $(addprefix $(STATIC_OUTDIR)/, $(PROGNAMES))\nSHARED_PROGRAMS := $(addprefix $(SHARED_OUTDIR)/, db_bench)\nendif\n\nSTATIC_LIBOBJECTS := $(addprefix $(STATIC_OUTDIR)/, $(SOURCES:.cc=.o))\nSTATIC_MEMENVOBJECTS := $(addprefix $(STATIC_OUTDIR)/, $(MEMENV_SOURCES:.cc=.o))\n\nDEVICE_LIBOBJECTS := $(addprefix $(DEVICE_OUTDIR)/, $(SOURCES:.cc=.o))\nDEVICE_MEMENVOBJECTS := $(addprefix $(DEVICE_OUTDIR)/, $(MEMENV_SOURCES:.cc=.o))\n\nSIMULATOR_LIBOBJECTS := $(addprefix $(SIMULATOR_OUTDIR)/, $(SOURCES:.cc=.o))\nSIMULATOR_MEMENVOBJECTS := $(addprefix $(SIMULATOR_OUTDIR)/, $(MEMENV_SOURCES:.cc=.o))\n\nSHARED_LIBOBJECTS := $(addprefix $(SHARED_OUTDIR)/, $(SOURCES:.cc=.o))\nSHARED_MEMENVOBJECTS := $(addprefix $(SHARED_OUTDIR)/, $(MEMENV_SOURCES:.cc=.o))\n\nTESTUTIL := $(STATIC_OUTDIR)/util/testutil.o\nTESTHARNESS := $(STATIC_OUTDIR)/util/testharness.o $(TESTUTIL)\n\nSTATIC_TESTOBJS := $(addprefix $(STATIC_OUTDIR)/, $(addsuffix .o, $(TESTS)))\nSTATIC_UTILOBJS := $(addprefix $(STATIC_OUTDIR)/, $(addsuffix .o, $(UTILS)))\nSTATIC_ALLOBJS := $(STATIC_LIBOBJECTS) $(STATIC_MEMENVOBJECTS) $(STATIC_TESTOBJS) $(STATIC_UTILOBJS) $(TESTHARNESS)\nDEVICE_ALLOBJS := $(DEVICE_LIBOBJECTS) $(DEVICE_MEMENVOBJECTS)\nSIMULATOR_ALLOBJS := $(SIMULATOR_LIBOBJECTS) $(SIMULATOR_MEMENVOBJECTS)\n\ndefault: all\n\n# Should we build shared libraries?\nifneq ($(PLATFORM_SHARED_EXT),)\n\n# Many leveldb test apps use non-exported API's. Only build a subset for testing.\nSHARED_ALLOBJS := $(SHARED_LIBOBJECTS) $(SHARED_MEMENVOBJECTS) $(TESTHARNESS)\n\nifneq ($(PLATFORM_SHARED_VERSIONED),true)\nSHARED_LIB1 = libleveldb.$(PLATFORM_SHARED_EXT)\nSHARED_LIB2 = $(SHARED_LIB1)\nSHARED_LIB3 = $(SHARED_LIB1)\nSHARED_LIBS = $(SHARED_LIB1)\nSHARED_MEMENVLIB = $(SHARED_OUTDIR)/libmemenv.a\nelse\n# Update db.h if you change these.\nSHARED_VERSION_MAJOR = 1\nSHARED_VERSION_MINOR = 20\nSHARED_LIB1 = libleveldb.$(PLATFORM_SHARED_EXT)\nSHARED_LIB2 = $(SHARED_LIB1).$(SHARED_VERSION_MAJOR)\nSHARED_LIB3 = $(SHARED_LIB1).$(SHARED_VERSION_MAJOR).$(SHARED_VERSION_MINOR)\nSHARED_LIBS = $(SHARED_OUTDIR)/$(SHARED_LIB1) $(SHARED_OUTDIR)/$(SHARED_LIB2) $(SHARED_OUTDIR)/$(SHARED_LIB3)\n$(SHARED_OUTDIR)/$(SHARED_LIB1): $(SHARED_OUTDIR)/$(SHARED_LIB3)\n\tln -fs $(SHARED_LIB3) $(SHARED_OUTDIR)/$(SHARED_LIB1)\n$(SHARED_OUTDIR)/$(SHARED_LIB2): $(SHARED_OUTDIR)/$(SHARED_LIB3)\n\tln -fs $(SHARED_LIB3) $(SHARED_OUTDIR)/$(SHARED_LIB2)\nSHARED_MEMENVLIB = $(SHARED_OUTDIR)/libmemenv.a\nendif\n\n$(SHARED_OUTDIR)/$(SHARED_LIB3): $(SHARED_LIBOBJECTS)\n\t$(CXX) $(LDFLAGS) $(PLATFORM_SHARED_LDFLAGS)$(SHARED_LIB2) $(SHARED_LIBOBJECTS) -o $(SHARED_OUTDIR)/$(SHARED_LIB3) $(LIBS)\n\nendif  # PLATFORM_SHARED_EXT\n\nall: $(STATIC_OUTDIR)/libleveldb.a $(STATIC_OUTDIR)/libmemenv.a\n\ncheck: $(STATIC_PROGRAMS)\n\tfor t in $(notdir $(TESTS)); do echo \"***** Running $$t\"; $(STATIC_OUTDIR)/$$t || exit 1; done\n\nclean:\n\t-rm -rf out-static out-shared out-ios-x86 out-ios-arm out-ios-universal\n\t-rm -f build_config.mk\n\t-rm -rf ios-x86 ios-arm\n\n$(STATIC_OUTDIR):\n\tmkdir $@\n\n$(STATIC_OUTDIR)/db: | $(STATIC_OUTDIR)\n\tmkdir $@\n\n$(STATIC_OUTDIR)/helpers/memenv: | $(STATIC_OUTDIR)\n\tmkdir -p $@\n\n$(STATIC_OUTDIR)/port: | $(STATIC_OUTDIR)\n\tmkdir $@\n\n$(STATIC_OUTDIR)/table: | $(STATIC_OUTDIR)\n\tmkdir $@\n\n$(STATIC_OUTDIR)/util: | $(STATIC_OUTDIR)\n\tmkdir $@\n\n.PHONY: STATIC_OBJDIRS\nSTATIC_OBJDIRS: \\\n\t$(STATIC_OUTDIR)/db \\\n\t$(STATIC_OUTDIR)/port \\\n\t$(STATIC_OUTDIR)/table \\\n\t$(STATIC_OUTDIR)/util \\\n\t$(STATIC_OUTDIR)/helpers/memenv\n\n$(SHARED_OUTDIR):\n\tmkdir $@\n\n$(SHARED_OUTDIR)/db: | $(SHARED_OUTDIR)\n\tmkdir $@\n\n$(SHARED_OUTDIR)/helpers/memenv: | $(SHARED_OUTDIR)\n\tmkdir -p $@\n\n$(SHARED_OUTDIR)/port: | $(SHARED_OUTDIR)\n\tmkdir $@\n\n$(SHARED_OUTDIR)/table: | $(SHARED_OUTDIR)\n\tmkdir $@\n\n$(SHARED_OUTDIR)/util: | $(SHARED_OUTDIR)\n\tmkdir $@\n\n.PHONY: SHARED_OBJDIRS\nSHARED_OBJDIRS: \\\n\t$(SHARED_OUTDIR)/db \\\n\t$(SHARED_OUTDIR)/port \\\n\t$(SHARED_OUTDIR)/table \\\n\t$(SHARED_OUTDIR)/util \\\n\t$(SHARED_OUTDIR)/helpers/memenv\n\n$(DEVICE_OUTDIR):\n\tmkdir $@\n\n$(DEVICE_OUTDIR)/db: | $(DEVICE_OUTDIR)\n\tmkdir $@\n\n$(DEVICE_OUTDIR)/helpers/memenv: | $(DEVICE_OUTDIR)\n\tmkdir -p $@\n\n$(DEVICE_OUTDIR)/port: | $(DEVICE_OUTDIR)\n\tmkdir $@\n\n$(DEVICE_OUTDIR)/table: | $(DEVICE_OUTDIR)\n\tmkdir $@\n\n$(DEVICE_OUTDIR)/util: | $(DEVICE_OUTDIR)\n\tmkdir $@\n\n.PHONY: DEVICE_OBJDIRS\nDEVICE_OBJDIRS: \\\n\t$(DEVICE_OUTDIR)/db \\\n\t$(DEVICE_OUTDIR)/port \\\n\t$(DEVICE_OUTDIR)/table \\\n\t$(DEVICE_OUTDIR)/util \\\n\t$(DEVICE_OUTDIR)/helpers/memenv\n\n$(SIMULATOR_OUTDIR):\n\tmkdir $@\n\n$(SIMULATOR_OUTDIR)/db: | $(SIMULATOR_OUTDIR)\n\tmkdir $@\n\n$(SIMULATOR_OUTDIR)/helpers/memenv: | $(SIMULATOR_OUTDIR)\n\tmkdir -p $@\n\n$(SIMULATOR_OUTDIR)/port: | $(SIMULATOR_OUTDIR)\n\tmkdir $@\n\n$(SIMULATOR_OUTDIR)/table: | $(SIMULATOR_OUTDIR)\n\tmkdir $@\n\n$(SIMULATOR_OUTDIR)/util: | $(SIMULATOR_OUTDIR)\n\tmkdir $@\n\n.PHONY: SIMULATOR_OBJDIRS\nSIMULATOR_OBJDIRS: \\\n\t$(SIMULATOR_OUTDIR)/db \\\n\t$(SIMULATOR_OUTDIR)/port \\\n\t$(SIMULATOR_OUTDIR)/table \\\n\t$(SIMULATOR_OUTDIR)/util \\\n\t$(SIMULATOR_OUTDIR)/helpers/memenv\n\n$(STATIC_ALLOBJS): | STATIC_OBJDIRS\n$(DEVICE_ALLOBJS): | DEVICE_OBJDIRS\n$(SIMULATOR_ALLOBJS): | SIMULATOR_OBJDIRS\n$(SHARED_ALLOBJS): | SHARED_OBJDIRS\n\nifeq ($(PLATFORM), IOS)\n$(DEVICE_OUTDIR)/libleveldb.a: $(DEVICE_LIBOBJECTS)\n\trm -f $@\n\t$(AR) -rs $@ $(DEVICE_LIBOBJECTS)\n\n$(SIMULATOR_OUTDIR)/libleveldb.a: $(SIMULATOR_LIBOBJECTS)\n\trm -f $@\n\t$(AR) -rs $@ $(SIMULATOR_LIBOBJECTS)\n\n$(DEVICE_OUTDIR)/libmemenv.a: $(DEVICE_MEMENVOBJECTS)\n\trm -f $@\n\t$(AR) -rs $@ $(DEVICE_MEMENVOBJECTS)\n\n$(SIMULATOR_OUTDIR)/libmemenv.a: $(SIMULATOR_MEMENVOBJECTS)\n\trm -f $@\n\t$(AR) -rs $@ $(SIMULATOR_MEMENVOBJECTS)\n\n# For iOS, create universal object libraries to be used on both the simulator and\n# a device.\n$(STATIC_OUTDIR)/libleveldb.a: $(STATIC_OUTDIR) $(DEVICE_OUTDIR)/libleveldb.a $(SIMULATOR_OUTDIR)/libleveldb.a\n\tlipo -create $(DEVICE_OUTDIR)/libleveldb.a $(SIMULATOR_OUTDIR)/libleveldb.a -output $@\n\n$(STATIC_OUTDIR)/libmemenv.a: $(STATIC_OUTDIR) $(DEVICE_OUTDIR)/libmemenv.a $(SIMULATOR_OUTDIR)/libmemenv.a\n\tlipo -create $(DEVICE_OUTDIR)/libmemenv.a $(SIMULATOR_OUTDIR)/libmemenv.a -output $@\nelse\n$(STATIC_OUTDIR)/libleveldb.a:$(STATIC_LIBOBJECTS)\n\trm -f $@\n\t$(AR) -rs $@ $(STATIC_LIBOBJECTS)\n\n$(STATIC_OUTDIR)/libmemenv.a:$(STATIC_MEMENVOBJECTS)\n\trm -f $@\n\t$(AR) -rs $@ $(STATIC_MEMENVOBJECTS)\nendif\n\n$(SHARED_MEMENVLIB):$(SHARED_MEMENVOBJECTS)\n\trm -f $@\n\t$(AR) -rs $@ $(SHARED_MEMENVOBJECTS)\n\n$(STATIC_OUTDIR)/db_bench:db/db_bench.cc $(STATIC_LIBOBJECTS) $(TESTUTIL)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/db_bench.cc $(STATIC_LIBOBJECTS) $(TESTUTIL) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/db_bench_sqlite3:doc/bench/db_bench_sqlite3.cc $(STATIC_LIBOBJECTS) $(TESTUTIL)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) doc/bench/db_bench_sqlite3.cc $(STATIC_LIBOBJECTS) $(TESTUTIL) -o $@ -lsqlite3 $(LIBS)\n\n$(STATIC_OUTDIR)/db_bench_tree_db:doc/bench/db_bench_tree_db.cc $(STATIC_LIBOBJECTS) $(TESTUTIL)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) doc/bench/db_bench_tree_db.cc $(STATIC_LIBOBJECTS) $(TESTUTIL) -o $@ -lkyotocabinet $(LIBS)\n\n$(STATIC_OUTDIR)/leveldbutil:db/leveldbutil.cc $(STATIC_LIBOBJECTS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/leveldbutil.cc $(STATIC_LIBOBJECTS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/arena_test:util/arena_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) util/arena_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/autocompact_test:db/autocompact_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/autocompact_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/bloom_test:util/bloom_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) util/bloom_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/c_test:$(STATIC_OUTDIR)/db/c_test.o $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(STATIC_OUTDIR)/db/c_test.o $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/cache_test:util/cache_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) util/cache_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/coding_test:util/coding_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) util/coding_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/corruption_test:db/corruption_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/corruption_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/crc32c_test:util/crc32c_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) util/crc32c_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/db_test:db/db_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/db_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/dbformat_test:db/dbformat_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/dbformat_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/env_posix_test:util/env_posix_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) util/env_posix_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/env_test:util/env_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) util/env_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/fault_injection_test:db/fault_injection_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/fault_injection_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/filename_test:db/filename_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/filename_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/filter_block_test:table/filter_block_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) table/filter_block_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/hash_test:util/hash_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) util/hash_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/issue178_test:issues/issue178_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) issues/issue178_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/issue200_test:issues/issue200_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) issues/issue200_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/log_test:db/log_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/log_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/recovery_test:db/recovery_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/recovery_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/table_test:table/table_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) table/table_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/skiplist_test:db/skiplist_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/skiplist_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/version_edit_test:db/version_edit_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/version_edit_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/version_set_test:db/version_set_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/version_set_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/write_batch_test:db/write_batch_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/write_batch_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/memenv_test:$(STATIC_OUTDIR)/helpers/memenv/memenv_test.o $(STATIC_OUTDIR)/libmemenv.a $(STATIC_OUTDIR)/libleveldb.a $(TESTHARNESS)\n\t$(XCRUN) $(CXX) $(LDFLAGS) $(STATIC_OUTDIR)/helpers/memenv/memenv_test.o $(STATIC_OUTDIR)/libmemenv.a $(STATIC_OUTDIR)/libleveldb.a $(TESTHARNESS) -o $@ $(LIBS)\n\n$(SHARED_OUTDIR)/db_bench:$(SHARED_OUTDIR)/db/db_bench.o $(SHARED_LIBS) $(TESTUTIL)\n\t$(XCRUN) $(CXX) $(LDFLAGS) $(CXXFLAGS) $(PLATFORM_SHARED_CFLAGS) $(SHARED_OUTDIR)/db/db_bench.o $(TESTUTIL) $(SHARED_OUTDIR)/$(SHARED_LIB3) -o $@ $(LIBS)\n\n.PHONY: run-shared\nrun-shared: $(SHARED_OUTDIR)/db_bench\n\tLD_LIBRARY_PATH=$(SHARED_OUTDIR) $(SHARED_OUTDIR)/db_bench\n\n$(SIMULATOR_OUTDIR)/%.o: %.cc\n\txcrun -sdk iphonesimulator $(CXX) $(CXXFLAGS) $(SIMULATOR_CFLAGS) -c $< -o $@\n\n$(DEVICE_OUTDIR)/%.o: %.cc\n\txcrun -sdk iphoneos $(CXX) $(CXXFLAGS) $(DEVICE_CFLAGS) -c $< -o $@\n\n$(SIMULATOR_OUTDIR)/%.o: %.c\n\txcrun -sdk iphonesimulator $(CC) $(CFLAGS) $(SIMULATOR_CFLAGS) -c $< -o $@\n\n$(DEVICE_OUTDIR)/%.o: %.c\n\txcrun -sdk iphoneos $(CC) $(CFLAGS) $(DEVICE_CFLAGS) -c $< -o $@\n\n$(STATIC_OUTDIR)/%.o: %.cc\n\t$(CXX) $(CXXFLAGS) -c $< -o $@\n\n$(STATIC_OUTDIR)/%.o: %.c\n\t$(CC) $(CFLAGS) -c $< -o $@\n\n$(SHARED_OUTDIR)/%.o: %.cc\n\t$(CXX) $(CXXFLAGS) $(PLATFORM_SHARED_CFLAGS) -c $< -o $@\n\n$(SHARED_OUTDIR)/%.o: %.c\n\t$(CC) $(CFLAGS) $(PLATFORM_SHARED_CFLAGS) -c $< -o $@\n\n$(STATIC_OUTDIR)/port/port_posix_sse.o: port/port_posix_sse.cc\n\t$(CXX) $(CXXFLAGS) $(PLATFORM_SSEFLAGS) -c $< -o $@\n\n$(SHARED_OUTDIR)/port/port_posix_sse.o: port/port_posix_sse.cc\n\t$(CXX) $(CXXFLAGS) $(PLATFORM_SHARED_CFLAGS) $(PLATFORM_SSEFLAGS) -c $< -o $@\n"
  },
  {
    "path": "deps/leveldb-1.20/Makefile.bk",
    "content": "# Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n# Use of this source code is governed by a BSD-style license that can be\n# found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#-----------------------------------------------\n# Uncomment exactly one of the lines labelled (A), (B), and (C) below\n# to switch between compilation modes.\n\n# (A) Production use (optimized mode)\nOPT ?= -O2 -DNDEBUG\n# (B) Debug mode, w/ full line-level debugging symbols\n# OPT ?= -g2\n# (C) Profiling mode: opt, but w/debugging symbols\n# OPT ?= -O2 -g2 -DNDEBUG\n#-----------------------------------------------\n\n# detect what platform we're building on\n$(shell CC=\"$(CC)\" CXX=\"$(CXX)\" TARGET_OS=\"$(TARGET_OS)\" \\\n    ./build_detect_platform build_config.mk ./)\n# this file is generated by the previous line to set build flags and sources\ninclude build_config.mk\n\nTESTS = \\\n\tdb/autocompact_test \\\n\tdb/c_test \\\n\tdb/corruption_test \\\n\tdb/db_test \\\n\tdb/dbformat_test \\\n\tdb/fault_injection_test \\\n\tdb/filename_test \\\n\tdb/log_test \\\n\tdb/recovery_test \\\n\tdb/skiplist_test \\\n\tdb/version_edit_test \\\n\tdb/version_set_test \\\n\tdb/write_batch_test \\\n\thelpers/memenv/memenv_test \\\n\tissues/issue178_test \\\n\tissues/issue200_test \\\n\ttable/filter_block_test \\\n\ttable/table_test \\\n\tutil/arena_test \\\n\tutil/bloom_test \\\n\tutil/cache_test \\\n\tutil/coding_test \\\n\tutil/crc32c_test \\\n\tutil/env_posix_test \\\n\tutil/env_test \\\n\tutil/hash_test\n\nUTILS = \\\n\tdb/db_bench \\\n\tdb/leveldbutil\n\n# Put the object files in a subdirectory, but the application at the top of the object dir.\nPROGNAMES := $(notdir $(TESTS) $(UTILS))\n\n# On Linux may need libkyotocabinet-dev for dependency.\nBENCHMARKS = \\\n\tdoc/bench/db_bench_sqlite3 \\\n\tdoc/bench/db_bench_tree_db\n\nCFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT)\nCXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT)\n\nLDFLAGS += $(PLATFORM_LDFLAGS)\nLIBS += $(PLATFORM_LIBS)\n\nSIMULATOR_OUTDIR=out-ios-x86\nDEVICE_OUTDIR=out-ios-arm\n\nifeq ($(PLATFORM), IOS)\n# Note: iOS should probably be using libtool, not ar.\nAR=xcrun ar\nSIMULATORSDK=$(shell xcrun -sdk iphonesimulator --show-sdk-path)\nDEVICESDK=$(shell xcrun -sdk iphoneos --show-sdk-path)\nDEVICE_CFLAGS = -isysroot \"$(DEVICESDK)\" -arch armv6 -arch armv7 -arch armv7s -arch arm64\nSIMULATOR_CFLAGS = -isysroot \"$(SIMULATORSDK)\" -arch i686 -arch x86_64\nSTATIC_OUTDIR=out-ios-universal\nelse\nSTATIC_OUTDIR=out-static\nSHARED_OUTDIR=out-shared\nSTATIC_PROGRAMS := $(addprefix $(STATIC_OUTDIR)/, $(PROGNAMES))\nSHARED_PROGRAMS := $(addprefix $(SHARED_OUTDIR)/, db_bench)\nendif\n\nSTATIC_LIBOBJECTS := $(addprefix $(STATIC_OUTDIR)/, $(SOURCES:.cc=.o))\nSTATIC_MEMENVOBJECTS := $(addprefix $(STATIC_OUTDIR)/, $(MEMENV_SOURCES:.cc=.o))\n\nDEVICE_LIBOBJECTS := $(addprefix $(DEVICE_OUTDIR)/, $(SOURCES:.cc=.o))\nDEVICE_MEMENVOBJECTS := $(addprefix $(DEVICE_OUTDIR)/, $(MEMENV_SOURCES:.cc=.o))\n\nSIMULATOR_LIBOBJECTS := $(addprefix $(SIMULATOR_OUTDIR)/, $(SOURCES:.cc=.o))\nSIMULATOR_MEMENVOBJECTS := $(addprefix $(SIMULATOR_OUTDIR)/, $(MEMENV_SOURCES:.cc=.o))\n\nSHARED_LIBOBJECTS := $(addprefix $(SHARED_OUTDIR)/, $(SOURCES:.cc=.o))\nSHARED_MEMENVOBJECTS := $(addprefix $(SHARED_OUTDIR)/, $(MEMENV_SOURCES:.cc=.o))\n\nTESTUTIL := $(STATIC_OUTDIR)/util/testutil.o\nTESTHARNESS := $(STATIC_OUTDIR)/util/testharness.o $(TESTUTIL)\n\nSTATIC_TESTOBJS := $(addprefix $(STATIC_OUTDIR)/, $(addsuffix .o, $(TESTS)))\nSTATIC_UTILOBJS := $(addprefix $(STATIC_OUTDIR)/, $(addsuffix .o, $(UTILS)))\nSTATIC_ALLOBJS := $(STATIC_LIBOBJECTS) $(STATIC_MEMENVOBJECTS) $(STATIC_TESTOBJS) $(STATIC_UTILOBJS) $(TESTHARNESS)\nDEVICE_ALLOBJS := $(DEVICE_LIBOBJECTS) $(DEVICE_MEMENVOBJECTS)\nSIMULATOR_ALLOBJS := $(SIMULATOR_LIBOBJECTS) $(SIMULATOR_MEMENVOBJECTS)\n\ndefault: all\n\n# Should we build shared libraries?\nifneq ($(PLATFORM_SHARED_EXT),)\n\n# Many leveldb test apps use non-exported API's. Only build a subset for testing.\nSHARED_ALLOBJS := $(SHARED_LIBOBJECTS) $(SHARED_MEMENVOBJECTS) $(TESTHARNESS)\n\nifneq ($(PLATFORM_SHARED_VERSIONED),true)\nSHARED_LIB1 = libleveldb.$(PLATFORM_SHARED_EXT)\nSHARED_LIB2 = $(SHARED_LIB1)\nSHARED_LIB3 = $(SHARED_LIB1)\nSHARED_LIBS = $(SHARED_LIB1)\nSHARED_MEMENVLIB = $(SHARED_OUTDIR)/libmemenv.a\nelse\n# Update db.h if you change these.\nSHARED_VERSION_MAJOR = 1\nSHARED_VERSION_MINOR = 20\nSHARED_LIB1 = libleveldb.$(PLATFORM_SHARED_EXT)\nSHARED_LIB2 = $(SHARED_LIB1).$(SHARED_VERSION_MAJOR)\nSHARED_LIB3 = $(SHARED_LIB1).$(SHARED_VERSION_MAJOR).$(SHARED_VERSION_MINOR)\nSHARED_LIBS = $(SHARED_OUTDIR)/$(SHARED_LIB1) $(SHARED_OUTDIR)/$(SHARED_LIB2) $(SHARED_OUTDIR)/$(SHARED_LIB3)\n$(SHARED_OUTDIR)/$(SHARED_LIB1): $(SHARED_OUTDIR)/$(SHARED_LIB3)\n\tln -fs $(SHARED_LIB3) $(SHARED_OUTDIR)/$(SHARED_LIB1)\n$(SHARED_OUTDIR)/$(SHARED_LIB2): $(SHARED_OUTDIR)/$(SHARED_LIB3)\n\tln -fs $(SHARED_LIB3) $(SHARED_OUTDIR)/$(SHARED_LIB2)\nSHARED_MEMENVLIB = $(SHARED_OUTDIR)/libmemenv.a\nendif\n\n$(SHARED_OUTDIR)/$(SHARED_LIB3): $(SHARED_LIBOBJECTS)\n\t$(CXX) $(LDFLAGS) $(PLATFORM_SHARED_LDFLAGS)$(SHARED_LIB2) $(SHARED_LIBOBJECTS) -o $(SHARED_OUTDIR)/$(SHARED_LIB3) $(LIBS)\n\nendif  # PLATFORM_SHARED_EXT\n\nall: $(SHARED_LIBS) $(SHARED_PROGRAMS) $(STATIC_OUTDIR)/libleveldb.a $(STATIC_OUTDIR)/libmemenv.a $(STATIC_PROGRAMS)\n\ncheck: $(STATIC_PROGRAMS)\n\tfor t in $(notdir $(TESTS)); do echo \"***** Running $$t\"; $(STATIC_OUTDIR)/$$t || exit 1; done\n\nclean:\n\t-rm -rf out-static out-shared out-ios-x86 out-ios-arm out-ios-universal\n\t-rm -f build_config.mk\n\t-rm -rf ios-x86 ios-arm\n\n$(STATIC_OUTDIR):\n\tmkdir $@\n\n$(STATIC_OUTDIR)/db: | $(STATIC_OUTDIR)\n\tmkdir $@\n\n$(STATIC_OUTDIR)/helpers/memenv: | $(STATIC_OUTDIR)\n\tmkdir -p $@\n\n$(STATIC_OUTDIR)/port: | $(STATIC_OUTDIR)\n\tmkdir $@\n\n$(STATIC_OUTDIR)/table: | $(STATIC_OUTDIR)\n\tmkdir $@\n\n$(STATIC_OUTDIR)/util: | $(STATIC_OUTDIR)\n\tmkdir $@\n\n.PHONY: STATIC_OBJDIRS\nSTATIC_OBJDIRS: \\\n\t$(STATIC_OUTDIR)/db \\\n\t$(STATIC_OUTDIR)/port \\\n\t$(STATIC_OUTDIR)/table \\\n\t$(STATIC_OUTDIR)/util \\\n\t$(STATIC_OUTDIR)/helpers/memenv\n\n$(SHARED_OUTDIR):\n\tmkdir $@\n\n$(SHARED_OUTDIR)/db: | $(SHARED_OUTDIR)\n\tmkdir $@\n\n$(SHARED_OUTDIR)/helpers/memenv: | $(SHARED_OUTDIR)\n\tmkdir -p $@\n\n$(SHARED_OUTDIR)/port: | $(SHARED_OUTDIR)\n\tmkdir $@\n\n$(SHARED_OUTDIR)/table: | $(SHARED_OUTDIR)\n\tmkdir $@\n\n$(SHARED_OUTDIR)/util: | $(SHARED_OUTDIR)\n\tmkdir $@\n\n.PHONY: SHARED_OBJDIRS\nSHARED_OBJDIRS: \\\n\t$(SHARED_OUTDIR)/db \\\n\t$(SHARED_OUTDIR)/port \\\n\t$(SHARED_OUTDIR)/table \\\n\t$(SHARED_OUTDIR)/util \\\n\t$(SHARED_OUTDIR)/helpers/memenv\n\n$(DEVICE_OUTDIR):\n\tmkdir $@\n\n$(DEVICE_OUTDIR)/db: | $(DEVICE_OUTDIR)\n\tmkdir $@\n\n$(DEVICE_OUTDIR)/helpers/memenv: | $(DEVICE_OUTDIR)\n\tmkdir -p $@\n\n$(DEVICE_OUTDIR)/port: | $(DEVICE_OUTDIR)\n\tmkdir $@\n\n$(DEVICE_OUTDIR)/table: | $(DEVICE_OUTDIR)\n\tmkdir $@\n\n$(DEVICE_OUTDIR)/util: | $(DEVICE_OUTDIR)\n\tmkdir $@\n\n.PHONY: DEVICE_OBJDIRS\nDEVICE_OBJDIRS: \\\n\t$(DEVICE_OUTDIR)/db \\\n\t$(DEVICE_OUTDIR)/port \\\n\t$(DEVICE_OUTDIR)/table \\\n\t$(DEVICE_OUTDIR)/util \\\n\t$(DEVICE_OUTDIR)/helpers/memenv\n\n$(SIMULATOR_OUTDIR):\n\tmkdir $@\n\n$(SIMULATOR_OUTDIR)/db: | $(SIMULATOR_OUTDIR)\n\tmkdir $@\n\n$(SIMULATOR_OUTDIR)/helpers/memenv: | $(SIMULATOR_OUTDIR)\n\tmkdir -p $@\n\n$(SIMULATOR_OUTDIR)/port: | $(SIMULATOR_OUTDIR)\n\tmkdir $@\n\n$(SIMULATOR_OUTDIR)/table: | $(SIMULATOR_OUTDIR)\n\tmkdir $@\n\n$(SIMULATOR_OUTDIR)/util: | $(SIMULATOR_OUTDIR)\n\tmkdir $@\n\n.PHONY: SIMULATOR_OBJDIRS\nSIMULATOR_OBJDIRS: \\\n\t$(SIMULATOR_OUTDIR)/db \\\n\t$(SIMULATOR_OUTDIR)/port \\\n\t$(SIMULATOR_OUTDIR)/table \\\n\t$(SIMULATOR_OUTDIR)/util \\\n\t$(SIMULATOR_OUTDIR)/helpers/memenv\n\n$(STATIC_ALLOBJS): | STATIC_OBJDIRS\n$(DEVICE_ALLOBJS): | DEVICE_OBJDIRS\n$(SIMULATOR_ALLOBJS): | SIMULATOR_OBJDIRS\n$(SHARED_ALLOBJS): | SHARED_OBJDIRS\n\nifeq ($(PLATFORM), IOS)\n$(DEVICE_OUTDIR)/libleveldb.a: $(DEVICE_LIBOBJECTS)\n\trm -f $@\n\t$(AR) -rs $@ $(DEVICE_LIBOBJECTS)\n\n$(SIMULATOR_OUTDIR)/libleveldb.a: $(SIMULATOR_LIBOBJECTS)\n\trm -f $@\n\t$(AR) -rs $@ $(SIMULATOR_LIBOBJECTS)\n\n$(DEVICE_OUTDIR)/libmemenv.a: $(DEVICE_MEMENVOBJECTS)\n\trm -f $@\n\t$(AR) -rs $@ $(DEVICE_MEMENVOBJECTS)\n\n$(SIMULATOR_OUTDIR)/libmemenv.a: $(SIMULATOR_MEMENVOBJECTS)\n\trm -f $@\n\t$(AR) -rs $@ $(SIMULATOR_MEMENVOBJECTS)\n\n# For iOS, create universal object libraries to be used on both the simulator and\n# a device.\n$(STATIC_OUTDIR)/libleveldb.a: $(STATIC_OUTDIR) $(DEVICE_OUTDIR)/libleveldb.a $(SIMULATOR_OUTDIR)/libleveldb.a\n\tlipo -create $(DEVICE_OUTDIR)/libleveldb.a $(SIMULATOR_OUTDIR)/libleveldb.a -output $@\n\n$(STATIC_OUTDIR)/libmemenv.a: $(STATIC_OUTDIR) $(DEVICE_OUTDIR)/libmemenv.a $(SIMULATOR_OUTDIR)/libmemenv.a\n\tlipo -create $(DEVICE_OUTDIR)/libmemenv.a $(SIMULATOR_OUTDIR)/libmemenv.a -output $@\nelse\n$(STATIC_OUTDIR)/libleveldb.a:$(STATIC_LIBOBJECTS)\n\trm -f $@\n\t$(AR) -rs $@ $(STATIC_LIBOBJECTS)\n\n$(STATIC_OUTDIR)/libmemenv.a:$(STATIC_MEMENVOBJECTS)\n\trm -f $@\n\t$(AR) -rs $@ $(STATIC_MEMENVOBJECTS)\nendif\n\n$(SHARED_MEMENVLIB):$(SHARED_MEMENVOBJECTS)\n\trm -f $@\n\t$(AR) -rs $@ $(SHARED_MEMENVOBJECTS)\n\n$(STATIC_OUTDIR)/db_bench:db/db_bench.cc $(STATIC_LIBOBJECTS) $(TESTUTIL)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/db_bench.cc $(STATIC_LIBOBJECTS) $(TESTUTIL) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/db_bench_sqlite3:doc/bench/db_bench_sqlite3.cc $(STATIC_LIBOBJECTS) $(TESTUTIL)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) doc/bench/db_bench_sqlite3.cc $(STATIC_LIBOBJECTS) $(TESTUTIL) -o $@ -lsqlite3 $(LIBS)\n\n$(STATIC_OUTDIR)/db_bench_tree_db:doc/bench/db_bench_tree_db.cc $(STATIC_LIBOBJECTS) $(TESTUTIL)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) doc/bench/db_bench_tree_db.cc $(STATIC_LIBOBJECTS) $(TESTUTIL) -o $@ -lkyotocabinet $(LIBS)\n\n$(STATIC_OUTDIR)/leveldbutil:db/leveldbutil.cc $(STATIC_LIBOBJECTS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/leveldbutil.cc $(STATIC_LIBOBJECTS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/arena_test:util/arena_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) util/arena_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/autocompact_test:db/autocompact_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/autocompact_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/bloom_test:util/bloom_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) util/bloom_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/c_test:$(STATIC_OUTDIR)/db/c_test.o $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(STATIC_OUTDIR)/db/c_test.o $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/cache_test:util/cache_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) util/cache_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/coding_test:util/coding_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) util/coding_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/corruption_test:db/corruption_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/corruption_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/crc32c_test:util/crc32c_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) util/crc32c_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/db_test:db/db_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/db_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/dbformat_test:db/dbformat_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/dbformat_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/env_posix_test:util/env_posix_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) util/env_posix_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/env_test:util/env_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) util/env_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/fault_injection_test:db/fault_injection_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/fault_injection_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/filename_test:db/filename_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/filename_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/filter_block_test:table/filter_block_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) table/filter_block_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/hash_test:util/hash_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) util/hash_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/issue178_test:issues/issue178_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) issues/issue178_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/issue200_test:issues/issue200_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) issues/issue200_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/log_test:db/log_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/log_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/recovery_test:db/recovery_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/recovery_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/table_test:table/table_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) table/table_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/skiplist_test:db/skiplist_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/skiplist_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/version_edit_test:db/version_edit_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/version_edit_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/version_set_test:db/version_set_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/version_set_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/write_batch_test:db/write_batch_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS)\n\t$(CXX) $(LDFLAGS) $(CXXFLAGS) db/write_batch_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)\n\n$(STATIC_OUTDIR)/memenv_test:$(STATIC_OUTDIR)/helpers/memenv/memenv_test.o $(STATIC_OUTDIR)/libmemenv.a $(STATIC_OUTDIR)/libleveldb.a $(TESTHARNESS)\n\t$(XCRUN) $(CXX) $(LDFLAGS) $(STATIC_OUTDIR)/helpers/memenv/memenv_test.o $(STATIC_OUTDIR)/libmemenv.a $(STATIC_OUTDIR)/libleveldb.a $(TESTHARNESS) -o $@ $(LIBS)\n\n$(SHARED_OUTDIR)/db_bench:$(SHARED_OUTDIR)/db/db_bench.o $(SHARED_LIBS) $(TESTUTIL)\n\t$(XCRUN) $(CXX) $(LDFLAGS) $(CXXFLAGS) $(PLATFORM_SHARED_CFLAGS) $(SHARED_OUTDIR)/db/db_bench.o $(TESTUTIL) $(SHARED_OUTDIR)/$(SHARED_LIB3) -o $@ $(LIBS)\n\n.PHONY: run-shared\nrun-shared: $(SHARED_OUTDIR)/db_bench\n\tLD_LIBRARY_PATH=$(SHARED_OUTDIR) $(SHARED_OUTDIR)/db_bench\n\n$(SIMULATOR_OUTDIR)/%.o: %.cc\n\txcrun -sdk iphonesimulator $(CXX) $(CXXFLAGS) $(SIMULATOR_CFLAGS) -c $< -o $@\n\n$(DEVICE_OUTDIR)/%.o: %.cc\n\txcrun -sdk iphoneos $(CXX) $(CXXFLAGS) $(DEVICE_CFLAGS) -c $< -o $@\n\n$(SIMULATOR_OUTDIR)/%.o: %.c\n\txcrun -sdk iphonesimulator $(CC) $(CFLAGS) $(SIMULATOR_CFLAGS) -c $< -o $@\n\n$(DEVICE_OUTDIR)/%.o: %.c\n\txcrun -sdk iphoneos $(CC) $(CFLAGS) $(DEVICE_CFLAGS) -c $< -o $@\n\n$(STATIC_OUTDIR)/%.o: %.cc\n\t$(CXX) $(CXXFLAGS) -c $< -o $@\n\n$(STATIC_OUTDIR)/%.o: %.c\n\t$(CC) $(CFLAGS) -c $< -o $@\n\n$(SHARED_OUTDIR)/%.o: %.cc\n\t$(CXX) $(CXXFLAGS) $(PLATFORM_SHARED_CFLAGS) -c $< -o $@\n\n$(SHARED_OUTDIR)/%.o: %.c\n\t$(CC) $(CFLAGS) $(PLATFORM_SHARED_CFLAGS) -c $< -o $@\n\n$(STATIC_OUTDIR)/port/port_posix_sse.o: port/port_posix_sse.cc\n\t$(CXX) $(CXXFLAGS) $(PLATFORM_SSEFLAGS) -c $< -o $@\n\n$(SHARED_OUTDIR)/port/port_posix_sse.o: port/port_posix_sse.cc\n\t$(CXX) $(CXXFLAGS) $(PLATFORM_SHARED_CFLAGS) $(PLATFORM_SSEFLAGS) -c $< -o $@\n"
  },
  {
    "path": "deps/leveldb-1.20/NEWS",
    "content": "Release 1.2 2011-05-16\n----------------------\n\nFixes for larger databases (tested up to one billion 100-byte entries,\ni.e., ~100GB).\n\n(1) Place hard limit on number of level-0 files.  This fixes errors\nof the form \"too many open files\".\n\n(2) Fixed memtable management.  Before the fix, a heavy write burst\ncould cause unbounded memory usage.\n\nA fix for a logging bug where the reader would incorrectly complain\nabout corruption.\n\nAllow public access to WriteBatch contents so that users can easily\nwrap a DB.\n"
  },
  {
    "path": "deps/leveldb-1.20/README.md",
    "content": "**LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values.**\n\n[![Build Status](https://travis-ci.org/google/leveldb.svg?branch=master)](https://travis-ci.org/google/leveldb)\n\nAuthors: Sanjay Ghemawat (sanjay@google.com) and Jeff Dean (jeff@google.com)\n\n# Features\n  * Keys and values are arbitrary byte arrays.\n  * Data is stored sorted by key.\n  * Callers can provide a custom comparison function to override the sort order.\n  * The basic operations are `Put(key,value)`, `Get(key)`, `Delete(key)`.\n  * Multiple changes can be made in one atomic batch.\n  * Users can create a transient snapshot to get a consistent view of data.\n  * Forward and backward iteration is supported over the data.\n  * Data is automatically compressed using the [Snappy compression library](http://google.github.io/snappy/).\n  * External activity (file system operations etc.) is relayed through a virtual interface so users can customize the operating system interactions.\n\n# Documentation\n  [LevelDB library documentation](https://github.com/google/leveldb/blob/master/doc/index.md) is online and bundled with the source code.\n\n\n# Limitations\n  * This is not a SQL database.  It does not have a relational data model, it does not support SQL queries, and it has no support for indexes.\n  * Only a single process (possibly multi-threaded) can access a particular database at a time.\n  * There is no client-server support builtin to the library.  An application that needs such support will have to wrap their own server around the library.\n\n# Contributing to the leveldb Project\nThe leveldb project welcomes contributions. leveldb's primary goal is to be\na reliable and fast key/value store. Changes that are in line with the\nfeatures/limitations outlined above, and meet the requirements below,\nwill be considered.\n\nContribution requirements:\n\n1. **POSIX only**. We _generally_ will only accept changes that are both\n   compiled, and tested on a POSIX platform - usually Linux. Very small\n   changes will sometimes be accepted, but consider that more of an\n   exception than the rule.\n\n2. **Stable API**. We strive very hard to maintain a stable API. Changes that\n   require changes for projects using leveldb _might_ be rejected without\n   sufficient benefit to the project.\n\n3. **Tests**: All changes must be accompanied by a new (or changed) test, or\n   a sufficient explanation as to why a new (or changed) test is not required.\n\n## Submitting a Pull Request\nBefore any pull request will be accepted the author must first sign a\nContributor License Agreement (CLA) at https://cla.developers.google.com/.\n\nIn order to keep the commit timeline linear\n[squash](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Squashing-Commits)\nyour changes down to a single commit and [rebase](https://git-scm.com/docs/git-rebase)\non google/leveldb/master. This keeps the commit timeline linear and more easily sync'ed\nwith the internal repository at Google. More information at GitHub's\n[About Git rebase](https://help.github.com/articles/about-git-rebase/) page.\n\n# Performance\n\nHere is a performance report (with explanations) from the run of the\nincluded db_bench program.  The results are somewhat noisy, but should\nbe enough to get a ballpark performance estimate.\n\n## Setup\n\nWe use a database with a million entries.  Each entry has a 16 byte\nkey, and a 100 byte value.  Values used by the benchmark compress to\nabout half their original size.\n\n    LevelDB:    version 1.1\n    Date:       Sun May  1 12:11:26 2011\n    CPU:        4 x Intel(R) Core(TM)2 Quad CPU    Q6600  @ 2.40GHz\n    CPUCache:   4096 KB\n    Keys:       16 bytes each\n    Values:     100 bytes each (50 bytes after compression)\n    Entries:    1000000\n    Raw Size:   110.6 MB (estimated)\n    File Size:  62.9 MB (estimated)\n\n## Write performance\n\nThe \"fill\" benchmarks create a brand new database, in either\nsequential, or random order.  The \"fillsync\" benchmark flushes data\nfrom the operating system to the disk after every operation; the other\nwrite operations leave the data sitting in the operating system buffer\ncache for a while.  The \"overwrite\" benchmark does random writes that\nupdate existing keys in the database.\n\n    fillseq      :       1.765 micros/op;   62.7 MB/s\n    fillsync     :     268.409 micros/op;    0.4 MB/s (10000 ops)\n    fillrandom   :       2.460 micros/op;   45.0 MB/s\n    overwrite    :       2.380 micros/op;   46.5 MB/s\n\nEach \"op\" above corresponds to a write of a single key/value pair.\nI.e., a random write benchmark goes at approximately 400,000 writes per second.\n\nEach \"fillsync\" operation costs much less (0.3 millisecond)\nthan a disk seek (typically 10 milliseconds).  We suspect that this is\nbecause the hard disk itself is buffering the update in its memory and\nresponding before the data has been written to the platter.  This may\nor may not be safe based on whether or not the hard disk has enough\npower to save its memory in the event of a power failure.\n\n## Read performance\n\nWe list the performance of reading sequentially in both the forward\nand reverse direction, and also the performance of a random lookup.\nNote that the database created by the benchmark is quite small.\nTherefore the report characterizes the performance of leveldb when the\nworking set fits in memory.  The cost of reading a piece of data that\nis not present in the operating system buffer cache will be dominated\nby the one or two disk seeks needed to fetch the data from disk.\nWrite performance will be mostly unaffected by whether or not the\nworking set fits in memory.\n\n    readrandom  : 16.677 micros/op;  (approximately 60,000 reads per second)\n    readseq     :  0.476 micros/op;  232.3 MB/s\n    readreverse :  0.724 micros/op;  152.9 MB/s\n\nLevelDB compacts its underlying storage data in the background to\nimprove read performance.  The results listed above were done\nimmediately after a lot of random writes.  The results after\ncompactions (which are usually triggered automatically) are better.\n\n    readrandom  : 11.602 micros/op;  (approximately 85,000 reads per second)\n    readseq     :  0.423 micros/op;  261.8 MB/s\n    readreverse :  0.663 micros/op;  166.9 MB/s\n\nSome of the high cost of reads comes from repeated decompression of blocks\nread from disk.  If we supply enough cache to the leveldb so it can hold the\nuncompressed blocks in memory, the read performance improves again:\n\n    readrandom  : 9.775 micros/op;  (approximately 100,000 reads per second before compaction)\n    readrandom  : 5.215 micros/op;  (approximately 190,000 reads per second after compaction)\n\n## Repository contents\n\nSee [doc/index.md](doc/index.md) for more explanation. See\n[doc/impl.md](doc/impl.md) for a brief overview of the implementation.\n\nThe public interface is in include/*.h.  Callers should not include or\nrely on the details of any other header files in this package.  Those\ninternal APIs may be changed without warning.\n\nGuide to header files:\n\n* **include/db.h**: Main interface to the DB: Start here\n\n* **include/options.h**: Control over the behavior of an entire database,\nand also control over the behavior of individual reads and writes.\n\n* **include/comparator.h**: Abstraction for user-specified comparison function.\nIf you want just bytewise comparison of keys, you can use the default\ncomparator, but clients can write their own comparator implementations if they\nwant custom ordering (e.g. to handle different character encodings, etc.)\n\n* **include/iterator.h**: Interface for iterating over data. You can get\nan iterator from a DB object.\n\n* **include/write_batch.h**: Interface for atomically applying multiple\nupdates to a database.\n\n* **include/slice.h**: A simple module for maintaining a pointer and a\nlength into some other byte array.\n\n* **include/status.h**: Status is returned from many of the public interfaces\nand is used to report success and various kinds of errors.\n\n* **include/env.h**:\nAbstraction of the OS environment.  A posix implementation of this interface is\nin util/env_posix.cc\n\n* **include/table.h, include/table_builder.h**: Lower-level modules that most\nclients probably won't use directly\n"
  },
  {
    "path": "deps/leveldb-1.20/TODO",
    "content": "ss\n- Stats\n\ndb\n- Maybe implement DB::BulkDeleteForRange(start_key, end_key)\n  that would blow away files whose ranges are entirely contained\n  within [start_key..end_key]?  For Chrome, deletion of obsolete\n  object stores, etc. can be done in the background anyway, so\n  probably not that important.\n- There have been requests for MultiGet.\n\nAfter a range is completely deleted, what gets rid of the\ncorresponding files if we do no future changes to that range.  Make\nthe conditions for triggering compactions fire in more situations?\n"
  },
  {
    "path": "deps/leveldb-1.20/build_detect_platform",
    "content": "#!/bin/sh\n#\n# Detects OS we're compiling on and outputs a file specified by the first\n# argument, which in turn gets read while processing Makefile.\n#\n# The output will set the following variables:\n#   CC                          C Compiler path\n#   CXX                         C++ Compiler path\n#   PLATFORM_LDFLAGS            Linker flags\n#   PLATFORM_LIBS               Libraries flags\n#   PLATFORM_SHARED_EXT         Extension for shared libraries\n#   PLATFORM_SHARED_LDFLAGS     Flags for building shared library\n#                               This flag is embedded just before the name\n#                               of the shared library without intervening spaces\n#   PLATFORM_SHARED_CFLAGS      Flags for compiling objects for shared library\n#   PLATFORM_CCFLAGS            C compiler flags\n#   PLATFORM_CXXFLAGS           C++ compiler flags.  Will contain:\n#   PLATFORM_SHARED_VERSIONED   Set to 'true' if platform supports versioned\n#                               shared libraries, empty otherwise.\n#\n# The PLATFORM_CCFLAGS and PLATFORM_CXXFLAGS might include the following:\n#\n#       -DLEVELDB_ATOMIC_PRESENT     if <atomic> is present\n#       -DLEVELDB_PLATFORM_POSIX     for Posix-based platforms\n#       -DSNAPPY                     if the Snappy library is present\n#\n\nOUTPUT=$1\nPREFIX=$2\nif test -z \"$OUTPUT\" || test -z \"$PREFIX\"; then\n  echo \"usage: $0 <output-filename> <directory_prefix>\" >&2\n  exit 1\nfi\n\n# Delete existing output, if it exists\nrm -f $OUTPUT\ntouch $OUTPUT\n\nif test -z \"$CC\"; then\n    CC=cc\nfi\n\nif test -z \"$CXX\"; then\n    CXX=g++\nfi\n\nif test -z \"$TMPDIR\"; then\n    TMPDIR=/tmp\nfi\n\n# Detect OS\nif test -z \"$TARGET_OS\"; then\n    TARGET_OS=`uname -s`\nfi\n\nCOMMON_FLAGS=\nCROSS_COMPILE=\nPLATFORM_CCFLAGS=\nPLATFORM_CXXFLAGS=\nPLATFORM_LDFLAGS=\nPLATFORM_LIBS=\nPLATFORM_SHARED_EXT=\"so\"\nPLATFORM_SHARED_LDFLAGS=\"-shared -Wl,-soname -Wl,\"\nPLATFORM_SHARED_CFLAGS=\"-fPIC\"\nPLATFORM_SHARED_VERSIONED=true\nPLATFORM_SSEFLAGS=\n\nMEMCMP_FLAG=\nif [ \"$CXX\" = \"g++\" ]; then\n    # Use libc's memcmp instead of GCC's memcmp.  This results in ~40%\n    # performance improvement on readrandom under gcc 4.4.3 on Linux/x86.\n    MEMCMP_FLAG=\"-fno-builtin-memcmp\"\nfi\n\ncase \"$TARGET_OS\" in\n    CYGWIN_*)\n        PLATFORM=OS_LINUX\n        COMMON_FLAGS=\"$MEMCMP_FLAG -lpthread -DOS_LINUX -DCYGWIN\"\n        COMMON_FLAGS=\"$MEMCMP_FLAG -lpthread -DOS_LINUX -DCYGWIN -std=gnu++0x\"\n        PLATFORM_LDFLAGS=\"-lpthread\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        ;;\n    Darwin)\n        PLATFORM=OS_MACOSX\n        COMMON_FLAGS=\"$MEMCMP_FLAG\"\n        PLATFORM_SHARED_EXT=dylib\n        [ -z \"$INSTALL_PATH\" ] && INSTALL_PATH=`pwd`\n        PLATFORM_SHARED_LDFLAGS=\"-dynamiclib -install_name $INSTALL_PATH/\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        ;;\n    Linux)\n        PLATFORM=OS_LINUX\n        COMMON_FLAGS=\"$MEMCMP_FLAG -pthread -DOS_LINUX\"\n        PLATFORM_LDFLAGS=\"-pthread\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        ;;\n    SunOS)\n        PLATFORM=OS_SOLARIS\n        COMMON_FLAGS=\"$MEMCMP_FLAG -D_REENTRANT -DOS_SOLARIS\"\n        PLATFORM_LIBS=\"-lpthread -lrt\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        ;;\n    FreeBSD)\n        PLATFORM=OS_FREEBSD\n        COMMON_FLAGS=\"$MEMCMP_FLAG -D_REENTRANT -DOS_FREEBSD\"\n        PLATFORM_LIBS=\"-lpthread\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        ;;\n    NetBSD)\n        PLATFORM=OS_NETBSD\n        COMMON_FLAGS=\"$MEMCMP_FLAG -D_REENTRANT -DOS_NETBSD\"\n        PLATFORM_LIBS=\"-lpthread -lgcc_s\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        ;;\n    OpenBSD)\n        PLATFORM=OS_OPENBSD\n        COMMON_FLAGS=\"$MEMCMP_FLAG -D_REENTRANT -DOS_OPENBSD\"\n        PLATFORM_LDFLAGS=\"-pthread\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        ;;\n    DragonFly)\n        PLATFORM=OS_DRAGONFLYBSD\n        COMMON_FLAGS=\"$MEMCMP_FLAG -D_REENTRANT -DOS_DRAGONFLYBSD\"\n        PLATFORM_LIBS=\"-lpthread\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        ;;\n    OS_ANDROID_CROSSCOMPILE)\n        PLATFORM=OS_ANDROID\n        COMMON_FLAGS=\"$MEMCMP_FLAG -D_REENTRANT -DOS_ANDROID -DLEVELDB_PLATFORM_POSIX\"\n        PLATFORM_LDFLAGS=\"\"  # All pthread features are in the Android C library\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        CROSS_COMPILE=true\n        ;;\n    HP-UX)\n        PLATFORM=OS_HPUX\n        COMMON_FLAGS=\"$MEMCMP_FLAG -D_REENTRANT -DOS_HPUX\"\n        PLATFORM_LDFLAGS=\"-pthread\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        # man ld: +h internal_name\n        PLATFORM_SHARED_LDFLAGS=\"-shared -Wl,+h -Wl,\"\n        ;;\n    IOS)\n        PLATFORM=IOS\n        COMMON_FLAGS=\"$MEMCMP_FLAG\"\n        [ -z \"$INSTALL_PATH\" ] && INSTALL_PATH=`pwd`\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        PLATFORM_SHARED_EXT=\n        PLATFORM_SHARED_LDFLAGS=\n        PLATFORM_SHARED_CFLAGS=\n        PLATFORM_SHARED_VERSIONED=\n        ;;\n    *)\n        echo \"Unknown platform!\" >&2\n        exit 1\nesac\n\n# We want to make a list of all cc files within util, db, table, and helpers\n# except for the test and benchmark files. By default, find will output a list\n# of all files matching either rule, so we need to append -print to make the\n# prune take effect.\nDIRS=\"$PREFIX/db $PREFIX/util $PREFIX/table\"\n\nset -f # temporarily disable globbing so that our patterns aren't expanded\nPRUNE_TEST=\"-name *test*.cc -prune\"\nPRUNE_BENCH=\"-name *_bench.cc -prune\"\nPRUNE_TOOL=\"-name leveldbutil.cc -prune\"\nPORTABLE_FILES=`find $DIRS $PRUNE_TEST -o $PRUNE_BENCH -o $PRUNE_TOOL -o -name '*.cc' -print | sort | sed \"s,^$PREFIX/,,\" | tr \"\\n\" \" \"`\n\nset +f # re-enable globbing\n\n# The sources consist of the portable files, plus the platform-specific port\n# file.\necho \"SOURCES=$PORTABLE_FILES $PORT_FILE $PORT_SSE_FILE\" >> $OUTPUT\necho \"MEMENV_SOURCES=helpers/memenv/memenv.cc\" >> $OUTPUT\n\nif [ \"$CROSS_COMPILE\" = \"true\" ]; then\n    # Cross-compiling; do not try any compilation tests.\n    true\nelse\n    CXXOUTPUT=\"${TMPDIR}/leveldb_build_detect_platform-cxx.$$\"\n\n    # If -std=c++0x works, use <atomic> as fallback for when memory barriers\n    # are not available.\n    $CXX $CXXFLAGS -std=c++0x -x c++ - -o $CXXOUTPUT 2>/dev/null  <<EOF\n      #include <atomic>\n      int main() {}\nEOF\n    if [ \"$?\" = 0 ]; then\n        COMMON_FLAGS=\"$COMMON_FLAGS -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT\"\n        PLATFORM_CXXFLAGS=\"-std=c++0x\"\n    else\n        COMMON_FLAGS=\"$COMMON_FLAGS -DLEVELDB_PLATFORM_POSIX\"\n    fi\n\n#    # Test whether Snappy library is installed\n#    # http://code.google.com/p/snappy/\n#    $CXX $CXXFLAGS -x c++ - -o $CXXOUTPUT 2>/dev/null  <<EOF\n#      #include <snappy.h>\n#      int main() {}\n#EOF\n#    if [ \"$?\" = 0 ]; then\n#        COMMON_FLAGS=\"$COMMON_FLAGS -DSNAPPY\"\n#        PLATFORM_LIBS=\"$PLATFORM_LIBS -lsnappy\"\n#    fi\n    COMMON_FLAGS=\"$COMMON_FLAGS -DSNAPPY -I../snappy-1.1.0\"\n    PLATFORM_LIBS=\"$PLATFORM_LIBS ../snappy-1.1.0/.libs/libsnappy.a\"\n\n    # Test whether tcmalloc is available\n    $CXX $CXXFLAGS -x c++ - -o $CXXOUTPUT -ltcmalloc 2>/dev/null  <<EOF\n      int main() {}\nEOF\n    if [ \"$?\" = 0 ]; then\n        PLATFORM_LIBS=\"$PLATFORM_LIBS -ltcmalloc\"\n    fi\n\n    rm -f $CXXOUTPUT 2>/dev/null\n\n    # Test if gcc SSE 4.2 is supported\n    $CXX $CXXFLAGS -x c++ - -o $CXXOUTPUT -msse4.2 2>/dev/null  <<EOF\n      int main() {}\nEOF\n    if [ \"$?\" = 0 ]; then\n        PLATFORM_SSEFLAGS=\"-msse4.2\"\n    fi\n\n    rm -f $CXXOUTPUT 2>/dev/null\nfi\n\n# Use the SSE 4.2 CRC32C intrinsics iff runtime checks indicate compiler supports them.\nif [ -n \"$PLATFORM_SSEFLAGS\" ]; then\n    PLATFORM_SSEFLAGS=\"$PLATFORM_SSEFLAGS -DLEVELDB_PLATFORM_POSIX_SSE\"\nfi\n\nPLATFORM_CCFLAGS=\"$PLATFORM_CCFLAGS $COMMON_FLAGS\"\nPLATFORM_CXXFLAGS=\"$PLATFORM_CXXFLAGS $COMMON_FLAGS\"\n\necho \"CC=$CC\" >> $OUTPUT\necho \"CXX=$CXX\" >> $OUTPUT\necho \"PLATFORM=$PLATFORM\" >> $OUTPUT\necho \"PLATFORM_LDFLAGS=$PLATFORM_LDFLAGS\" >> $OUTPUT\necho \"PLATFORM_LIBS=$PLATFORM_LIBS\" >> $OUTPUT\necho \"PLATFORM_CCFLAGS=$PLATFORM_CCFLAGS\" >> $OUTPUT\necho \"PLATFORM_CXXFLAGS=$PLATFORM_CXXFLAGS\" >> $OUTPUT\necho \"PLATFORM_SSEFLAGS=$PLATFORM_SSEFLAGS\" >> $OUTPUT\necho \"PLATFORM_SHARED_CFLAGS=$PLATFORM_SHARED_CFLAGS\" >> $OUTPUT\necho \"PLATFORM_SHARED_EXT=$PLATFORM_SHARED_EXT\" >> $OUTPUT\necho \"PLATFORM_SHARED_LDFLAGS=$PLATFORM_SHARED_LDFLAGS\" >> $OUTPUT\necho \"PLATFORM_SHARED_VERSIONED=$PLATFORM_SHARED_VERSIONED\" >> $OUTPUT\n"
  },
  {
    "path": "deps/leveldb-1.20/build_detect_platform.bk",
    "content": "#!/bin/sh\n#\n# Detects OS we're compiling on and outputs a file specified by the first\n# argument, which in turn gets read while processing Makefile.\n#\n# The output will set the following variables:\n#   CC                          C Compiler path\n#   CXX                         C++ Compiler path\n#   PLATFORM_LDFLAGS            Linker flags\n#   PLATFORM_LIBS               Libraries flags\n#   PLATFORM_SHARED_EXT         Extension for shared libraries\n#   PLATFORM_SHARED_LDFLAGS     Flags for building shared library\n#                               This flag is embedded just before the name\n#                               of the shared library without intervening spaces\n#   PLATFORM_SHARED_CFLAGS      Flags for compiling objects for shared library\n#   PLATFORM_CCFLAGS            C compiler flags\n#   PLATFORM_CXXFLAGS           C++ compiler flags.  Will contain:\n#   PLATFORM_SHARED_VERSIONED   Set to 'true' if platform supports versioned\n#                               shared libraries, empty otherwise.\n#\n# The PLATFORM_CCFLAGS and PLATFORM_CXXFLAGS might include the following:\n#\n#       -DLEVELDB_ATOMIC_PRESENT     if <atomic> is present\n#       -DLEVELDB_PLATFORM_POSIX     for Posix-based platforms\n#       -DSNAPPY                     if the Snappy library is present\n#\n\nOUTPUT=$1\nPREFIX=$2\nif test -z \"$OUTPUT\" || test -z \"$PREFIX\"; then\n  echo \"usage: $0 <output-filename> <directory_prefix>\" >&2\n  exit 1\nfi\n\n# Delete existing output, if it exists\nrm -f $OUTPUT\ntouch $OUTPUT\n\nif test -z \"$CC\"; then\n    CC=cc\nfi\n\nif test -z \"$CXX\"; then\n    CXX=g++\nfi\n\nif test -z \"$TMPDIR\"; then\n    TMPDIR=/tmp\nfi\n\n# Detect OS\nif test -z \"$TARGET_OS\"; then\n    TARGET_OS=`uname -s`\nfi\n\nCOMMON_FLAGS=\nCROSS_COMPILE=\nPLATFORM_CCFLAGS=\nPLATFORM_CXXFLAGS=\nPLATFORM_LDFLAGS=\nPLATFORM_LIBS=\nPLATFORM_SHARED_EXT=\"so\"\nPLATFORM_SHARED_LDFLAGS=\"-shared -Wl,-soname -Wl,\"\nPLATFORM_SHARED_CFLAGS=\"-fPIC\"\nPLATFORM_SHARED_VERSIONED=true\nPLATFORM_SSEFLAGS=\n\nMEMCMP_FLAG=\nif [ \"$CXX\" = \"g++\" ]; then\n    # Use libc's memcmp instead of GCC's memcmp.  This results in ~40%\n    # performance improvement on readrandom under gcc 4.4.3 on Linux/x86.\n    MEMCMP_FLAG=\"-fno-builtin-memcmp\"\nfi\n\ncase \"$TARGET_OS\" in\n    CYGWIN_*)\n        PLATFORM=OS_LINUX\n        COMMON_FLAGS=\"$MEMCMP_FLAG -lpthread -DOS_LINUX -DCYGWIN\"\n        PLATFORM_LDFLAGS=\"-lpthread\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        ;;\n    Darwin)\n        PLATFORM=OS_MACOSX\n        COMMON_FLAGS=\"$MEMCMP_FLAG\"\n        PLATFORM_SHARED_EXT=dylib\n        [ -z \"$INSTALL_PATH\" ] && INSTALL_PATH=`pwd`\n        PLATFORM_SHARED_LDFLAGS=\"-dynamiclib -install_name $INSTALL_PATH/\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        ;;\n    Linux)\n        PLATFORM=OS_LINUX\n        COMMON_FLAGS=\"$MEMCMP_FLAG -pthread -DOS_LINUX\"\n        PLATFORM_LDFLAGS=\"-pthread\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        ;;\n    SunOS)\n        PLATFORM=OS_SOLARIS\n        COMMON_FLAGS=\"$MEMCMP_FLAG -D_REENTRANT -DOS_SOLARIS\"\n        PLATFORM_LIBS=\"-lpthread -lrt\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        ;;\n    FreeBSD)\n        PLATFORM=OS_FREEBSD\n        COMMON_FLAGS=\"$MEMCMP_FLAG -D_REENTRANT -DOS_FREEBSD\"\n        PLATFORM_LIBS=\"-lpthread\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        ;;\n    NetBSD)\n        PLATFORM=OS_NETBSD\n        COMMON_FLAGS=\"$MEMCMP_FLAG -D_REENTRANT -DOS_NETBSD\"\n        PLATFORM_LIBS=\"-lpthread -lgcc_s\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        ;;\n    OpenBSD)\n        PLATFORM=OS_OPENBSD\n        COMMON_FLAGS=\"$MEMCMP_FLAG -D_REENTRANT -DOS_OPENBSD\"\n        PLATFORM_LDFLAGS=\"-pthread\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        ;;\n    DragonFly)\n        PLATFORM=OS_DRAGONFLYBSD\n        COMMON_FLAGS=\"$MEMCMP_FLAG -D_REENTRANT -DOS_DRAGONFLYBSD\"\n        PLATFORM_LIBS=\"-lpthread\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        ;;\n    OS_ANDROID_CROSSCOMPILE)\n        PLATFORM=OS_ANDROID\n        COMMON_FLAGS=\"$MEMCMP_FLAG -D_REENTRANT -DOS_ANDROID -DLEVELDB_PLATFORM_POSIX\"\n        PLATFORM_LDFLAGS=\"\"  # All pthread features are in the Android C library\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        CROSS_COMPILE=true\n        ;;\n    HP-UX)\n        PLATFORM=OS_HPUX\n        COMMON_FLAGS=\"$MEMCMP_FLAG -D_REENTRANT -DOS_HPUX\"\n        PLATFORM_LDFLAGS=\"-pthread\"\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        # man ld: +h internal_name\n        PLATFORM_SHARED_LDFLAGS=\"-shared -Wl,+h -Wl,\"\n        ;;\n    IOS)\n        PLATFORM=IOS\n        COMMON_FLAGS=\"$MEMCMP_FLAG\"\n        [ -z \"$INSTALL_PATH\" ] && INSTALL_PATH=`pwd`\n        PORT_FILE=port/port_posix.cc\n        PORT_SSE_FILE=port/port_posix_sse.cc\n        PLATFORM_SHARED_EXT=\n        PLATFORM_SHARED_LDFLAGS=\n        PLATFORM_SHARED_CFLAGS=\n        PLATFORM_SHARED_VERSIONED=\n        ;;\n    *)\n        echo \"Unknown platform!\" >&2\n        exit 1\nesac\n\n# We want to make a list of all cc files within util, db, table, and helpers\n# except for the test and benchmark files. By default, find will output a list\n# of all files matching either rule, so we need to append -print to make the\n# prune take effect.\nDIRS=\"$PREFIX/db $PREFIX/util $PREFIX/table\"\n\nset -f # temporarily disable globbing so that our patterns aren't expanded\nPRUNE_TEST=\"-name *test*.cc -prune\"\nPRUNE_BENCH=\"-name *_bench.cc -prune\"\nPRUNE_TOOL=\"-name leveldbutil.cc -prune\"\nPORTABLE_FILES=`find $DIRS $PRUNE_TEST -o $PRUNE_BENCH -o $PRUNE_TOOL -o -name '*.cc' -print | sort | sed \"s,^$PREFIX/,,\" | tr \"\\n\" \" \"`\n\nset +f # re-enable globbing\n\n# The sources consist of the portable files, plus the platform-specific port\n# file.\necho \"SOURCES=$PORTABLE_FILES $PORT_FILE $PORT_SSE_FILE\" >> $OUTPUT\necho \"MEMENV_SOURCES=helpers/memenv/memenv.cc\" >> $OUTPUT\n\nif [ \"$CROSS_COMPILE\" = \"true\" ]; then\n    # Cross-compiling; do not try any compilation tests.\n    true\nelse\n    CXXOUTPUT=\"${TMPDIR}/leveldb_build_detect_platform-cxx.$$\"\n\n    # If -std=c++0x works, use <atomic> as fallback for when memory barriers\n    # are not available.\n    $CXX $CXXFLAGS -std=c++0x -x c++ - -o $CXXOUTPUT 2>/dev/null  <<EOF\n      #include <atomic>\n      int main() {}\nEOF\n    if [ \"$?\" = 0 ]; then\n        COMMON_FLAGS=\"$COMMON_FLAGS -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT\"\n        PLATFORM_CXXFLAGS=\"-std=c++0x\"\n    else\n        COMMON_FLAGS=\"$COMMON_FLAGS -DLEVELDB_PLATFORM_POSIX\"\n    fi\n\n    # Test whether Snappy library is installed\n    # http://code.google.com/p/snappy/\n    $CXX $CXXFLAGS -x c++ - -o $CXXOUTPUT 2>/dev/null  <<EOF\n      #include <snappy.h>\n      int main() {}\nEOF\n    if [ \"$?\" = 0 ]; then\n        COMMON_FLAGS=\"$COMMON_FLAGS -DSNAPPY\"\n        PLATFORM_LIBS=\"$PLATFORM_LIBS -lsnappy\"\n    fi\n\n    # Test whether tcmalloc is available\n    $CXX $CXXFLAGS -x c++ - -o $CXXOUTPUT -ltcmalloc 2>/dev/null  <<EOF\n      int main() {}\nEOF\n    if [ \"$?\" = 0 ]; then\n        PLATFORM_LIBS=\"$PLATFORM_LIBS -ltcmalloc\"\n    fi\n\n    rm -f $CXXOUTPUT 2>/dev/null\n\n    # Test if gcc SSE 4.2 is supported\n    $CXX $CXXFLAGS -x c++ - -o $CXXOUTPUT -msse4.2 2>/dev/null  <<EOF\n      int main() {}\nEOF\n    if [ \"$?\" = 0 ]; then\n        PLATFORM_SSEFLAGS=\"-msse4.2\"\n    fi\n\n    rm -f $CXXOUTPUT 2>/dev/null\nfi\n\n# Use the SSE 4.2 CRC32C intrinsics iff runtime checks indicate compiler supports them.\nif [ -n \"$PLATFORM_SSEFLAGS\" ]; then\n    PLATFORM_SSEFLAGS=\"$PLATFORM_SSEFLAGS -DLEVELDB_PLATFORM_POSIX_SSE\"\nfi\n\nPLATFORM_CCFLAGS=\"$PLATFORM_CCFLAGS $COMMON_FLAGS\"\nPLATFORM_CXXFLAGS=\"$PLATFORM_CXXFLAGS $COMMON_FLAGS\"\n\necho \"CC=$CC\" >> $OUTPUT\necho \"CXX=$CXX\" >> $OUTPUT\necho \"PLATFORM=$PLATFORM\" >> $OUTPUT\necho \"PLATFORM_LDFLAGS=$PLATFORM_LDFLAGS\" >> $OUTPUT\necho \"PLATFORM_LIBS=$PLATFORM_LIBS\" >> $OUTPUT\necho \"PLATFORM_CCFLAGS=$PLATFORM_CCFLAGS\" >> $OUTPUT\necho \"PLATFORM_CXXFLAGS=$PLATFORM_CXXFLAGS\" >> $OUTPUT\necho \"PLATFORM_SSEFLAGS=$PLATFORM_SSEFLAGS\" >> $OUTPUT\necho \"PLATFORM_SHARED_CFLAGS=$PLATFORM_SHARED_CFLAGS\" >> $OUTPUT\necho \"PLATFORM_SHARED_EXT=$PLATFORM_SHARED_EXT\" >> $OUTPUT\necho \"PLATFORM_SHARED_LDFLAGS=$PLATFORM_SHARED_LDFLAGS\" >> $OUTPUT\necho \"PLATFORM_SHARED_VERSIONED=$PLATFORM_SHARED_VERSIONED\" >> $OUTPUT\n"
  },
  {
    "path": "deps/leveldb-1.20/db/autocompact_test.cc",
    "content": "// Copyright (c) 2013 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/db.h\"\n#include \"db/db_impl.h\"\n#include \"leveldb/cache.h\"\n#include \"util/testharness.h\"\n#include \"util/testutil.h\"\n\nnamespace leveldb {\n\nclass AutoCompactTest {\n public:\n  std::string dbname_;\n  Cache* tiny_cache_;\n  Options options_;\n  DB* db_;\n\n  AutoCompactTest() {\n    dbname_ = test::TmpDir() + \"/autocompact_test\";\n    tiny_cache_ = NewLRUCache(100);\n    options_.block_cache = tiny_cache_;\n    DestroyDB(dbname_, options_);\n    options_.create_if_missing = true;\n    options_.compression = kNoCompression;\n    ASSERT_OK(DB::Open(options_, dbname_, &db_));\n  }\n\n  ~AutoCompactTest() {\n    delete db_;\n    DestroyDB(dbname_, Options());\n    delete tiny_cache_;\n  }\n\n  std::string Key(int i) {\n    char buf[100];\n    snprintf(buf, sizeof(buf), \"key%06d\", i);\n    return std::string(buf);\n  }\n\n  uint64_t Size(const Slice& start, const Slice& limit) {\n    Range r(start, limit);\n    uint64_t size;\n    db_->GetApproximateSizes(&r, 1, &size);\n    return size;\n  }\n\n  void DoReads(int n);\n};\n\nstatic const int kValueSize = 200 * 1024;\nstatic const int kTotalSize = 100 * 1024 * 1024;\nstatic const int kCount = kTotalSize / kValueSize;\n\n// Read through the first n keys repeatedly and check that they get\n// compacted (verified by checking the size of the key space).\nvoid AutoCompactTest::DoReads(int n) {\n  std::string value(kValueSize, 'x');\n  DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);\n\n  // Fill database\n  for (int i = 0; i < kCount; i++) {\n    ASSERT_OK(db_->Put(WriteOptions(), Key(i), value));\n  }\n  ASSERT_OK(dbi->TEST_CompactMemTable());\n\n  // Delete everything\n  for (int i = 0; i < kCount; i++) {\n    ASSERT_OK(db_->Delete(WriteOptions(), Key(i)));\n  }\n  ASSERT_OK(dbi->TEST_CompactMemTable());\n\n  // Get initial measurement of the space we will be reading.\n  const int64_t initial_size = Size(Key(0), Key(n));\n  const int64_t initial_other_size = Size(Key(n), Key(kCount));\n\n  // Read until size drops significantly.\n  std::string limit_key = Key(n);\n  for (int read = 0; true; read++) {\n    ASSERT_LT(read, 100) << \"Taking too long to compact\";\n    Iterator* iter = db_->NewIterator(ReadOptions());\n    for (iter->SeekToFirst();\n         iter->Valid() && iter->key().ToString() < limit_key;\n         iter->Next()) {\n      // Drop data\n    }\n    delete iter;\n    // Wait a little bit to allow any triggered compactions to complete.\n    Env::Default()->SleepForMicroseconds(1000000);\n    uint64_t size = Size(Key(0), Key(n));\n    fprintf(stderr, \"iter %3d => %7.3f MB [other %7.3f MB]\\n\",\n            read+1, size/1048576.0, Size(Key(n), Key(kCount))/1048576.0);\n    if (size <= initial_size/10) {\n      break;\n    }\n  }\n\n  // Verify that the size of the key space not touched by the reads\n  // is pretty much unchanged.\n  const int64_t final_other_size = Size(Key(n), Key(kCount));\n  ASSERT_LE(final_other_size, initial_other_size + 1048576);\n  ASSERT_GE(final_other_size, initial_other_size/5 - 1048576);\n}\n\nTEST(AutoCompactTest, ReadAll) {\n  DoReads(kCount);\n}\n\nTEST(AutoCompactTest, ReadHalf) {\n  DoReads(kCount/2);\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/db/builder.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/builder.h\"\n\n#include \"db/filename.h\"\n#include \"db/dbformat.h\"\n#include \"db/table_cache.h\"\n#include \"db/version_edit.h\"\n#include \"leveldb/db.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/iterator.h\"\n\nnamespace leveldb {\n\nStatus BuildTable(const std::string& dbname,\n                  Env* env,\n                  const Options& options,\n                  TableCache* table_cache,\n                  Iterator* iter,\n                  FileMetaData* meta) {\n  Status s;\n  meta->file_size = 0;\n  iter->SeekToFirst();\n\n  std::string fname = TableFileName(dbname, meta->number);\n  if (iter->Valid()) {\n    WritableFile* file;\n    s = env->NewWritableFile(fname, &file);\n    if (!s.ok()) {\n      return s;\n    }\n\n    TableBuilder* builder = new TableBuilder(options, file);\n    meta->smallest.DecodeFrom(iter->key());\n    for (; iter->Valid(); iter->Next()) {\n      Slice key = iter->key();\n      meta->largest.DecodeFrom(key);\n      builder->Add(key, iter->value());\n    }\n\n    // Finish and check for builder errors\n    s = builder->Finish();\n    if (s.ok()) {\n      meta->file_size = builder->FileSize();\n      assert(meta->file_size > 0);\n    }\n    delete builder;\n\n    // Finish and check for file errors\n    if (s.ok()) {\n      s = file->Sync();\n    }\n    if (s.ok()) {\n      s = file->Close();\n    }\n    delete file;\n    file = NULL;\n\n    if (s.ok()) {\n      // Verify that the table is usable\n      Iterator* it = table_cache->NewIterator(ReadOptions(),\n                                              meta->number,\n                                              meta->file_size);\n      s = it->status();\n      delete it;\n    }\n  }\n\n  // Check for input iterator errors\n  if (!iter->status().ok()) {\n    s = iter->status();\n  }\n\n  if (s.ok() && meta->file_size > 0) {\n    // Keep it\n  } else {\n    env->DeleteFile(fname);\n  }\n  return s;\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/db/builder.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_DB_BUILDER_H_\n#define STORAGE_LEVELDB_DB_BUILDER_H_\n\n#include \"leveldb/status.h\"\n\nnamespace leveldb {\n\nstruct Options;\nstruct FileMetaData;\n\nclass Env;\nclass Iterator;\nclass TableCache;\nclass VersionEdit;\n\n// Build a Table file from the contents of *iter.  The generated file\n// will be named according to meta->number.  On success, the rest of\n// *meta will be filled with metadata about the generated table.\n// If no data is present in *iter, meta->file_size will be set to\n// zero, and no Table file will be produced.\nextern Status BuildTable(const std::string& dbname,\n                         Env* env,\n                         const Options& options,\n                         TableCache* table_cache,\n                         Iterator* iter,\n                         FileMetaData* meta);\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_DB_BUILDER_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/db/c.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/c.h\"\n\n#include <stdlib.h>\n#include <unistd.h>\n#include \"leveldb/cache.h\"\n#include \"leveldb/comparator.h\"\n#include \"leveldb/db.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/filter_policy.h\"\n#include \"leveldb/iterator.h\"\n#include \"leveldb/options.h\"\n#include \"leveldb/status.h\"\n#include \"leveldb/write_batch.h\"\n\nusing leveldb::Cache;\nusing leveldb::Comparator;\nusing leveldb::CompressionType;\nusing leveldb::DB;\nusing leveldb::Env;\nusing leveldb::FileLock;\nusing leveldb::FilterPolicy;\nusing leveldb::Iterator;\nusing leveldb::kMajorVersion;\nusing leveldb::kMinorVersion;\nusing leveldb::Logger;\nusing leveldb::NewBloomFilterPolicy;\nusing leveldb::NewLRUCache;\nusing leveldb::Options;\nusing leveldb::RandomAccessFile;\nusing leveldb::Range;\nusing leveldb::ReadOptions;\nusing leveldb::SequentialFile;\nusing leveldb::Slice;\nusing leveldb::Snapshot;\nusing leveldb::Status;\nusing leveldb::WritableFile;\nusing leveldb::WriteBatch;\nusing leveldb::WriteOptions;\n\nextern \"C\" {\n\nstruct leveldb_t              { DB*               rep; };\nstruct leveldb_iterator_t     { Iterator*         rep; };\nstruct leveldb_writebatch_t   { WriteBatch        rep; };\nstruct leveldb_snapshot_t     { const Snapshot*   rep; };\nstruct leveldb_readoptions_t  { ReadOptions       rep; };\nstruct leveldb_writeoptions_t { WriteOptions      rep; };\nstruct leveldb_options_t      { Options           rep; };\nstruct leveldb_cache_t        { Cache*            rep; };\nstruct leveldb_seqfile_t      { SequentialFile*   rep; };\nstruct leveldb_randomfile_t   { RandomAccessFile* rep; };\nstruct leveldb_writablefile_t { WritableFile*     rep; };\nstruct leveldb_logger_t       { Logger*           rep; };\nstruct leveldb_filelock_t     { FileLock*         rep; };\n\nstruct leveldb_comparator_t : public Comparator {\n  void* state_;\n  void (*destructor_)(void*);\n  int (*compare_)(\n      void*,\n      const char* a, size_t alen,\n      const char* b, size_t blen);\n  const char* (*name_)(void*);\n\n  virtual ~leveldb_comparator_t() {\n    (*destructor_)(state_);\n  }\n\n  virtual int Compare(const Slice& a, const Slice& b) const {\n    return (*compare_)(state_, a.data(), a.size(), b.data(), b.size());\n  }\n\n  virtual const char* Name() const {\n    return (*name_)(state_);\n  }\n\n  // No-ops since the C binding does not support key shortening methods.\n  virtual void FindShortestSeparator(std::string*, const Slice&) const { }\n  virtual void FindShortSuccessor(std::string* key) const { }\n};\n\nstruct leveldb_filterpolicy_t : public FilterPolicy {\n  void* state_;\n  void (*destructor_)(void*);\n  const char* (*name_)(void*);\n  char* (*create_)(\n      void*,\n      const char* const* key_array, const size_t* key_length_array,\n      int num_keys,\n      size_t* filter_length);\n  unsigned char (*key_match_)(\n      void*,\n      const char* key, size_t length,\n      const char* filter, size_t filter_length);\n\n  virtual ~leveldb_filterpolicy_t() {\n    (*destructor_)(state_);\n  }\n\n  virtual const char* Name() const {\n    return (*name_)(state_);\n  }\n\n  virtual void CreateFilter(const Slice* keys, int n, std::string* dst) const {\n    std::vector<const char*> key_pointers(n);\n    std::vector<size_t> key_sizes(n);\n    for (int i = 0; i < n; i++) {\n      key_pointers[i] = keys[i].data();\n      key_sizes[i] = keys[i].size();\n    }\n    size_t len;\n    char* filter = (*create_)(state_, &key_pointers[0], &key_sizes[0], n, &len);\n    dst->append(filter, len);\n    free(filter);\n  }\n\n  virtual bool KeyMayMatch(const Slice& key, const Slice& filter) const {\n    return (*key_match_)(state_, key.data(), key.size(),\n                         filter.data(), filter.size());\n  }\n};\n\nstruct leveldb_env_t {\n  Env* rep;\n  bool is_default;\n};\n\nstatic bool SaveError(char** errptr, const Status& s) {\n  assert(errptr != NULL);\n  if (s.ok()) {\n    return false;\n  } else if (*errptr == NULL) {\n    *errptr = strdup(s.ToString().c_str());\n  } else {\n    // TODO(sanjay): Merge with existing error?\n    free(*errptr);\n    *errptr = strdup(s.ToString().c_str());\n  }\n  return true;\n}\n\nstatic char* CopyString(const std::string& str) {\n  char* result = reinterpret_cast<char*>(malloc(sizeof(char) * str.size()));\n  memcpy(result, str.data(), sizeof(char) * str.size());\n  return result;\n}\n\nleveldb_t* leveldb_open(\n    const leveldb_options_t* options,\n    const char* name,\n    char** errptr) {\n  DB* db;\n  if (SaveError(errptr, DB::Open(options->rep, std::string(name), &db))) {\n    return NULL;\n  }\n  leveldb_t* result = new leveldb_t;\n  result->rep = db;\n  return result;\n}\n\nvoid leveldb_close(leveldb_t* db) {\n  delete db->rep;\n  delete db;\n}\n\nvoid leveldb_put(\n    leveldb_t* db,\n    const leveldb_writeoptions_t* options,\n    const char* key, size_t keylen,\n    const char* val, size_t vallen,\n    char** errptr) {\n  SaveError(errptr,\n            db->rep->Put(options->rep, Slice(key, keylen), Slice(val, vallen)));\n}\n\nvoid leveldb_delete(\n    leveldb_t* db,\n    const leveldb_writeoptions_t* options,\n    const char* key, size_t keylen,\n    char** errptr) {\n  SaveError(errptr, db->rep->Delete(options->rep, Slice(key, keylen)));\n}\n\n\nvoid leveldb_write(\n    leveldb_t* db,\n    const leveldb_writeoptions_t* options,\n    leveldb_writebatch_t* batch,\n    char** errptr) {\n  SaveError(errptr, db->rep->Write(options->rep, &batch->rep));\n}\n\nchar* leveldb_get(\n    leveldb_t* db,\n    const leveldb_readoptions_t* options,\n    const char* key, size_t keylen,\n    size_t* vallen,\n    char** errptr) {\n  char* result = NULL;\n  std::string tmp;\n  Status s = db->rep->Get(options->rep, Slice(key, keylen), &tmp);\n  if (s.ok()) {\n    *vallen = tmp.size();\n    result = CopyString(tmp);\n  } else {\n    *vallen = 0;\n    if (!s.IsNotFound()) {\n      SaveError(errptr, s);\n    }\n  }\n  return result;\n}\n\nleveldb_iterator_t* leveldb_create_iterator(\n    leveldb_t* db,\n    const leveldb_readoptions_t* options) {\n  leveldb_iterator_t* result = new leveldb_iterator_t;\n  result->rep = db->rep->NewIterator(options->rep);\n  return result;\n}\n\nconst leveldb_snapshot_t* leveldb_create_snapshot(\n    leveldb_t* db) {\n  leveldb_snapshot_t* result = new leveldb_snapshot_t;\n  result->rep = db->rep->GetSnapshot();\n  return result;\n}\n\nvoid leveldb_release_snapshot(\n    leveldb_t* db,\n    const leveldb_snapshot_t* snapshot) {\n  db->rep->ReleaseSnapshot(snapshot->rep);\n  delete snapshot;\n}\n\nchar* leveldb_property_value(\n    leveldb_t* db,\n    const char* propname) {\n  std::string tmp;\n  if (db->rep->GetProperty(Slice(propname), &tmp)) {\n    // We use strdup() since we expect human readable output.\n    return strdup(tmp.c_str());\n  } else {\n    return NULL;\n  }\n}\n\nvoid leveldb_approximate_sizes(\n    leveldb_t* db,\n    int num_ranges,\n    const char* const* range_start_key, const size_t* range_start_key_len,\n    const char* const* range_limit_key, const size_t* range_limit_key_len,\n    uint64_t* sizes) {\n  Range* ranges = new Range[num_ranges];\n  for (int i = 0; i < num_ranges; i++) {\n    ranges[i].start = Slice(range_start_key[i], range_start_key_len[i]);\n    ranges[i].limit = Slice(range_limit_key[i], range_limit_key_len[i]);\n  }\n  db->rep->GetApproximateSizes(ranges, num_ranges, sizes);\n  delete[] ranges;\n}\n\nvoid leveldb_compact_range(\n    leveldb_t* db,\n    const char* start_key, size_t start_key_len,\n    const char* limit_key, size_t limit_key_len) {\n  Slice a, b;\n  db->rep->CompactRange(\n      // Pass NULL Slice if corresponding \"const char*\" is NULL\n      (start_key ? (a = Slice(start_key, start_key_len), &a) : NULL),\n      (limit_key ? (b = Slice(limit_key, limit_key_len), &b) : NULL));\n}\n\nvoid leveldb_destroy_db(\n    const leveldb_options_t* options,\n    const char* name,\n    char** errptr) {\n  SaveError(errptr, DestroyDB(name, options->rep));\n}\n\nvoid leveldb_repair_db(\n    const leveldb_options_t* options,\n    const char* name,\n    char** errptr) {\n  SaveError(errptr, RepairDB(name, options->rep));\n}\n\nvoid leveldb_iter_destroy(leveldb_iterator_t* iter) {\n  delete iter->rep;\n  delete iter;\n}\n\nunsigned char leveldb_iter_valid(const leveldb_iterator_t* iter) {\n  return iter->rep->Valid();\n}\n\nvoid leveldb_iter_seek_to_first(leveldb_iterator_t* iter) {\n  iter->rep->SeekToFirst();\n}\n\nvoid leveldb_iter_seek_to_last(leveldb_iterator_t* iter) {\n  iter->rep->SeekToLast();\n}\n\nvoid leveldb_iter_seek(leveldb_iterator_t* iter, const char* k, size_t klen) {\n  iter->rep->Seek(Slice(k, klen));\n}\n\nvoid leveldb_iter_next(leveldb_iterator_t* iter) {\n  iter->rep->Next();\n}\n\nvoid leveldb_iter_prev(leveldb_iterator_t* iter) {\n  iter->rep->Prev();\n}\n\nconst char* leveldb_iter_key(const leveldb_iterator_t* iter, size_t* klen) {\n  Slice s = iter->rep->key();\n  *klen = s.size();\n  return s.data();\n}\n\nconst char* leveldb_iter_value(const leveldb_iterator_t* iter, size_t* vlen) {\n  Slice s = iter->rep->value();\n  *vlen = s.size();\n  return s.data();\n}\n\nvoid leveldb_iter_get_error(const leveldb_iterator_t* iter, char** errptr) {\n  SaveError(errptr, iter->rep->status());\n}\n\nleveldb_writebatch_t* leveldb_writebatch_create() {\n  return new leveldb_writebatch_t;\n}\n\nvoid leveldb_writebatch_destroy(leveldb_writebatch_t* b) {\n  delete b;\n}\n\nvoid leveldb_writebatch_clear(leveldb_writebatch_t* b) {\n  b->rep.Clear();\n}\n\nvoid leveldb_writebatch_put(\n    leveldb_writebatch_t* b,\n    const char* key, size_t klen,\n    const char* val, size_t vlen) {\n  b->rep.Put(Slice(key, klen), Slice(val, vlen));\n}\n\nvoid leveldb_writebatch_delete(\n    leveldb_writebatch_t* b,\n    const char* key, size_t klen) {\n  b->rep.Delete(Slice(key, klen));\n}\n\nvoid leveldb_writebatch_iterate(\n    leveldb_writebatch_t* b,\n    void* state,\n    void (*put)(void*, const char* k, size_t klen, const char* v, size_t vlen),\n    void (*deleted)(void*, const char* k, size_t klen)) {\n  class H : public WriteBatch::Handler {\n   public:\n    void* state_;\n    void (*put_)(void*, const char* k, size_t klen, const char* v, size_t vlen);\n    void (*deleted_)(void*, const char* k, size_t klen);\n    virtual void Put(const Slice& key, const Slice& value) {\n      (*put_)(state_, key.data(), key.size(), value.data(), value.size());\n    }\n    virtual void Delete(const Slice& key) {\n      (*deleted_)(state_, key.data(), key.size());\n    }\n  };\n  H handler;\n  handler.state_ = state;\n  handler.put_ = put;\n  handler.deleted_ = deleted;\n  b->rep.Iterate(&handler);\n}\n\nleveldb_options_t* leveldb_options_create() {\n  return new leveldb_options_t;\n}\n\nvoid leveldb_options_destroy(leveldb_options_t* options) {\n  delete options;\n}\n\nvoid leveldb_options_set_comparator(\n    leveldb_options_t* opt,\n    leveldb_comparator_t* cmp) {\n  opt->rep.comparator = cmp;\n}\n\nvoid leveldb_options_set_filter_policy(\n    leveldb_options_t* opt,\n    leveldb_filterpolicy_t* policy) {\n  opt->rep.filter_policy = policy;\n}\n\nvoid leveldb_options_set_create_if_missing(\n    leveldb_options_t* opt, unsigned char v) {\n  opt->rep.create_if_missing = v;\n}\n\nvoid leveldb_options_set_error_if_exists(\n    leveldb_options_t* opt, unsigned char v) {\n  opt->rep.error_if_exists = v;\n}\n\nvoid leveldb_options_set_paranoid_checks(\n    leveldb_options_t* opt, unsigned char v) {\n  opt->rep.paranoid_checks = v;\n}\n\nvoid leveldb_options_set_env(leveldb_options_t* opt, leveldb_env_t* env) {\n  opt->rep.env = (env ? env->rep : NULL);\n}\n\nvoid leveldb_options_set_info_log(leveldb_options_t* opt, leveldb_logger_t* l) {\n  opt->rep.info_log = (l ? l->rep : NULL);\n}\n\nvoid leveldb_options_set_write_buffer_size(leveldb_options_t* opt, size_t s) {\n  opt->rep.write_buffer_size = s;\n}\n\nvoid leveldb_options_set_max_open_files(leveldb_options_t* opt, int n) {\n  opt->rep.max_open_files = n;\n}\n\nvoid leveldb_options_set_cache(leveldb_options_t* opt, leveldb_cache_t* c) {\n  opt->rep.block_cache = c->rep;\n}\n\nvoid leveldb_options_set_block_size(leveldb_options_t* opt, size_t s) {\n  opt->rep.block_size = s;\n}\n\nvoid leveldb_options_set_block_restart_interval(leveldb_options_t* opt, int n) {\n  opt->rep.block_restart_interval = n;\n}\n\nvoid leveldb_options_set_compression(leveldb_options_t* opt, int t) {\n  opt->rep.compression = static_cast<CompressionType>(t);\n}\n\nleveldb_comparator_t* leveldb_comparator_create(\n    void* state,\n    void (*destructor)(void*),\n    int (*compare)(\n        void*,\n        const char* a, size_t alen,\n        const char* b, size_t blen),\n    const char* (*name)(void*)) {\n  leveldb_comparator_t* result = new leveldb_comparator_t;\n  result->state_ = state;\n  result->destructor_ = destructor;\n  result->compare_ = compare;\n  result->name_ = name;\n  return result;\n}\n\nvoid leveldb_comparator_destroy(leveldb_comparator_t* cmp) {\n  delete cmp;\n}\n\nleveldb_filterpolicy_t* leveldb_filterpolicy_create(\n    void* state,\n    void (*destructor)(void*),\n    char* (*create_filter)(\n        void*,\n        const char* const* key_array, const size_t* key_length_array,\n        int num_keys,\n        size_t* filter_length),\n    unsigned char (*key_may_match)(\n        void*,\n        const char* key, size_t length,\n        const char* filter, size_t filter_length),\n    const char* (*name)(void*)) {\n  leveldb_filterpolicy_t* result = new leveldb_filterpolicy_t;\n  result->state_ = state;\n  result->destructor_ = destructor;\n  result->create_ = create_filter;\n  result->key_match_ = key_may_match;\n  result->name_ = name;\n  return result;\n}\n\nvoid leveldb_filterpolicy_destroy(leveldb_filterpolicy_t* filter) {\n  delete filter;\n}\n\nleveldb_filterpolicy_t* leveldb_filterpolicy_create_bloom(int bits_per_key) {\n  // Make a leveldb_filterpolicy_t, but override all of its methods so\n  // they delegate to a NewBloomFilterPolicy() instead of user\n  // supplied C functions.\n  struct Wrapper : public leveldb_filterpolicy_t {\n    const FilterPolicy* rep_;\n    ~Wrapper() { delete rep_; }\n    const char* Name() const { return rep_->Name(); }\n    void CreateFilter(const Slice* keys, int n, std::string* dst) const {\n      return rep_->CreateFilter(keys, n, dst);\n    }\n    bool KeyMayMatch(const Slice& key, const Slice& filter) const {\n      return rep_->KeyMayMatch(key, filter);\n    }\n    static void DoNothing(void*) { }\n  };\n  Wrapper* wrapper = new Wrapper;\n  wrapper->rep_ = NewBloomFilterPolicy(bits_per_key);\n  wrapper->state_ = NULL;\n  wrapper->destructor_ = &Wrapper::DoNothing;\n  return wrapper;\n}\n\nleveldb_readoptions_t* leveldb_readoptions_create() {\n  return new leveldb_readoptions_t;\n}\n\nvoid leveldb_readoptions_destroy(leveldb_readoptions_t* opt) {\n  delete opt;\n}\n\nvoid leveldb_readoptions_set_verify_checksums(\n    leveldb_readoptions_t* opt,\n    unsigned char v) {\n  opt->rep.verify_checksums = v;\n}\n\nvoid leveldb_readoptions_set_fill_cache(\n    leveldb_readoptions_t* opt, unsigned char v) {\n  opt->rep.fill_cache = v;\n}\n\nvoid leveldb_readoptions_set_snapshot(\n    leveldb_readoptions_t* opt,\n    const leveldb_snapshot_t* snap) {\n  opt->rep.snapshot = (snap ? snap->rep : NULL);\n}\n\nleveldb_writeoptions_t* leveldb_writeoptions_create() {\n  return new leveldb_writeoptions_t;\n}\n\nvoid leveldb_writeoptions_destroy(leveldb_writeoptions_t* opt) {\n  delete opt;\n}\n\nvoid leveldb_writeoptions_set_sync(\n    leveldb_writeoptions_t* opt, unsigned char v) {\n  opt->rep.sync = v;\n}\n\nleveldb_cache_t* leveldb_cache_create_lru(size_t capacity) {\n  leveldb_cache_t* c = new leveldb_cache_t;\n  c->rep = NewLRUCache(capacity);\n  return c;\n}\n\nvoid leveldb_cache_destroy(leveldb_cache_t* cache) {\n  delete cache->rep;\n  delete cache;\n}\n\nleveldb_env_t* leveldb_create_default_env() {\n  leveldb_env_t* result = new leveldb_env_t;\n  result->rep = Env::Default();\n  result->is_default = true;\n  return result;\n}\n\nvoid leveldb_env_destroy(leveldb_env_t* env) {\n  if (!env->is_default) delete env->rep;\n  delete env;\n}\n\nvoid leveldb_free(void* ptr) {\n  free(ptr);\n}\n\nint leveldb_major_version() {\n  return kMajorVersion;\n}\n\nint leveldb_minor_version() {\n  return kMinorVersion;\n}\n\n}  // end extern \"C\"\n"
  },
  {
    "path": "deps/leveldb-1.20/db/c_test.c",
    "content": "/* Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n   Use of this source code is governed by a BSD-style license that can be\n   found in the LICENSE file. See the AUTHORS file for names of contributors. */\n\n#include \"leveldb/c.h\"\n\n#include <stddef.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/types.h>\n#include <unistd.h>\n\nconst char* phase = \"\";\nstatic char dbname[200];\n\nstatic void StartPhase(const char* name) {\n  fprintf(stderr, \"=== Test %s\\n\", name);\n  phase = name;\n}\n\nstatic const char* GetTempDir(void) {\n    const char* ret = getenv(\"TEST_TMPDIR\");\n    if (ret == NULL || ret[0] == '\\0')\n        ret = \"/tmp\";\n    return ret;\n}\n\n#define CheckNoError(err)                                               \\\n  if ((err) != NULL) {                                                  \\\n    fprintf(stderr, \"%s:%d: %s: %s\\n\", __FILE__, __LINE__, phase, (err)); \\\n    abort();                                                            \\\n  }\n\n#define CheckCondition(cond)                                            \\\n  if (!(cond)) {                                                        \\\n    fprintf(stderr, \"%s:%d: %s: %s\\n\", __FILE__, __LINE__, phase, #cond); \\\n    abort();                                                            \\\n  }\n\nstatic void CheckEqual(const char* expected, const char* v, size_t n) {\n  if (expected == NULL && v == NULL) {\n    // ok\n  } else if (expected != NULL && v != NULL && n == strlen(expected) &&\n             memcmp(expected, v, n) == 0) {\n    // ok\n    return;\n  } else {\n    fprintf(stderr, \"%s: expected '%s', got '%s'\\n\",\n            phase,\n            (expected ? expected : \"(null)\"),\n            (v ? v : \"(null\"));\n    abort();\n  }\n}\n\nstatic void Free(char** ptr) {\n  if (*ptr) {\n    free(*ptr);\n    *ptr = NULL;\n  }\n}\n\nstatic void CheckGet(\n    leveldb_t* db,\n    const leveldb_readoptions_t* options,\n    const char* key,\n    const char* expected) {\n  char* err = NULL;\n  size_t val_len;\n  char* val;\n  val = leveldb_get(db, options, key, strlen(key), &val_len, &err);\n  CheckNoError(err);\n  CheckEqual(expected, val, val_len);\n  Free(&val);\n}\n\nstatic void CheckIter(leveldb_iterator_t* iter,\n                      const char* key, const char* val) {\n  size_t len;\n  const char* str;\n  str = leveldb_iter_key(iter, &len);\n  CheckEqual(key, str, len);\n  str = leveldb_iter_value(iter, &len);\n  CheckEqual(val, str, len);\n}\n\n// Callback from leveldb_writebatch_iterate()\nstatic void CheckPut(void* ptr,\n                     const char* k, size_t klen,\n                     const char* v, size_t vlen) {\n  int* state = (int*) ptr;\n  CheckCondition(*state < 2);\n  switch (*state) {\n    case 0:\n      CheckEqual(\"bar\", k, klen);\n      CheckEqual(\"b\", v, vlen);\n      break;\n    case 1:\n      CheckEqual(\"box\", k, klen);\n      CheckEqual(\"c\", v, vlen);\n      break;\n  }\n  (*state)++;\n}\n\n// Callback from leveldb_writebatch_iterate()\nstatic void CheckDel(void* ptr, const char* k, size_t klen) {\n  int* state = (int*) ptr;\n  CheckCondition(*state == 2);\n  CheckEqual(\"bar\", k, klen);\n  (*state)++;\n}\n\nstatic void CmpDestroy(void* arg) { }\n\nstatic int CmpCompare(void* arg, const char* a, size_t alen,\n                      const char* b, size_t blen) {\n  int n = (alen < blen) ? alen : blen;\n  int r = memcmp(a, b, n);\n  if (r == 0) {\n    if (alen < blen) r = -1;\n    else if (alen > blen) r = +1;\n  }\n  return r;\n}\n\nstatic const char* CmpName(void* arg) {\n  return \"foo\";\n}\n\n// Custom filter policy\nstatic unsigned char fake_filter_result = 1;\nstatic void FilterDestroy(void* arg) { }\nstatic const char* FilterName(void* arg) {\n  return \"TestFilter\";\n}\nstatic char* FilterCreate(\n    void* arg,\n    const char* const* key_array, const size_t* key_length_array,\n    int num_keys,\n    size_t* filter_length) {\n  *filter_length = 4;\n  char* result = malloc(4);\n  memcpy(result, \"fake\", 4);\n  return result;\n}\nunsigned char FilterKeyMatch(\n    void* arg,\n    const char* key, size_t length,\n    const char* filter, size_t filter_length) {\n  CheckCondition(filter_length == 4);\n  CheckCondition(memcmp(filter, \"fake\", 4) == 0);\n  return fake_filter_result;\n}\n\nint main(int argc, char** argv) {\n  leveldb_t* db;\n  leveldb_comparator_t* cmp;\n  leveldb_cache_t* cache;\n  leveldb_env_t* env;\n  leveldb_options_t* options;\n  leveldb_readoptions_t* roptions;\n  leveldb_writeoptions_t* woptions;\n  char* err = NULL;\n  int run = -1;\n\n  CheckCondition(leveldb_major_version() >= 1);\n  CheckCondition(leveldb_minor_version() >= 1);\n\n  snprintf(dbname, sizeof(dbname),\n           \"%s/leveldb_c_test-%d\",\n           GetTempDir(),\n           ((int) geteuid()));\n\n  StartPhase(\"create_objects\");\n  cmp = leveldb_comparator_create(NULL, CmpDestroy, CmpCompare, CmpName);\n  env = leveldb_create_default_env();\n  cache = leveldb_cache_create_lru(100000);\n\n  options = leveldb_options_create();\n  leveldb_options_set_comparator(options, cmp);\n  leveldb_options_set_error_if_exists(options, 1);\n  leveldb_options_set_cache(options, cache);\n  leveldb_options_set_env(options, env);\n  leveldb_options_set_info_log(options, NULL);\n  leveldb_options_set_write_buffer_size(options, 100000);\n  leveldb_options_set_paranoid_checks(options, 1);\n  leveldb_options_set_max_open_files(options, 10);\n  leveldb_options_set_block_size(options, 1024);\n  leveldb_options_set_block_restart_interval(options, 8);\n  leveldb_options_set_compression(options, leveldb_no_compression);\n\n  roptions = leveldb_readoptions_create();\n  leveldb_readoptions_set_verify_checksums(roptions, 1);\n  leveldb_readoptions_set_fill_cache(roptions, 0);\n\n  woptions = leveldb_writeoptions_create();\n  leveldb_writeoptions_set_sync(woptions, 1);\n\n  StartPhase(\"destroy\");\n  leveldb_destroy_db(options, dbname, &err);\n  Free(&err);\n\n  StartPhase(\"open_error\");\n  db = leveldb_open(options, dbname, &err);\n  CheckCondition(err != NULL);\n  Free(&err);\n\n  StartPhase(\"leveldb_free\");\n  db = leveldb_open(options, dbname, &err);\n  CheckCondition(err != NULL);\n  leveldb_free(err);\n  err = NULL;\n\n  StartPhase(\"open\");\n  leveldb_options_set_create_if_missing(options, 1);\n  db = leveldb_open(options, dbname, &err);\n  CheckNoError(err);\n  CheckGet(db, roptions, \"foo\", NULL);\n\n  StartPhase(\"put\");\n  leveldb_put(db, woptions, \"foo\", 3, \"hello\", 5, &err);\n  CheckNoError(err);\n  CheckGet(db, roptions, \"foo\", \"hello\");\n\n  StartPhase(\"compactall\");\n  leveldb_compact_range(db, NULL, 0, NULL, 0);\n  CheckGet(db, roptions, \"foo\", \"hello\");\n\n  StartPhase(\"compactrange\");\n  leveldb_compact_range(db, \"a\", 1, \"z\", 1);\n  CheckGet(db, roptions, \"foo\", \"hello\");\n\n  StartPhase(\"writebatch\");\n  {\n    leveldb_writebatch_t* wb = leveldb_writebatch_create();\n    leveldb_writebatch_put(wb, \"foo\", 3, \"a\", 1);\n    leveldb_writebatch_clear(wb);\n    leveldb_writebatch_put(wb, \"bar\", 3, \"b\", 1);\n    leveldb_writebatch_put(wb, \"box\", 3, \"c\", 1);\n    leveldb_writebatch_delete(wb, \"bar\", 3);\n    leveldb_write(db, woptions, wb, &err);\n    CheckNoError(err);\n    CheckGet(db, roptions, \"foo\", \"hello\");\n    CheckGet(db, roptions, \"bar\", NULL);\n    CheckGet(db, roptions, \"box\", \"c\");\n    int pos = 0;\n    leveldb_writebatch_iterate(wb, &pos, CheckPut, CheckDel);\n    CheckCondition(pos == 3);\n    leveldb_writebatch_destroy(wb);\n  }\n\n  StartPhase(\"iter\");\n  {\n    leveldb_iterator_t* iter = leveldb_create_iterator(db, roptions);\n    CheckCondition(!leveldb_iter_valid(iter));\n    leveldb_iter_seek_to_first(iter);\n    CheckCondition(leveldb_iter_valid(iter));\n    CheckIter(iter, \"box\", \"c\");\n    leveldb_iter_next(iter);\n    CheckIter(iter, \"foo\", \"hello\");\n    leveldb_iter_prev(iter);\n    CheckIter(iter, \"box\", \"c\");\n    leveldb_iter_prev(iter);\n    CheckCondition(!leveldb_iter_valid(iter));\n    leveldb_iter_seek_to_last(iter);\n    CheckIter(iter, \"foo\", \"hello\");\n    leveldb_iter_seek(iter, \"b\", 1);\n    CheckIter(iter, \"box\", \"c\");\n    leveldb_iter_get_error(iter, &err);\n    CheckNoError(err);\n    leveldb_iter_destroy(iter);\n  }\n\n  StartPhase(\"approximate_sizes\");\n  {\n    int i;\n    int n = 20000;\n    char keybuf[100];\n    char valbuf[100];\n    uint64_t sizes[2];\n    const char* start[2] = { \"a\", \"k00000000000000010000\" };\n    size_t start_len[2] = { 1, 21 };\n    const char* limit[2] = { \"k00000000000000010000\", \"z\" };\n    size_t limit_len[2] = { 21, 1 };\n    leveldb_writeoptions_set_sync(woptions, 0);\n    for (i = 0; i < n; i++) {\n      snprintf(keybuf, sizeof(keybuf), \"k%020d\", i);\n      snprintf(valbuf, sizeof(valbuf), \"v%020d\", i);\n      leveldb_put(db, woptions, keybuf, strlen(keybuf), valbuf, strlen(valbuf),\n                  &err);\n      CheckNoError(err);\n    }\n    leveldb_approximate_sizes(db, 2, start, start_len, limit, limit_len, sizes);\n    CheckCondition(sizes[0] > 0);\n    CheckCondition(sizes[1] > 0);\n  }\n\n  StartPhase(\"property\");\n  {\n    char* prop = leveldb_property_value(db, \"nosuchprop\");\n    CheckCondition(prop == NULL);\n    prop = leveldb_property_value(db, \"leveldb.stats\");\n    CheckCondition(prop != NULL);\n    Free(&prop);\n  }\n\n  StartPhase(\"snapshot\");\n  {\n    const leveldb_snapshot_t* snap;\n    snap = leveldb_create_snapshot(db);\n    leveldb_delete(db, woptions, \"foo\", 3, &err);\n    CheckNoError(err);\n    leveldb_readoptions_set_snapshot(roptions, snap);\n    CheckGet(db, roptions, \"foo\", \"hello\");\n    leveldb_readoptions_set_snapshot(roptions, NULL);\n    CheckGet(db, roptions, \"foo\", NULL);\n    leveldb_release_snapshot(db, snap);\n  }\n\n  StartPhase(\"repair\");\n  {\n    leveldb_close(db);\n    leveldb_options_set_create_if_missing(options, 0);\n    leveldb_options_set_error_if_exists(options, 0);\n    leveldb_repair_db(options, dbname, &err);\n    CheckNoError(err);\n    db = leveldb_open(options, dbname, &err);\n    CheckNoError(err);\n    CheckGet(db, roptions, \"foo\", NULL);\n    CheckGet(db, roptions, \"bar\", NULL);\n    CheckGet(db, roptions, \"box\", \"c\");\n    leveldb_options_set_create_if_missing(options, 1);\n    leveldb_options_set_error_if_exists(options, 1);\n  }\n\n  StartPhase(\"filter\");\n  for (run = 0; run < 2; run++) {\n    // First run uses custom filter, second run uses bloom filter\n    CheckNoError(err);\n    leveldb_filterpolicy_t* policy;\n    if (run == 0) {\n      policy = leveldb_filterpolicy_create(\n          NULL, FilterDestroy, FilterCreate, FilterKeyMatch, FilterName);\n    } else {\n      policy = leveldb_filterpolicy_create_bloom(10);\n    }\n\n    // Create new database\n    leveldb_close(db);\n    leveldb_destroy_db(options, dbname, &err);\n    leveldb_options_set_filter_policy(options, policy);\n    db = leveldb_open(options, dbname, &err);\n    CheckNoError(err);\n    leveldb_put(db, woptions, \"foo\", 3, \"foovalue\", 8, &err);\n    CheckNoError(err);\n    leveldb_put(db, woptions, \"bar\", 3, \"barvalue\", 8, &err);\n    CheckNoError(err);\n    leveldb_compact_range(db, NULL, 0, NULL, 0);\n\n    fake_filter_result = 1;\n    CheckGet(db, roptions, \"foo\", \"foovalue\");\n    CheckGet(db, roptions, \"bar\", \"barvalue\");\n    if (phase == 0) {\n      // Must not find value when custom filter returns false\n      fake_filter_result = 0;\n      CheckGet(db, roptions, \"foo\", NULL);\n      CheckGet(db, roptions, \"bar\", NULL);\n      fake_filter_result = 1;\n\n      CheckGet(db, roptions, \"foo\", \"foovalue\");\n      CheckGet(db, roptions, \"bar\", \"barvalue\");\n    }\n    leveldb_options_set_filter_policy(options, NULL);\n    leveldb_filterpolicy_destroy(policy);\n  }\n\n  StartPhase(\"cleanup\");\n  leveldb_close(db);\n  leveldb_options_destroy(options);\n  leveldb_readoptions_destroy(roptions);\n  leveldb_writeoptions_destroy(woptions);\n  leveldb_cache_destroy(cache);\n  leveldb_comparator_destroy(cmp);\n  leveldb_env_destroy(env);\n\n  fprintf(stderr, \"PASS\\n\");\n  return 0;\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/db/corruption_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/db.h\"\n\n#include <errno.h>\n#include <fcntl.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include \"leveldb/cache.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/table.h\"\n#include \"leveldb/write_batch.h\"\n#include \"db/db_impl.h\"\n#include \"db/filename.h\"\n#include \"db/log_format.h\"\n#include \"db/version_set.h\"\n#include \"util/logging.h\"\n#include \"util/testharness.h\"\n#include \"util/testutil.h\"\n\nnamespace leveldb {\n\nstatic const int kValueSize = 1000;\n\nclass CorruptionTest {\n public:\n  test::ErrorEnv env_;\n  std::string dbname_;\n  Cache* tiny_cache_;\n  Options options_;\n  DB* db_;\n\n  CorruptionTest() {\n    tiny_cache_ = NewLRUCache(100);\n    options_.env = &env_;\n    options_.block_cache = tiny_cache_;\n    dbname_ = test::TmpDir() + \"/corruption_test\";\n    DestroyDB(dbname_, options_);\n\n    db_ = NULL;\n    options_.create_if_missing = true;\n    Reopen();\n    options_.create_if_missing = false;\n  }\n\n  ~CorruptionTest() {\n     delete db_;\n     DestroyDB(dbname_, Options());\n     delete tiny_cache_;\n  }\n\n  Status TryReopen() {\n    delete db_;\n    db_ = NULL;\n    return DB::Open(options_, dbname_, &db_);\n  }\n\n  void Reopen() {\n    ASSERT_OK(TryReopen());\n  }\n\n  void RepairDB() {\n    delete db_;\n    db_ = NULL;\n    ASSERT_OK(::leveldb::RepairDB(dbname_, options_));\n  }\n\n  void Build(int n) {\n    std::string key_space, value_space;\n    WriteBatch batch;\n    for (int i = 0; i < n; i++) {\n      //if ((i % 100) == 0) fprintf(stderr, \"@ %d of %d\\n\", i, n);\n      Slice key = Key(i, &key_space);\n      batch.Clear();\n      batch.Put(key, Value(i, &value_space));\n      WriteOptions options;\n      // Corrupt() doesn't work without this sync on windows; stat reports 0 for\n      // the file size.\n      if (i == n - 1) {\n        options.sync = true;\n      }\n      ASSERT_OK(db_->Write(options, &batch));\n    }\n  }\n\n  void Check(int min_expected, int max_expected) {\n    int next_expected = 0;\n    int missed = 0;\n    int bad_keys = 0;\n    int bad_values = 0;\n    int correct = 0;\n    std::string value_space;\n    Iterator* iter = db_->NewIterator(ReadOptions());\n    for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {\n      uint64_t key;\n      Slice in(iter->key());\n      if (in == \"\" || in == \"~\") {\n        // Ignore boundary keys.\n        continue;\n      }\n      if (!ConsumeDecimalNumber(&in, &key) ||\n          !in.empty() ||\n          key < next_expected) {\n        bad_keys++;\n        continue;\n      }\n      missed += (key - next_expected);\n      next_expected = key + 1;\n      if (iter->value() != Value(key, &value_space)) {\n        bad_values++;\n      } else {\n        correct++;\n      }\n    }\n    delete iter;\n\n    fprintf(stderr,\n            \"expected=%d..%d; got=%d; bad_keys=%d; bad_values=%d; missed=%d\\n\",\n            min_expected, max_expected, correct, bad_keys, bad_values, missed);\n    ASSERT_LE(min_expected, correct);\n    ASSERT_GE(max_expected, correct);\n  }\n\n  void Corrupt(FileType filetype, int offset, int bytes_to_corrupt) {\n    // Pick file to corrupt\n    std::vector<std::string> filenames;\n    ASSERT_OK(env_.GetChildren(dbname_, &filenames));\n    uint64_t number;\n    FileType type;\n    std::string fname;\n    int picked_number = -1;\n    for (size_t i = 0; i < filenames.size(); i++) {\n      if (ParseFileName(filenames[i], &number, &type) &&\n          type == filetype &&\n          int(number) > picked_number) {  // Pick latest file\n        fname = dbname_ + \"/\" + filenames[i];\n        picked_number = number;\n      }\n    }\n    ASSERT_TRUE(!fname.empty()) << filetype;\n\n    struct stat sbuf;\n    if (stat(fname.c_str(), &sbuf) != 0) {\n      const char* msg = strerror(errno);\n      ASSERT_TRUE(false) << fname << \": \" << msg;\n    }\n\n    if (offset < 0) {\n      // Relative to end of file; make it absolute\n      if (-offset > sbuf.st_size) {\n        offset = 0;\n      } else {\n        offset = sbuf.st_size + offset;\n      }\n    }\n    if (offset > sbuf.st_size) {\n      offset = sbuf.st_size;\n    }\n    if (offset + bytes_to_corrupt > sbuf.st_size) {\n      bytes_to_corrupt = sbuf.st_size - offset;\n    }\n\n    // Do it\n    std::string contents;\n    Status s = ReadFileToString(Env::Default(), fname, &contents);\n    ASSERT_TRUE(s.ok()) << s.ToString();\n    for (int i = 0; i < bytes_to_corrupt; i++) {\n      contents[i + offset] ^= 0x80;\n    }\n    s = WriteStringToFile(Env::Default(), contents, fname);\n    ASSERT_TRUE(s.ok()) << s.ToString();\n  }\n\n  int Property(const std::string& name) {\n    std::string property;\n    int result;\n    if (db_->GetProperty(name, &property) &&\n        sscanf(property.c_str(), \"%d\", &result) == 1) {\n      return result;\n    } else {\n      return -1;\n    }\n  }\n\n  // Return the ith key\n  Slice Key(int i, std::string* storage) {\n    char buf[100];\n    snprintf(buf, sizeof(buf), \"%016d\", i);\n    storage->assign(buf, strlen(buf));\n    return Slice(*storage);\n  }\n\n  // Return the value to associate with the specified key\n  Slice Value(int k, std::string* storage) {\n    Random r(k);\n    return test::RandomString(&r, kValueSize, storage);\n  }\n};\n\nTEST(CorruptionTest, Recovery) {\n  Build(100);\n  Check(100, 100);\n  Corrupt(kLogFile, 19, 1);      // WriteBatch tag for first record\n  Corrupt(kLogFile, log::kBlockSize + 1000, 1);  // Somewhere in second block\n  Reopen();\n\n  // The 64 records in the first two log blocks are completely lost.\n  Check(36, 36);\n}\n\nTEST(CorruptionTest, RecoverWriteError) {\n  env_.writable_file_error_ = true;\n  Status s = TryReopen();\n  ASSERT_TRUE(!s.ok());\n}\n\nTEST(CorruptionTest, NewFileErrorDuringWrite) {\n  // Do enough writing to force minor compaction\n  env_.writable_file_error_ = true;\n  const int num = 3 + (Options().write_buffer_size / kValueSize);\n  std::string value_storage;\n  Status s;\n  for (int i = 0; s.ok() && i < num; i++) {\n    WriteBatch batch;\n    batch.Put(\"a\", Value(100, &value_storage));\n    s = db_->Write(WriteOptions(), &batch);\n  }\n  ASSERT_TRUE(!s.ok());\n  ASSERT_GE(env_.num_writable_file_errors_, 1);\n  env_.writable_file_error_ = false;\n  Reopen();\n}\n\nTEST(CorruptionTest, TableFile) {\n  Build(100);\n  DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);\n  dbi->TEST_CompactMemTable();\n  dbi->TEST_CompactRange(0, NULL, NULL);\n  dbi->TEST_CompactRange(1, NULL, NULL);\n\n  Corrupt(kTableFile, 100, 1);\n  Check(90, 99);\n}\n\nTEST(CorruptionTest, TableFileRepair) {\n  options_.block_size = 2 * kValueSize;  // Limit scope of corruption\n  options_.paranoid_checks = true;\n  Reopen();\n  Build(100);\n  DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);\n  dbi->TEST_CompactMemTable();\n  dbi->TEST_CompactRange(0, NULL, NULL);\n  dbi->TEST_CompactRange(1, NULL, NULL);\n\n  Corrupt(kTableFile, 100, 1);\n  RepairDB();\n  Reopen();\n  Check(95, 99);\n}\n\nTEST(CorruptionTest, TableFileIndexData) {\n  Build(10000);  // Enough to build multiple Tables\n  DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);\n  dbi->TEST_CompactMemTable();\n\n  Corrupt(kTableFile, -2000, 500);\n  Reopen();\n  Check(5000, 9999);\n}\n\nTEST(CorruptionTest, MissingDescriptor) {\n  Build(1000);\n  RepairDB();\n  Reopen();\n  Check(1000, 1000);\n}\n\nTEST(CorruptionTest, SequenceNumberRecovery) {\n  ASSERT_OK(db_->Put(WriteOptions(), \"foo\", \"v1\"));\n  ASSERT_OK(db_->Put(WriteOptions(), \"foo\", \"v2\"));\n  ASSERT_OK(db_->Put(WriteOptions(), \"foo\", \"v3\"));\n  ASSERT_OK(db_->Put(WriteOptions(), \"foo\", \"v4\"));\n  ASSERT_OK(db_->Put(WriteOptions(), \"foo\", \"v5\"));\n  RepairDB();\n  Reopen();\n  std::string v;\n  ASSERT_OK(db_->Get(ReadOptions(), \"foo\", &v));\n  ASSERT_EQ(\"v5\", v);\n  // Write something.  If sequence number was not recovered properly,\n  // it will be hidden by an earlier write.\n  ASSERT_OK(db_->Put(WriteOptions(), \"foo\", \"v6\"));\n  ASSERT_OK(db_->Get(ReadOptions(), \"foo\", &v));\n  ASSERT_EQ(\"v6\", v);\n  Reopen();\n  ASSERT_OK(db_->Get(ReadOptions(), \"foo\", &v));\n  ASSERT_EQ(\"v6\", v);\n}\n\nTEST(CorruptionTest, CorruptedDescriptor) {\n  ASSERT_OK(db_->Put(WriteOptions(), \"foo\", \"hello\"));\n  DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);\n  dbi->TEST_CompactMemTable();\n  dbi->TEST_CompactRange(0, NULL, NULL);\n\n  Corrupt(kDescriptorFile, 0, 1000);\n  Status s = TryReopen();\n  ASSERT_TRUE(!s.ok());\n\n  RepairDB();\n  Reopen();\n  std::string v;\n  ASSERT_OK(db_->Get(ReadOptions(), \"foo\", &v));\n  ASSERT_EQ(\"hello\", v);\n}\n\nTEST(CorruptionTest, CompactionInputError) {\n  Build(10);\n  DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);\n  dbi->TEST_CompactMemTable();\n  const int last = config::kMaxMemCompactLevel;\n  ASSERT_EQ(1, Property(\"leveldb.num-files-at-level\" + NumberToString(last)));\n\n  Corrupt(kTableFile, 100, 1);\n  Check(5, 9);\n\n  // Force compactions by writing lots of values\n  Build(10000);\n  Check(10000, 10000);\n}\n\nTEST(CorruptionTest, CompactionInputErrorParanoid) {\n  options_.paranoid_checks = true;\n  options_.write_buffer_size = 512 << 10;\n  Reopen();\n  DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);\n\n  // Make multiple inputs so we need to compact.\n  for (int i = 0; i < 2; i++) {\n    Build(10);\n    dbi->TEST_CompactMemTable();\n    Corrupt(kTableFile, 100, 1);\n    env_.SleepForMicroseconds(100000);\n  }\n  dbi->CompactRange(NULL, NULL);\n\n  // Write must fail because of corrupted table\n  std::string tmp1, tmp2;\n  Status s = db_->Put(WriteOptions(), Key(5, &tmp1), Value(5, &tmp2));\n  ASSERT_TRUE(!s.ok()) << \"write did not fail in corrupted paranoid db\";\n}\n\nTEST(CorruptionTest, UnrelatedKeys) {\n  Build(10);\n  DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);\n  dbi->TEST_CompactMemTable();\n  Corrupt(kTableFile, 100, 1);\n\n  std::string tmp1, tmp2;\n  ASSERT_OK(db_->Put(WriteOptions(), Key(1000, &tmp1), Value(1000, &tmp2)));\n  std::string v;\n  ASSERT_OK(db_->Get(ReadOptions(), Key(1000, &tmp1), &v));\n  ASSERT_EQ(Value(1000, &tmp2).ToString(), v);\n  dbi->TEST_CompactMemTable();\n  ASSERT_OK(db_->Get(ReadOptions(), Key(1000, &tmp1), &v));\n  ASSERT_EQ(Value(1000, &tmp2).ToString(), v);\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/db/db_bench.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include <sys/types.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include \"db/db_impl.h\"\n#include \"db/version_set.h\"\n#include \"leveldb/cache.h\"\n#include \"leveldb/db.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/write_batch.h\"\n#include \"port/port.h\"\n#include \"util/crc32c.h\"\n#include \"util/histogram.h\"\n#include \"util/mutexlock.h\"\n#include \"util/random.h\"\n#include \"util/testutil.h\"\n\n// Comma-separated list of operations to run in the specified order\n//   Actual benchmarks:\n//      fillseq       -- write N values in sequential key order in async mode\n//      fillrandom    -- write N values in random key order in async mode\n//      overwrite     -- overwrite N values in random key order in async mode\n//      fillsync      -- write N/100 values in random key order in sync mode\n//      fill100K      -- write N/1000 100K values in random order in async mode\n//      deleteseq     -- delete N keys in sequential order\n//      deleterandom  -- delete N keys in random order\n//      readseq       -- read N times sequentially\n//      readreverse   -- read N times in reverse order\n//      readrandom    -- read N times in random order\n//      readmissing   -- read N missing keys in random order\n//      readhot       -- read N times in random order from 1% section of DB\n//      seekrandom    -- N random seeks\n//      open          -- cost of opening a DB\n//      crc32c        -- repeated crc32c of 4K of data\n//      acquireload   -- load N*1000 times\n//   Meta operations:\n//      compact     -- Compact the entire DB\n//      stats       -- Print DB stats\n//      sstables    -- Print sstable info\n//      heapprofile -- Dump a heap profile (if supported by this port)\nstatic const char* FLAGS_benchmarks =\n    \"fillseq,\"\n    \"fillsync,\"\n    \"fillrandom,\"\n    \"overwrite,\"\n    \"readrandom,\"\n    \"readrandom,\"  // Extra run to allow previous compactions to quiesce\n    \"readseq,\"\n    \"readreverse,\"\n    \"compact,\"\n    \"readrandom,\"\n    \"readseq,\"\n    \"readreverse,\"\n    \"fill100K,\"\n    \"crc32c,\"\n    \"snappycomp,\"\n    \"snappyuncomp,\"\n    \"acquireload,\"\n    ;\n\n// Number of key/values to place in database\nstatic int FLAGS_num = 1000000;\n\n// Number of read operations to do.  If negative, do FLAGS_num reads.\nstatic int FLAGS_reads = -1;\n\n// Number of concurrent threads to run.\nstatic int FLAGS_threads = 1;\n\n// Size of each value\nstatic int FLAGS_value_size = 100;\n\n// Arrange to generate values that shrink to this fraction of\n// their original size after compression\nstatic double FLAGS_compression_ratio = 0.5;\n\n// Print histogram of operation timings\nstatic bool FLAGS_histogram = false;\n\n// Number of bytes to buffer in memtable before compacting\n// (initialized to default value by \"main\")\nstatic int FLAGS_write_buffer_size = 0;\n\n// Number of bytes written to each file.\n// (initialized to default value by \"main\")\nstatic int FLAGS_max_file_size = 0;\n\n// Approximate size of user data packed per block (before compression.\n// (initialized to default value by \"main\")\nstatic int FLAGS_block_size = 0;\n\n// Number of bytes to use as a cache of uncompressed data.\n// Negative means use default settings.\nstatic int FLAGS_cache_size = -1;\n\n// Maximum number of files to keep open at the same time (use default if == 0)\nstatic int FLAGS_open_files = 0;\n\n// Bloom filter bits per key.\n// Negative means use default settings.\nstatic int FLAGS_bloom_bits = -1;\n\n// If true, do not destroy the existing database.  If you set this\n// flag and also specify a benchmark that wants a fresh database, that\n// benchmark will fail.\nstatic bool FLAGS_use_existing_db = false;\n\n// If true, reuse existing log/MANIFEST files when re-opening a database.\nstatic bool FLAGS_reuse_logs = false;\n\n// Use the db with the following name.\nstatic const char* FLAGS_db = NULL;\n\nnamespace leveldb {\n\nnamespace {\nleveldb::Env* g_env = NULL;\n\n// Helper for quickly generating random data.\nclass RandomGenerator {\n private:\n  std::string data_;\n  int pos_;\n\n public:\n  RandomGenerator() {\n    // We use a limited amount of data over and over again and ensure\n    // that it is larger than the compression window (32KB), and also\n    // large enough to serve all typical value sizes we want to write.\n    Random rnd(301);\n    std::string piece;\n    while (data_.size() < 1048576) {\n      // Add a short fragment that is as compressible as specified\n      // by FLAGS_compression_ratio.\n      test::CompressibleString(&rnd, FLAGS_compression_ratio, 100, &piece);\n      data_.append(piece);\n    }\n    pos_ = 0;\n  }\n\n  Slice Generate(size_t len) {\n    if (pos_ + len > data_.size()) {\n      pos_ = 0;\n      assert(len < data_.size());\n    }\n    pos_ += len;\n    return Slice(data_.data() + pos_ - len, len);\n  }\n};\n\n#if defined(__linux)\nstatic Slice TrimSpace(Slice s) {\n  size_t start = 0;\n  while (start < s.size() && isspace(s[start])) {\n    start++;\n  }\n  size_t limit = s.size();\n  while (limit > start && isspace(s[limit-1])) {\n    limit--;\n  }\n  return Slice(s.data() + start, limit - start);\n}\n#endif\n\nstatic void AppendWithSpace(std::string* str, Slice msg) {\n  if (msg.empty()) return;\n  if (!str->empty()) {\n    str->push_back(' ');\n  }\n  str->append(msg.data(), msg.size());\n}\n\nclass Stats {\n private:\n  double start_;\n  double finish_;\n  double seconds_;\n  int done_;\n  int next_report_;\n  int64_t bytes_;\n  double last_op_finish_;\n  Histogram hist_;\n  std::string message_;\n\n public:\n  Stats() { Start(); }\n\n  void Start() {\n    next_report_ = 100;\n    last_op_finish_ = start_;\n    hist_.Clear();\n    done_ = 0;\n    bytes_ = 0;\n    seconds_ = 0;\n    start_ = g_env->NowMicros();\n    finish_ = start_;\n    message_.clear();\n  }\n\n  void Merge(const Stats& other) {\n    hist_.Merge(other.hist_);\n    done_ += other.done_;\n    bytes_ += other.bytes_;\n    seconds_ += other.seconds_;\n    if (other.start_ < start_) start_ = other.start_;\n    if (other.finish_ > finish_) finish_ = other.finish_;\n\n    // Just keep the messages from one thread\n    if (message_.empty()) message_ = other.message_;\n  }\n\n  void Stop() {\n    finish_ = g_env->NowMicros();\n    seconds_ = (finish_ - start_) * 1e-6;\n  }\n\n  void AddMessage(Slice msg) {\n    AppendWithSpace(&message_, msg);\n  }\n\n  void FinishedSingleOp() {\n    if (FLAGS_histogram) {\n      double now = g_env->NowMicros();\n      double micros = now - last_op_finish_;\n      hist_.Add(micros);\n      if (micros > 20000) {\n        fprintf(stderr, \"long op: %.1f micros%30s\\r\", micros, \"\");\n        fflush(stderr);\n      }\n      last_op_finish_ = now;\n    }\n\n    done_++;\n    if (done_ >= next_report_) {\n      if      (next_report_ < 1000)   next_report_ += 100;\n      else if (next_report_ < 5000)   next_report_ += 500;\n      else if (next_report_ < 10000)  next_report_ += 1000;\n      else if (next_report_ < 50000)  next_report_ += 5000;\n      else if (next_report_ < 100000) next_report_ += 10000;\n      else if (next_report_ < 500000) next_report_ += 50000;\n      else                            next_report_ += 100000;\n      fprintf(stderr, \"... finished %d ops%30s\\r\", done_, \"\");\n      fflush(stderr);\n    }\n  }\n\n  void AddBytes(int64_t n) {\n    bytes_ += n;\n  }\n\n  void Report(const Slice& name) {\n    // Pretend at least one op was done in case we are running a benchmark\n    // that does not call FinishedSingleOp().\n    if (done_ < 1) done_ = 1;\n\n    std::string extra;\n    if (bytes_ > 0) {\n      // Rate is computed on actual elapsed time, not the sum of per-thread\n      // elapsed times.\n      double elapsed = (finish_ - start_) * 1e-6;\n      char rate[100];\n      snprintf(rate, sizeof(rate), \"%6.1f MB/s\",\n               (bytes_ / 1048576.0) / elapsed);\n      extra = rate;\n    }\n    AppendWithSpace(&extra, message_);\n\n    fprintf(stdout, \"%-12s : %11.3f micros/op;%s%s\\n\",\n            name.ToString().c_str(),\n            seconds_ * 1e6 / done_,\n            (extra.empty() ? \"\" : \" \"),\n            extra.c_str());\n    if (FLAGS_histogram) {\n      fprintf(stdout, \"Microseconds per op:\\n%s\\n\", hist_.ToString().c_str());\n    }\n    fflush(stdout);\n  }\n};\n\n// State shared by all concurrent executions of the same benchmark.\nstruct SharedState {\n  port::Mutex mu;\n  port::CondVar cv;\n  int total;\n\n  // Each thread goes through the following states:\n  //    (1) initializing\n  //    (2) waiting for others to be initialized\n  //    (3) running\n  //    (4) done\n\n  int num_initialized;\n  int num_done;\n  bool start;\n\n  SharedState() : cv(&mu) { }\n};\n\n// Per-thread state for concurrent executions of the same benchmark.\nstruct ThreadState {\n  int tid;             // 0..n-1 when running in n threads\n  Random rand;         // Has different seeds for different threads\n  Stats stats;\n  SharedState* shared;\n\n  ThreadState(int index)\n      : tid(index),\n        rand(1000 + index) {\n  }\n};\n\n}  // namespace\n\nclass Benchmark {\n private:\n  Cache* cache_;\n  const FilterPolicy* filter_policy_;\n  DB* db_;\n  int num_;\n  int value_size_;\n  int entries_per_batch_;\n  WriteOptions write_options_;\n  int reads_;\n  int heap_counter_;\n\n  void PrintHeader() {\n    const int kKeySize = 16;\n    PrintEnvironment();\n    fprintf(stdout, \"Keys:       %d bytes each\\n\", kKeySize);\n    fprintf(stdout, \"Values:     %d bytes each (%d bytes after compression)\\n\",\n            FLAGS_value_size,\n            static_cast<int>(FLAGS_value_size * FLAGS_compression_ratio + 0.5));\n    fprintf(stdout, \"Entries:    %d\\n\", num_);\n    fprintf(stdout, \"RawSize:    %.1f MB (estimated)\\n\",\n            ((static_cast<int64_t>(kKeySize + FLAGS_value_size) * num_)\n             / 1048576.0));\n    fprintf(stdout, \"FileSize:   %.1f MB (estimated)\\n\",\n            (((kKeySize + FLAGS_value_size * FLAGS_compression_ratio) * num_)\n             / 1048576.0));\n    PrintWarnings();\n    fprintf(stdout, \"------------------------------------------------\\n\");\n  }\n\n  void PrintWarnings() {\n#if defined(__GNUC__) && !defined(__OPTIMIZE__)\n    fprintf(stdout,\n            \"WARNING: Optimization is disabled: benchmarks unnecessarily slow\\n\"\n            );\n#endif\n#ifndef NDEBUG\n    fprintf(stdout,\n            \"WARNING: Assertions are enabled; benchmarks unnecessarily slow\\n\");\n#endif\n\n    // See if snappy is working by attempting to compress a compressible string\n    const char text[] = \"yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\";\n    std::string compressed;\n    if (!port::Snappy_Compress(text, sizeof(text), &compressed)) {\n      fprintf(stdout, \"WARNING: Snappy compression is not enabled\\n\");\n    } else if (compressed.size() >= sizeof(text)) {\n      fprintf(stdout, \"WARNING: Snappy compression is not effective\\n\");\n    }\n  }\n\n  void PrintEnvironment() {\n    fprintf(stderr, \"LevelDB:    version %d.%d\\n\",\n            kMajorVersion, kMinorVersion);\n\n#if defined(__linux)\n    time_t now = time(NULL);\n    fprintf(stderr, \"Date:       %s\", ctime(&now));  // ctime() adds newline\n\n    FILE* cpuinfo = fopen(\"/proc/cpuinfo\", \"r\");\n    if (cpuinfo != NULL) {\n      char line[1000];\n      int num_cpus = 0;\n      std::string cpu_type;\n      std::string cache_size;\n      while (fgets(line, sizeof(line), cpuinfo) != NULL) {\n        const char* sep = strchr(line, ':');\n        if (sep == NULL) {\n          continue;\n        }\n        Slice key = TrimSpace(Slice(line, sep - 1 - line));\n        Slice val = TrimSpace(Slice(sep + 1));\n        if (key == \"model name\") {\n          ++num_cpus;\n          cpu_type = val.ToString();\n        } else if (key == \"cache size\") {\n          cache_size = val.ToString();\n        }\n      }\n      fclose(cpuinfo);\n      fprintf(stderr, \"CPU:        %d * %s\\n\", num_cpus, cpu_type.c_str());\n      fprintf(stderr, \"CPUCache:   %s\\n\", cache_size.c_str());\n    }\n#endif\n  }\n\n public:\n  Benchmark()\n  : cache_(FLAGS_cache_size >= 0 ? NewLRUCache(FLAGS_cache_size) : NULL),\n    filter_policy_(FLAGS_bloom_bits >= 0\n                   ? NewBloomFilterPolicy(FLAGS_bloom_bits)\n                   : NULL),\n    db_(NULL),\n    num_(FLAGS_num),\n    value_size_(FLAGS_value_size),\n    entries_per_batch_(1),\n    reads_(FLAGS_reads < 0 ? FLAGS_num : FLAGS_reads),\n    heap_counter_(0) {\n    std::vector<std::string> files;\n    g_env->GetChildren(FLAGS_db, &files);\n    for (size_t i = 0; i < files.size(); i++) {\n      if (Slice(files[i]).starts_with(\"heap-\")) {\n        g_env->DeleteFile(std::string(FLAGS_db) + \"/\" + files[i]);\n      }\n    }\n    if (!FLAGS_use_existing_db) {\n      DestroyDB(FLAGS_db, Options());\n    }\n  }\n\n  ~Benchmark() {\n    delete db_;\n    delete cache_;\n    delete filter_policy_;\n  }\n\n  void Run() {\n    PrintHeader();\n    Open();\n\n    const char* benchmarks = FLAGS_benchmarks;\n    while (benchmarks != NULL) {\n      const char* sep = strchr(benchmarks, ',');\n      Slice name;\n      if (sep == NULL) {\n        name = benchmarks;\n        benchmarks = NULL;\n      } else {\n        name = Slice(benchmarks, sep - benchmarks);\n        benchmarks = sep + 1;\n      }\n\n      // Reset parameters that may be overridden below\n      num_ = FLAGS_num;\n      reads_ = (FLAGS_reads < 0 ? FLAGS_num : FLAGS_reads);\n      value_size_ = FLAGS_value_size;\n      entries_per_batch_ = 1;\n      write_options_ = WriteOptions();\n\n      void (Benchmark::*method)(ThreadState*) = NULL;\n      bool fresh_db = false;\n      int num_threads = FLAGS_threads;\n\n      if (name == Slice(\"open\")) {\n        method = &Benchmark::OpenBench;\n        num_ /= 10000;\n        if (num_ < 1) num_ = 1;\n      } else if (name == Slice(\"fillseq\")) {\n        fresh_db = true;\n        method = &Benchmark::WriteSeq;\n      } else if (name == Slice(\"fillbatch\")) {\n        fresh_db = true;\n        entries_per_batch_ = 1000;\n        method = &Benchmark::WriteSeq;\n      } else if (name == Slice(\"fillrandom\")) {\n        fresh_db = true;\n        method = &Benchmark::WriteRandom;\n      } else if (name == Slice(\"overwrite\")) {\n        fresh_db = false;\n        method = &Benchmark::WriteRandom;\n      } else if (name == Slice(\"fillsync\")) {\n        fresh_db = true;\n        num_ /= 1000;\n        write_options_.sync = true;\n        method = &Benchmark::WriteRandom;\n      } else if (name == Slice(\"fill100K\")) {\n        fresh_db = true;\n        num_ /= 1000;\n        value_size_ = 100 * 1000;\n        method = &Benchmark::WriteRandom;\n      } else if (name == Slice(\"readseq\")) {\n        method = &Benchmark::ReadSequential;\n      } else if (name == Slice(\"readreverse\")) {\n        method = &Benchmark::ReadReverse;\n      } else if (name == Slice(\"readrandom\")) {\n        method = &Benchmark::ReadRandom;\n      } else if (name == Slice(\"readmissing\")) {\n        method = &Benchmark::ReadMissing;\n      } else if (name == Slice(\"seekrandom\")) {\n        method = &Benchmark::SeekRandom;\n      } else if (name == Slice(\"readhot\")) {\n        method = &Benchmark::ReadHot;\n      } else if (name == Slice(\"readrandomsmall\")) {\n        reads_ /= 1000;\n        method = &Benchmark::ReadRandom;\n      } else if (name == Slice(\"deleteseq\")) {\n        method = &Benchmark::DeleteSeq;\n      } else if (name == Slice(\"deleterandom\")) {\n        method = &Benchmark::DeleteRandom;\n      } else if (name == Slice(\"readwhilewriting\")) {\n        num_threads++;  // Add extra thread for writing\n        method = &Benchmark::ReadWhileWriting;\n      } else if (name == Slice(\"compact\")) {\n        method = &Benchmark::Compact;\n      } else if (name == Slice(\"crc32c\")) {\n        method = &Benchmark::Crc32c;\n      } else if (name == Slice(\"acquireload\")) {\n        method = &Benchmark::AcquireLoad;\n      } else if (name == Slice(\"snappycomp\")) {\n        method = &Benchmark::SnappyCompress;\n      } else if (name == Slice(\"snappyuncomp\")) {\n        method = &Benchmark::SnappyUncompress;\n      } else if (name == Slice(\"heapprofile\")) {\n        HeapProfile();\n      } else if (name == Slice(\"stats\")) {\n        PrintStats(\"leveldb.stats\");\n      } else if (name == Slice(\"sstables\")) {\n        PrintStats(\"leveldb.sstables\");\n      } else {\n        if (name != Slice()) {  // No error message for empty name\n          fprintf(stderr, \"unknown benchmark '%s'\\n\", name.ToString().c_str());\n        }\n      }\n\n      if (fresh_db) {\n        if (FLAGS_use_existing_db) {\n          fprintf(stdout, \"%-12s : skipped (--use_existing_db is true)\\n\",\n                  name.ToString().c_str());\n          method = NULL;\n        } else {\n          delete db_;\n          db_ = NULL;\n          DestroyDB(FLAGS_db, Options());\n          Open();\n        }\n      }\n\n      if (method != NULL) {\n        RunBenchmark(num_threads, name, method);\n      }\n    }\n  }\n\n private:\n  struct ThreadArg {\n    Benchmark* bm;\n    SharedState* shared;\n    ThreadState* thread;\n    void (Benchmark::*method)(ThreadState*);\n  };\n\n  static void ThreadBody(void* v) {\n    ThreadArg* arg = reinterpret_cast<ThreadArg*>(v);\n    SharedState* shared = arg->shared;\n    ThreadState* thread = arg->thread;\n    {\n      MutexLock l(&shared->mu);\n      shared->num_initialized++;\n      if (shared->num_initialized >= shared->total) {\n        shared->cv.SignalAll();\n      }\n      while (!shared->start) {\n        shared->cv.Wait();\n      }\n    }\n\n    thread->stats.Start();\n    (arg->bm->*(arg->method))(thread);\n    thread->stats.Stop();\n\n    {\n      MutexLock l(&shared->mu);\n      shared->num_done++;\n      if (shared->num_done >= shared->total) {\n        shared->cv.SignalAll();\n      }\n    }\n  }\n\n  void RunBenchmark(int n, Slice name,\n                    void (Benchmark::*method)(ThreadState*)) {\n    SharedState shared;\n    shared.total = n;\n    shared.num_initialized = 0;\n    shared.num_done = 0;\n    shared.start = false;\n\n    ThreadArg* arg = new ThreadArg[n];\n    for (int i = 0; i < n; i++) {\n      arg[i].bm = this;\n      arg[i].method = method;\n      arg[i].shared = &shared;\n      arg[i].thread = new ThreadState(i);\n      arg[i].thread->shared = &shared;\n      g_env->StartThread(ThreadBody, &arg[i]);\n    }\n\n    shared.mu.Lock();\n    while (shared.num_initialized < n) {\n      shared.cv.Wait();\n    }\n\n    shared.start = true;\n    shared.cv.SignalAll();\n    while (shared.num_done < n) {\n      shared.cv.Wait();\n    }\n    shared.mu.Unlock();\n\n    for (int i = 1; i < n; i++) {\n      arg[0].thread->stats.Merge(arg[i].thread->stats);\n    }\n    arg[0].thread->stats.Report(name);\n\n    for (int i = 0; i < n; i++) {\n      delete arg[i].thread;\n    }\n    delete[] arg;\n  }\n\n  void Crc32c(ThreadState* thread) {\n    // Checksum about 500MB of data total\n    const int size = 4096;\n    const char* label = \"(4K per op)\";\n    std::string data(size, 'x');\n    int64_t bytes = 0;\n    uint32_t crc = 0;\n    while (bytes < 500 * 1048576) {\n      crc = crc32c::Value(data.data(), size);\n      thread->stats.FinishedSingleOp();\n      bytes += size;\n    }\n    // Print so result is not dead\n    fprintf(stderr, \"... crc=0x%x\\r\", static_cast<unsigned int>(crc));\n\n    thread->stats.AddBytes(bytes);\n    thread->stats.AddMessage(label);\n  }\n\n  void AcquireLoad(ThreadState* thread) {\n    int dummy;\n    port::AtomicPointer ap(&dummy);\n    int count = 0;\n    void *ptr = NULL;\n    thread->stats.AddMessage(\"(each op is 1000 loads)\");\n    while (count < 100000) {\n      for (int i = 0; i < 1000; i++) {\n        ptr = ap.Acquire_Load();\n      }\n      count++;\n      thread->stats.FinishedSingleOp();\n    }\n    if (ptr == NULL) exit(1); // Disable unused variable warning.\n  }\n\n  void SnappyCompress(ThreadState* thread) {\n    RandomGenerator gen;\n    Slice input = gen.Generate(Options().block_size);\n    int64_t bytes = 0;\n    int64_t produced = 0;\n    bool ok = true;\n    std::string compressed;\n    while (ok && bytes < 1024 * 1048576) {  // Compress 1G\n      ok = port::Snappy_Compress(input.data(), input.size(), &compressed);\n      produced += compressed.size();\n      bytes += input.size();\n      thread->stats.FinishedSingleOp();\n    }\n\n    if (!ok) {\n      thread->stats.AddMessage(\"(snappy failure)\");\n    } else {\n      char buf[100];\n      snprintf(buf, sizeof(buf), \"(output: %.1f%%)\",\n               (produced * 100.0) / bytes);\n      thread->stats.AddMessage(buf);\n      thread->stats.AddBytes(bytes);\n    }\n  }\n\n  void SnappyUncompress(ThreadState* thread) {\n    RandomGenerator gen;\n    Slice input = gen.Generate(Options().block_size);\n    std::string compressed;\n    bool ok = port::Snappy_Compress(input.data(), input.size(), &compressed);\n    int64_t bytes = 0;\n    char* uncompressed = new char[input.size()];\n    while (ok && bytes < 1024 * 1048576) {  // Compress 1G\n      ok =  port::Snappy_Uncompress(compressed.data(), compressed.size(),\n                                    uncompressed);\n      bytes += input.size();\n      thread->stats.FinishedSingleOp();\n    }\n    delete[] uncompressed;\n\n    if (!ok) {\n      thread->stats.AddMessage(\"(snappy failure)\");\n    } else {\n      thread->stats.AddBytes(bytes);\n    }\n  }\n\n  void Open() {\n    assert(db_ == NULL);\n    Options options;\n    options.env = g_env;\n    options.create_if_missing = !FLAGS_use_existing_db;\n    options.block_cache = cache_;\n    options.write_buffer_size = FLAGS_write_buffer_size;\n    options.max_file_size = FLAGS_max_file_size;\n    options.block_size = FLAGS_block_size;\n    options.max_open_files = FLAGS_open_files;\n    options.filter_policy = filter_policy_;\n    options.reuse_logs = FLAGS_reuse_logs;\n    Status s = DB::Open(options, FLAGS_db, &db_);\n    if (!s.ok()) {\n      fprintf(stderr, \"open error: %s\\n\", s.ToString().c_str());\n      exit(1);\n    }\n  }\n\n  void OpenBench(ThreadState* thread) {\n    for (int i = 0; i < num_; i++) {\n      delete db_;\n      Open();\n      thread->stats.FinishedSingleOp();\n    }\n  }\n\n  void WriteSeq(ThreadState* thread) {\n    DoWrite(thread, true);\n  }\n\n  void WriteRandom(ThreadState* thread) {\n    DoWrite(thread, false);\n  }\n\n  void DoWrite(ThreadState* thread, bool seq) {\n    if (num_ != FLAGS_num) {\n      char msg[100];\n      snprintf(msg, sizeof(msg), \"(%d ops)\", num_);\n      thread->stats.AddMessage(msg);\n    }\n\n    RandomGenerator gen;\n    WriteBatch batch;\n    Status s;\n    int64_t bytes = 0;\n    for (int i = 0; i < num_; i += entries_per_batch_) {\n      batch.Clear();\n      for (int j = 0; j < entries_per_batch_; j++) {\n        const int k = seq ? i+j : (thread->rand.Next() % FLAGS_num);\n        char key[100];\n        snprintf(key, sizeof(key), \"%016d\", k);\n        batch.Put(key, gen.Generate(value_size_));\n        bytes += value_size_ + strlen(key);\n        thread->stats.FinishedSingleOp();\n      }\n      s = db_->Write(write_options_, &batch);\n      if (!s.ok()) {\n        fprintf(stderr, \"put error: %s\\n\", s.ToString().c_str());\n        exit(1);\n      }\n    }\n    thread->stats.AddBytes(bytes);\n  }\n\n  void ReadSequential(ThreadState* thread) {\n    Iterator* iter = db_->NewIterator(ReadOptions());\n    int i = 0;\n    int64_t bytes = 0;\n    for (iter->SeekToFirst(); i < reads_ && iter->Valid(); iter->Next()) {\n      bytes += iter->key().size() + iter->value().size();\n      thread->stats.FinishedSingleOp();\n      ++i;\n    }\n    delete iter;\n    thread->stats.AddBytes(bytes);\n  }\n\n  void ReadReverse(ThreadState* thread) {\n    Iterator* iter = db_->NewIterator(ReadOptions());\n    int i = 0;\n    int64_t bytes = 0;\n    for (iter->SeekToLast(); i < reads_ && iter->Valid(); iter->Prev()) {\n      bytes += iter->key().size() + iter->value().size();\n      thread->stats.FinishedSingleOp();\n      ++i;\n    }\n    delete iter;\n    thread->stats.AddBytes(bytes);\n  }\n\n  void ReadRandom(ThreadState* thread) {\n    ReadOptions options;\n    std::string value;\n    int found = 0;\n    for (int i = 0; i < reads_; i++) {\n      char key[100];\n      const int k = thread->rand.Next() % FLAGS_num;\n      snprintf(key, sizeof(key), \"%016d\", k);\n      if (db_->Get(options, key, &value).ok()) {\n        found++;\n      }\n      thread->stats.FinishedSingleOp();\n    }\n    char msg[100];\n    snprintf(msg, sizeof(msg), \"(%d of %d found)\", found, num_);\n    thread->stats.AddMessage(msg);\n  }\n\n  void ReadMissing(ThreadState* thread) {\n    ReadOptions options;\n    std::string value;\n    for (int i = 0; i < reads_; i++) {\n      char key[100];\n      const int k = thread->rand.Next() % FLAGS_num;\n      snprintf(key, sizeof(key), \"%016d.\", k);\n      db_->Get(options, key, &value);\n      thread->stats.FinishedSingleOp();\n    }\n  }\n\n  void ReadHot(ThreadState* thread) {\n    ReadOptions options;\n    std::string value;\n    const int range = (FLAGS_num + 99) / 100;\n    for (int i = 0; i < reads_; i++) {\n      char key[100];\n      const int k = thread->rand.Next() % range;\n      snprintf(key, sizeof(key), \"%016d\", k);\n      db_->Get(options, key, &value);\n      thread->stats.FinishedSingleOp();\n    }\n  }\n\n  void SeekRandom(ThreadState* thread) {\n    ReadOptions options;\n    int found = 0;\n    for (int i = 0; i < reads_; i++) {\n      Iterator* iter = db_->NewIterator(options);\n      char key[100];\n      const int k = thread->rand.Next() % FLAGS_num;\n      snprintf(key, sizeof(key), \"%016d\", k);\n      iter->Seek(key);\n      if (iter->Valid() && iter->key() == key) found++;\n      delete iter;\n      thread->stats.FinishedSingleOp();\n    }\n    char msg[100];\n    snprintf(msg, sizeof(msg), \"(%d of %d found)\", found, num_);\n    thread->stats.AddMessage(msg);\n  }\n\n  void DoDelete(ThreadState* thread, bool seq) {\n    RandomGenerator gen;\n    WriteBatch batch;\n    Status s;\n    for (int i = 0; i < num_; i += entries_per_batch_) {\n      batch.Clear();\n      for (int j = 0; j < entries_per_batch_; j++) {\n        const int k = seq ? i+j : (thread->rand.Next() % FLAGS_num);\n        char key[100];\n        snprintf(key, sizeof(key), \"%016d\", k);\n        batch.Delete(key);\n        thread->stats.FinishedSingleOp();\n      }\n      s = db_->Write(write_options_, &batch);\n      if (!s.ok()) {\n        fprintf(stderr, \"del error: %s\\n\", s.ToString().c_str());\n        exit(1);\n      }\n    }\n  }\n\n  void DeleteSeq(ThreadState* thread) {\n    DoDelete(thread, true);\n  }\n\n  void DeleteRandom(ThreadState* thread) {\n    DoDelete(thread, false);\n  }\n\n  void ReadWhileWriting(ThreadState* thread) {\n    if (thread->tid > 0) {\n      ReadRandom(thread);\n    } else {\n      // Special thread that keeps writing until other threads are done.\n      RandomGenerator gen;\n      while (true) {\n        {\n          MutexLock l(&thread->shared->mu);\n          if (thread->shared->num_done + 1 >= thread->shared->num_initialized) {\n            // Other threads have finished\n            break;\n          }\n        }\n\n        const int k = thread->rand.Next() % FLAGS_num;\n        char key[100];\n        snprintf(key, sizeof(key), \"%016d\", k);\n        Status s = db_->Put(write_options_, key, gen.Generate(value_size_));\n        if (!s.ok()) {\n          fprintf(stderr, \"put error: %s\\n\", s.ToString().c_str());\n          exit(1);\n        }\n      }\n\n      // Do not count any of the preceding work/delay in stats.\n      thread->stats.Start();\n    }\n  }\n\n  void Compact(ThreadState* thread) {\n    db_->CompactRange(NULL, NULL);\n  }\n\n  void PrintStats(const char* key) {\n    std::string stats;\n    if (!db_->GetProperty(key, &stats)) {\n      stats = \"(failed)\";\n    }\n    fprintf(stdout, \"\\n%s\\n\", stats.c_str());\n  }\n\n  static void WriteToFile(void* arg, const char* buf, int n) {\n    reinterpret_cast<WritableFile*>(arg)->Append(Slice(buf, n));\n  }\n\n  void HeapProfile() {\n    char fname[100];\n    snprintf(fname, sizeof(fname), \"%s/heap-%04d\", FLAGS_db, ++heap_counter_);\n    WritableFile* file;\n    Status s = g_env->NewWritableFile(fname, &file);\n    if (!s.ok()) {\n      fprintf(stderr, \"%s\\n\", s.ToString().c_str());\n      return;\n    }\n    bool ok = port::GetHeapProfile(WriteToFile, file);\n    delete file;\n    if (!ok) {\n      fprintf(stderr, \"heap profiling not supported\\n\");\n      g_env->DeleteFile(fname);\n    }\n  }\n};\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  FLAGS_write_buffer_size = leveldb::Options().write_buffer_size;\n  FLAGS_max_file_size = leveldb::Options().max_file_size;\n  FLAGS_block_size = leveldb::Options().block_size;\n  FLAGS_open_files = leveldb::Options().max_open_files;\n  std::string default_db_path;\n\n  for (int i = 1; i < argc; i++) {\n    double d;\n    int n;\n    char junk;\n    if (leveldb::Slice(argv[i]).starts_with(\"--benchmarks=\")) {\n      FLAGS_benchmarks = argv[i] + strlen(\"--benchmarks=\");\n    } else if (sscanf(argv[i], \"--compression_ratio=%lf%c\", &d, &junk) == 1) {\n      FLAGS_compression_ratio = d;\n    } else if (sscanf(argv[i], \"--histogram=%d%c\", &n, &junk) == 1 &&\n               (n == 0 || n == 1)) {\n      FLAGS_histogram = n;\n    } else if (sscanf(argv[i], \"--use_existing_db=%d%c\", &n, &junk) == 1 &&\n               (n == 0 || n == 1)) {\n      FLAGS_use_existing_db = n;\n    } else if (sscanf(argv[i], \"--reuse_logs=%d%c\", &n, &junk) == 1 &&\n               (n == 0 || n == 1)) {\n      FLAGS_reuse_logs = n;\n    } else if (sscanf(argv[i], \"--num=%d%c\", &n, &junk) == 1) {\n      FLAGS_num = n;\n    } else if (sscanf(argv[i], \"--reads=%d%c\", &n, &junk) == 1) {\n      FLAGS_reads = n;\n    } else if (sscanf(argv[i], \"--threads=%d%c\", &n, &junk) == 1) {\n      FLAGS_threads = n;\n    } else if (sscanf(argv[i], \"--value_size=%d%c\", &n, &junk) == 1) {\n      FLAGS_value_size = n;\n    } else if (sscanf(argv[i], \"--write_buffer_size=%d%c\", &n, &junk) == 1) {\n      FLAGS_write_buffer_size = n;\n    } else if (sscanf(argv[i], \"--max_file_size=%d%c\", &n, &junk) == 1) {\n      FLAGS_max_file_size = n;\n    } else if (sscanf(argv[i], \"--block_size=%d%c\", &n, &junk) == 1) {\n      FLAGS_block_size = n;\n    } else if (sscanf(argv[i], \"--cache_size=%d%c\", &n, &junk) == 1) {\n      FLAGS_cache_size = n;\n    } else if (sscanf(argv[i], \"--bloom_bits=%d%c\", &n, &junk) == 1) {\n      FLAGS_bloom_bits = n;\n    } else if (sscanf(argv[i], \"--open_files=%d%c\", &n, &junk) == 1) {\n      FLAGS_open_files = n;\n    } else if (strncmp(argv[i], \"--db=\", 5) == 0) {\n      FLAGS_db = argv[i] + 5;\n    } else {\n      fprintf(stderr, \"Invalid flag '%s'\\n\", argv[i]);\n      exit(1);\n    }\n  }\n\n  leveldb::g_env = leveldb::Env::Default();\n\n  // Choose a location for the test database if none given with --db=<path>\n  if (FLAGS_db == NULL) {\n      leveldb::g_env->GetTestDirectory(&default_db_path);\n      default_db_path += \"/dbbench\";\n      FLAGS_db = default_db_path.c_str();\n  }\n\n  leveldb::Benchmark benchmark;\n  benchmark.Run();\n  return 0;\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/db/db_impl.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/db_impl.h\"\n\n#include <algorithm>\n#include <set>\n#include <string>\n#include <stdint.h>\n#include <stdio.h>\n#include <vector>\n#include \"db/builder.h\"\n#include \"db/db_iter.h\"\n#include \"db/dbformat.h\"\n#include \"db/filename.h\"\n#include \"db/log_reader.h\"\n#include \"db/log_writer.h\"\n#include \"db/memtable.h\"\n#include \"db/table_cache.h\"\n#include \"db/version_set.h\"\n#include \"db/write_batch_internal.h\"\n#include \"leveldb/db.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/status.h\"\n#include \"leveldb/table.h\"\n#include \"leveldb/table_builder.h\"\n#include \"port/port.h\"\n#include \"table/block.h\"\n#include \"table/merger.h\"\n#include \"table/two_level_iterator.h\"\n#include \"util/coding.h\"\n#include \"util/logging.h\"\n#include \"util/mutexlock.h\"\n\nnamespace leveldb {\n\nconst int kNumNonTableCacheFiles = 10;\n\n// Information kept for every waiting writer\nstruct DBImpl::Writer {\n  Status status;\n  WriteBatch* batch;\n  bool sync;\n  bool done;\n  port::CondVar cv;\n\n  explicit Writer(port::Mutex* mu) : cv(mu) { }\n};\n\nstruct DBImpl::CompactionState {\n  Compaction* const compaction;\n\n  // Sequence numbers < smallest_snapshot are not significant since we\n  // will never have to service a snapshot below smallest_snapshot.\n  // Therefore if we have seen a sequence number S <= smallest_snapshot,\n  // we can drop all entries for the same key with sequence numbers < S.\n  SequenceNumber smallest_snapshot;\n\n  // Files produced by compaction\n  struct Output {\n    uint64_t number;\n    uint64_t file_size;\n    InternalKey smallest, largest;\n  };\n  std::vector<Output> outputs;\n\n  // State kept for output being generated\n  WritableFile* outfile;\n  TableBuilder* builder;\n\n  uint64_t total_bytes;\n\n  Output* current_output() { return &outputs[outputs.size()-1]; }\n\n  explicit CompactionState(Compaction* c)\n      : compaction(c),\n        outfile(NULL),\n        builder(NULL),\n        total_bytes(0) {\n  }\n};\n\n// Fix user-supplied options to be reasonable\ntemplate <class T,class V>\nstatic void ClipToRange(T* ptr, V minvalue, V maxvalue) {\n  if (static_cast<V>(*ptr) > maxvalue) *ptr = maxvalue;\n  if (static_cast<V>(*ptr) < minvalue) *ptr = minvalue;\n}\nOptions SanitizeOptions(const std::string& dbname,\n                        const InternalKeyComparator* icmp,\n                        const InternalFilterPolicy* ipolicy,\n                        const Options& src) {\n  Options result = src;\n  result.comparator = icmp;\n  result.filter_policy = (src.filter_policy != NULL) ? ipolicy : NULL;\n  ClipToRange(&result.max_open_files,    64 + kNumNonTableCacheFiles, 50000);\n  ClipToRange(&result.write_buffer_size, 64<<10,                      1<<30);\n  ClipToRange(&result.max_file_size,     1<<20,                       1<<30);\n  ClipToRange(&result.block_size,        1<<10,                       4<<20);\n  if (result.info_log == NULL) {\n    // Open a log file in the same directory as the db\n    src.env->CreateDir(dbname);  // In case it does not exist\n    src.env->RenameFile(InfoLogFileName(dbname), OldInfoLogFileName(dbname));\n    Status s = src.env->NewLogger(InfoLogFileName(dbname), &result.info_log);\n    if (!s.ok()) {\n      // No place suitable for logging\n      result.info_log = NULL;\n    }\n  }\n  if (result.block_cache == NULL) {\n    result.block_cache = NewLRUCache(8 << 20);\n  }\n  return result;\n}\n\nDBImpl::DBImpl(const Options& raw_options, const std::string& dbname)\n    : env_(raw_options.env),\n      internal_comparator_(raw_options.comparator),\n      internal_filter_policy_(raw_options.filter_policy),\n      options_(SanitizeOptions(dbname, &internal_comparator_,\n                               &internal_filter_policy_, raw_options)),\n      owns_info_log_(options_.info_log != raw_options.info_log),\n      owns_cache_(options_.block_cache != raw_options.block_cache),\n      dbname_(dbname),\n      db_lock_(NULL),\n      shutting_down_(NULL),\n      bg_cv_(&mutex_),\n      mem_(NULL),\n      imm_(NULL),\n      logfile_(NULL),\n      logfile_number_(0),\n      log_(NULL),\n      seed_(0),\n      tmp_batch_(new WriteBatch),\n      bg_compaction_scheduled_(false),\n      manual_compaction_(NULL) {\n  has_imm_.Release_Store(NULL);\n\n  // Reserve ten files or so for other uses and give the rest to TableCache.\n  const int table_cache_size = options_.max_open_files - kNumNonTableCacheFiles;\n  table_cache_ = new TableCache(dbname_, &options_, table_cache_size);\n\n  versions_ = new VersionSet(dbname_, &options_, table_cache_,\n                             &internal_comparator_);\n}\n\nDBImpl::~DBImpl() {\n  // Wait for background work to finish\n  mutex_.Lock();\n  shutting_down_.Release_Store(this);  // Any non-NULL value is ok\n  while (bg_compaction_scheduled_) {\n    bg_cv_.Wait();\n  }\n  mutex_.Unlock();\n\n  if (db_lock_ != NULL) {\n    env_->UnlockFile(db_lock_);\n  }\n\n  delete versions_;\n  if (mem_ != NULL) mem_->Unref();\n  if (imm_ != NULL) imm_->Unref();\n  delete tmp_batch_;\n  delete log_;\n  delete logfile_;\n  delete table_cache_;\n\n  if (owns_info_log_) {\n    delete options_.info_log;\n  }\n  if (owns_cache_) {\n    delete options_.block_cache;\n  }\n}\n\nStatus DBImpl::NewDB() {\n  VersionEdit new_db;\n  new_db.SetComparatorName(user_comparator()->Name());\n  new_db.SetLogNumber(0);\n  new_db.SetNextFile(2);\n  new_db.SetLastSequence(0);\n\n  const std::string manifest = DescriptorFileName(dbname_, 1);\n  WritableFile* file;\n  Status s = env_->NewWritableFile(manifest, &file);\n  if (!s.ok()) {\n    return s;\n  }\n  {\n    log::Writer log(file);\n    std::string record;\n    new_db.EncodeTo(&record);\n    s = log.AddRecord(record);\n    if (s.ok()) {\n      s = file->Close();\n    }\n  }\n  delete file;\n  if (s.ok()) {\n    // Make \"CURRENT\" file that points to the new manifest file.\n    s = SetCurrentFile(env_, dbname_, 1);\n  } else {\n    env_->DeleteFile(manifest);\n  }\n  return s;\n}\n\nvoid DBImpl::MaybeIgnoreError(Status* s) const {\n  if (s->ok() || options_.paranoid_checks) {\n    // No change needed\n  } else {\n    Log(options_.info_log, \"Ignoring error %s\", s->ToString().c_str());\n    *s = Status::OK();\n  }\n}\n\nvoid DBImpl::DeleteObsoleteFiles() {\n  if (!bg_error_.ok()) {\n    // After a background error, we don't know whether a new version may\n    // or may not have been committed, so we cannot safely garbage collect.\n    return;\n  }\n\n  // Make a set of all of the live files\n  std::set<uint64_t> live = pending_outputs_;\n  versions_->AddLiveFiles(&live);\n\n  std::vector<std::string> filenames;\n  env_->GetChildren(dbname_, &filenames); // Ignoring errors on purpose\n  uint64_t number;\n  FileType type;\n  for (size_t i = 0; i < filenames.size(); i++) {\n    if (ParseFileName(filenames[i], &number, &type)) {\n      bool keep = true;\n      switch (type) {\n        case kLogFile:\n          keep = ((number >= versions_->LogNumber()) ||\n                  (number == versions_->PrevLogNumber()));\n          break;\n        case kDescriptorFile:\n          // Keep my manifest file, and any newer incarnations'\n          // (in case there is a race that allows other incarnations)\n          keep = (number >= versions_->ManifestFileNumber());\n          break;\n        case kTableFile:\n          keep = (live.find(number) != live.end());\n          break;\n        case kTempFile:\n          // Any temp files that are currently being written to must\n          // be recorded in pending_outputs_, which is inserted into \"live\"\n          keep = (live.find(number) != live.end());\n          break;\n        case kCurrentFile:\n        case kDBLockFile:\n        case kInfoLogFile:\n          keep = true;\n          break;\n      }\n\n      if (!keep) {\n        if (type == kTableFile) {\n          table_cache_->Evict(number);\n        }\n        Log(options_.info_log, \"Delete type=%d #%lld\\n\",\n            int(type),\n            static_cast<unsigned long long>(number));\n        env_->DeleteFile(dbname_ + \"/\" + filenames[i]);\n      }\n    }\n  }\n}\n\nStatus DBImpl::Recover(VersionEdit* edit, bool *save_manifest) {\n  mutex_.AssertHeld();\n\n  // Ignore error from CreateDir since the creation of the DB is\n  // committed only when the descriptor is created, and this directory\n  // may already exist from a previous failed creation attempt.\n  env_->CreateDir(dbname_);\n  assert(db_lock_ == NULL);\n  Status s = env_->LockFile(LockFileName(dbname_), &db_lock_);\n  if (!s.ok()) {\n    return s;\n  }\n\n  if (!env_->FileExists(CurrentFileName(dbname_))) {\n    if (options_.create_if_missing) {\n      s = NewDB();\n      if (!s.ok()) {\n        return s;\n      }\n    } else {\n      return Status::InvalidArgument(\n          dbname_, \"does not exist (create_if_missing is false)\");\n    }\n  } else {\n    if (options_.error_if_exists) {\n      return Status::InvalidArgument(\n          dbname_, \"exists (error_if_exists is true)\");\n    }\n  }\n\n  s = versions_->Recover(save_manifest);\n  if (!s.ok()) {\n    return s;\n  }\n  SequenceNumber max_sequence(0);\n\n  // Recover from all newer log files than the ones named in the\n  // descriptor (new log files may have been added by the previous\n  // incarnation without registering them in the descriptor).\n  //\n  // Note that PrevLogNumber() is no longer used, but we pay\n  // attention to it in case we are recovering a database\n  // produced by an older version of leveldb.\n  const uint64_t min_log = versions_->LogNumber();\n  const uint64_t prev_log = versions_->PrevLogNumber();\n  std::vector<std::string> filenames;\n  s = env_->GetChildren(dbname_, &filenames);\n  if (!s.ok()) {\n    return s;\n  }\n  std::set<uint64_t> expected;\n  versions_->AddLiveFiles(&expected);\n  uint64_t number;\n  FileType type;\n  std::vector<uint64_t> logs;\n  for (size_t i = 0; i < filenames.size(); i++) {\n    if (ParseFileName(filenames[i], &number, &type)) {\n      expected.erase(number);\n      if (type == kLogFile && ((number >= min_log) || (number == prev_log)))\n        logs.push_back(number);\n    }\n  }\n  if (!expected.empty()) {\n    char buf[50];\n    snprintf(buf, sizeof(buf), \"%d missing files; e.g.\",\n             static_cast<int>(expected.size()));\n    return Status::Corruption(buf, TableFileName(dbname_, *(expected.begin())));\n  }\n\n  // Recover in the order in which the logs were generated\n  std::sort(logs.begin(), logs.end());\n  for (size_t i = 0; i < logs.size(); i++) {\n    s = RecoverLogFile(logs[i], (i == logs.size() - 1), save_manifest, edit,\n                       &max_sequence);\n    if (!s.ok()) {\n      return s;\n    }\n\n    // The previous incarnation may not have written any MANIFEST\n    // records after allocating this log number.  So we manually\n    // update the file number allocation counter in VersionSet.\n    versions_->MarkFileNumberUsed(logs[i]);\n  }\n\n  if (versions_->LastSequence() < max_sequence) {\n    versions_->SetLastSequence(max_sequence);\n  }\n\n  return Status::OK();\n}\n\nStatus DBImpl::RecoverLogFile(uint64_t log_number, bool last_log,\n                              bool* save_manifest, VersionEdit* edit,\n                              SequenceNumber* max_sequence) {\n  struct LogReporter : public log::Reader::Reporter {\n    Env* env;\n    Logger* info_log;\n    const char* fname;\n    Status* status;  // NULL if options_.paranoid_checks==false\n    virtual void Corruption(size_t bytes, const Status& s) {\n      Log(info_log, \"%s%s: dropping %d bytes; %s\",\n          (this->status == NULL ? \"(ignoring error) \" : \"\"),\n          fname, static_cast<int>(bytes), s.ToString().c_str());\n      if (this->status != NULL && this->status->ok()) *this->status = s;\n    }\n  };\n\n  mutex_.AssertHeld();\n\n  // Open the log file\n  std::string fname = LogFileName(dbname_, log_number);\n  SequentialFile* file;\n  Status status = env_->NewSequentialFile(fname, &file);\n  if (!status.ok()) {\n    MaybeIgnoreError(&status);\n    return status;\n  }\n\n  // Create the log reader.\n  LogReporter reporter;\n  reporter.env = env_;\n  reporter.info_log = options_.info_log;\n  reporter.fname = fname.c_str();\n  reporter.status = (options_.paranoid_checks ? &status : NULL);\n  // We intentionally make log::Reader do checksumming even if\n  // paranoid_checks==false so that corruptions cause entire commits\n  // to be skipped instead of propagating bad information (like overly\n  // large sequence numbers).\n  log::Reader reader(file, &reporter, true/*checksum*/,\n                     0/*initial_offset*/);\n  Log(options_.info_log, \"Recovering log #%llu\",\n      (unsigned long long) log_number);\n\n  // Read all the records and add to a memtable\n  std::string scratch;\n  Slice record;\n  WriteBatch batch;\n  int compactions = 0;\n  MemTable* mem = NULL;\n  while (reader.ReadRecord(&record, &scratch) &&\n         status.ok()) {\n    if (record.size() < 12) {\n      reporter.Corruption(\n          record.size(), Status::Corruption(\"log record too small\"));\n      continue;\n    }\n    WriteBatchInternal::SetContents(&batch, record);\n\n    if (mem == NULL) {\n      mem = new MemTable(internal_comparator_);\n      mem->Ref();\n    }\n    status = WriteBatchInternal::InsertInto(&batch, mem);\n    MaybeIgnoreError(&status);\n    if (!status.ok()) {\n      break;\n    }\n    const SequenceNumber last_seq =\n        WriteBatchInternal::Sequence(&batch) +\n        WriteBatchInternal::Count(&batch) - 1;\n    if (last_seq > *max_sequence) {\n      *max_sequence = last_seq;\n    }\n\n    if (mem->ApproximateMemoryUsage() > options_.write_buffer_size) {\n      compactions++;\n      *save_manifest = true;\n      status = WriteLevel0Table(mem, edit, NULL);\n      mem->Unref();\n      mem = NULL;\n      if (!status.ok()) {\n        // Reflect errors immediately so that conditions like full\n        // file-systems cause the DB::Open() to fail.\n        break;\n      }\n    }\n  }\n\n  delete file;\n\n  // See if we should keep reusing the last log file.\n  if (status.ok() && options_.reuse_logs && last_log && compactions == 0) {\n    assert(logfile_ == NULL);\n    assert(log_ == NULL);\n    assert(mem_ == NULL);\n    uint64_t lfile_size;\n    if (env_->GetFileSize(fname, &lfile_size).ok() &&\n        env_->NewAppendableFile(fname, &logfile_).ok()) {\n      Log(options_.info_log, \"Reusing old log %s \\n\", fname.c_str());\n      log_ = new log::Writer(logfile_, lfile_size);\n      logfile_number_ = log_number;\n      if (mem != NULL) {\n        mem_ = mem;\n        mem = NULL;\n      } else {\n        // mem can be NULL if lognum exists but was empty.\n        mem_ = new MemTable(internal_comparator_);\n        mem_->Ref();\n      }\n    }\n  }\n\n  if (mem != NULL) {\n    // mem did not get reused; compact it.\n    if (status.ok()) {\n      *save_manifest = true;\n      status = WriteLevel0Table(mem, edit, NULL);\n    }\n    mem->Unref();\n  }\n\n  return status;\n}\n\nStatus DBImpl::WriteLevel0Table(MemTable* mem, VersionEdit* edit,\n                                Version* base) {\n  mutex_.AssertHeld();\n  const uint64_t start_micros = env_->NowMicros();\n  FileMetaData meta;\n  meta.number = versions_->NewFileNumber();\n  pending_outputs_.insert(meta.number);\n  Iterator* iter = mem->NewIterator();\n  Log(options_.info_log, \"Level-0 table #%llu: started\",\n      (unsigned long long) meta.number);\n\n  Status s;\n  {\n    mutex_.Unlock();\n    s = BuildTable(dbname_, env_, options_, table_cache_, iter, &meta);\n    mutex_.Lock();\n  }\n\n  Log(options_.info_log, \"Level-0 table #%llu: %lld bytes %s\",\n      (unsigned long long) meta.number,\n      (unsigned long long) meta.file_size,\n      s.ToString().c_str());\n  delete iter;\n  pending_outputs_.erase(meta.number);\n\n\n  // Note that if file_size is zero, the file has been deleted and\n  // should not be added to the manifest.\n  int level = 0;\n  if (s.ok() && meta.file_size > 0) {\n    const Slice min_user_key = meta.smallest.user_key();\n    const Slice max_user_key = meta.largest.user_key();\n    if (base != NULL) {\n      level = base->PickLevelForMemTableOutput(min_user_key, max_user_key);\n    }\n    edit->AddFile(level, meta.number, meta.file_size,\n                  meta.smallest, meta.largest);\n  }\n\n  CompactionStats stats;\n  stats.micros = env_->NowMicros() - start_micros;\n  stats.bytes_written = meta.file_size;\n  stats_[level].Add(stats);\n  return s;\n}\n\nvoid DBImpl::CompactMemTable() {\n  mutex_.AssertHeld();\n  assert(imm_ != NULL);\n\n  // Save the contents of the memtable as a new Table\n  VersionEdit edit;\n  Version* base = versions_->current();\n  base->Ref();\n  Status s = WriteLevel0Table(imm_, &edit, base);\n  base->Unref();\n\n  if (s.ok() && shutting_down_.Acquire_Load()) {\n    s = Status::IOError(\"Deleting DB during memtable compaction\");\n  }\n\n  // Replace immutable memtable with the generated Table\n  if (s.ok()) {\n    edit.SetPrevLogNumber(0);\n    edit.SetLogNumber(logfile_number_);  // Earlier logs no longer needed\n    s = versions_->LogAndApply(&edit, &mutex_);\n  }\n\n  if (s.ok()) {\n    // Commit to the new state\n    imm_->Unref();\n    imm_ = NULL;\n    has_imm_.Release_Store(NULL);\n    DeleteObsoleteFiles();\n  } else {\n    RecordBackgroundError(s);\n  }\n}\n\nvoid DBImpl::CompactRange(const Slice* begin, const Slice* end) {\n  int max_level_with_files = 1;\n  {\n    MutexLock l(&mutex_);\n    Version* base = versions_->current();\n    for (int level = 1; level < config::kNumLevels; level++) {\n      if (base->OverlapInLevel(level, begin, end)) {\n        max_level_with_files = level;\n      }\n    }\n  }\n  TEST_CompactMemTable(); // TODO(sanjay): Skip if memtable does not overlap\n  for (int level = 0; level < max_level_with_files; level++) {\n    TEST_CompactRange(level, begin, end);\n  }\n}\n\nvoid DBImpl::TEST_CompactRange(int level, const Slice* begin,const Slice* end) {\n  assert(level >= 0);\n  assert(level + 1 < config::kNumLevels);\n\n  InternalKey begin_storage, end_storage;\n\n  ManualCompaction manual;\n  manual.level = level;\n  manual.done = false;\n  if (begin == NULL) {\n    manual.begin = NULL;\n  } else {\n    begin_storage = InternalKey(*begin, kMaxSequenceNumber, kValueTypeForSeek);\n    manual.begin = &begin_storage;\n  }\n  if (end == NULL) {\n    manual.end = NULL;\n  } else {\n    end_storage = InternalKey(*end, 0, static_cast<ValueType>(0));\n    manual.end = &end_storage;\n  }\n\n  MutexLock l(&mutex_);\n  while (!manual.done && !shutting_down_.Acquire_Load() && bg_error_.ok()) {\n    if (manual_compaction_ == NULL) {  // Idle\n      manual_compaction_ = &manual;\n      MaybeScheduleCompaction();\n    } else {  // Running either my compaction or another compaction.\n      bg_cv_.Wait();\n    }\n  }\n  if (manual_compaction_ == &manual) {\n    // Cancel my manual compaction since we aborted early for some reason.\n    manual_compaction_ = NULL;\n  }\n}\n\nStatus DBImpl::TEST_CompactMemTable() {\n  // NULL batch means just wait for earlier writes to be done\n  Status s = Write(WriteOptions(), NULL);\n  if (s.ok()) {\n    // Wait until the compaction completes\n    MutexLock l(&mutex_);\n    while (imm_ != NULL && bg_error_.ok()) {\n      bg_cv_.Wait();\n    }\n    if (imm_ != NULL) {\n      s = bg_error_;\n    }\n  }\n  return s;\n}\n\nvoid DBImpl::RecordBackgroundError(const Status& s) {\n  mutex_.AssertHeld();\n  if (bg_error_.ok()) {\n    bg_error_ = s;\n    bg_cv_.SignalAll();\n  }\n}\n\nvoid DBImpl::MaybeScheduleCompaction() {\n  mutex_.AssertHeld();\n  if (bg_compaction_scheduled_) {\n    // Already scheduled\n  } else if (shutting_down_.Acquire_Load()) {\n    // DB is being deleted; no more background compactions\n  } else if (!bg_error_.ok()) {\n    // Already got an error; no more changes\n  } else if (imm_ == NULL &&\n             manual_compaction_ == NULL &&\n             !versions_->NeedsCompaction()) {\n    // No work to be done\n  } else {\n    bg_compaction_scheduled_ = true;\n    env_->Schedule(&DBImpl::BGWork, this);\n  }\n}\n\nvoid DBImpl::BGWork(void* db) {\n  reinterpret_cast<DBImpl*>(db)->BackgroundCall();\n}\n\nvoid DBImpl::BackgroundCall() {\n  MutexLock l(&mutex_);\n  assert(bg_compaction_scheduled_);\n  if (shutting_down_.Acquire_Load()) {\n    // No more background work when shutting down.\n  } else if (!bg_error_.ok()) {\n    // No more background work after a background error.\n  } else {\n    BackgroundCompaction();\n  }\n\n  bg_compaction_scheduled_ = false;\n\n  // Previous compaction may have produced too many files in a level,\n  // so reschedule another compaction if needed.\n  MaybeScheduleCompaction();\n  bg_cv_.SignalAll();\n}\n\nvoid DBImpl::BackgroundCompaction() {\n  mutex_.AssertHeld();\n\n  if (imm_ != NULL) {\n    CompactMemTable();\n    return;\n  }\n\n  Compaction* c;\n  bool is_manual = (manual_compaction_ != NULL);\n  InternalKey manual_end;\n  if (is_manual) {\n    ManualCompaction* m = manual_compaction_;\n    c = versions_->CompactRange(m->level, m->begin, m->end);\n    m->done = (c == NULL);\n    if (c != NULL) {\n      manual_end = c->input(0, c->num_input_files(0) - 1)->largest;\n    }\n    Log(options_.info_log,\n        \"Manual compaction at level-%d from %s .. %s; will stop at %s\\n\",\n        m->level,\n        (m->begin ? m->begin->DebugString().c_str() : \"(begin)\"),\n        (m->end ? m->end->DebugString().c_str() : \"(end)\"),\n        (m->done ? \"(end)\" : manual_end.DebugString().c_str()));\n  } else {\n    c = versions_->PickCompaction();\n  }\n\n  Status status;\n  if (c == NULL) {\n    // Nothing to do\n  } else if (!is_manual && c->IsTrivialMove()) {\n    // Move file to next level\n    assert(c->num_input_files(0) == 1);\n    FileMetaData* f = c->input(0, 0);\n    c->edit()->DeleteFile(c->level(), f->number);\n    c->edit()->AddFile(c->level() + 1, f->number, f->file_size,\n                       f->smallest, f->largest);\n    status = versions_->LogAndApply(c->edit(), &mutex_);\n    if (!status.ok()) {\n      RecordBackgroundError(status);\n    }\n    VersionSet::LevelSummaryStorage tmp;\n    Log(options_.info_log, \"Moved #%lld to level-%d %lld bytes %s: %s\\n\",\n        static_cast<unsigned long long>(f->number),\n        c->level() + 1,\n        static_cast<unsigned long long>(f->file_size),\n        status.ToString().c_str(),\n        versions_->LevelSummary(&tmp));\n  } else {\n    CompactionState* compact = new CompactionState(c);\n    status = DoCompactionWork(compact);\n    if (!status.ok()) {\n      RecordBackgroundError(status);\n    }\n    CleanupCompaction(compact);\n    c->ReleaseInputs();\n    DeleteObsoleteFiles();\n  }\n  delete c;\n\n  if (status.ok()) {\n    // Done\n  } else if (shutting_down_.Acquire_Load()) {\n    // Ignore compaction errors found during shutting down\n  } else {\n    Log(options_.info_log,\n        \"Compaction error: %s\", status.ToString().c_str());\n  }\n\n  if (is_manual) {\n    ManualCompaction* m = manual_compaction_;\n    if (!status.ok()) {\n      m->done = true;\n    }\n    if (!m->done) {\n      // We only compacted part of the requested range.  Update *m\n      // to the range that is left to be compacted.\n      m->tmp_storage = manual_end;\n      m->begin = &m->tmp_storage;\n    }\n    manual_compaction_ = NULL;\n  }\n}\n\nvoid DBImpl::CleanupCompaction(CompactionState* compact) {\n  mutex_.AssertHeld();\n  if (compact->builder != NULL) {\n    // May happen if we get a shutdown call in the middle of compaction\n    compact->builder->Abandon();\n    delete compact->builder;\n  } else {\n    assert(compact->outfile == NULL);\n  }\n  delete compact->outfile;\n  for (size_t i = 0; i < compact->outputs.size(); i++) {\n    const CompactionState::Output& out = compact->outputs[i];\n    pending_outputs_.erase(out.number);\n  }\n  delete compact;\n}\n\nStatus DBImpl::OpenCompactionOutputFile(CompactionState* compact) {\n  assert(compact != NULL);\n  assert(compact->builder == NULL);\n  uint64_t file_number;\n  {\n    mutex_.Lock();\n    file_number = versions_->NewFileNumber();\n    pending_outputs_.insert(file_number);\n    CompactionState::Output out;\n    out.number = file_number;\n    out.smallest.Clear();\n    out.largest.Clear();\n    compact->outputs.push_back(out);\n    mutex_.Unlock();\n  }\n\n  // Make the output file\n  std::string fname = TableFileName(dbname_, file_number);\n  Status s = env_->NewWritableFile(fname, &compact->outfile);\n  if (s.ok()) {\n    compact->builder = new TableBuilder(options_, compact->outfile);\n  }\n  return s;\n}\n\nStatus DBImpl::FinishCompactionOutputFile(CompactionState* compact,\n                                          Iterator* input) {\n  assert(compact != NULL);\n  assert(compact->outfile != NULL);\n  assert(compact->builder != NULL);\n\n  const uint64_t output_number = compact->current_output()->number;\n  assert(output_number != 0);\n\n  // Check for iterator errors\n  Status s = input->status();\n  const uint64_t current_entries = compact->builder->NumEntries();\n  if (s.ok()) {\n    s = compact->builder->Finish();\n  } else {\n    compact->builder->Abandon();\n  }\n  const uint64_t current_bytes = compact->builder->FileSize();\n  compact->current_output()->file_size = current_bytes;\n  compact->total_bytes += current_bytes;\n  delete compact->builder;\n  compact->builder = NULL;\n\n  // Finish and check for file errors\n  if (s.ok()) {\n    s = compact->outfile->Sync();\n  }\n  if (s.ok()) {\n    s = compact->outfile->Close();\n  }\n  delete compact->outfile;\n  compact->outfile = NULL;\n\n  if (s.ok() && current_entries > 0) {\n    // Verify that the table is usable\n    Iterator* iter = table_cache_->NewIterator(ReadOptions(),\n                                               output_number,\n                                               current_bytes);\n    s = iter->status();\n    delete iter;\n    if (s.ok()) {\n      Log(options_.info_log,\n          \"Generated table #%llu@%d: %lld keys, %lld bytes\",\n          (unsigned long long) output_number,\n          compact->compaction->level(),\n          (unsigned long long) current_entries,\n          (unsigned long long) current_bytes);\n\n      // Writing current_bytes to disk is considered no expense(cost no time),\n      // so we calculate how many IOs will match the compaction speed,\n      // then sleep 1s/IOs\n      // Added by me@ideawu.com\n      int mbs = current_bytes/1024/1024;\n      if(options_.compaction_speed > 0 && mbs > 1){\n        int count = options_.compaction_speed/mbs;\n        if(count < 1){\n          count = 1;\n        }\n        int pause = 1000 * 1000 / count;\n        Log(options_.info_log, \"compaction_speed: %d MB/s, pause: %d us\",\n          options_.compaction_speed, pause);\n        env_->SleepForMicroseconds(pause);\n      }\n    }\n  }\n  return s;\n}\n\n\nStatus DBImpl::InstallCompactionResults(CompactionState* compact) {\n  mutex_.AssertHeld();\n  Log(options_.info_log,  \"Compacted %d@%d + %d@%d files => %lld bytes\",\n      compact->compaction->num_input_files(0),\n      compact->compaction->level(),\n      compact->compaction->num_input_files(1),\n      compact->compaction->level() + 1,\n      static_cast<long long>(compact->total_bytes));\n\n  // Add compaction outputs\n  compact->compaction->AddInputDeletions(compact->compaction->edit());\n  const int level = compact->compaction->level();\n  for (size_t i = 0; i < compact->outputs.size(); i++) {\n    const CompactionState::Output& out = compact->outputs[i];\n    compact->compaction->edit()->AddFile(\n        level + 1,\n        out.number, out.file_size, out.smallest, out.largest);\n  }\n  return versions_->LogAndApply(compact->compaction->edit(), &mutex_);\n}\n\nStatus DBImpl::DoCompactionWork(CompactionState* compact) {\n  const uint64_t start_micros = env_->NowMicros();\n  int64_t imm_micros = 0;  // Micros spent doing imm_ compactions\n\n  Log(options_.info_log,  \"Compacting %d@%d + %d@%d files\",\n      compact->compaction->num_input_files(0),\n      compact->compaction->level(),\n      compact->compaction->num_input_files(1),\n      compact->compaction->level() + 1);\n\n  assert(versions_->NumLevelFiles(compact->compaction->level()) > 0);\n  assert(compact->builder == NULL);\n  assert(compact->outfile == NULL);\n  if (snapshots_.empty()) {\n    compact->smallest_snapshot = versions_->LastSequence();\n  } else {\n    compact->smallest_snapshot = snapshots_.oldest()->number_;\n  }\n\n  // Release mutex while we're actually doing the compaction work\n  mutex_.Unlock();\n\n  Iterator* input = versions_->MakeInputIterator(compact->compaction);\n  input->SeekToFirst();\n  Status status;\n  ParsedInternalKey ikey;\n  std::string current_user_key;\n  bool has_current_user_key = false;\n  SequenceNumber last_sequence_for_key = kMaxSequenceNumber;\n  for (; input->Valid() && !shutting_down_.Acquire_Load(); ) {\n    // Prioritize immutable compaction work\n    if (has_imm_.NoBarrier_Load() != NULL) {\n      const uint64_t imm_start = env_->NowMicros();\n      mutex_.Lock();\n      if (imm_ != NULL) {\n        CompactMemTable();\n        bg_cv_.SignalAll();  // Wakeup MakeRoomForWrite() if necessary\n      }\n      mutex_.Unlock();\n      imm_micros += (env_->NowMicros() - imm_start);\n    }\n\n    Slice key = input->key();\n    if (compact->compaction->ShouldStopBefore(key) &&\n        compact->builder != NULL) {\n      status = FinishCompactionOutputFile(compact, input);\n      if (!status.ok()) {\n        break;\n      }\n    }\n\n    // Handle key/value, add to state, etc.\n    bool drop = false;\n    if (!ParseInternalKey(key, &ikey)) {\n      // Do not hide error keys\n      current_user_key.clear();\n      has_current_user_key = false;\n      last_sequence_for_key = kMaxSequenceNumber;\n    } else {\n      if (!has_current_user_key ||\n          user_comparator()->Compare(ikey.user_key,\n                                     Slice(current_user_key)) != 0) {\n        // First occurrence of this user key\n        current_user_key.assign(ikey.user_key.data(), ikey.user_key.size());\n        has_current_user_key = true;\n        last_sequence_for_key = kMaxSequenceNumber;\n      }\n\n      if (last_sequence_for_key <= compact->smallest_snapshot) {\n        // Hidden by an newer entry for same user key\n        drop = true;    // (A)\n      } else if (ikey.type == kTypeDeletion &&\n                 ikey.sequence <= compact->smallest_snapshot &&\n                 compact->compaction->IsBaseLevelForKey(ikey.user_key)) {\n        // For this user key:\n        // (1) there is no data in higher levels\n        // (2) data in lower levels will have larger sequence numbers\n        // (3) data in layers that are being compacted here and have\n        //     smaller sequence numbers will be dropped in the next\n        //     few iterations of this loop (by rule (A) above).\n        // Therefore this deletion marker is obsolete and can be dropped.\n        drop = true;\n      }\n\n      last_sequence_for_key = ikey.sequence;\n    }\n#if 0\n    Log(options_.info_log,\n        \"  Compact: %s, seq %d, type: %d %d, drop: %d, is_base: %d, \"\n        \"%d smallest_snapshot: %d\",\n        ikey.user_key.ToString().c_str(),\n        (int)ikey.sequence, ikey.type, kTypeValue, drop,\n        compact->compaction->IsBaseLevelForKey(ikey.user_key),\n        (int)last_sequence_for_key, (int)compact->smallest_snapshot);\n#endif\n\n    if (!drop) {\n      // Open output file if necessary\n      if (compact->builder == NULL) {\n        status = OpenCompactionOutputFile(compact);\n        if (!status.ok()) {\n          break;\n        }\n      }\n      if (compact->builder->NumEntries() == 0) {\n        compact->current_output()->smallest.DecodeFrom(key);\n      }\n      compact->current_output()->largest.DecodeFrom(key);\n      compact->builder->Add(key, input->value());\n\n      // Close output file if it is big enough\n      if (compact->builder->FileSize() >=\n          compact->compaction->MaxOutputFileSize()) {\n        status = FinishCompactionOutputFile(compact, input);\n        if (!status.ok()) {\n          break;\n        }\n      }\n    }\n\n    input->Next();\n  }\n\n  if (status.ok() && shutting_down_.Acquire_Load()) {\n    status = Status::IOError(\"Deleting DB during compaction\");\n  }\n  if (status.ok() && compact->builder != NULL) {\n    status = FinishCompactionOutputFile(compact, input);\n  }\n  if (status.ok()) {\n    status = input->status();\n  }\n  delete input;\n  input = NULL;\n\n  CompactionStats stats;\n  stats.micros = env_->NowMicros() - start_micros - imm_micros;\n  for (int which = 0; which < 2; which++) {\n    for (int i = 0; i < compact->compaction->num_input_files(which); i++) {\n      stats.bytes_read += compact->compaction->input(which, i)->file_size;\n    }\n  }\n  for (size_t i = 0; i < compact->outputs.size(); i++) {\n    stats.bytes_written += compact->outputs[i].file_size;\n  }\n\n  mutex_.Lock();\n  stats_[compact->compaction->level() + 1].Add(stats);\n\n  if (status.ok()) {\n    status = InstallCompactionResults(compact);\n  }\n  if (!status.ok()) {\n    RecordBackgroundError(status);\n  }\n  VersionSet::LevelSummaryStorage tmp;\n  Log(options_.info_log,\n      \"compacted to: %s\", versions_->LevelSummary(&tmp));\n  return status;\n}\n\nnamespace {\nstruct IterState {\n  port::Mutex* mu;\n  Version* version;\n  MemTable* mem;\n  MemTable* imm;\n};\n\nstatic void CleanupIteratorState(void* arg1, void* arg2) {\n  IterState* state = reinterpret_cast<IterState*>(arg1);\n  state->mu->Lock();\n  state->mem->Unref();\n  if (state->imm != NULL) state->imm->Unref();\n  state->version->Unref();\n  state->mu->Unlock();\n  delete state;\n}\n}  // namespace\n\nIterator* DBImpl::NewInternalIterator(const ReadOptions& options,\n                                      SequenceNumber* latest_snapshot,\n                                      uint32_t* seed) {\n  IterState* cleanup = new IterState;\n  mutex_.Lock();\n  *latest_snapshot = versions_->LastSequence();\n\n  // Collect together all needed child iterators\n  std::vector<Iterator*> list;\n  list.push_back(mem_->NewIterator());\n  mem_->Ref();\n  if (imm_ != NULL) {\n    list.push_back(imm_->NewIterator());\n    imm_->Ref();\n  }\n  versions_->current()->AddIterators(options, &list);\n  Iterator* internal_iter =\n      NewMergingIterator(&internal_comparator_, &list[0], list.size());\n  versions_->current()->Ref();\n\n  cleanup->mu = &mutex_;\n  cleanup->mem = mem_;\n  cleanup->imm = imm_;\n  cleanup->version = versions_->current();\n  internal_iter->RegisterCleanup(CleanupIteratorState, cleanup, NULL);\n\n  *seed = ++seed_;\n  mutex_.Unlock();\n  return internal_iter;\n}\n\nIterator* DBImpl::TEST_NewInternalIterator() {\n  SequenceNumber ignored;\n  uint32_t ignored_seed;\n  return NewInternalIterator(ReadOptions(), &ignored, &ignored_seed);\n}\n\nint64_t DBImpl::TEST_MaxNextLevelOverlappingBytes() {\n  MutexLock l(&mutex_);\n  return versions_->MaxNextLevelOverlappingBytes();\n}\n\nStatus DBImpl::Get(const ReadOptions& options,\n                   const Slice& key,\n                   std::string* value) {\n  Status s;\n  MutexLock l(&mutex_);\n  SequenceNumber snapshot;\n  if (options.snapshot != NULL) {\n    snapshot = reinterpret_cast<const SnapshotImpl*>(options.snapshot)->number_;\n  } else {\n    snapshot = versions_->LastSequence();\n  }\n\n  MemTable* mem = mem_;\n  MemTable* imm = imm_;\n  Version* current = versions_->current();\n  mem->Ref();\n  if (imm != NULL) imm->Ref();\n  current->Ref();\n\n  bool have_stat_update = false;\n  Version::GetStats stats;\n\n  // Unlock while reading from files and memtables\n  {\n    mutex_.Unlock();\n    // First look in the memtable, then in the immutable memtable (if any).\n    LookupKey lkey(key, snapshot);\n    if (mem->Get(lkey, value, &s)) {\n      // Done\n    } else if (imm != NULL && imm->Get(lkey, value, &s)) {\n      // Done\n    } else {\n      s = current->Get(options, lkey, value, &stats);\n      have_stat_update = true;\n    }\n    mutex_.Lock();\n  }\n\n  if (have_stat_update && current->UpdateStats(stats)) {\n    MaybeScheduleCompaction();\n  }\n  mem->Unref();\n  if (imm != NULL) imm->Unref();\n  current->Unref();\n  return s;\n}\n\nIterator* DBImpl::NewIterator(const ReadOptions& options) {\n  SequenceNumber latest_snapshot;\n  uint32_t seed;\n  Iterator* iter = NewInternalIterator(options, &latest_snapshot, &seed);\n  return NewDBIterator(\n      this, user_comparator(), iter,\n      (options.snapshot != NULL\n       ? reinterpret_cast<const SnapshotImpl*>(options.snapshot)->number_\n       : latest_snapshot),\n      seed);\n}\n\nvoid DBImpl::RecordReadSample(Slice key) {\n  MutexLock l(&mutex_);\n  if (versions_->current()->RecordReadSample(key)) {\n    MaybeScheduleCompaction();\n  }\n}\n\nconst Snapshot* DBImpl::GetSnapshot() {\n  MutexLock l(&mutex_);\n  return snapshots_.New(versions_->LastSequence());\n}\n\nvoid DBImpl::ReleaseSnapshot(const Snapshot* s) {\n  MutexLock l(&mutex_);\n  snapshots_.Delete(reinterpret_cast<const SnapshotImpl*>(s));\n}\n\n// Convenience methods\nStatus DBImpl::Put(const WriteOptions& o, const Slice& key, const Slice& val) {\n  return DB::Put(o, key, val);\n}\n\nStatus DBImpl::Delete(const WriteOptions& options, const Slice& key) {\n  return DB::Delete(options, key);\n}\n\nStatus DBImpl::Write(const WriteOptions& options, WriteBatch* my_batch) {\n  Writer w(&mutex_);\n  w.batch = my_batch;\n  w.sync = options.sync;\n  w.done = false;\n\n  MutexLock l(&mutex_);\n  writers_.push_back(&w);\n  while (!w.done && &w != writers_.front()) {\n    w.cv.Wait();\n  }\n  if (w.done) {\n    return w.status;\n  }\n\n  // May temporarily unlock and wait.\n  Status status = MakeRoomForWrite(my_batch == NULL);\n  uint64_t last_sequence = versions_->LastSequence();\n  Writer* last_writer = &w;\n  if (status.ok() && my_batch != NULL) {  // NULL batch is for compactions\n    WriteBatch* updates = BuildBatchGroup(&last_writer);\n    WriteBatchInternal::SetSequence(updates, last_sequence + 1);\n    last_sequence += WriteBatchInternal::Count(updates);\n\n    // Add to log and apply to memtable.  We can release the lock\n    // during this phase since &w is currently responsible for logging\n    // and protects against concurrent loggers and concurrent writes\n    // into mem_.\n    {\n      mutex_.Unlock();\n      status = log_->AddRecord(WriteBatchInternal::Contents(updates));\n      bool sync_error = false;\n      if (status.ok() && options.sync) {\n        status = logfile_->Sync();\n        if (!status.ok()) {\n          sync_error = true;\n        }\n      }\n      if (status.ok()) {\n        status = WriteBatchInternal::InsertInto(updates, mem_);\n      }\n      mutex_.Lock();\n      if (sync_error) {\n        // The state of the log file is indeterminate: the log record we\n        // just added may or may not show up when the DB is re-opened.\n        // So we force the DB into a mode where all future writes fail.\n        RecordBackgroundError(status);\n      }\n    }\n    if (updates == tmp_batch_) tmp_batch_->Clear();\n\n    versions_->SetLastSequence(last_sequence);\n  }\n\n  while (true) {\n    Writer* ready = writers_.front();\n    writers_.pop_front();\n    if (ready != &w) {\n      ready->status = status;\n      ready->done = true;\n      ready->cv.Signal();\n    }\n    if (ready == last_writer) break;\n  }\n\n  // Notify new head of write queue\n  if (!writers_.empty()) {\n    writers_.front()->cv.Signal();\n  }\n\n  return status;\n}\n\n// REQUIRES: Writer list must be non-empty\n// REQUIRES: First writer must have a non-NULL batch\nWriteBatch* DBImpl::BuildBatchGroup(Writer** last_writer) {\n  assert(!writers_.empty());\n  Writer* first = writers_.front();\n  WriteBatch* result = first->batch;\n  assert(result != NULL);\n\n  size_t size = WriteBatchInternal::ByteSize(first->batch);\n\n  // Allow the group to grow up to a maximum size, but if the\n  // original write is small, limit the growth so we do not slow\n  // down the small write too much.\n  size_t max_size = 1 << 20;\n  if (size <= (128<<10)) {\n    max_size = size + (128<<10);\n  }\n\n  *last_writer = first;\n  std::deque<Writer*>::iterator iter = writers_.begin();\n  ++iter;  // Advance past \"first\"\n  for (; iter != writers_.end(); ++iter) {\n    Writer* w = *iter;\n    if (w->sync && !first->sync) {\n      // Do not include a sync write into a batch handled by a non-sync write.\n      break;\n    }\n\n    if (w->batch != NULL) {\n      size += WriteBatchInternal::ByteSize(w->batch);\n      if (size > max_size) {\n        // Do not make batch too big\n        break;\n      }\n\n      // Append to *result\n      if (result == first->batch) {\n        // Switch to temporary batch instead of disturbing caller's batch\n        result = tmp_batch_;\n        assert(WriteBatchInternal::Count(result) == 0);\n        WriteBatchInternal::Append(result, first->batch);\n      }\n      WriteBatchInternal::Append(result, w->batch);\n    }\n    *last_writer = w;\n  }\n  return result;\n}\n\n// REQUIRES: mutex_ is held\n// REQUIRES: this thread is currently at the front of the writer queue\nStatus DBImpl::MakeRoomForWrite(bool force) {\n  mutex_.AssertHeld();\n  assert(!writers_.empty());\n  bool allow_delay = !force;\n  Status s;\n  while (true) {\n    if (!bg_error_.ok()) {\n      // Yield previous error\n      s = bg_error_;\n      break;\n    } else if (\n        allow_delay &&\n        versions_->NumLevelFiles(0) >= config::kL0_SlowdownWritesTrigger) {\n      // We are getting close to hitting a hard limit on the number of\n      // L0 files.  Rather than delaying a single write by several\n      // seconds when we hit the hard limit, start delaying each\n      // individual write by 1ms to reduce latency variance.  Also,\n      // this delay hands over some CPU to the compaction thread in\n      // case it is sharing the same core as the writer.\n      mutex_.Unlock();\n      env_->SleepForMicroseconds(1000);\n      allow_delay = false;  // Do not delay a single write more than once\n      mutex_.Lock();\n    } else if (!force &&\n               (mem_->ApproximateMemoryUsage() <= options_.write_buffer_size)) {\n      // There is room in current memtable\n      break;\n    } else if (imm_ != NULL) {\n      // We have filled up the current memtable, but the previous\n      // one is still being compacted, so we wait.\n      Log(options_.info_log, \"Current memtable full; waiting...\\n\");\n      bg_cv_.Wait();\n    } else if (versions_->NumLevelFiles(0) >= config::kL0_StopWritesTrigger) {\n      // There are too many level-0 files.\n      Log(options_.info_log, \"Too many L0 files; waiting...\\n\");\n      bg_cv_.Wait();\n    } else {\n      // Attempt to switch to a new memtable and trigger compaction of old\n      assert(versions_->PrevLogNumber() == 0);\n      uint64_t new_log_number = versions_->NewFileNumber();\n      WritableFile* lfile = NULL;\n      s = env_->NewWritableFile(LogFileName(dbname_, new_log_number), &lfile);\n      if (!s.ok()) {\n        // Avoid chewing through file number space in a tight loop.\n        versions_->ReuseFileNumber(new_log_number);\n        break;\n      }\n      delete log_;\n      delete logfile_;\n      logfile_ = lfile;\n      logfile_number_ = new_log_number;\n      log_ = new log::Writer(lfile);\n      imm_ = mem_;\n      has_imm_.Release_Store(imm_);\n      mem_ = new MemTable(internal_comparator_);\n      mem_->Ref();\n      force = false;   // Do not force another compaction if have room\n      MaybeScheduleCompaction();\n    }\n  }\n  return s;\n}\n\nbool DBImpl::GetProperty(const Slice& property, std::string* value) {\n  value->clear();\n\n  MutexLock l(&mutex_);\n  Slice in = property;\n  Slice prefix(\"leveldb.\");\n  if (!in.starts_with(prefix)) return false;\n  in.remove_prefix(prefix.size());\n\n  if (in.starts_with(\"num-files-at-level\")) {\n    in.remove_prefix(strlen(\"num-files-at-level\"));\n    uint64_t level;\n    bool ok = ConsumeDecimalNumber(&in, &level) && in.empty();\n    if (!ok || level >= config::kNumLevels) {\n      return false;\n    } else {\n      char buf[100];\n      snprintf(buf, sizeof(buf), \"%d\",\n               versions_->NumLevelFiles(static_cast<int>(level)));\n      *value = buf;\n      return true;\n    }\n  } else if (in == \"stats\") {\n    char buf[200];\n    snprintf(buf, sizeof(buf),\n             \"                               Compactions\\n\"\n             \"Level  Files Size(MB) Time(sec) Read(MB) Write(MB)\\n\"\n             \"--------------------------------------------------\\n\"\n             );\n    value->append(buf);\n    for (int level = 0; level < config::kNumLevels; level++) {\n      int files = versions_->NumLevelFiles(level);\n      if (stats_[level].micros > 0 || files > 0) {\n        snprintf(\n            buf, sizeof(buf),\n            \"%3d %8d %8.0f %9.0f %8.0f %9.0f\\n\",\n            level,\n            files,\n            versions_->NumLevelBytes(level) / 1048576.0,\n            stats_[level].micros / 1e6,\n            stats_[level].bytes_read / 1048576.0,\n            stats_[level].bytes_written / 1048576.0);\n        value->append(buf);\n      }\n    }\n    return true;\n  } else if (in == \"sstables\") {\n    *value = versions_->current()->DebugString();\n    return true;\n  } else if (in == \"approximate-memory-usage\") {\n    size_t total_usage = options_.block_cache->TotalCharge();\n    if (mem_) {\n      total_usage += mem_->ApproximateMemoryUsage();\n    }\n    if (imm_) {\n      total_usage += imm_->ApproximateMemoryUsage();\n    }\n    char buf[50];\n    snprintf(buf, sizeof(buf), \"%llu\",\n             static_cast<unsigned long long>(total_usage));\n    value->append(buf);\n    return true;\n  }\n\n  return false;\n}\n\nvoid DBImpl::GetApproximateSizes(\n    const Range* range, int n,\n    uint64_t* sizes) {\n  // TODO(opt): better implementation\n  Version* v;\n  {\n    MutexLock l(&mutex_);\n    versions_->current()->Ref();\n    v = versions_->current();\n  }\n\n  for (int i = 0; i < n; i++) {\n    // Convert user_key into a corresponding internal key.\n    InternalKey k1(range[i].start, kMaxSequenceNumber, kValueTypeForSeek);\n    InternalKey k2(range[i].limit, kMaxSequenceNumber, kValueTypeForSeek);\n    uint64_t start = versions_->ApproximateOffsetOf(v, k1);\n    uint64_t limit = versions_->ApproximateOffsetOf(v, k2);\n    sizes[i] = (limit >= start ? limit - start : 0);\n  }\n\n  {\n    MutexLock l(&mutex_);\n    v->Unref();\n  }\n}\n\n// Default implementations of convenience methods that subclasses of DB\n// can call if they wish\nStatus DB::Put(const WriteOptions& opt, const Slice& key, const Slice& value) {\n  WriteBatch batch;\n  batch.Put(key, value);\n  return Write(opt, &batch);\n}\n\nStatus DB::Delete(const WriteOptions& opt, const Slice& key) {\n  WriteBatch batch;\n  batch.Delete(key);\n  return Write(opt, &batch);\n}\n\nDB::~DB() { }\n\nStatus DB::Open(const Options& options, const std::string& dbname,\n                DB** dbptr) {\n  *dbptr = NULL;\n\n  DBImpl* impl = new DBImpl(options, dbname);\n  impl->mutex_.Lock();\n  VersionEdit edit;\n  // Recover handles create_if_missing, error_if_exists\n  bool save_manifest = false;\n  Status s = impl->Recover(&edit, &save_manifest);\n  if (s.ok() && impl->mem_ == NULL) {\n    // Create new log and a corresponding memtable.\n    uint64_t new_log_number = impl->versions_->NewFileNumber();\n    WritableFile* lfile;\n    s = options.env->NewWritableFile(LogFileName(dbname, new_log_number),\n                                     &lfile);\n    if (s.ok()) {\n      edit.SetLogNumber(new_log_number);\n      impl->logfile_ = lfile;\n      impl->logfile_number_ = new_log_number;\n      impl->log_ = new log::Writer(lfile);\n      impl->mem_ = new MemTable(impl->internal_comparator_);\n      impl->mem_->Ref();\n    }\n  }\n  if (s.ok() && save_manifest) {\n    edit.SetPrevLogNumber(0);  // No older logs needed after recovery.\n    edit.SetLogNumber(impl->logfile_number_);\n    s = impl->versions_->LogAndApply(&edit, &impl->mutex_);\n  }\n  if (s.ok()) {\n    impl->DeleteObsoleteFiles();\n    impl->MaybeScheduleCompaction();\n  }\n  impl->mutex_.Unlock();\n  if (s.ok()) {\n    assert(impl->mem_ != NULL);\n    *dbptr = impl;\n  } else {\n    delete impl;\n  }\n  return s;\n}\n\nSnapshot::~Snapshot() {\n}\n\nStatus DestroyDB(const std::string& dbname, const Options& options) {\n  Env* env = options.env;\n  std::vector<std::string> filenames;\n  // Ignore error in case directory does not exist\n  env->GetChildren(dbname, &filenames);\n  if (filenames.empty()) {\n    return Status::OK();\n  }\n\n  FileLock* lock;\n  const std::string lockname = LockFileName(dbname);\n  Status result = env->LockFile(lockname, &lock);\n  if (result.ok()) {\n    uint64_t number;\n    FileType type;\n    for (size_t i = 0; i < filenames.size(); i++) {\n      if (ParseFileName(filenames[i], &number, &type) &&\n          type != kDBLockFile) {  // Lock file will be deleted at end\n        Status del = env->DeleteFile(dbname + \"/\" + filenames[i]);\n        if (result.ok() && !del.ok()) {\n          result = del;\n        }\n      }\n    }\n    env->UnlockFile(lock);  // Ignore error since state is already gone\n    env->DeleteFile(lockname);\n    env->DeleteDir(dbname);  // Ignore error in case dir contains other files\n  }\n  return result;\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/db/db_impl.cc.bk",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/db_impl.h\"\n\n#include <algorithm>\n#include <set>\n#include <string>\n#include <stdint.h>\n#include <stdio.h>\n#include <vector>\n#include \"db/builder.h\"\n#include \"db/db_iter.h\"\n#include \"db/dbformat.h\"\n#include \"db/filename.h\"\n#include \"db/log_reader.h\"\n#include \"db/log_writer.h\"\n#include \"db/memtable.h\"\n#include \"db/table_cache.h\"\n#include \"db/version_set.h\"\n#include \"db/write_batch_internal.h\"\n#include \"leveldb/db.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/status.h\"\n#include \"leveldb/table.h\"\n#include \"leveldb/table_builder.h\"\n#include \"port/port.h\"\n#include \"table/block.h\"\n#include \"table/merger.h\"\n#include \"table/two_level_iterator.h\"\n#include \"util/coding.h\"\n#include \"util/logging.h\"\n#include \"util/mutexlock.h\"\n\nnamespace leveldb {\n\nconst int kNumNonTableCacheFiles = 10;\n\n// Information kept for every waiting writer\nstruct DBImpl::Writer {\n  Status status;\n  WriteBatch* batch;\n  bool sync;\n  bool done;\n  port::CondVar cv;\n\n  explicit Writer(port::Mutex* mu) : cv(mu) { }\n};\n\nstruct DBImpl::CompactionState {\n  Compaction* const compaction;\n\n  // Sequence numbers < smallest_snapshot are not significant since we\n  // will never have to service a snapshot below smallest_snapshot.\n  // Therefore if we have seen a sequence number S <= smallest_snapshot,\n  // we can drop all entries for the same key with sequence numbers < S.\n  SequenceNumber smallest_snapshot;\n\n  // Files produced by compaction\n  struct Output {\n    uint64_t number;\n    uint64_t file_size;\n    InternalKey smallest, largest;\n  };\n  std::vector<Output> outputs;\n\n  // State kept for output being generated\n  WritableFile* outfile;\n  TableBuilder* builder;\n\n  uint64_t total_bytes;\n\n  Output* current_output() { return &outputs[outputs.size()-1]; }\n\n  explicit CompactionState(Compaction* c)\n      : compaction(c),\n        outfile(NULL),\n        builder(NULL),\n        total_bytes(0) {\n  }\n};\n\n// Fix user-supplied options to be reasonable\ntemplate <class T,class V>\nstatic void ClipToRange(T* ptr, V minvalue, V maxvalue) {\n  if (static_cast<V>(*ptr) > maxvalue) *ptr = maxvalue;\n  if (static_cast<V>(*ptr) < minvalue) *ptr = minvalue;\n}\nOptions SanitizeOptions(const std::string& dbname,\n                        const InternalKeyComparator* icmp,\n                        const InternalFilterPolicy* ipolicy,\n                        const Options& src) {\n  Options result = src;\n  result.comparator = icmp;\n  result.filter_policy = (src.filter_policy != NULL) ? ipolicy : NULL;\n  ClipToRange(&result.max_open_files,    64 + kNumNonTableCacheFiles, 50000);\n  ClipToRange(&result.write_buffer_size, 64<<10,                      1<<30);\n  ClipToRange(&result.max_file_size,     1<<20,                       1<<30);\n  ClipToRange(&result.block_size,        1<<10,                       4<<20);\n  if (result.info_log == NULL) {\n    // Open a log file in the same directory as the db\n    src.env->CreateDir(dbname);  // In case it does not exist\n    src.env->RenameFile(InfoLogFileName(dbname), OldInfoLogFileName(dbname));\n    Status s = src.env->NewLogger(InfoLogFileName(dbname), &result.info_log);\n    if (!s.ok()) {\n      // No place suitable for logging\n      result.info_log = NULL;\n    }\n  }\n  if (result.block_cache == NULL) {\n    result.block_cache = NewLRUCache(8 << 20);\n  }\n  return result;\n}\n\nDBImpl::DBImpl(const Options& raw_options, const std::string& dbname)\n    : env_(raw_options.env),\n      internal_comparator_(raw_options.comparator),\n      internal_filter_policy_(raw_options.filter_policy),\n      options_(SanitizeOptions(dbname, &internal_comparator_,\n                               &internal_filter_policy_, raw_options)),\n      owns_info_log_(options_.info_log != raw_options.info_log),\n      owns_cache_(options_.block_cache != raw_options.block_cache),\n      dbname_(dbname),\n      db_lock_(NULL),\n      shutting_down_(NULL),\n      bg_cv_(&mutex_),\n      mem_(NULL),\n      imm_(NULL),\n      logfile_(NULL),\n      logfile_number_(0),\n      log_(NULL),\n      seed_(0),\n      tmp_batch_(new WriteBatch),\n      bg_compaction_scheduled_(false),\n      manual_compaction_(NULL) {\n  has_imm_.Release_Store(NULL);\n\n  // Reserve ten files or so for other uses and give the rest to TableCache.\n  const int table_cache_size = options_.max_open_files - kNumNonTableCacheFiles;\n  table_cache_ = new TableCache(dbname_, &options_, table_cache_size);\n\n  versions_ = new VersionSet(dbname_, &options_, table_cache_,\n                             &internal_comparator_);\n}\n\nDBImpl::~DBImpl() {\n  // Wait for background work to finish\n  mutex_.Lock();\n  shutting_down_.Release_Store(this);  // Any non-NULL value is ok\n  while (bg_compaction_scheduled_) {\n    bg_cv_.Wait();\n  }\n  mutex_.Unlock();\n\n  if (db_lock_ != NULL) {\n    env_->UnlockFile(db_lock_);\n  }\n\n  delete versions_;\n  if (mem_ != NULL) mem_->Unref();\n  if (imm_ != NULL) imm_->Unref();\n  delete tmp_batch_;\n  delete log_;\n  delete logfile_;\n  delete table_cache_;\n\n  if (owns_info_log_) {\n    delete options_.info_log;\n  }\n  if (owns_cache_) {\n    delete options_.block_cache;\n  }\n}\n\nStatus DBImpl::NewDB() {\n  VersionEdit new_db;\n  new_db.SetComparatorName(user_comparator()->Name());\n  new_db.SetLogNumber(0);\n  new_db.SetNextFile(2);\n  new_db.SetLastSequence(0);\n\n  const std::string manifest = DescriptorFileName(dbname_, 1);\n  WritableFile* file;\n  Status s = env_->NewWritableFile(manifest, &file);\n  if (!s.ok()) {\n    return s;\n  }\n  {\n    log::Writer log(file);\n    std::string record;\n    new_db.EncodeTo(&record);\n    s = log.AddRecord(record);\n    if (s.ok()) {\n      s = file->Close();\n    }\n  }\n  delete file;\n  if (s.ok()) {\n    // Make \"CURRENT\" file that points to the new manifest file.\n    s = SetCurrentFile(env_, dbname_, 1);\n  } else {\n    env_->DeleteFile(manifest);\n  }\n  return s;\n}\n\nvoid DBImpl::MaybeIgnoreError(Status* s) const {\n  if (s->ok() || options_.paranoid_checks) {\n    // No change needed\n  } else {\n    Log(options_.info_log, \"Ignoring error %s\", s->ToString().c_str());\n    *s = Status::OK();\n  }\n}\n\nvoid DBImpl::DeleteObsoleteFiles() {\n  if (!bg_error_.ok()) {\n    // After a background error, we don't know whether a new version may\n    // or may not have been committed, so we cannot safely garbage collect.\n    return;\n  }\n\n  // Make a set of all of the live files\n  std::set<uint64_t> live = pending_outputs_;\n  versions_->AddLiveFiles(&live);\n\n  std::vector<std::string> filenames;\n  env_->GetChildren(dbname_, &filenames); // Ignoring errors on purpose\n  uint64_t number;\n  FileType type;\n  for (size_t i = 0; i < filenames.size(); i++) {\n    if (ParseFileName(filenames[i], &number, &type)) {\n      bool keep = true;\n      switch (type) {\n        case kLogFile:\n          keep = ((number >= versions_->LogNumber()) ||\n                  (number == versions_->PrevLogNumber()));\n          break;\n        case kDescriptorFile:\n          // Keep my manifest file, and any newer incarnations'\n          // (in case there is a race that allows other incarnations)\n          keep = (number >= versions_->ManifestFileNumber());\n          break;\n        case kTableFile:\n          keep = (live.find(number) != live.end());\n          break;\n        case kTempFile:\n          // Any temp files that are currently being written to must\n          // be recorded in pending_outputs_, which is inserted into \"live\"\n          keep = (live.find(number) != live.end());\n          break;\n        case kCurrentFile:\n        case kDBLockFile:\n        case kInfoLogFile:\n          keep = true;\n          break;\n      }\n\n      if (!keep) {\n        if (type == kTableFile) {\n          table_cache_->Evict(number);\n        }\n        Log(options_.info_log, \"Delete type=%d #%lld\\n\",\n            int(type),\n            static_cast<unsigned long long>(number));\n        env_->DeleteFile(dbname_ + \"/\" + filenames[i]);\n      }\n    }\n  }\n}\n\nStatus DBImpl::Recover(VersionEdit* edit, bool *save_manifest) {\n  mutex_.AssertHeld();\n\n  // Ignore error from CreateDir since the creation of the DB is\n  // committed only when the descriptor is created, and this directory\n  // may already exist from a previous failed creation attempt.\n  env_->CreateDir(dbname_);\n  assert(db_lock_ == NULL);\n  Status s = env_->LockFile(LockFileName(dbname_), &db_lock_);\n  if (!s.ok()) {\n    return s;\n  }\n\n  if (!env_->FileExists(CurrentFileName(dbname_))) {\n    if (options_.create_if_missing) {\n      s = NewDB();\n      if (!s.ok()) {\n        return s;\n      }\n    } else {\n      return Status::InvalidArgument(\n          dbname_, \"does not exist (create_if_missing is false)\");\n    }\n  } else {\n    if (options_.error_if_exists) {\n      return Status::InvalidArgument(\n          dbname_, \"exists (error_if_exists is true)\");\n    }\n  }\n\n  s = versions_->Recover(save_manifest);\n  if (!s.ok()) {\n    return s;\n  }\n  SequenceNumber max_sequence(0);\n\n  // Recover from all newer log files than the ones named in the\n  // descriptor (new log files may have been added by the previous\n  // incarnation without registering them in the descriptor).\n  //\n  // Note that PrevLogNumber() is no longer used, but we pay\n  // attention to it in case we are recovering a database\n  // produced by an older version of leveldb.\n  const uint64_t min_log = versions_->LogNumber();\n  const uint64_t prev_log = versions_->PrevLogNumber();\n  std::vector<std::string> filenames;\n  s = env_->GetChildren(dbname_, &filenames);\n  if (!s.ok()) {\n    return s;\n  }\n  std::set<uint64_t> expected;\n  versions_->AddLiveFiles(&expected);\n  uint64_t number;\n  FileType type;\n  std::vector<uint64_t> logs;\n  for (size_t i = 0; i < filenames.size(); i++) {\n    if (ParseFileName(filenames[i], &number, &type)) {\n      expected.erase(number);\n      if (type == kLogFile && ((number >= min_log) || (number == prev_log)))\n        logs.push_back(number);\n    }\n  }\n  if (!expected.empty()) {\n    char buf[50];\n    snprintf(buf, sizeof(buf), \"%d missing files; e.g.\",\n             static_cast<int>(expected.size()));\n    return Status::Corruption(buf, TableFileName(dbname_, *(expected.begin())));\n  }\n\n  // Recover in the order in which the logs were generated\n  std::sort(logs.begin(), logs.end());\n  for (size_t i = 0; i < logs.size(); i++) {\n    s = RecoverLogFile(logs[i], (i == logs.size() - 1), save_manifest, edit,\n                       &max_sequence);\n    if (!s.ok()) {\n      return s;\n    }\n\n    // The previous incarnation may not have written any MANIFEST\n    // records after allocating this log number.  So we manually\n    // update the file number allocation counter in VersionSet.\n    versions_->MarkFileNumberUsed(logs[i]);\n  }\n\n  if (versions_->LastSequence() < max_sequence) {\n    versions_->SetLastSequence(max_sequence);\n  }\n\n  return Status::OK();\n}\n\nStatus DBImpl::RecoverLogFile(uint64_t log_number, bool last_log,\n                              bool* save_manifest, VersionEdit* edit,\n                              SequenceNumber* max_sequence) {\n  struct LogReporter : public log::Reader::Reporter {\n    Env* env;\n    Logger* info_log;\n    const char* fname;\n    Status* status;  // NULL if options_.paranoid_checks==false\n    virtual void Corruption(size_t bytes, const Status& s) {\n      Log(info_log, \"%s%s: dropping %d bytes; %s\",\n          (this->status == NULL ? \"(ignoring error) \" : \"\"),\n          fname, static_cast<int>(bytes), s.ToString().c_str());\n      if (this->status != NULL && this->status->ok()) *this->status = s;\n    }\n  };\n\n  mutex_.AssertHeld();\n\n  // Open the log file\n  std::string fname = LogFileName(dbname_, log_number);\n  SequentialFile* file;\n  Status status = env_->NewSequentialFile(fname, &file);\n  if (!status.ok()) {\n    MaybeIgnoreError(&status);\n    return status;\n  }\n\n  // Create the log reader.\n  LogReporter reporter;\n  reporter.env = env_;\n  reporter.info_log = options_.info_log;\n  reporter.fname = fname.c_str();\n  reporter.status = (options_.paranoid_checks ? &status : NULL);\n  // We intentionally make log::Reader do checksumming even if\n  // paranoid_checks==false so that corruptions cause entire commits\n  // to be skipped instead of propagating bad information (like overly\n  // large sequence numbers).\n  log::Reader reader(file, &reporter, true/*checksum*/,\n                     0/*initial_offset*/);\n  Log(options_.info_log, \"Recovering log #%llu\",\n      (unsigned long long) log_number);\n\n  // Read all the records and add to a memtable\n  std::string scratch;\n  Slice record;\n  WriteBatch batch;\n  int compactions = 0;\n  MemTable* mem = NULL;\n  while (reader.ReadRecord(&record, &scratch) &&\n         status.ok()) {\n    if (record.size() < 12) {\n      reporter.Corruption(\n          record.size(), Status::Corruption(\"log record too small\"));\n      continue;\n    }\n    WriteBatchInternal::SetContents(&batch, record);\n\n    if (mem == NULL) {\n      mem = new MemTable(internal_comparator_);\n      mem->Ref();\n    }\n    status = WriteBatchInternal::InsertInto(&batch, mem);\n    MaybeIgnoreError(&status);\n    if (!status.ok()) {\n      break;\n    }\n    const SequenceNumber last_seq =\n        WriteBatchInternal::Sequence(&batch) +\n        WriteBatchInternal::Count(&batch) - 1;\n    if (last_seq > *max_sequence) {\n      *max_sequence = last_seq;\n    }\n\n    if (mem->ApproximateMemoryUsage() > options_.write_buffer_size) {\n      compactions++;\n      *save_manifest = true;\n      status = WriteLevel0Table(mem, edit, NULL);\n      mem->Unref();\n      mem = NULL;\n      if (!status.ok()) {\n        // Reflect errors immediately so that conditions like full\n        // file-systems cause the DB::Open() to fail.\n        break;\n      }\n    }\n  }\n\n  delete file;\n\n  // See if we should keep reusing the last log file.\n  if (status.ok() && options_.reuse_logs && last_log && compactions == 0) {\n    assert(logfile_ == NULL);\n    assert(log_ == NULL);\n    assert(mem_ == NULL);\n    uint64_t lfile_size;\n    if (env_->GetFileSize(fname, &lfile_size).ok() &&\n        env_->NewAppendableFile(fname, &logfile_).ok()) {\n      Log(options_.info_log, \"Reusing old log %s \\n\", fname.c_str());\n      log_ = new log::Writer(logfile_, lfile_size);\n      logfile_number_ = log_number;\n      if (mem != NULL) {\n        mem_ = mem;\n        mem = NULL;\n      } else {\n        // mem can be NULL if lognum exists but was empty.\n        mem_ = new MemTable(internal_comparator_);\n        mem_->Ref();\n      }\n    }\n  }\n\n  if (mem != NULL) {\n    // mem did not get reused; compact it.\n    if (status.ok()) {\n      *save_manifest = true;\n      status = WriteLevel0Table(mem, edit, NULL);\n    }\n    mem->Unref();\n  }\n\n  return status;\n}\n\nStatus DBImpl::WriteLevel0Table(MemTable* mem, VersionEdit* edit,\n                                Version* base) {\n  mutex_.AssertHeld();\n  const uint64_t start_micros = env_->NowMicros();\n  FileMetaData meta;\n  meta.number = versions_->NewFileNumber();\n  pending_outputs_.insert(meta.number);\n  Iterator* iter = mem->NewIterator();\n  Log(options_.info_log, \"Level-0 table #%llu: started\",\n      (unsigned long long) meta.number);\n\n  Status s;\n  {\n    mutex_.Unlock();\n    s = BuildTable(dbname_, env_, options_, table_cache_, iter, &meta);\n    mutex_.Lock();\n  }\n\n  Log(options_.info_log, \"Level-0 table #%llu: %lld bytes %s\",\n      (unsigned long long) meta.number,\n      (unsigned long long) meta.file_size,\n      s.ToString().c_str());\n  delete iter;\n  pending_outputs_.erase(meta.number);\n\n\n  // Note that if file_size is zero, the file has been deleted and\n  // should not be added to the manifest.\n  int level = 0;\n  if (s.ok() && meta.file_size > 0) {\n    const Slice min_user_key = meta.smallest.user_key();\n    const Slice max_user_key = meta.largest.user_key();\n    if (base != NULL) {\n      level = base->PickLevelForMemTableOutput(min_user_key, max_user_key);\n    }\n    edit->AddFile(level, meta.number, meta.file_size,\n                  meta.smallest, meta.largest);\n  }\n\n  CompactionStats stats;\n  stats.micros = env_->NowMicros() - start_micros;\n  stats.bytes_written = meta.file_size;\n  stats_[level].Add(stats);\n  return s;\n}\n\nvoid DBImpl::CompactMemTable() {\n  mutex_.AssertHeld();\n  assert(imm_ != NULL);\n\n  // Save the contents of the memtable as a new Table\n  VersionEdit edit;\n  Version* base = versions_->current();\n  base->Ref();\n  Status s = WriteLevel0Table(imm_, &edit, base);\n  base->Unref();\n\n  if (s.ok() && shutting_down_.Acquire_Load()) {\n    s = Status::IOError(\"Deleting DB during memtable compaction\");\n  }\n\n  // Replace immutable memtable with the generated Table\n  if (s.ok()) {\n    edit.SetPrevLogNumber(0);\n    edit.SetLogNumber(logfile_number_);  // Earlier logs no longer needed\n    s = versions_->LogAndApply(&edit, &mutex_);\n  }\n\n  if (s.ok()) {\n    // Commit to the new state\n    imm_->Unref();\n    imm_ = NULL;\n    has_imm_.Release_Store(NULL);\n    DeleteObsoleteFiles();\n  } else {\n    RecordBackgroundError(s);\n  }\n}\n\nvoid DBImpl::CompactRange(const Slice* begin, const Slice* end) {\n  int max_level_with_files = 1;\n  {\n    MutexLock l(&mutex_);\n    Version* base = versions_->current();\n    for (int level = 1; level < config::kNumLevels; level++) {\n      if (base->OverlapInLevel(level, begin, end)) {\n        max_level_with_files = level;\n      }\n    }\n  }\n  TEST_CompactMemTable(); // TODO(sanjay): Skip if memtable does not overlap\n  for (int level = 0; level < max_level_with_files; level++) {\n    TEST_CompactRange(level, begin, end);\n  }\n}\n\nvoid DBImpl::TEST_CompactRange(int level, const Slice* begin,const Slice* end) {\n  assert(level >= 0);\n  assert(level + 1 < config::kNumLevels);\n\n  InternalKey begin_storage, end_storage;\n\n  ManualCompaction manual;\n  manual.level = level;\n  manual.done = false;\n  if (begin == NULL) {\n    manual.begin = NULL;\n  } else {\n    begin_storage = InternalKey(*begin, kMaxSequenceNumber, kValueTypeForSeek);\n    manual.begin = &begin_storage;\n  }\n  if (end == NULL) {\n    manual.end = NULL;\n  } else {\n    end_storage = InternalKey(*end, 0, static_cast<ValueType>(0));\n    manual.end = &end_storage;\n  }\n\n  MutexLock l(&mutex_);\n  while (!manual.done && !shutting_down_.Acquire_Load() && bg_error_.ok()) {\n    if (manual_compaction_ == NULL) {  // Idle\n      manual_compaction_ = &manual;\n      MaybeScheduleCompaction();\n    } else {  // Running either my compaction or another compaction.\n      bg_cv_.Wait();\n    }\n  }\n  if (manual_compaction_ == &manual) {\n    // Cancel my manual compaction since we aborted early for some reason.\n    manual_compaction_ = NULL;\n  }\n}\n\nStatus DBImpl::TEST_CompactMemTable() {\n  // NULL batch means just wait for earlier writes to be done\n  Status s = Write(WriteOptions(), NULL);\n  if (s.ok()) {\n    // Wait until the compaction completes\n    MutexLock l(&mutex_);\n    while (imm_ != NULL && bg_error_.ok()) {\n      bg_cv_.Wait();\n    }\n    if (imm_ != NULL) {\n      s = bg_error_;\n    }\n  }\n  return s;\n}\n\nvoid DBImpl::RecordBackgroundError(const Status& s) {\n  mutex_.AssertHeld();\n  if (bg_error_.ok()) {\n    bg_error_ = s;\n    bg_cv_.SignalAll();\n  }\n}\n\nvoid DBImpl::MaybeScheduleCompaction() {\n  mutex_.AssertHeld();\n  if (bg_compaction_scheduled_) {\n    // Already scheduled\n  } else if (shutting_down_.Acquire_Load()) {\n    // DB is being deleted; no more background compactions\n  } else if (!bg_error_.ok()) {\n    // Already got an error; no more changes\n  } else if (imm_ == NULL &&\n             manual_compaction_ == NULL &&\n             !versions_->NeedsCompaction()) {\n    // No work to be done\n  } else {\n    bg_compaction_scheduled_ = true;\n    env_->Schedule(&DBImpl::BGWork, this);\n  }\n}\n\nvoid DBImpl::BGWork(void* db) {\n  reinterpret_cast<DBImpl*>(db)->BackgroundCall();\n}\n\nvoid DBImpl::BackgroundCall() {\n  MutexLock l(&mutex_);\n  assert(bg_compaction_scheduled_);\n  if (shutting_down_.Acquire_Load()) {\n    // No more background work when shutting down.\n  } else if (!bg_error_.ok()) {\n    // No more background work after a background error.\n  } else {\n    BackgroundCompaction();\n  }\n\n  bg_compaction_scheduled_ = false;\n\n  // Previous compaction may have produced too many files in a level,\n  // so reschedule another compaction if needed.\n  MaybeScheduleCompaction();\n  bg_cv_.SignalAll();\n}\n\nvoid DBImpl::BackgroundCompaction() {\n  mutex_.AssertHeld();\n\n  if (imm_ != NULL) {\n    CompactMemTable();\n    return;\n  }\n\n  Compaction* c;\n  bool is_manual = (manual_compaction_ != NULL);\n  InternalKey manual_end;\n  if (is_manual) {\n    ManualCompaction* m = manual_compaction_;\n    c = versions_->CompactRange(m->level, m->begin, m->end);\n    m->done = (c == NULL);\n    if (c != NULL) {\n      manual_end = c->input(0, c->num_input_files(0) - 1)->largest;\n    }\n    Log(options_.info_log,\n        \"Manual compaction at level-%d from %s .. %s; will stop at %s\\n\",\n        m->level,\n        (m->begin ? m->begin->DebugString().c_str() : \"(begin)\"),\n        (m->end ? m->end->DebugString().c_str() : \"(end)\"),\n        (m->done ? \"(end)\" : manual_end.DebugString().c_str()));\n  } else {\n    c = versions_->PickCompaction();\n  }\n\n  Status status;\n  if (c == NULL) {\n    // Nothing to do\n  } else if (!is_manual && c->IsTrivialMove()) {\n    // Move file to next level\n    assert(c->num_input_files(0) == 1);\n    FileMetaData* f = c->input(0, 0);\n    c->edit()->DeleteFile(c->level(), f->number);\n    c->edit()->AddFile(c->level() + 1, f->number, f->file_size,\n                       f->smallest, f->largest);\n    status = versions_->LogAndApply(c->edit(), &mutex_);\n    if (!status.ok()) {\n      RecordBackgroundError(status);\n    }\n    VersionSet::LevelSummaryStorage tmp;\n    Log(options_.info_log, \"Moved #%lld to level-%d %lld bytes %s: %s\\n\",\n        static_cast<unsigned long long>(f->number),\n        c->level() + 1,\n        static_cast<unsigned long long>(f->file_size),\n        status.ToString().c_str(),\n        versions_->LevelSummary(&tmp));\n  } else {\n    CompactionState* compact = new CompactionState(c);\n    status = DoCompactionWork(compact);\n    if (!status.ok()) {\n      RecordBackgroundError(status);\n    }\n    CleanupCompaction(compact);\n    c->ReleaseInputs();\n    DeleteObsoleteFiles();\n  }\n  delete c;\n\n  if (status.ok()) {\n    // Done\n  } else if (shutting_down_.Acquire_Load()) {\n    // Ignore compaction errors found during shutting down\n  } else {\n    Log(options_.info_log,\n        \"Compaction error: %s\", status.ToString().c_str());\n  }\n\n  if (is_manual) {\n    ManualCompaction* m = manual_compaction_;\n    if (!status.ok()) {\n      m->done = true;\n    }\n    if (!m->done) {\n      // We only compacted part of the requested range.  Update *m\n      // to the range that is left to be compacted.\n      m->tmp_storage = manual_end;\n      m->begin = &m->tmp_storage;\n    }\n    manual_compaction_ = NULL;\n  }\n}\n\nvoid DBImpl::CleanupCompaction(CompactionState* compact) {\n  mutex_.AssertHeld();\n  if (compact->builder != NULL) {\n    // May happen if we get a shutdown call in the middle of compaction\n    compact->builder->Abandon();\n    delete compact->builder;\n  } else {\n    assert(compact->outfile == NULL);\n  }\n  delete compact->outfile;\n  for (size_t i = 0; i < compact->outputs.size(); i++) {\n    const CompactionState::Output& out = compact->outputs[i];\n    pending_outputs_.erase(out.number);\n  }\n  delete compact;\n}\n\nStatus DBImpl::OpenCompactionOutputFile(CompactionState* compact) {\n  assert(compact != NULL);\n  assert(compact->builder == NULL);\n  uint64_t file_number;\n  {\n    mutex_.Lock();\n    file_number = versions_->NewFileNumber();\n    pending_outputs_.insert(file_number);\n    CompactionState::Output out;\n    out.number = file_number;\n    out.smallest.Clear();\n    out.largest.Clear();\n    compact->outputs.push_back(out);\n    mutex_.Unlock();\n  }\n\n  // Make the output file\n  std::string fname = TableFileName(dbname_, file_number);\n  Status s = env_->NewWritableFile(fname, &compact->outfile);\n  if (s.ok()) {\n    compact->builder = new TableBuilder(options_, compact->outfile);\n  }\n  return s;\n}\n\nStatus DBImpl::FinishCompactionOutputFile(CompactionState* compact,\n                                          Iterator* input) {\n  assert(compact != NULL);\n  assert(compact->outfile != NULL);\n  assert(compact->builder != NULL);\n\n  const uint64_t output_number = compact->current_output()->number;\n  assert(output_number != 0);\n\n  // Check for iterator errors\n  Status s = input->status();\n  const uint64_t current_entries = compact->builder->NumEntries();\n  if (s.ok()) {\n    s = compact->builder->Finish();\n  } else {\n    compact->builder->Abandon();\n  }\n  const uint64_t current_bytes = compact->builder->FileSize();\n  compact->current_output()->file_size = current_bytes;\n  compact->total_bytes += current_bytes;\n  delete compact->builder;\n  compact->builder = NULL;\n\n  // Finish and check for file errors\n  if (s.ok()) {\n    s = compact->outfile->Sync();\n  }\n  if (s.ok()) {\n    s = compact->outfile->Close();\n  }\n  delete compact->outfile;\n  compact->outfile = NULL;\n\n  if (s.ok() && current_entries > 0) {\n    // Verify that the table is usable\n    Iterator* iter = table_cache_->NewIterator(ReadOptions(),\n                                               output_number,\n                                               current_bytes);\n    s = iter->status();\n    delete iter;\n    if (s.ok()) {\n      Log(options_.info_log,\n          \"Generated table #%llu@%d: %lld keys, %lld bytes\",\n          (unsigned long long) output_number,\n          compact->compaction->level(),\n          (unsigned long long) current_entries,\n          (unsigned long long) current_bytes);\n    }\n  }\n  return s;\n}\n\n\nStatus DBImpl::InstallCompactionResults(CompactionState* compact) {\n  mutex_.AssertHeld();\n  Log(options_.info_log,  \"Compacted %d@%d + %d@%d files => %lld bytes\",\n      compact->compaction->num_input_files(0),\n      compact->compaction->level(),\n      compact->compaction->num_input_files(1),\n      compact->compaction->level() + 1,\n      static_cast<long long>(compact->total_bytes));\n\n  // Add compaction outputs\n  compact->compaction->AddInputDeletions(compact->compaction->edit());\n  const int level = compact->compaction->level();\n  for (size_t i = 0; i < compact->outputs.size(); i++) {\n    const CompactionState::Output& out = compact->outputs[i];\n    compact->compaction->edit()->AddFile(\n        level + 1,\n        out.number, out.file_size, out.smallest, out.largest);\n  }\n  return versions_->LogAndApply(compact->compaction->edit(), &mutex_);\n}\n\nStatus DBImpl::DoCompactionWork(CompactionState* compact) {\n  const uint64_t start_micros = env_->NowMicros();\n  int64_t imm_micros = 0;  // Micros spent doing imm_ compactions\n\n  Log(options_.info_log,  \"Compacting %d@%d + %d@%d files\",\n      compact->compaction->num_input_files(0),\n      compact->compaction->level(),\n      compact->compaction->num_input_files(1),\n      compact->compaction->level() + 1);\n\n  assert(versions_->NumLevelFiles(compact->compaction->level()) > 0);\n  assert(compact->builder == NULL);\n  assert(compact->outfile == NULL);\n  if (snapshots_.empty()) {\n    compact->smallest_snapshot = versions_->LastSequence();\n  } else {\n    compact->smallest_snapshot = snapshots_.oldest()->number_;\n  }\n\n  // Release mutex while we're actually doing the compaction work\n  mutex_.Unlock();\n\n  Iterator* input = versions_->MakeInputIterator(compact->compaction);\n  input->SeekToFirst();\n  Status status;\n  ParsedInternalKey ikey;\n  std::string current_user_key;\n  bool has_current_user_key = false;\n  SequenceNumber last_sequence_for_key = kMaxSequenceNumber;\n  for (; input->Valid() && !shutting_down_.Acquire_Load(); ) {\n    // Prioritize immutable compaction work\n    if (has_imm_.NoBarrier_Load() != NULL) {\n      const uint64_t imm_start = env_->NowMicros();\n      mutex_.Lock();\n      if (imm_ != NULL) {\n        CompactMemTable();\n        bg_cv_.SignalAll();  // Wakeup MakeRoomForWrite() if necessary\n      }\n      mutex_.Unlock();\n      imm_micros += (env_->NowMicros() - imm_start);\n    }\n\n    Slice key = input->key();\n    if (compact->compaction->ShouldStopBefore(key) &&\n        compact->builder != NULL) {\n      status = FinishCompactionOutputFile(compact, input);\n      if (!status.ok()) {\n        break;\n      }\n    }\n\n    // Handle key/value, add to state, etc.\n    bool drop = false;\n    if (!ParseInternalKey(key, &ikey)) {\n      // Do not hide error keys\n      current_user_key.clear();\n      has_current_user_key = false;\n      last_sequence_for_key = kMaxSequenceNumber;\n    } else {\n      if (!has_current_user_key ||\n          user_comparator()->Compare(ikey.user_key,\n                                     Slice(current_user_key)) != 0) {\n        // First occurrence of this user key\n        current_user_key.assign(ikey.user_key.data(), ikey.user_key.size());\n        has_current_user_key = true;\n        last_sequence_for_key = kMaxSequenceNumber;\n      }\n\n      if (last_sequence_for_key <= compact->smallest_snapshot) {\n        // Hidden by an newer entry for same user key\n        drop = true;    // (A)\n      } else if (ikey.type == kTypeDeletion &&\n                 ikey.sequence <= compact->smallest_snapshot &&\n                 compact->compaction->IsBaseLevelForKey(ikey.user_key)) {\n        // For this user key:\n        // (1) there is no data in higher levels\n        // (2) data in lower levels will have larger sequence numbers\n        // (3) data in layers that are being compacted here and have\n        //     smaller sequence numbers will be dropped in the next\n        //     few iterations of this loop (by rule (A) above).\n        // Therefore this deletion marker is obsolete and can be dropped.\n        drop = true;\n      }\n\n      last_sequence_for_key = ikey.sequence;\n    }\n#if 0\n    Log(options_.info_log,\n        \"  Compact: %s, seq %d, type: %d %d, drop: %d, is_base: %d, \"\n        \"%d smallest_snapshot: %d\",\n        ikey.user_key.ToString().c_str(),\n        (int)ikey.sequence, ikey.type, kTypeValue, drop,\n        compact->compaction->IsBaseLevelForKey(ikey.user_key),\n        (int)last_sequence_for_key, (int)compact->smallest_snapshot);\n#endif\n\n    if (!drop) {\n      // Open output file if necessary\n      if (compact->builder == NULL) {\n        status = OpenCompactionOutputFile(compact);\n        if (!status.ok()) {\n          break;\n        }\n      }\n      if (compact->builder->NumEntries() == 0) {\n        compact->current_output()->smallest.DecodeFrom(key);\n      }\n      compact->current_output()->largest.DecodeFrom(key);\n      compact->builder->Add(key, input->value());\n\n      // Close output file if it is big enough\n      if (compact->builder->FileSize() >=\n          compact->compaction->MaxOutputFileSize()) {\n        status = FinishCompactionOutputFile(compact, input);\n        if (!status.ok()) {\n          break;\n        }\n      }\n    }\n\n    input->Next();\n  }\n\n  if (status.ok() && shutting_down_.Acquire_Load()) {\n    status = Status::IOError(\"Deleting DB during compaction\");\n  }\n  if (status.ok() && compact->builder != NULL) {\n    status = FinishCompactionOutputFile(compact, input);\n  }\n  if (status.ok()) {\n    status = input->status();\n  }\n  delete input;\n  input = NULL;\n\n  CompactionStats stats;\n  stats.micros = env_->NowMicros() - start_micros - imm_micros;\n  for (int which = 0; which < 2; which++) {\n    for (int i = 0; i < compact->compaction->num_input_files(which); i++) {\n      stats.bytes_read += compact->compaction->input(which, i)->file_size;\n    }\n  }\n  for (size_t i = 0; i < compact->outputs.size(); i++) {\n    stats.bytes_written += compact->outputs[i].file_size;\n  }\n\n  mutex_.Lock();\n  stats_[compact->compaction->level() + 1].Add(stats);\n\n  if (status.ok()) {\n    status = InstallCompactionResults(compact);\n  }\n  if (!status.ok()) {\n    RecordBackgroundError(status);\n  }\n  VersionSet::LevelSummaryStorage tmp;\n  Log(options_.info_log,\n      \"compacted to: %s\", versions_->LevelSummary(&tmp));\n  return status;\n}\n\nnamespace {\nstruct IterState {\n  port::Mutex* mu;\n  Version* version;\n  MemTable* mem;\n  MemTable* imm;\n};\n\nstatic void CleanupIteratorState(void* arg1, void* arg2) {\n  IterState* state = reinterpret_cast<IterState*>(arg1);\n  state->mu->Lock();\n  state->mem->Unref();\n  if (state->imm != NULL) state->imm->Unref();\n  state->version->Unref();\n  state->mu->Unlock();\n  delete state;\n}\n}  // namespace\n\nIterator* DBImpl::NewInternalIterator(const ReadOptions& options,\n                                      SequenceNumber* latest_snapshot,\n                                      uint32_t* seed) {\n  IterState* cleanup = new IterState;\n  mutex_.Lock();\n  *latest_snapshot = versions_->LastSequence();\n\n  // Collect together all needed child iterators\n  std::vector<Iterator*> list;\n  list.push_back(mem_->NewIterator());\n  mem_->Ref();\n  if (imm_ != NULL) {\n    list.push_back(imm_->NewIterator());\n    imm_->Ref();\n  }\n  versions_->current()->AddIterators(options, &list);\n  Iterator* internal_iter =\n      NewMergingIterator(&internal_comparator_, &list[0], list.size());\n  versions_->current()->Ref();\n\n  cleanup->mu = &mutex_;\n  cleanup->mem = mem_;\n  cleanup->imm = imm_;\n  cleanup->version = versions_->current();\n  internal_iter->RegisterCleanup(CleanupIteratorState, cleanup, NULL);\n\n  *seed = ++seed_;\n  mutex_.Unlock();\n  return internal_iter;\n}\n\nIterator* DBImpl::TEST_NewInternalIterator() {\n  SequenceNumber ignored;\n  uint32_t ignored_seed;\n  return NewInternalIterator(ReadOptions(), &ignored, &ignored_seed);\n}\n\nint64_t DBImpl::TEST_MaxNextLevelOverlappingBytes() {\n  MutexLock l(&mutex_);\n  return versions_->MaxNextLevelOverlappingBytes();\n}\n\nStatus DBImpl::Get(const ReadOptions& options,\n                   const Slice& key,\n                   std::string* value) {\n  Status s;\n  MutexLock l(&mutex_);\n  SequenceNumber snapshot;\n  if (options.snapshot != NULL) {\n    snapshot = reinterpret_cast<const SnapshotImpl*>(options.snapshot)->number_;\n  } else {\n    snapshot = versions_->LastSequence();\n  }\n\n  MemTable* mem = mem_;\n  MemTable* imm = imm_;\n  Version* current = versions_->current();\n  mem->Ref();\n  if (imm != NULL) imm->Ref();\n  current->Ref();\n\n  bool have_stat_update = false;\n  Version::GetStats stats;\n\n  // Unlock while reading from files and memtables\n  {\n    mutex_.Unlock();\n    // First look in the memtable, then in the immutable memtable (if any).\n    LookupKey lkey(key, snapshot);\n    if (mem->Get(lkey, value, &s)) {\n      // Done\n    } else if (imm != NULL && imm->Get(lkey, value, &s)) {\n      // Done\n    } else {\n      s = current->Get(options, lkey, value, &stats);\n      have_stat_update = true;\n    }\n    mutex_.Lock();\n  }\n\n  if (have_stat_update && current->UpdateStats(stats)) {\n    MaybeScheduleCompaction();\n  }\n  mem->Unref();\n  if (imm != NULL) imm->Unref();\n  current->Unref();\n  return s;\n}\n\nIterator* DBImpl::NewIterator(const ReadOptions& options) {\n  SequenceNumber latest_snapshot;\n  uint32_t seed;\n  Iterator* iter = NewInternalIterator(options, &latest_snapshot, &seed);\n  return NewDBIterator(\n      this, user_comparator(), iter,\n      (options.snapshot != NULL\n       ? reinterpret_cast<const SnapshotImpl*>(options.snapshot)->number_\n       : latest_snapshot),\n      seed);\n}\n\nvoid DBImpl::RecordReadSample(Slice key) {\n  MutexLock l(&mutex_);\n  if (versions_->current()->RecordReadSample(key)) {\n    MaybeScheduleCompaction();\n  }\n}\n\nconst Snapshot* DBImpl::GetSnapshot() {\n  MutexLock l(&mutex_);\n  return snapshots_.New(versions_->LastSequence());\n}\n\nvoid DBImpl::ReleaseSnapshot(const Snapshot* s) {\n  MutexLock l(&mutex_);\n  snapshots_.Delete(reinterpret_cast<const SnapshotImpl*>(s));\n}\n\n// Convenience methods\nStatus DBImpl::Put(const WriteOptions& o, const Slice& key, const Slice& val) {\n  return DB::Put(o, key, val);\n}\n\nStatus DBImpl::Delete(const WriteOptions& options, const Slice& key) {\n  return DB::Delete(options, key);\n}\n\nStatus DBImpl::Write(const WriteOptions& options, WriteBatch* my_batch) {\n  Writer w(&mutex_);\n  w.batch = my_batch;\n  w.sync = options.sync;\n  w.done = false;\n\n  MutexLock l(&mutex_);\n  writers_.push_back(&w);\n  while (!w.done && &w != writers_.front()) {\n    w.cv.Wait();\n  }\n  if (w.done) {\n    return w.status;\n  }\n\n  // May temporarily unlock and wait.\n  Status status = MakeRoomForWrite(my_batch == NULL);\n  uint64_t last_sequence = versions_->LastSequence();\n  Writer* last_writer = &w;\n  if (status.ok() && my_batch != NULL) {  // NULL batch is for compactions\n    WriteBatch* updates = BuildBatchGroup(&last_writer);\n    WriteBatchInternal::SetSequence(updates, last_sequence + 1);\n    last_sequence += WriteBatchInternal::Count(updates);\n\n    // Add to log and apply to memtable.  We can release the lock\n    // during this phase since &w is currently responsible for logging\n    // and protects against concurrent loggers and concurrent writes\n    // into mem_.\n    {\n      mutex_.Unlock();\n      status = log_->AddRecord(WriteBatchInternal::Contents(updates));\n      bool sync_error = false;\n      if (status.ok() && options.sync) {\n        status = logfile_->Sync();\n        if (!status.ok()) {\n          sync_error = true;\n        }\n      }\n      if (status.ok()) {\n        status = WriteBatchInternal::InsertInto(updates, mem_);\n      }\n      mutex_.Lock();\n      if (sync_error) {\n        // The state of the log file is indeterminate: the log record we\n        // just added may or may not show up when the DB is re-opened.\n        // So we force the DB into a mode where all future writes fail.\n        RecordBackgroundError(status);\n      }\n    }\n    if (updates == tmp_batch_) tmp_batch_->Clear();\n\n    versions_->SetLastSequence(last_sequence);\n  }\n\n  while (true) {\n    Writer* ready = writers_.front();\n    writers_.pop_front();\n    if (ready != &w) {\n      ready->status = status;\n      ready->done = true;\n      ready->cv.Signal();\n    }\n    if (ready == last_writer) break;\n  }\n\n  // Notify new head of write queue\n  if (!writers_.empty()) {\n    writers_.front()->cv.Signal();\n  }\n\n  return status;\n}\n\n// REQUIRES: Writer list must be non-empty\n// REQUIRES: First writer must have a non-NULL batch\nWriteBatch* DBImpl::BuildBatchGroup(Writer** last_writer) {\n  assert(!writers_.empty());\n  Writer* first = writers_.front();\n  WriteBatch* result = first->batch;\n  assert(result != NULL);\n\n  size_t size = WriteBatchInternal::ByteSize(first->batch);\n\n  // Allow the group to grow up to a maximum size, but if the\n  // original write is small, limit the growth so we do not slow\n  // down the small write too much.\n  size_t max_size = 1 << 20;\n  if (size <= (128<<10)) {\n    max_size = size + (128<<10);\n  }\n\n  *last_writer = first;\n  std::deque<Writer*>::iterator iter = writers_.begin();\n  ++iter;  // Advance past \"first\"\n  for (; iter != writers_.end(); ++iter) {\n    Writer* w = *iter;\n    if (w->sync && !first->sync) {\n      // Do not include a sync write into a batch handled by a non-sync write.\n      break;\n    }\n\n    if (w->batch != NULL) {\n      size += WriteBatchInternal::ByteSize(w->batch);\n      if (size > max_size) {\n        // Do not make batch too big\n        break;\n      }\n\n      // Append to *result\n      if (result == first->batch) {\n        // Switch to temporary batch instead of disturbing caller's batch\n        result = tmp_batch_;\n        assert(WriteBatchInternal::Count(result) == 0);\n        WriteBatchInternal::Append(result, first->batch);\n      }\n      WriteBatchInternal::Append(result, w->batch);\n    }\n    *last_writer = w;\n  }\n  return result;\n}\n\n// REQUIRES: mutex_ is held\n// REQUIRES: this thread is currently at the front of the writer queue\nStatus DBImpl::MakeRoomForWrite(bool force) {\n  mutex_.AssertHeld();\n  assert(!writers_.empty());\n  bool allow_delay = !force;\n  Status s;\n  while (true) {\n    if (!bg_error_.ok()) {\n      // Yield previous error\n      s = bg_error_;\n      break;\n    } else if (\n        allow_delay &&\n        versions_->NumLevelFiles(0) >= config::kL0_SlowdownWritesTrigger) {\n      // We are getting close to hitting a hard limit on the number of\n      // L0 files.  Rather than delaying a single write by several\n      // seconds when we hit the hard limit, start delaying each\n      // individual write by 1ms to reduce latency variance.  Also,\n      // this delay hands over some CPU to the compaction thread in\n      // case it is sharing the same core as the writer.\n      mutex_.Unlock();\n      env_->SleepForMicroseconds(1000);\n      allow_delay = false;  // Do not delay a single write more than once\n      mutex_.Lock();\n    } else if (!force &&\n               (mem_->ApproximateMemoryUsage() <= options_.write_buffer_size)) {\n      // There is room in current memtable\n      break;\n    } else if (imm_ != NULL) {\n      // We have filled up the current memtable, but the previous\n      // one is still being compacted, so we wait.\n      Log(options_.info_log, \"Current memtable full; waiting...\\n\");\n      bg_cv_.Wait();\n    } else if (versions_->NumLevelFiles(0) >= config::kL0_StopWritesTrigger) {\n      // There are too many level-0 files.\n      Log(options_.info_log, \"Too many L0 files; waiting...\\n\");\n      bg_cv_.Wait();\n    } else {\n      // Attempt to switch to a new memtable and trigger compaction of old\n      assert(versions_->PrevLogNumber() == 0);\n      uint64_t new_log_number = versions_->NewFileNumber();\n      WritableFile* lfile = NULL;\n      s = env_->NewWritableFile(LogFileName(dbname_, new_log_number), &lfile);\n      if (!s.ok()) {\n        // Avoid chewing through file number space in a tight loop.\n        versions_->ReuseFileNumber(new_log_number);\n        break;\n      }\n      delete log_;\n      delete logfile_;\n      logfile_ = lfile;\n      logfile_number_ = new_log_number;\n      log_ = new log::Writer(lfile);\n      imm_ = mem_;\n      has_imm_.Release_Store(imm_);\n      mem_ = new MemTable(internal_comparator_);\n      mem_->Ref();\n      force = false;   // Do not force another compaction if have room\n      MaybeScheduleCompaction();\n    }\n  }\n  return s;\n}\n\nbool DBImpl::GetProperty(const Slice& property, std::string* value) {\n  value->clear();\n\n  MutexLock l(&mutex_);\n  Slice in = property;\n  Slice prefix(\"leveldb.\");\n  if (!in.starts_with(prefix)) return false;\n  in.remove_prefix(prefix.size());\n\n  if (in.starts_with(\"num-files-at-level\")) {\n    in.remove_prefix(strlen(\"num-files-at-level\"));\n    uint64_t level;\n    bool ok = ConsumeDecimalNumber(&in, &level) && in.empty();\n    if (!ok || level >= config::kNumLevels) {\n      return false;\n    } else {\n      char buf[100];\n      snprintf(buf, sizeof(buf), \"%d\",\n               versions_->NumLevelFiles(static_cast<int>(level)));\n      *value = buf;\n      return true;\n    }\n  } else if (in == \"stats\") {\n    char buf[200];\n    snprintf(buf, sizeof(buf),\n             \"                               Compactions\\n\"\n             \"Level  Files Size(MB) Time(sec) Read(MB) Write(MB)\\n\"\n             \"--------------------------------------------------\\n\"\n             );\n    value->append(buf);\n    for (int level = 0; level < config::kNumLevels; level++) {\n      int files = versions_->NumLevelFiles(level);\n      if (stats_[level].micros > 0 || files > 0) {\n        snprintf(\n            buf, sizeof(buf),\n            \"%3d %8d %8.0f %9.0f %8.0f %9.0f\\n\",\n            level,\n            files,\n            versions_->NumLevelBytes(level) / 1048576.0,\n            stats_[level].micros / 1e6,\n            stats_[level].bytes_read / 1048576.0,\n            stats_[level].bytes_written / 1048576.0);\n        value->append(buf);\n      }\n    }\n    return true;\n  } else if (in == \"sstables\") {\n    *value = versions_->current()->DebugString();\n    return true;\n  } else if (in == \"approximate-memory-usage\") {\n    size_t total_usage = options_.block_cache->TotalCharge();\n    if (mem_) {\n      total_usage += mem_->ApproximateMemoryUsage();\n    }\n    if (imm_) {\n      total_usage += imm_->ApproximateMemoryUsage();\n    }\n    char buf[50];\n    snprintf(buf, sizeof(buf), \"%llu\",\n             static_cast<unsigned long long>(total_usage));\n    value->append(buf);\n    return true;\n  }\n\n  return false;\n}\n\nvoid DBImpl::GetApproximateSizes(\n    const Range* range, int n,\n    uint64_t* sizes) {\n  // TODO(opt): better implementation\n  Version* v;\n  {\n    MutexLock l(&mutex_);\n    versions_->current()->Ref();\n    v = versions_->current();\n  }\n\n  for (int i = 0; i < n; i++) {\n    // Convert user_key into a corresponding internal key.\n    InternalKey k1(range[i].start, kMaxSequenceNumber, kValueTypeForSeek);\n    InternalKey k2(range[i].limit, kMaxSequenceNumber, kValueTypeForSeek);\n    uint64_t start = versions_->ApproximateOffsetOf(v, k1);\n    uint64_t limit = versions_->ApproximateOffsetOf(v, k2);\n    sizes[i] = (limit >= start ? limit - start : 0);\n  }\n\n  {\n    MutexLock l(&mutex_);\n    v->Unref();\n  }\n}\n\n// Default implementations of convenience methods that subclasses of DB\n// can call if they wish\nStatus DB::Put(const WriteOptions& opt, const Slice& key, const Slice& value) {\n  WriteBatch batch;\n  batch.Put(key, value);\n  return Write(opt, &batch);\n}\n\nStatus DB::Delete(const WriteOptions& opt, const Slice& key) {\n  WriteBatch batch;\n  batch.Delete(key);\n  return Write(opt, &batch);\n}\n\nDB::~DB() { }\n\nStatus DB::Open(const Options& options, const std::string& dbname,\n                DB** dbptr) {\n  *dbptr = NULL;\n\n  DBImpl* impl = new DBImpl(options, dbname);\n  impl->mutex_.Lock();\n  VersionEdit edit;\n  // Recover handles create_if_missing, error_if_exists\n  bool save_manifest = false;\n  Status s = impl->Recover(&edit, &save_manifest);\n  if (s.ok() && impl->mem_ == NULL) {\n    // Create new log and a corresponding memtable.\n    uint64_t new_log_number = impl->versions_->NewFileNumber();\n    WritableFile* lfile;\n    s = options.env->NewWritableFile(LogFileName(dbname, new_log_number),\n                                     &lfile);\n    if (s.ok()) {\n      edit.SetLogNumber(new_log_number);\n      impl->logfile_ = lfile;\n      impl->logfile_number_ = new_log_number;\n      impl->log_ = new log::Writer(lfile);\n      impl->mem_ = new MemTable(impl->internal_comparator_);\n      impl->mem_->Ref();\n    }\n  }\n  if (s.ok() && save_manifest) {\n    edit.SetPrevLogNumber(0);  // No older logs needed after recovery.\n    edit.SetLogNumber(impl->logfile_number_);\n    s = impl->versions_->LogAndApply(&edit, &impl->mutex_);\n  }\n  if (s.ok()) {\n    impl->DeleteObsoleteFiles();\n    impl->MaybeScheduleCompaction();\n  }\n  impl->mutex_.Unlock();\n  if (s.ok()) {\n    assert(impl->mem_ != NULL);\n    *dbptr = impl;\n  } else {\n    delete impl;\n  }\n  return s;\n}\n\nSnapshot::~Snapshot() {\n}\n\nStatus DestroyDB(const std::string& dbname, const Options& options) {\n  Env* env = options.env;\n  std::vector<std::string> filenames;\n  // Ignore error in case directory does not exist\n  env->GetChildren(dbname, &filenames);\n  if (filenames.empty()) {\n    return Status::OK();\n  }\n\n  FileLock* lock;\n  const std::string lockname = LockFileName(dbname);\n  Status result = env->LockFile(lockname, &lock);\n  if (result.ok()) {\n    uint64_t number;\n    FileType type;\n    for (size_t i = 0; i < filenames.size(); i++) {\n      if (ParseFileName(filenames[i], &number, &type) &&\n          type != kDBLockFile) {  // Lock file will be deleted at end\n        Status del = env->DeleteFile(dbname + \"/\" + filenames[i]);\n        if (result.ok() && !del.ok()) {\n          result = del;\n        }\n      }\n    }\n    env->UnlockFile(lock);  // Ignore error since state is already gone\n    env->DeleteFile(lockname);\n    env->DeleteDir(dbname);  // Ignore error in case dir contains other files\n  }\n  return result;\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/db/db_impl.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_DB_DB_IMPL_H_\n#define STORAGE_LEVELDB_DB_DB_IMPL_H_\n\n#include <deque>\n#include <set>\n#include \"db/dbformat.h\"\n#include \"db/log_writer.h\"\n#include \"db/snapshot.h\"\n#include \"leveldb/db.h\"\n#include \"leveldb/env.h\"\n#include \"port/port.h\"\n#include \"port/thread_annotations.h\"\n\nnamespace leveldb {\n\nclass MemTable;\nclass TableCache;\nclass Version;\nclass VersionEdit;\nclass VersionSet;\n\nclass DBImpl : public DB {\n public:\n  DBImpl(const Options& options, const std::string& dbname);\n  virtual ~DBImpl();\n\n  // Implementations of the DB interface\n  virtual Status Put(const WriteOptions&, const Slice& key, const Slice& value);\n  virtual Status Delete(const WriteOptions&, const Slice& key);\n  virtual Status Write(const WriteOptions& options, WriteBatch* updates);\n  virtual Status Get(const ReadOptions& options,\n                     const Slice& key,\n                     std::string* value);\n  virtual Iterator* NewIterator(const ReadOptions&);\n  virtual const Snapshot* GetSnapshot();\n  virtual void ReleaseSnapshot(const Snapshot* snapshot);\n  virtual bool GetProperty(const Slice& property, std::string* value);\n  virtual void GetApproximateSizes(const Range* range, int n, uint64_t* sizes);\n  virtual void CompactRange(const Slice* begin, const Slice* end);\n\n  // Extra methods (for testing) that are not in the public DB interface\n\n  // Compact any files in the named level that overlap [*begin,*end]\n  void TEST_CompactRange(int level, const Slice* begin, const Slice* end);\n\n  // Force current memtable contents to be compacted.\n  Status TEST_CompactMemTable();\n\n  // Return an internal iterator over the current state of the database.\n  // The keys of this iterator are internal keys (see format.h).\n  // The returned iterator should be deleted when no longer needed.\n  Iterator* TEST_NewInternalIterator();\n\n  // Return the maximum overlapping data (in bytes) at next level for any\n  // file at a level >= 1.\n  int64_t TEST_MaxNextLevelOverlappingBytes();\n\n  // Record a sample of bytes read at the specified internal key.\n  // Samples are taken approximately once every config::kReadBytesPeriod\n  // bytes.\n  void RecordReadSample(Slice key);\n\n private:\n  friend class DB;\n  struct CompactionState;\n  struct Writer;\n\n  Iterator* NewInternalIterator(const ReadOptions&,\n                                SequenceNumber* latest_snapshot,\n                                uint32_t* seed);\n\n  Status NewDB();\n\n  // Recover the descriptor from persistent storage.  May do a significant\n  // amount of work to recover recently logged updates.  Any changes to\n  // be made to the descriptor are added to *edit.\n  Status Recover(VersionEdit* edit, bool* save_manifest)\n      EXCLUSIVE_LOCKS_REQUIRED(mutex_);\n\n  void MaybeIgnoreError(Status* s) const;\n\n  // Delete any unneeded files and stale in-memory entries.\n  void DeleteObsoleteFiles();\n\n  // Compact the in-memory write buffer to disk.  Switches to a new\n  // log-file/memtable and writes a new descriptor iff successful.\n  // Errors are recorded in bg_error_.\n  void CompactMemTable() EXCLUSIVE_LOCKS_REQUIRED(mutex_);\n\n  Status RecoverLogFile(uint64_t log_number, bool last_log, bool* save_manifest,\n                        VersionEdit* edit, SequenceNumber* max_sequence)\n      EXCLUSIVE_LOCKS_REQUIRED(mutex_);\n\n  Status WriteLevel0Table(MemTable* mem, VersionEdit* edit, Version* base)\n      EXCLUSIVE_LOCKS_REQUIRED(mutex_);\n\n  Status MakeRoomForWrite(bool force /* compact even if there is room? */)\n      EXCLUSIVE_LOCKS_REQUIRED(mutex_);\n  WriteBatch* BuildBatchGroup(Writer** last_writer);\n\n  void RecordBackgroundError(const Status& s);\n\n  void MaybeScheduleCompaction() EXCLUSIVE_LOCKS_REQUIRED(mutex_);\n  static void BGWork(void* db);\n  void BackgroundCall();\n  void  BackgroundCompaction() EXCLUSIVE_LOCKS_REQUIRED(mutex_);\n  void CleanupCompaction(CompactionState* compact)\n      EXCLUSIVE_LOCKS_REQUIRED(mutex_);\n  Status DoCompactionWork(CompactionState* compact)\n      EXCLUSIVE_LOCKS_REQUIRED(mutex_);\n\n  Status OpenCompactionOutputFile(CompactionState* compact);\n  Status FinishCompactionOutputFile(CompactionState* compact, Iterator* input);\n  Status InstallCompactionResults(CompactionState* compact)\n      EXCLUSIVE_LOCKS_REQUIRED(mutex_);\n\n  // Constant after construction\n  Env* const env_;\n  const InternalKeyComparator internal_comparator_;\n  const InternalFilterPolicy internal_filter_policy_;\n  const Options options_;  // options_.comparator == &internal_comparator_\n  bool owns_info_log_;\n  bool owns_cache_;\n  const std::string dbname_;\n\n  // table_cache_ provides its own synchronization\n  TableCache* table_cache_;\n\n  // Lock over the persistent DB state.  Non-NULL iff successfully acquired.\n  FileLock* db_lock_;\n\n  // State below is protected by mutex_\n  port::Mutex mutex_;\n  port::AtomicPointer shutting_down_;\n  port::CondVar bg_cv_;          // Signalled when background work finishes\n  MemTable* mem_;\n  MemTable* imm_;                // Memtable being compacted\n  port::AtomicPointer has_imm_;  // So bg thread can detect non-NULL imm_\n  WritableFile* logfile_;\n  uint64_t logfile_number_;\n  log::Writer* log_;\n  uint32_t seed_;                // For sampling.\n\n  // Queue of writers.\n  std::deque<Writer*> writers_;\n  WriteBatch* tmp_batch_;\n\n  SnapshotList snapshots_;\n\n  // Set of table files to protect from deletion because they are\n  // part of ongoing compactions.\n  std::set<uint64_t> pending_outputs_;\n\n  // Has a background compaction been scheduled or is running?\n  bool bg_compaction_scheduled_;\n\n  // Information for a manual compaction\n  struct ManualCompaction {\n    int level;\n    bool done;\n    const InternalKey* begin;   // NULL means beginning of key range\n    const InternalKey* end;     // NULL means end of key range\n    InternalKey tmp_storage;    // Used to keep track of compaction progress\n  };\n  ManualCompaction* manual_compaction_;\n\n  VersionSet* versions_;\n\n  // Have we encountered a background error in paranoid mode?\n  Status bg_error_;\n\n  // Per level compaction stats.  stats_[level] stores the stats for\n  // compactions that produced data for the specified \"level\".\n  struct CompactionStats {\n    int64_t micros;\n    int64_t bytes_read;\n    int64_t bytes_written;\n\n    CompactionStats() : micros(0), bytes_read(0), bytes_written(0) { }\n\n    void Add(const CompactionStats& c) {\n      this->micros += c.micros;\n      this->bytes_read += c.bytes_read;\n      this->bytes_written += c.bytes_written;\n    }\n  };\n  CompactionStats stats_[config::kNumLevels];\n\n  // No copying allowed\n  DBImpl(const DBImpl&);\n  void operator=(const DBImpl&);\n\n  const Comparator* user_comparator() const {\n    return internal_comparator_.user_comparator();\n  }\n};\n\n// Sanitize db options.  The caller should delete result.info_log if\n// it is not equal to src.info_log.\nextern Options SanitizeOptions(const std::string& db,\n                               const InternalKeyComparator* icmp,\n                               const InternalFilterPolicy* ipolicy,\n                               const Options& src);\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_DB_DB_IMPL_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/db/db_iter.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/db_iter.h\"\n\n#include \"db/filename.h\"\n#include \"db/db_impl.h\"\n#include \"db/dbformat.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/iterator.h\"\n#include \"port/port.h\"\n#include \"util/logging.h\"\n#include \"util/mutexlock.h\"\n#include \"util/random.h\"\n\nnamespace leveldb {\n\n#if 0\nstatic void DumpInternalIter(Iterator* iter) {\n  for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {\n    ParsedInternalKey k;\n    if (!ParseInternalKey(iter->key(), &k)) {\n      fprintf(stderr, \"Corrupt '%s'\\n\", EscapeString(iter->key()).c_str());\n    } else {\n      fprintf(stderr, \"@ '%s'\\n\", k.DebugString().c_str());\n    }\n  }\n}\n#endif\n\nnamespace {\n\n// Memtables and sstables that make the DB representation contain\n// (userkey,seq,type) => uservalue entries.  DBIter\n// combines multiple entries for the same userkey found in the DB\n// representation into a single entry while accounting for sequence\n// numbers, deletion markers, overwrites, etc.\nclass DBIter: public Iterator {\n public:\n  // Which direction is the iterator currently moving?\n  // (1) When moving forward, the internal iterator is positioned at\n  //     the exact entry that yields this->key(), this->value()\n  // (2) When moving backwards, the internal iterator is positioned\n  //     just before all entries whose user key == this->key().\n  enum Direction {\n    kForward,\n    kReverse\n  };\n\n  DBIter(DBImpl* db, const Comparator* cmp, Iterator* iter, SequenceNumber s,\n         uint32_t seed)\n      : db_(db),\n        user_comparator_(cmp),\n        iter_(iter),\n        sequence_(s),\n        direction_(kForward),\n        valid_(false),\n        rnd_(seed),\n        bytes_counter_(RandomPeriod()) {\n  }\n  virtual ~DBIter() {\n    delete iter_;\n  }\n  virtual bool Valid() const { return valid_; }\n  virtual Slice key() const {\n    assert(valid_);\n    return (direction_ == kForward) ? ExtractUserKey(iter_->key()) : saved_key_;\n  }\n  virtual Slice value() const {\n    assert(valid_);\n    return (direction_ == kForward) ? iter_->value() : saved_value_;\n  }\n  virtual Status status() const {\n    if (status_.ok()) {\n      return iter_->status();\n    } else {\n      return status_;\n    }\n  }\n\n  virtual void Next();\n  virtual void Prev();\n  virtual void Seek(const Slice& target);\n  virtual void SeekToFirst();\n  virtual void SeekToLast();\n\n private:\n  void FindNextUserEntry(bool skipping, std::string* skip);\n  void FindPrevUserEntry();\n  bool ParseKey(ParsedInternalKey* key);\n\n  inline void SaveKey(const Slice& k, std::string* dst) {\n    dst->assign(k.data(), k.size());\n  }\n\n  inline void ClearSavedValue() {\n    if (saved_value_.capacity() > 1048576) {\n      std::string empty;\n      swap(empty, saved_value_);\n    } else {\n      saved_value_.clear();\n    }\n  }\n\n  // Pick next gap with average value of config::kReadBytesPeriod.\n  ssize_t RandomPeriod() {\n    return rnd_.Uniform(2*config::kReadBytesPeriod);\n  }\n\n  DBImpl* db_;\n  const Comparator* const user_comparator_;\n  Iterator* const iter_;\n  SequenceNumber const sequence_;\n\n  Status status_;\n  std::string saved_key_;     // == current key when direction_==kReverse\n  std::string saved_value_;   // == current raw value when direction_==kReverse\n  Direction direction_;\n  bool valid_;\n\n  Random rnd_;\n  ssize_t bytes_counter_;\n\n  // No copying allowed\n  DBIter(const DBIter&);\n  void operator=(const DBIter&);\n};\n\ninline bool DBIter::ParseKey(ParsedInternalKey* ikey) {\n  Slice k = iter_->key();\n  ssize_t n = k.size() + iter_->value().size();\n  bytes_counter_ -= n;\n  while (bytes_counter_ < 0) {\n    bytes_counter_ += RandomPeriod();\n    db_->RecordReadSample(k);\n  }\n  if (!ParseInternalKey(k, ikey)) {\n    status_ = Status::Corruption(\"corrupted internal key in DBIter\");\n    return false;\n  } else {\n    return true;\n  }\n}\n\nvoid DBIter::Next() {\n  assert(valid_);\n\n  if (direction_ == kReverse) {  // Switch directions?\n    direction_ = kForward;\n    // iter_ is pointing just before the entries for this->key(),\n    // so advance into the range of entries for this->key() and then\n    // use the normal skipping code below.\n    if (!iter_->Valid()) {\n      iter_->SeekToFirst();\n    } else {\n      iter_->Next();\n    }\n    if (!iter_->Valid()) {\n      valid_ = false;\n      saved_key_.clear();\n      return;\n    }\n    // saved_key_ already contains the key to skip past.\n  } else {\n    // Store in saved_key_ the current key so we skip it below.\n    SaveKey(ExtractUserKey(iter_->key()), &saved_key_);\n  }\n\n  FindNextUserEntry(true, &saved_key_);\n}\n\nvoid DBIter::FindNextUserEntry(bool skipping, std::string* skip) {\n  // Loop until we hit an acceptable entry to yield\n  assert(iter_->Valid());\n  assert(direction_ == kForward);\n  do {\n    ParsedInternalKey ikey;\n    if (ParseKey(&ikey) && ikey.sequence <= sequence_) {\n      switch (ikey.type) {\n        case kTypeDeletion:\n          // Arrange to skip all upcoming entries for this key since\n          // they are hidden by this deletion.\n          SaveKey(ikey.user_key, skip);\n          skipping = true;\n          break;\n        case kTypeValue:\n          if (skipping &&\n              user_comparator_->Compare(ikey.user_key, *skip) <= 0) {\n            // Entry hidden\n          } else {\n            valid_ = true;\n            saved_key_.clear();\n            return;\n          }\n          break;\n      }\n    }\n    iter_->Next();\n  } while (iter_->Valid());\n  saved_key_.clear();\n  valid_ = false;\n}\n\nvoid DBIter::Prev() {\n  assert(valid_);\n\n  if (direction_ == kForward) {  // Switch directions?\n    // iter_ is pointing at the current entry.  Scan backwards until\n    // the key changes so we can use the normal reverse scanning code.\n    assert(iter_->Valid());  // Otherwise valid_ would have been false\n    SaveKey(ExtractUserKey(iter_->key()), &saved_key_);\n    while (true) {\n      iter_->Prev();\n      if (!iter_->Valid()) {\n        valid_ = false;\n        saved_key_.clear();\n        ClearSavedValue();\n        return;\n      }\n      if (user_comparator_->Compare(ExtractUserKey(iter_->key()),\n                                    saved_key_) < 0) {\n        break;\n      }\n    }\n    direction_ = kReverse;\n  }\n\n  FindPrevUserEntry();\n}\n\nvoid DBIter::FindPrevUserEntry() {\n  assert(direction_ == kReverse);\n\n  ValueType value_type = kTypeDeletion;\n  if (iter_->Valid()) {\n    do {\n      ParsedInternalKey ikey;\n      if (ParseKey(&ikey) && ikey.sequence <= sequence_) {\n        if ((value_type != kTypeDeletion) &&\n            user_comparator_->Compare(ikey.user_key, saved_key_) < 0) {\n          // We encountered a non-deleted value in entries for previous keys,\n          break;\n        }\n        value_type = ikey.type;\n        if (value_type == kTypeDeletion) {\n          saved_key_.clear();\n          ClearSavedValue();\n        } else {\n          Slice raw_value = iter_->value();\n          if (saved_value_.capacity() > raw_value.size() + 1048576) {\n            std::string empty;\n            swap(empty, saved_value_);\n          }\n          SaveKey(ExtractUserKey(iter_->key()), &saved_key_);\n          saved_value_.assign(raw_value.data(), raw_value.size());\n        }\n      }\n      iter_->Prev();\n    } while (iter_->Valid());\n  }\n\n  if (value_type == kTypeDeletion) {\n    // End\n    valid_ = false;\n    saved_key_.clear();\n    ClearSavedValue();\n    direction_ = kForward;\n  } else {\n    valid_ = true;\n  }\n}\n\nvoid DBIter::Seek(const Slice& target) {\n  direction_ = kForward;\n  ClearSavedValue();\n  saved_key_.clear();\n  AppendInternalKey(\n      &saved_key_, ParsedInternalKey(target, sequence_, kValueTypeForSeek));\n  iter_->Seek(saved_key_);\n  if (iter_->Valid()) {\n    FindNextUserEntry(false, &saved_key_ /* temporary storage */);\n  } else {\n    valid_ = false;\n  }\n}\n\nvoid DBIter::SeekToFirst() {\n  direction_ = kForward;\n  ClearSavedValue();\n  iter_->SeekToFirst();\n  if (iter_->Valid()) {\n    FindNextUserEntry(false, &saved_key_ /* temporary storage */);\n  } else {\n    valid_ = false;\n  }\n}\n\nvoid DBIter::SeekToLast() {\n  direction_ = kReverse;\n  ClearSavedValue();\n  iter_->SeekToLast();\n  FindPrevUserEntry();\n}\n\n}  // anonymous namespace\n\nIterator* NewDBIterator(\n    DBImpl* db,\n    const Comparator* user_key_comparator,\n    Iterator* internal_iter,\n    SequenceNumber sequence,\n    uint32_t seed) {\n  return new DBIter(db, user_key_comparator, internal_iter, sequence, seed);\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/db/db_iter.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_DB_DB_ITER_H_\n#define STORAGE_LEVELDB_DB_DB_ITER_H_\n\n#include <stdint.h>\n#include \"leveldb/db.h\"\n#include \"db/dbformat.h\"\n\nnamespace leveldb {\n\nclass DBImpl;\n\n// Return a new iterator that converts internal keys (yielded by\n// \"*internal_iter\") that were live at the specified \"sequence\" number\n// into appropriate user keys.\nextern Iterator* NewDBIterator(\n    DBImpl* db,\n    const Comparator* user_key_comparator,\n    Iterator* internal_iter,\n    SequenceNumber sequence,\n    uint32_t seed);\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_DB_DB_ITER_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/db/db_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/db.h\"\n#include \"leveldb/filter_policy.h\"\n#include \"db/db_impl.h\"\n#include \"db/filename.h\"\n#include \"db/version_set.h\"\n#include \"db/write_batch_internal.h\"\n#include \"leveldb/cache.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/table.h\"\n#include \"util/hash.h\"\n#include \"util/logging.h\"\n#include \"util/mutexlock.h\"\n#include \"util/testharness.h\"\n#include \"util/testutil.h\"\n\nnamespace leveldb {\n\nstatic std::string RandomString(Random* rnd, int len) {\n  std::string r;\n  test::RandomString(rnd, len, &r);\n  return r;\n}\n\nnamespace {\nclass AtomicCounter {\n private:\n  port::Mutex mu_;\n  int count_;\n public:\n  AtomicCounter() : count_(0) { }\n  void Increment() {\n    IncrementBy(1);\n  }\n  void IncrementBy(int count) {\n    MutexLock l(&mu_);\n    count_ += count;\n  }\n  int Read() {\n    MutexLock l(&mu_);\n    return count_;\n  }\n  void Reset() {\n    MutexLock l(&mu_);\n    count_ = 0;\n  }\n};\n\nvoid DelayMilliseconds(int millis) {\n  Env::Default()->SleepForMicroseconds(millis * 1000);\n}\n}\n\n// Special Env used to delay background operations\nclass SpecialEnv : public EnvWrapper {\n public:\n  // sstable/log Sync() calls are blocked while this pointer is non-NULL.\n  port::AtomicPointer delay_data_sync_;\n\n  // sstable/log Sync() calls return an error.\n  port::AtomicPointer data_sync_error_;\n\n  // Simulate no-space errors while this pointer is non-NULL.\n  port::AtomicPointer no_space_;\n\n  // Simulate non-writable file system while this pointer is non-NULL\n  port::AtomicPointer non_writable_;\n\n  // Force sync of manifest files to fail while this pointer is non-NULL\n  port::AtomicPointer manifest_sync_error_;\n\n  // Force write to manifest files to fail while this pointer is non-NULL\n  port::AtomicPointer manifest_write_error_;\n\n  bool count_random_reads_;\n  AtomicCounter random_read_counter_;\n\n  explicit SpecialEnv(Env* base) : EnvWrapper(base) {\n    delay_data_sync_.Release_Store(NULL);\n    data_sync_error_.Release_Store(NULL);\n    no_space_.Release_Store(NULL);\n    non_writable_.Release_Store(NULL);\n    count_random_reads_ = false;\n    manifest_sync_error_.Release_Store(NULL);\n    manifest_write_error_.Release_Store(NULL);\n  }\n\n  Status NewWritableFile(const std::string& f, WritableFile** r) {\n    class DataFile : public WritableFile {\n     private:\n      SpecialEnv* env_;\n      WritableFile* base_;\n\n     public:\n      DataFile(SpecialEnv* env, WritableFile* base)\n          : env_(env),\n            base_(base) {\n      }\n      ~DataFile() { delete base_; }\n      Status Append(const Slice& data) {\n        if (env_->no_space_.Acquire_Load() != NULL) {\n          // Drop writes on the floor\n          return Status::OK();\n        } else {\n          return base_->Append(data);\n        }\n      }\n      Status Close() { return base_->Close(); }\n      Status Flush() { return base_->Flush(); }\n      Status Sync() {\n        if (env_->data_sync_error_.Acquire_Load() != NULL) {\n          return Status::IOError(\"simulated data sync error\");\n        }\n        while (env_->delay_data_sync_.Acquire_Load() != NULL) {\n          DelayMilliseconds(100);\n        }\n        return base_->Sync();\n      }\n    };\n    class ManifestFile : public WritableFile {\n     private:\n      SpecialEnv* env_;\n      WritableFile* base_;\n     public:\n      ManifestFile(SpecialEnv* env, WritableFile* b) : env_(env), base_(b) { }\n      ~ManifestFile() { delete base_; }\n      Status Append(const Slice& data) {\n        if (env_->manifest_write_error_.Acquire_Load() != NULL) {\n          return Status::IOError(\"simulated writer error\");\n        } else {\n          return base_->Append(data);\n        }\n      }\n      Status Close() { return base_->Close(); }\n      Status Flush() { return base_->Flush(); }\n      Status Sync() {\n        if (env_->manifest_sync_error_.Acquire_Load() != NULL) {\n          return Status::IOError(\"simulated sync error\");\n        } else {\n          return base_->Sync();\n        }\n      }\n    };\n\n    if (non_writable_.Acquire_Load() != NULL) {\n      return Status::IOError(\"simulated write error\");\n    }\n\n    Status s = target()->NewWritableFile(f, r);\n    if (s.ok()) {\n      if (strstr(f.c_str(), \".ldb\") != NULL ||\n          strstr(f.c_str(), \".log\") != NULL) {\n        *r = new DataFile(this, *r);\n      } else if (strstr(f.c_str(), \"MANIFEST\") != NULL) {\n        *r = new ManifestFile(this, *r);\n      }\n    }\n    return s;\n  }\n\n  Status NewRandomAccessFile(const std::string& f, RandomAccessFile** r) {\n    class CountingFile : public RandomAccessFile {\n     private:\n      RandomAccessFile* target_;\n      AtomicCounter* counter_;\n     public:\n      CountingFile(RandomAccessFile* target, AtomicCounter* counter)\n          : target_(target), counter_(counter) {\n      }\n      virtual ~CountingFile() { delete target_; }\n      virtual Status Read(uint64_t offset, size_t n, Slice* result,\n                          char* scratch) const {\n        counter_->Increment();\n        return target_->Read(offset, n, result, scratch);\n      }\n    };\n\n    Status s = target()->NewRandomAccessFile(f, r);\n    if (s.ok() && count_random_reads_) {\n      *r = new CountingFile(*r, &random_read_counter_);\n    }\n    return s;\n  }\n};\n\nclass DBTest {\n private:\n  const FilterPolicy* filter_policy_;\n\n  // Sequence of option configurations to try\n  enum OptionConfig {\n    kDefault,\n    kReuse,\n    kFilter,\n    kUncompressed,\n    kEnd\n  };\n  int option_config_;\n\n public:\n  std::string dbname_;\n  SpecialEnv* env_;\n  DB* db_;\n\n  Options last_options_;\n\n  DBTest() : option_config_(kDefault),\n             env_(new SpecialEnv(Env::Default())) {\n    filter_policy_ = NewBloomFilterPolicy(10);\n    dbname_ = test::TmpDir() + \"/db_test\";\n    DestroyDB(dbname_, Options());\n    db_ = NULL;\n    Reopen();\n  }\n\n  ~DBTest() {\n    delete db_;\n    DestroyDB(dbname_, Options());\n    delete env_;\n    delete filter_policy_;\n  }\n\n  // Switch to a fresh database with the next option configuration to\n  // test.  Return false if there are no more configurations to test.\n  bool ChangeOptions() {\n    option_config_++;\n    if (option_config_ >= kEnd) {\n      return false;\n    } else {\n      DestroyAndReopen();\n      return true;\n    }\n  }\n\n  // Return the current option configuration.\n  Options CurrentOptions() {\n    Options options;\n    options.reuse_logs = false;\n    switch (option_config_) {\n      case kReuse:\n        options.reuse_logs = true;\n        break;\n      case kFilter:\n        options.filter_policy = filter_policy_;\n        break;\n      case kUncompressed:\n        options.compression = kNoCompression;\n        break;\n      default:\n        break;\n    }\n    return options;\n  }\n\n  DBImpl* dbfull() {\n    return reinterpret_cast<DBImpl*>(db_);\n  }\n\n  void Reopen(Options* options = NULL) {\n    ASSERT_OK(TryReopen(options));\n  }\n\n  void Close() {\n    delete db_;\n    db_ = NULL;\n  }\n\n  void DestroyAndReopen(Options* options = NULL) {\n    delete db_;\n    db_ = NULL;\n    DestroyDB(dbname_, Options());\n    ASSERT_OK(TryReopen(options));\n  }\n\n  Status TryReopen(Options* options) {\n    delete db_;\n    db_ = NULL;\n    Options opts;\n    if (options != NULL) {\n      opts = *options;\n    } else {\n      opts = CurrentOptions();\n      opts.create_if_missing = true;\n    }\n    last_options_ = opts;\n\n    return DB::Open(opts, dbname_, &db_);\n  }\n\n  Status Put(const std::string& k, const std::string& v) {\n    return db_->Put(WriteOptions(), k, v);\n  }\n\n  Status Delete(const std::string& k) {\n    return db_->Delete(WriteOptions(), k);\n  }\n\n  std::string Get(const std::string& k, const Snapshot* snapshot = NULL) {\n    ReadOptions options;\n    options.snapshot = snapshot;\n    std::string result;\n    Status s = db_->Get(options, k, &result);\n    if (s.IsNotFound()) {\n      result = \"NOT_FOUND\";\n    } else if (!s.ok()) {\n      result = s.ToString();\n    }\n    return result;\n  }\n\n  // Return a string that contains all key,value pairs in order,\n  // formatted like \"(k1->v1)(k2->v2)\".\n  std::string Contents() {\n    std::vector<std::string> forward;\n    std::string result;\n    Iterator* iter = db_->NewIterator(ReadOptions());\n    for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {\n      std::string s = IterStatus(iter);\n      result.push_back('(');\n      result.append(s);\n      result.push_back(')');\n      forward.push_back(s);\n    }\n\n    // Check reverse iteration results are the reverse of forward results\n    size_t matched = 0;\n    for (iter->SeekToLast(); iter->Valid(); iter->Prev()) {\n      ASSERT_LT(matched, forward.size());\n      ASSERT_EQ(IterStatus(iter), forward[forward.size() - matched - 1]);\n      matched++;\n    }\n    ASSERT_EQ(matched, forward.size());\n\n    delete iter;\n    return result;\n  }\n\n  std::string AllEntriesFor(const Slice& user_key) {\n    Iterator* iter = dbfull()->TEST_NewInternalIterator();\n    InternalKey target(user_key, kMaxSequenceNumber, kTypeValue);\n    iter->Seek(target.Encode());\n    std::string result;\n    if (!iter->status().ok()) {\n      result = iter->status().ToString();\n    } else {\n      result = \"[ \";\n      bool first = true;\n      while (iter->Valid()) {\n        ParsedInternalKey ikey;\n        if (!ParseInternalKey(iter->key(), &ikey)) {\n          result += \"CORRUPTED\";\n        } else {\n          if (last_options_.comparator->Compare(ikey.user_key, user_key) != 0) {\n            break;\n          }\n          if (!first) {\n            result += \", \";\n          }\n          first = false;\n          switch (ikey.type) {\n            case kTypeValue:\n              result += iter->value().ToString();\n              break;\n            case kTypeDeletion:\n              result += \"DEL\";\n              break;\n          }\n        }\n        iter->Next();\n      }\n      if (!first) {\n        result += \" \";\n      }\n      result += \"]\";\n    }\n    delete iter;\n    return result;\n  }\n\n  int NumTableFilesAtLevel(int level) {\n    std::string property;\n    ASSERT_TRUE(\n        db_->GetProperty(\"leveldb.num-files-at-level\" + NumberToString(level),\n                         &property));\n    return atoi(property.c_str());\n  }\n\n  int TotalTableFiles() {\n    int result = 0;\n    for (int level = 0; level < config::kNumLevels; level++) {\n      result += NumTableFilesAtLevel(level);\n    }\n    return result;\n  }\n\n  // Return spread of files per level\n  std::string FilesPerLevel() {\n    std::string result;\n    int last_non_zero_offset = 0;\n    for (int level = 0; level < config::kNumLevels; level++) {\n      int f = NumTableFilesAtLevel(level);\n      char buf[100];\n      snprintf(buf, sizeof(buf), \"%s%d\", (level ? \",\" : \"\"), f);\n      result += buf;\n      if (f > 0) {\n        last_non_zero_offset = result.size();\n      }\n    }\n    result.resize(last_non_zero_offset);\n    return result;\n  }\n\n  int CountFiles() {\n    std::vector<std::string> files;\n    env_->GetChildren(dbname_, &files);\n    return static_cast<int>(files.size());\n  }\n\n  uint64_t Size(const Slice& start, const Slice& limit) {\n    Range r(start, limit);\n    uint64_t size;\n    db_->GetApproximateSizes(&r, 1, &size);\n    return size;\n  }\n\n  void Compact(const Slice& start, const Slice& limit) {\n    db_->CompactRange(&start, &limit);\n  }\n\n  // Do n memtable compactions, each of which produces an sstable\n  // covering the range [small,large].\n  void MakeTables(int n, const std::string& small, const std::string& large) {\n    for (int i = 0; i < n; i++) {\n      Put(small, \"begin\");\n      Put(large, \"end\");\n      dbfull()->TEST_CompactMemTable();\n    }\n  }\n\n  // Prevent pushing of new sstables into deeper levels by adding\n  // tables that cover a specified range to all levels.\n  void FillLevels(const std::string& smallest, const std::string& largest) {\n    MakeTables(config::kNumLevels, smallest, largest);\n  }\n\n  void DumpFileCounts(const char* label) {\n    fprintf(stderr, \"---\\n%s:\\n\", label);\n    fprintf(stderr, \"maxoverlap: %lld\\n\",\n            static_cast<long long>(\n                dbfull()->TEST_MaxNextLevelOverlappingBytes()));\n    for (int level = 0; level < config::kNumLevels; level++) {\n      int num = NumTableFilesAtLevel(level);\n      if (num > 0) {\n        fprintf(stderr, \"  level %3d : %d files\\n\", level, num);\n      }\n    }\n  }\n\n  std::string DumpSSTableList() {\n    std::string property;\n    db_->GetProperty(\"leveldb.sstables\", &property);\n    return property;\n  }\n\n  std::string IterStatus(Iterator* iter) {\n    std::string result;\n    if (iter->Valid()) {\n      result = iter->key().ToString() + \"->\" + iter->value().ToString();\n    } else {\n      result = \"(invalid)\";\n    }\n    return result;\n  }\n\n  bool DeleteAnSSTFile() {\n    std::vector<std::string> filenames;\n    ASSERT_OK(env_->GetChildren(dbname_, &filenames));\n    uint64_t number;\n    FileType type;\n    for (size_t i = 0; i < filenames.size(); i++) {\n      if (ParseFileName(filenames[i], &number, &type) && type == kTableFile) {\n        ASSERT_OK(env_->DeleteFile(TableFileName(dbname_, number)));\n        return true;\n      }\n    }\n    return false;\n  }\n\n  // Returns number of files renamed.\n  int RenameLDBToSST() {\n    std::vector<std::string> filenames;\n    ASSERT_OK(env_->GetChildren(dbname_, &filenames));\n    uint64_t number;\n    FileType type;\n    int files_renamed = 0;\n    for (size_t i = 0; i < filenames.size(); i++) {\n      if (ParseFileName(filenames[i], &number, &type) && type == kTableFile) {\n        const std::string from = TableFileName(dbname_, number);\n        const std::string to = SSTTableFileName(dbname_, number);\n        ASSERT_OK(env_->RenameFile(from, to));\n        files_renamed++;\n      }\n    }\n    return files_renamed;\n  }\n};\n\nTEST(DBTest, Empty) {\n  do {\n    ASSERT_TRUE(db_ != NULL);\n    ASSERT_EQ(\"NOT_FOUND\", Get(\"foo\"));\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, ReadWrite) {\n  do {\n    ASSERT_OK(Put(\"foo\", \"v1\"));\n    ASSERT_EQ(\"v1\", Get(\"foo\"));\n    ASSERT_OK(Put(\"bar\", \"v2\"));\n    ASSERT_OK(Put(\"foo\", \"v3\"));\n    ASSERT_EQ(\"v3\", Get(\"foo\"));\n    ASSERT_EQ(\"v2\", Get(\"bar\"));\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, PutDeleteGet) {\n  do {\n    ASSERT_OK(db_->Put(WriteOptions(), \"foo\", \"v1\"));\n    ASSERT_EQ(\"v1\", Get(\"foo\"));\n    ASSERT_OK(db_->Put(WriteOptions(), \"foo\", \"v2\"));\n    ASSERT_EQ(\"v2\", Get(\"foo\"));\n    ASSERT_OK(db_->Delete(WriteOptions(), \"foo\"));\n    ASSERT_EQ(\"NOT_FOUND\", Get(\"foo\"));\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, GetFromImmutableLayer) {\n  do {\n    Options options = CurrentOptions();\n    options.env = env_;\n    options.write_buffer_size = 100000;  // Small write buffer\n    Reopen(&options);\n\n    ASSERT_OK(Put(\"foo\", \"v1\"));\n    ASSERT_EQ(\"v1\", Get(\"foo\"));\n\n    env_->delay_data_sync_.Release_Store(env_);      // Block sync calls\n    Put(\"k1\", std::string(100000, 'x'));             // Fill memtable\n    Put(\"k2\", std::string(100000, 'y'));             // Trigger compaction\n    ASSERT_EQ(\"v1\", Get(\"foo\"));\n    env_->delay_data_sync_.Release_Store(NULL);      // Release sync calls\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, GetFromVersions) {\n  do {\n    ASSERT_OK(Put(\"foo\", \"v1\"));\n    dbfull()->TEST_CompactMemTable();\n    ASSERT_EQ(\"v1\", Get(\"foo\"));\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, GetMemUsage) {\n  do {\n    ASSERT_OK(Put(\"foo\", \"v1\"));\n    std::string val;\n    ASSERT_TRUE(db_->GetProperty(\"leveldb.approximate-memory-usage\", &val));\n    int mem_usage = atoi(val.c_str());\n    ASSERT_GT(mem_usage, 0);\n    ASSERT_LT(mem_usage, 5*1024*1024);\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, GetSnapshot) {\n  do {\n    // Try with both a short key and a long key\n    for (int i = 0; i < 2; i++) {\n      std::string key = (i == 0) ? std::string(\"foo\") : std::string(200, 'x');\n      ASSERT_OK(Put(key, \"v1\"));\n      const Snapshot* s1 = db_->GetSnapshot();\n      ASSERT_OK(Put(key, \"v2\"));\n      ASSERT_EQ(\"v2\", Get(key));\n      ASSERT_EQ(\"v1\", Get(key, s1));\n      dbfull()->TEST_CompactMemTable();\n      ASSERT_EQ(\"v2\", Get(key));\n      ASSERT_EQ(\"v1\", Get(key, s1));\n      db_->ReleaseSnapshot(s1);\n    }\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, GetLevel0Ordering) {\n  do {\n    // Check that we process level-0 files in correct order.  The code\n    // below generates two level-0 files where the earlier one comes\n    // before the later one in the level-0 file list since the earlier\n    // one has a smaller \"smallest\" key.\n    ASSERT_OK(Put(\"bar\", \"b\"));\n    ASSERT_OK(Put(\"foo\", \"v1\"));\n    dbfull()->TEST_CompactMemTable();\n    ASSERT_OK(Put(\"foo\", \"v2\"));\n    dbfull()->TEST_CompactMemTable();\n    ASSERT_EQ(\"v2\", Get(\"foo\"));\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, GetOrderedByLevels) {\n  do {\n    ASSERT_OK(Put(\"foo\", \"v1\"));\n    Compact(\"a\", \"z\");\n    ASSERT_EQ(\"v1\", Get(\"foo\"));\n    ASSERT_OK(Put(\"foo\", \"v2\"));\n    ASSERT_EQ(\"v2\", Get(\"foo\"));\n    dbfull()->TEST_CompactMemTable();\n    ASSERT_EQ(\"v2\", Get(\"foo\"));\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, GetPicksCorrectFile) {\n  do {\n    // Arrange to have multiple files in a non-level-0 level.\n    ASSERT_OK(Put(\"a\", \"va\"));\n    Compact(\"a\", \"b\");\n    ASSERT_OK(Put(\"x\", \"vx\"));\n    Compact(\"x\", \"y\");\n    ASSERT_OK(Put(\"f\", \"vf\"));\n    Compact(\"f\", \"g\");\n    ASSERT_EQ(\"va\", Get(\"a\"));\n    ASSERT_EQ(\"vf\", Get(\"f\"));\n    ASSERT_EQ(\"vx\", Get(\"x\"));\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, GetEncountersEmptyLevel) {\n  do {\n    // Arrange for the following to happen:\n    //   * sstable A in level 0\n    //   * nothing in level 1\n    //   * sstable B in level 2\n    // Then do enough Get() calls to arrange for an automatic compaction\n    // of sstable A.  A bug would cause the compaction to be marked as\n    // occurring at level 1 (instead of the correct level 0).\n\n    // Step 1: First place sstables in levels 0 and 2\n    int compaction_count = 0;\n    while (NumTableFilesAtLevel(0) == 0 ||\n           NumTableFilesAtLevel(2) == 0) {\n      ASSERT_LE(compaction_count, 100) << \"could not fill levels 0 and 2\";\n      compaction_count++;\n      Put(\"a\", \"begin\");\n      Put(\"z\", \"end\");\n      dbfull()->TEST_CompactMemTable();\n    }\n\n    // Step 2: clear level 1 if necessary.\n    dbfull()->TEST_CompactRange(1, NULL, NULL);\n    ASSERT_EQ(NumTableFilesAtLevel(0), 1);\n    ASSERT_EQ(NumTableFilesAtLevel(1), 0);\n    ASSERT_EQ(NumTableFilesAtLevel(2), 1);\n\n    // Step 3: read a bunch of times\n    for (int i = 0; i < 1000; i++) {\n      ASSERT_EQ(\"NOT_FOUND\", Get(\"missing\"));\n    }\n\n    // Step 4: Wait for compaction to finish\n    DelayMilliseconds(1000);\n\n    ASSERT_EQ(NumTableFilesAtLevel(0), 0);\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, IterEmpty) {\n  Iterator* iter = db_->NewIterator(ReadOptions());\n\n  iter->SeekToFirst();\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n\n  iter->SeekToLast();\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n\n  iter->Seek(\"foo\");\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n\n  delete iter;\n}\n\nTEST(DBTest, IterSingle) {\n  ASSERT_OK(Put(\"a\", \"va\"));\n  Iterator* iter = db_->NewIterator(ReadOptions());\n\n  iter->SeekToFirst();\n  ASSERT_EQ(IterStatus(iter), \"a->va\");\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n  iter->SeekToFirst();\n  ASSERT_EQ(IterStatus(iter), \"a->va\");\n  iter->Prev();\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n\n  iter->SeekToLast();\n  ASSERT_EQ(IterStatus(iter), \"a->va\");\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n  iter->SeekToLast();\n  ASSERT_EQ(IterStatus(iter), \"a->va\");\n  iter->Prev();\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n\n  iter->Seek(\"\");\n  ASSERT_EQ(IterStatus(iter), \"a->va\");\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n\n  iter->Seek(\"a\");\n  ASSERT_EQ(IterStatus(iter), \"a->va\");\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n\n  iter->Seek(\"b\");\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n\n  delete iter;\n}\n\nTEST(DBTest, IterMulti) {\n  ASSERT_OK(Put(\"a\", \"va\"));\n  ASSERT_OK(Put(\"b\", \"vb\"));\n  ASSERT_OK(Put(\"c\", \"vc\"));\n  Iterator* iter = db_->NewIterator(ReadOptions());\n\n  iter->SeekToFirst();\n  ASSERT_EQ(IterStatus(iter), \"a->va\");\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"b->vb\");\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"c->vc\");\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n  iter->SeekToFirst();\n  ASSERT_EQ(IterStatus(iter), \"a->va\");\n  iter->Prev();\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n\n  iter->SeekToLast();\n  ASSERT_EQ(IterStatus(iter), \"c->vc\");\n  iter->Prev();\n  ASSERT_EQ(IterStatus(iter), \"b->vb\");\n  iter->Prev();\n  ASSERT_EQ(IterStatus(iter), \"a->va\");\n  iter->Prev();\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n  iter->SeekToLast();\n  ASSERT_EQ(IterStatus(iter), \"c->vc\");\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n\n  iter->Seek(\"\");\n  ASSERT_EQ(IterStatus(iter), \"a->va\");\n  iter->Seek(\"a\");\n  ASSERT_EQ(IterStatus(iter), \"a->va\");\n  iter->Seek(\"ax\");\n  ASSERT_EQ(IterStatus(iter), \"b->vb\");\n  iter->Seek(\"b\");\n  ASSERT_EQ(IterStatus(iter), \"b->vb\");\n  iter->Seek(\"z\");\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n\n  // Switch from reverse to forward\n  iter->SeekToLast();\n  iter->Prev();\n  iter->Prev();\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"b->vb\");\n\n  // Switch from forward to reverse\n  iter->SeekToFirst();\n  iter->Next();\n  iter->Next();\n  iter->Prev();\n  ASSERT_EQ(IterStatus(iter), \"b->vb\");\n\n  // Make sure iter stays at snapshot\n  ASSERT_OK(Put(\"a\",  \"va2\"));\n  ASSERT_OK(Put(\"a2\", \"va3\"));\n  ASSERT_OK(Put(\"b\",  \"vb2\"));\n  ASSERT_OK(Put(\"c\",  \"vc2\"));\n  ASSERT_OK(Delete(\"b\"));\n  iter->SeekToFirst();\n  ASSERT_EQ(IterStatus(iter), \"a->va\");\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"b->vb\");\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"c->vc\");\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n  iter->SeekToLast();\n  ASSERT_EQ(IterStatus(iter), \"c->vc\");\n  iter->Prev();\n  ASSERT_EQ(IterStatus(iter), \"b->vb\");\n  iter->Prev();\n  ASSERT_EQ(IterStatus(iter), \"a->va\");\n  iter->Prev();\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n\n  delete iter;\n}\n\nTEST(DBTest, IterSmallAndLargeMix) {\n  ASSERT_OK(Put(\"a\", \"va\"));\n  ASSERT_OK(Put(\"b\", std::string(100000, 'b')));\n  ASSERT_OK(Put(\"c\", \"vc\"));\n  ASSERT_OK(Put(\"d\", std::string(100000, 'd')));\n  ASSERT_OK(Put(\"e\", std::string(100000, 'e')));\n\n  Iterator* iter = db_->NewIterator(ReadOptions());\n\n  iter->SeekToFirst();\n  ASSERT_EQ(IterStatus(iter), \"a->va\");\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"b->\" + std::string(100000, 'b'));\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"c->vc\");\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"d->\" + std::string(100000, 'd'));\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"e->\" + std::string(100000, 'e'));\n  iter->Next();\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n\n  iter->SeekToLast();\n  ASSERT_EQ(IterStatus(iter), \"e->\" + std::string(100000, 'e'));\n  iter->Prev();\n  ASSERT_EQ(IterStatus(iter), \"d->\" + std::string(100000, 'd'));\n  iter->Prev();\n  ASSERT_EQ(IterStatus(iter), \"c->vc\");\n  iter->Prev();\n  ASSERT_EQ(IterStatus(iter), \"b->\" + std::string(100000, 'b'));\n  iter->Prev();\n  ASSERT_EQ(IterStatus(iter), \"a->va\");\n  iter->Prev();\n  ASSERT_EQ(IterStatus(iter), \"(invalid)\");\n\n  delete iter;\n}\n\nTEST(DBTest, IterMultiWithDelete) {\n  do {\n    ASSERT_OK(Put(\"a\", \"va\"));\n    ASSERT_OK(Put(\"b\", \"vb\"));\n    ASSERT_OK(Put(\"c\", \"vc\"));\n    ASSERT_OK(Delete(\"b\"));\n    ASSERT_EQ(\"NOT_FOUND\", Get(\"b\"));\n\n    Iterator* iter = db_->NewIterator(ReadOptions());\n    iter->Seek(\"c\");\n    ASSERT_EQ(IterStatus(iter), \"c->vc\");\n    iter->Prev();\n    ASSERT_EQ(IterStatus(iter), \"a->va\");\n    delete iter;\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, Recover) {\n  do {\n    ASSERT_OK(Put(\"foo\", \"v1\"));\n    ASSERT_OK(Put(\"baz\", \"v5\"));\n\n    Reopen();\n    ASSERT_EQ(\"v1\", Get(\"foo\"));\n\n    ASSERT_EQ(\"v1\", Get(\"foo\"));\n    ASSERT_EQ(\"v5\", Get(\"baz\"));\n    ASSERT_OK(Put(\"bar\", \"v2\"));\n    ASSERT_OK(Put(\"foo\", \"v3\"));\n\n    Reopen();\n    ASSERT_EQ(\"v3\", Get(\"foo\"));\n    ASSERT_OK(Put(\"foo\", \"v4\"));\n    ASSERT_EQ(\"v4\", Get(\"foo\"));\n    ASSERT_EQ(\"v2\", Get(\"bar\"));\n    ASSERT_EQ(\"v5\", Get(\"baz\"));\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, RecoveryWithEmptyLog) {\n  do {\n    ASSERT_OK(Put(\"foo\", \"v1\"));\n    ASSERT_OK(Put(\"foo\", \"v2\"));\n    Reopen();\n    Reopen();\n    ASSERT_OK(Put(\"foo\", \"v3\"));\n    Reopen();\n    ASSERT_EQ(\"v3\", Get(\"foo\"));\n  } while (ChangeOptions());\n}\n\n// Check that writes done during a memtable compaction are recovered\n// if the database is shutdown during the memtable compaction.\nTEST(DBTest, RecoverDuringMemtableCompaction) {\n  do {\n    Options options = CurrentOptions();\n    options.env = env_;\n    options.write_buffer_size = 1000000;\n    Reopen(&options);\n\n    // Trigger a long memtable compaction and reopen the database during it\n    ASSERT_OK(Put(\"foo\", \"v1\"));                         // Goes to 1st log file\n    ASSERT_OK(Put(\"big1\", std::string(10000000, 'x')));  // Fills memtable\n    ASSERT_OK(Put(\"big2\", std::string(1000, 'y')));      // Triggers compaction\n    ASSERT_OK(Put(\"bar\", \"v2\"));                         // Goes to new log file\n\n    Reopen(&options);\n    ASSERT_EQ(\"v1\", Get(\"foo\"));\n    ASSERT_EQ(\"v2\", Get(\"bar\"));\n    ASSERT_EQ(std::string(10000000, 'x'), Get(\"big1\"));\n    ASSERT_EQ(std::string(1000, 'y'), Get(\"big2\"));\n  } while (ChangeOptions());\n}\n\nstatic std::string Key(int i) {\n  char buf[100];\n  snprintf(buf, sizeof(buf), \"key%06d\", i);\n  return std::string(buf);\n}\n\nTEST(DBTest, MinorCompactionsHappen) {\n  Options options = CurrentOptions();\n  options.write_buffer_size = 10000;\n  Reopen(&options);\n\n  const int N = 500;\n\n  int starting_num_tables = TotalTableFiles();\n  for (int i = 0; i < N; i++) {\n    ASSERT_OK(Put(Key(i), Key(i) + std::string(1000, 'v')));\n  }\n  int ending_num_tables = TotalTableFiles();\n  ASSERT_GT(ending_num_tables, starting_num_tables);\n\n  for (int i = 0; i < N; i++) {\n    ASSERT_EQ(Key(i) + std::string(1000, 'v'), Get(Key(i)));\n  }\n\n  Reopen();\n\n  for (int i = 0; i < N; i++) {\n    ASSERT_EQ(Key(i) + std::string(1000, 'v'), Get(Key(i)));\n  }\n}\n\nTEST(DBTest, RecoverWithLargeLog) {\n  {\n    Options options = CurrentOptions();\n    Reopen(&options);\n    ASSERT_OK(Put(\"big1\", std::string(200000, '1')));\n    ASSERT_OK(Put(\"big2\", std::string(200000, '2')));\n    ASSERT_OK(Put(\"small3\", std::string(10, '3')));\n    ASSERT_OK(Put(\"small4\", std::string(10, '4')));\n    ASSERT_EQ(NumTableFilesAtLevel(0), 0);\n  }\n\n  // Make sure that if we re-open with a small write buffer size that\n  // we flush table files in the middle of a large log file.\n  Options options = CurrentOptions();\n  options.write_buffer_size = 100000;\n  Reopen(&options);\n  ASSERT_EQ(NumTableFilesAtLevel(0), 3);\n  ASSERT_EQ(std::string(200000, '1'), Get(\"big1\"));\n  ASSERT_EQ(std::string(200000, '2'), Get(\"big2\"));\n  ASSERT_EQ(std::string(10, '3'), Get(\"small3\"));\n  ASSERT_EQ(std::string(10, '4'), Get(\"small4\"));\n  ASSERT_GT(NumTableFilesAtLevel(0), 1);\n}\n\nTEST(DBTest, CompactionsGenerateMultipleFiles) {\n  Options options = CurrentOptions();\n  options.write_buffer_size = 100000000;        // Large write buffer\n  Reopen(&options);\n\n  Random rnd(301);\n\n  // Write 8MB (80 values, each 100K)\n  ASSERT_EQ(NumTableFilesAtLevel(0), 0);\n  std::vector<std::string> values;\n  for (int i = 0; i < 80; i++) {\n    values.push_back(RandomString(&rnd, 100000));\n    ASSERT_OK(Put(Key(i), values[i]));\n  }\n\n  // Reopening moves updates to level-0\n  Reopen(&options);\n  dbfull()->TEST_CompactRange(0, NULL, NULL);\n\n  ASSERT_EQ(NumTableFilesAtLevel(0), 0);\n  ASSERT_GT(NumTableFilesAtLevel(1), 1);\n  for (int i = 0; i < 80; i++) {\n    ASSERT_EQ(Get(Key(i)), values[i]);\n  }\n}\n\nTEST(DBTest, RepeatedWritesToSameKey) {\n  Options options = CurrentOptions();\n  options.env = env_;\n  options.write_buffer_size = 100000;  // Small write buffer\n  Reopen(&options);\n\n  // We must have at most one file per level except for level-0,\n  // which may have up to kL0_StopWritesTrigger files.\n  const int kMaxFiles = config::kNumLevels + config::kL0_StopWritesTrigger;\n\n  Random rnd(301);\n  std::string value = RandomString(&rnd, 2 * options.write_buffer_size);\n  for (int i = 0; i < 5 * kMaxFiles; i++) {\n    Put(\"key\", value);\n    ASSERT_LE(TotalTableFiles(), kMaxFiles);\n    fprintf(stderr, \"after %d: %d files\\n\", int(i+1), TotalTableFiles());\n  }\n}\n\nTEST(DBTest, SparseMerge) {\n  Options options = CurrentOptions();\n  options.compression = kNoCompression;\n  Reopen(&options);\n\n  FillLevels(\"A\", \"Z\");\n\n  // Suppose there is:\n  //    small amount of data with prefix A\n  //    large amount of data with prefix B\n  //    small amount of data with prefix C\n  // and that recent updates have made small changes to all three prefixes.\n  // Check that we do not do a compaction that merges all of B in one shot.\n  const std::string value(1000, 'x');\n  Put(\"A\", \"va\");\n  // Write approximately 100MB of \"B\" values\n  for (int i = 0; i < 100000; i++) {\n    char key[100];\n    snprintf(key, sizeof(key), \"B%010d\", i);\n    Put(key, value);\n  }\n  Put(\"C\", \"vc\");\n  dbfull()->TEST_CompactMemTable();\n  dbfull()->TEST_CompactRange(0, NULL, NULL);\n\n  // Make sparse update\n  Put(\"A\",    \"va2\");\n  Put(\"B100\", \"bvalue2\");\n  Put(\"C\",    \"vc2\");\n  dbfull()->TEST_CompactMemTable();\n\n  // Compactions should not cause us to create a situation where\n  // a file overlaps too much data at the next level.\n  ASSERT_LE(dbfull()->TEST_MaxNextLevelOverlappingBytes(), 20*1048576);\n  dbfull()->TEST_CompactRange(0, NULL, NULL);\n  ASSERT_LE(dbfull()->TEST_MaxNextLevelOverlappingBytes(), 20*1048576);\n  dbfull()->TEST_CompactRange(1, NULL, NULL);\n  ASSERT_LE(dbfull()->TEST_MaxNextLevelOverlappingBytes(), 20*1048576);\n}\n\nstatic bool Between(uint64_t val, uint64_t low, uint64_t high) {\n  bool result = (val >= low) && (val <= high);\n  if (!result) {\n    fprintf(stderr, \"Value %llu is not in range [%llu, %llu]\\n\",\n            (unsigned long long)(val),\n            (unsigned long long)(low),\n            (unsigned long long)(high));\n  }\n  return result;\n}\n\nTEST(DBTest, ApproximateSizes) {\n  do {\n    Options options = CurrentOptions();\n    options.write_buffer_size = 100000000;        // Large write buffer\n    options.compression = kNoCompression;\n    DestroyAndReopen();\n\n    ASSERT_TRUE(Between(Size(\"\", \"xyz\"), 0, 0));\n    Reopen(&options);\n    ASSERT_TRUE(Between(Size(\"\", \"xyz\"), 0, 0));\n\n    // Write 8MB (80 values, each 100K)\n    ASSERT_EQ(NumTableFilesAtLevel(0), 0);\n    const int N = 80;\n    static const int S1 = 100000;\n    static const int S2 = 105000;  // Allow some expansion from metadata\n    Random rnd(301);\n    for (int i = 0; i < N; i++) {\n      ASSERT_OK(Put(Key(i), RandomString(&rnd, S1)));\n    }\n\n    // 0 because GetApproximateSizes() does not account for memtable space\n    ASSERT_TRUE(Between(Size(\"\", Key(50)), 0, 0));\n\n    if (options.reuse_logs) {\n      // Recovery will reuse memtable, and GetApproximateSizes() does not\n      // account for memtable usage;\n      Reopen(&options);\n      ASSERT_TRUE(Between(Size(\"\", Key(50)), 0, 0));\n      continue;\n    }\n\n    // Check sizes across recovery by reopening a few times\n    for (int run = 0; run < 3; run++) {\n      Reopen(&options);\n\n      for (int compact_start = 0; compact_start < N; compact_start += 10) {\n        for (int i = 0; i < N; i += 10) {\n          ASSERT_TRUE(Between(Size(\"\", Key(i)), S1*i, S2*i));\n          ASSERT_TRUE(Between(Size(\"\", Key(i)+\".suffix\"), S1*(i+1), S2*(i+1)));\n          ASSERT_TRUE(Between(Size(Key(i), Key(i+10)), S1*10, S2*10));\n        }\n        ASSERT_TRUE(Between(Size(\"\", Key(50)), S1*50, S2*50));\n        ASSERT_TRUE(Between(Size(\"\", Key(50)+\".suffix\"), S1*50, S2*50));\n\n        std::string cstart_str = Key(compact_start);\n        std::string cend_str = Key(compact_start + 9);\n        Slice cstart = cstart_str;\n        Slice cend = cend_str;\n        dbfull()->TEST_CompactRange(0, &cstart, &cend);\n      }\n\n      ASSERT_EQ(NumTableFilesAtLevel(0), 0);\n      ASSERT_GT(NumTableFilesAtLevel(1), 0);\n    }\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, ApproximateSizes_MixOfSmallAndLarge) {\n  do {\n    Options options = CurrentOptions();\n    options.compression = kNoCompression;\n    Reopen();\n\n    Random rnd(301);\n    std::string big1 = RandomString(&rnd, 100000);\n    ASSERT_OK(Put(Key(0), RandomString(&rnd, 10000)));\n    ASSERT_OK(Put(Key(1), RandomString(&rnd, 10000)));\n    ASSERT_OK(Put(Key(2), big1));\n    ASSERT_OK(Put(Key(3), RandomString(&rnd, 10000)));\n    ASSERT_OK(Put(Key(4), big1));\n    ASSERT_OK(Put(Key(5), RandomString(&rnd, 10000)));\n    ASSERT_OK(Put(Key(6), RandomString(&rnd, 300000)));\n    ASSERT_OK(Put(Key(7), RandomString(&rnd, 10000)));\n\n    if (options.reuse_logs) {\n      // Need to force a memtable compaction since recovery does not do so.\n      ASSERT_OK(dbfull()->TEST_CompactMemTable());\n    }\n\n    // Check sizes across recovery by reopening a few times\n    for (int run = 0; run < 3; run++) {\n      Reopen(&options);\n\n      ASSERT_TRUE(Between(Size(\"\", Key(0)), 0, 0));\n      ASSERT_TRUE(Between(Size(\"\", Key(1)), 10000, 11000));\n      ASSERT_TRUE(Between(Size(\"\", Key(2)), 20000, 21000));\n      ASSERT_TRUE(Between(Size(\"\", Key(3)), 120000, 121000));\n      ASSERT_TRUE(Between(Size(\"\", Key(4)), 130000, 131000));\n      ASSERT_TRUE(Between(Size(\"\", Key(5)), 230000, 231000));\n      ASSERT_TRUE(Between(Size(\"\", Key(6)), 240000, 241000));\n      ASSERT_TRUE(Between(Size(\"\", Key(7)), 540000, 541000));\n      ASSERT_TRUE(Between(Size(\"\", Key(8)), 550000, 560000));\n\n      ASSERT_TRUE(Between(Size(Key(3), Key(5)), 110000, 111000));\n\n      dbfull()->TEST_CompactRange(0, NULL, NULL);\n    }\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, IteratorPinsRef) {\n  Put(\"foo\", \"hello\");\n\n  // Get iterator that will yield the current contents of the DB.\n  Iterator* iter = db_->NewIterator(ReadOptions());\n\n  // Write to force compactions\n  Put(\"foo\", \"newvalue1\");\n  for (int i = 0; i < 100; i++) {\n    ASSERT_OK(Put(Key(i), Key(i) + std::string(100000, 'v'))); // 100K values\n  }\n  Put(\"foo\", \"newvalue2\");\n\n  iter->SeekToFirst();\n  ASSERT_TRUE(iter->Valid());\n  ASSERT_EQ(\"foo\", iter->key().ToString());\n  ASSERT_EQ(\"hello\", iter->value().ToString());\n  iter->Next();\n  ASSERT_TRUE(!iter->Valid());\n  delete iter;\n}\n\nTEST(DBTest, Snapshot) {\n  do {\n    Put(\"foo\", \"v1\");\n    const Snapshot* s1 = db_->GetSnapshot();\n    Put(\"foo\", \"v2\");\n    const Snapshot* s2 = db_->GetSnapshot();\n    Put(\"foo\", \"v3\");\n    const Snapshot* s3 = db_->GetSnapshot();\n\n    Put(\"foo\", \"v4\");\n    ASSERT_EQ(\"v1\", Get(\"foo\", s1));\n    ASSERT_EQ(\"v2\", Get(\"foo\", s2));\n    ASSERT_EQ(\"v3\", Get(\"foo\", s3));\n    ASSERT_EQ(\"v4\", Get(\"foo\"));\n\n    db_->ReleaseSnapshot(s3);\n    ASSERT_EQ(\"v1\", Get(\"foo\", s1));\n    ASSERT_EQ(\"v2\", Get(\"foo\", s2));\n    ASSERT_EQ(\"v4\", Get(\"foo\"));\n\n    db_->ReleaseSnapshot(s1);\n    ASSERT_EQ(\"v2\", Get(\"foo\", s2));\n    ASSERT_EQ(\"v4\", Get(\"foo\"));\n\n    db_->ReleaseSnapshot(s2);\n    ASSERT_EQ(\"v4\", Get(\"foo\"));\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, HiddenValuesAreRemoved) {\n  do {\n    Random rnd(301);\n    FillLevels(\"a\", \"z\");\n\n    std::string big = RandomString(&rnd, 50000);\n    Put(\"foo\", big);\n    Put(\"pastfoo\", \"v\");\n    const Snapshot* snapshot = db_->GetSnapshot();\n    Put(\"foo\", \"tiny\");\n    Put(\"pastfoo2\", \"v2\");        // Advance sequence number one more\n\n    ASSERT_OK(dbfull()->TEST_CompactMemTable());\n    ASSERT_GT(NumTableFilesAtLevel(0), 0);\n\n    ASSERT_EQ(big, Get(\"foo\", snapshot));\n    ASSERT_TRUE(Between(Size(\"\", \"pastfoo\"), 50000, 60000));\n    db_->ReleaseSnapshot(snapshot);\n    ASSERT_EQ(AllEntriesFor(\"foo\"), \"[ tiny, \" + big + \" ]\");\n    Slice x(\"x\");\n    dbfull()->TEST_CompactRange(0, NULL, &x);\n    ASSERT_EQ(AllEntriesFor(\"foo\"), \"[ tiny ]\");\n    ASSERT_EQ(NumTableFilesAtLevel(0), 0);\n    ASSERT_GE(NumTableFilesAtLevel(1), 1);\n    dbfull()->TEST_CompactRange(1, NULL, &x);\n    ASSERT_EQ(AllEntriesFor(\"foo\"), \"[ tiny ]\");\n\n    ASSERT_TRUE(Between(Size(\"\", \"pastfoo\"), 0, 1000));\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, DeletionMarkers1) {\n  Put(\"foo\", \"v1\");\n  ASSERT_OK(dbfull()->TEST_CompactMemTable());\n  const int last = config::kMaxMemCompactLevel;\n  ASSERT_EQ(NumTableFilesAtLevel(last), 1);   // foo => v1 is now in last level\n\n  // Place a table at level last-1 to prevent merging with preceding mutation\n  Put(\"a\", \"begin\");\n  Put(\"z\", \"end\");\n  dbfull()->TEST_CompactMemTable();\n  ASSERT_EQ(NumTableFilesAtLevel(last), 1);\n  ASSERT_EQ(NumTableFilesAtLevel(last-1), 1);\n\n  Delete(\"foo\");\n  Put(\"foo\", \"v2\");\n  ASSERT_EQ(AllEntriesFor(\"foo\"), \"[ v2, DEL, v1 ]\");\n  ASSERT_OK(dbfull()->TEST_CompactMemTable());  // Moves to level last-2\n  ASSERT_EQ(AllEntriesFor(\"foo\"), \"[ v2, DEL, v1 ]\");\n  Slice z(\"z\");\n  dbfull()->TEST_CompactRange(last-2, NULL, &z);\n  // DEL eliminated, but v1 remains because we aren't compacting that level\n  // (DEL can be eliminated because v2 hides v1).\n  ASSERT_EQ(AllEntriesFor(\"foo\"), \"[ v2, v1 ]\");\n  dbfull()->TEST_CompactRange(last-1, NULL, NULL);\n  // Merging last-1 w/ last, so we are the base level for \"foo\", so\n  // DEL is removed.  (as is v1).\n  ASSERT_EQ(AllEntriesFor(\"foo\"), \"[ v2 ]\");\n}\n\nTEST(DBTest, DeletionMarkers2) {\n  Put(\"foo\", \"v1\");\n  ASSERT_OK(dbfull()->TEST_CompactMemTable());\n  const int last = config::kMaxMemCompactLevel;\n  ASSERT_EQ(NumTableFilesAtLevel(last), 1);   // foo => v1 is now in last level\n\n  // Place a table at level last-1 to prevent merging with preceding mutation\n  Put(\"a\", \"begin\");\n  Put(\"z\", \"end\");\n  dbfull()->TEST_CompactMemTable();\n  ASSERT_EQ(NumTableFilesAtLevel(last), 1);\n  ASSERT_EQ(NumTableFilesAtLevel(last-1), 1);\n\n  Delete(\"foo\");\n  ASSERT_EQ(AllEntriesFor(\"foo\"), \"[ DEL, v1 ]\");\n  ASSERT_OK(dbfull()->TEST_CompactMemTable());  // Moves to level last-2\n  ASSERT_EQ(AllEntriesFor(\"foo\"), \"[ DEL, v1 ]\");\n  dbfull()->TEST_CompactRange(last-2, NULL, NULL);\n  // DEL kept: \"last\" file overlaps\n  ASSERT_EQ(AllEntriesFor(\"foo\"), \"[ DEL, v1 ]\");\n  dbfull()->TEST_CompactRange(last-1, NULL, NULL);\n  // Merging last-1 w/ last, so we are the base level for \"foo\", so\n  // DEL is removed.  (as is v1).\n  ASSERT_EQ(AllEntriesFor(\"foo\"), \"[ ]\");\n}\n\nTEST(DBTest, OverlapInLevel0) {\n  do {\n    ASSERT_EQ(config::kMaxMemCompactLevel, 2) << \"Fix test to match config\";\n\n    // Fill levels 1 and 2 to disable the pushing of new memtables to levels > 0.\n    ASSERT_OK(Put(\"100\", \"v100\"));\n    ASSERT_OK(Put(\"999\", \"v999\"));\n    dbfull()->TEST_CompactMemTable();\n    ASSERT_OK(Delete(\"100\"));\n    ASSERT_OK(Delete(\"999\"));\n    dbfull()->TEST_CompactMemTable();\n    ASSERT_EQ(\"0,1,1\", FilesPerLevel());\n\n    // Make files spanning the following ranges in level-0:\n    //  files[0]  200 .. 900\n    //  files[1]  300 .. 500\n    // Note that files are sorted by smallest key.\n    ASSERT_OK(Put(\"300\", \"v300\"));\n    ASSERT_OK(Put(\"500\", \"v500\"));\n    dbfull()->TEST_CompactMemTable();\n    ASSERT_OK(Put(\"200\", \"v200\"));\n    ASSERT_OK(Put(\"600\", \"v600\"));\n    ASSERT_OK(Put(\"900\", \"v900\"));\n    dbfull()->TEST_CompactMemTable();\n    ASSERT_EQ(\"2,1,1\", FilesPerLevel());\n\n    // Compact away the placeholder files we created initially\n    dbfull()->TEST_CompactRange(1, NULL, NULL);\n    dbfull()->TEST_CompactRange(2, NULL, NULL);\n    ASSERT_EQ(\"2\", FilesPerLevel());\n\n    // Do a memtable compaction.  Before bug-fix, the compaction would\n    // not detect the overlap with level-0 files and would incorrectly place\n    // the deletion in a deeper level.\n    ASSERT_OK(Delete(\"600\"));\n    dbfull()->TEST_CompactMemTable();\n    ASSERT_EQ(\"3\", FilesPerLevel());\n    ASSERT_EQ(\"NOT_FOUND\", Get(\"600\"));\n  } while (ChangeOptions());\n}\n\nTEST(DBTest, L0_CompactionBug_Issue44_a) {\n  Reopen();\n  ASSERT_OK(Put(\"b\", \"v\"));\n  Reopen();\n  ASSERT_OK(Delete(\"b\"));\n  ASSERT_OK(Delete(\"a\"));\n  Reopen();\n  ASSERT_OK(Delete(\"a\"));\n  Reopen();\n  ASSERT_OK(Put(\"a\", \"v\"));\n  Reopen();\n  Reopen();\n  ASSERT_EQ(\"(a->v)\", Contents());\n  DelayMilliseconds(1000);  // Wait for compaction to finish\n  ASSERT_EQ(\"(a->v)\", Contents());\n}\n\nTEST(DBTest, L0_CompactionBug_Issue44_b) {\n  Reopen();\n  Put(\"\",\"\");\n  Reopen();\n  Delete(\"e\");\n  Put(\"\",\"\");\n  Reopen();\n  Put(\"c\", \"cv\");\n  Reopen();\n  Put(\"\",\"\");\n  Reopen();\n  Put(\"\",\"\");\n  DelayMilliseconds(1000);  // Wait for compaction to finish\n  Reopen();\n  Put(\"d\",\"dv\");\n  Reopen();\n  Put(\"\",\"\");\n  Reopen();\n  Delete(\"d\");\n  Delete(\"b\");\n  Reopen();\n  ASSERT_EQ(\"(->)(c->cv)\", Contents());\n  DelayMilliseconds(1000);  // Wait for compaction to finish\n  ASSERT_EQ(\"(->)(c->cv)\", Contents());\n}\n\nTEST(DBTest, ComparatorCheck) {\n  class NewComparator : public Comparator {\n   public:\n    virtual const char* Name() const { return \"leveldb.NewComparator\"; }\n    virtual int Compare(const Slice& a, const Slice& b) const {\n      return BytewiseComparator()->Compare(a, b);\n    }\n    virtual void FindShortestSeparator(std::string* s, const Slice& l) const {\n      BytewiseComparator()->FindShortestSeparator(s, l);\n    }\n    virtual void FindShortSuccessor(std::string* key) const {\n      BytewiseComparator()->FindShortSuccessor(key);\n    }\n  };\n  NewComparator cmp;\n  Options new_options = CurrentOptions();\n  new_options.comparator = &cmp;\n  Status s = TryReopen(&new_options);\n  ASSERT_TRUE(!s.ok());\n  ASSERT_TRUE(s.ToString().find(\"comparator\") != std::string::npos)\n      << s.ToString();\n}\n\nTEST(DBTest, CustomComparator) {\n  class NumberComparator : public Comparator {\n   public:\n    virtual const char* Name() const { return \"test.NumberComparator\"; }\n    virtual int Compare(const Slice& a, const Slice& b) const {\n      return ToNumber(a) - ToNumber(b);\n    }\n    virtual void FindShortestSeparator(std::string* s, const Slice& l) const {\n      ToNumber(*s);     // Check format\n      ToNumber(l);      // Check format\n    }\n    virtual void FindShortSuccessor(std::string* key) const {\n      ToNumber(*key);   // Check format\n    }\n   private:\n    static int ToNumber(const Slice& x) {\n      // Check that there are no extra characters.\n      ASSERT_TRUE(x.size() >= 2 && x[0] == '[' && x[x.size()-1] == ']')\n          << EscapeString(x);\n      int val;\n      char ignored;\n      ASSERT_TRUE(sscanf(x.ToString().c_str(), \"[%i]%c\", &val, &ignored) == 1)\n          << EscapeString(x);\n      return val;\n    }\n  };\n  NumberComparator cmp;\n  Options new_options = CurrentOptions();\n  new_options.create_if_missing = true;\n  new_options.comparator = &cmp;\n  new_options.filter_policy = NULL;     // Cannot use bloom filters\n  new_options.write_buffer_size = 1000;  // Compact more often\n  DestroyAndReopen(&new_options);\n  ASSERT_OK(Put(\"[10]\", \"ten\"));\n  ASSERT_OK(Put(\"[0x14]\", \"twenty\"));\n  for (int i = 0; i < 2; i++) {\n    ASSERT_EQ(\"ten\", Get(\"[10]\"));\n    ASSERT_EQ(\"ten\", Get(\"[0xa]\"));\n    ASSERT_EQ(\"twenty\", Get(\"[20]\"));\n    ASSERT_EQ(\"twenty\", Get(\"[0x14]\"));\n    ASSERT_EQ(\"NOT_FOUND\", Get(\"[15]\"));\n    ASSERT_EQ(\"NOT_FOUND\", Get(\"[0xf]\"));\n    Compact(\"[0]\", \"[9999]\");\n  }\n\n  for (int run = 0; run < 2; run++) {\n    for (int i = 0; i < 1000; i++) {\n      char buf[100];\n      snprintf(buf, sizeof(buf), \"[%d]\", i*10);\n      ASSERT_OK(Put(buf, buf));\n    }\n    Compact(\"[0]\", \"[1000000]\");\n  }\n}\n\nTEST(DBTest, ManualCompaction) {\n  ASSERT_EQ(config::kMaxMemCompactLevel, 2)\n      << \"Need to update this test to match kMaxMemCompactLevel\";\n\n  MakeTables(3, \"p\", \"q\");\n  ASSERT_EQ(\"1,1,1\", FilesPerLevel());\n\n  // Compaction range falls before files\n  Compact(\"\", \"c\");\n  ASSERT_EQ(\"1,1,1\", FilesPerLevel());\n\n  // Compaction range falls after files\n  Compact(\"r\", \"z\");\n  ASSERT_EQ(\"1,1,1\", FilesPerLevel());\n\n  // Compaction range overlaps files\n  Compact(\"p1\", \"p9\");\n  ASSERT_EQ(\"0,0,1\", FilesPerLevel());\n\n  // Populate a different range\n  MakeTables(3, \"c\", \"e\");\n  ASSERT_EQ(\"1,1,2\", FilesPerLevel());\n\n  // Compact just the new range\n  Compact(\"b\", \"f\");\n  ASSERT_EQ(\"0,0,2\", FilesPerLevel());\n\n  // Compact all\n  MakeTables(1, \"a\", \"z\");\n  ASSERT_EQ(\"0,1,2\", FilesPerLevel());\n  db_->CompactRange(NULL, NULL);\n  ASSERT_EQ(\"0,0,1\", FilesPerLevel());\n}\n\nTEST(DBTest, DBOpen_Options) {\n  std::string dbname = test::TmpDir() + \"/db_options_test\";\n  DestroyDB(dbname, Options());\n\n  // Does not exist, and create_if_missing == false: error\n  DB* db = NULL;\n  Options opts;\n  opts.create_if_missing = false;\n  Status s = DB::Open(opts, dbname, &db);\n  ASSERT_TRUE(strstr(s.ToString().c_str(), \"does not exist\") != NULL);\n  ASSERT_TRUE(db == NULL);\n\n  // Does not exist, and create_if_missing == true: OK\n  opts.create_if_missing = true;\n  s = DB::Open(opts, dbname, &db);\n  ASSERT_OK(s);\n  ASSERT_TRUE(db != NULL);\n\n  delete db;\n  db = NULL;\n\n  // Does exist, and error_if_exists == true: error\n  opts.create_if_missing = false;\n  opts.error_if_exists = true;\n  s = DB::Open(opts, dbname, &db);\n  ASSERT_TRUE(strstr(s.ToString().c_str(), \"exists\") != NULL);\n  ASSERT_TRUE(db == NULL);\n\n  // Does exist, and error_if_exists == false: OK\n  opts.create_if_missing = true;\n  opts.error_if_exists = false;\n  s = DB::Open(opts, dbname, &db);\n  ASSERT_OK(s);\n  ASSERT_TRUE(db != NULL);\n\n  delete db;\n  db = NULL;\n}\n\nTEST(DBTest, Locking) {\n  DB* db2 = NULL;\n  Status s = DB::Open(CurrentOptions(), dbname_, &db2);\n  ASSERT_TRUE(!s.ok()) << \"Locking did not prevent re-opening db\";\n}\n\n// Check that number of files does not grow when we are out of space\nTEST(DBTest, NoSpace) {\n  Options options = CurrentOptions();\n  options.env = env_;\n  Reopen(&options);\n\n  ASSERT_OK(Put(\"foo\", \"v1\"));\n  ASSERT_EQ(\"v1\", Get(\"foo\"));\n  Compact(\"a\", \"z\");\n  const int num_files = CountFiles();\n  env_->no_space_.Release_Store(env_);   // Force out-of-space errors\n  for (int i = 0; i < 10; i++) {\n    for (int level = 0; level < config::kNumLevels-1; level++) {\n      dbfull()->TEST_CompactRange(level, NULL, NULL);\n    }\n  }\n  env_->no_space_.Release_Store(NULL);\n  ASSERT_LT(CountFiles(), num_files + 3);\n}\n\nTEST(DBTest, NonWritableFileSystem) {\n  Options options = CurrentOptions();\n  options.write_buffer_size = 1000;\n  options.env = env_;\n  Reopen(&options);\n  ASSERT_OK(Put(\"foo\", \"v1\"));\n  env_->non_writable_.Release_Store(env_);  // Force errors for new files\n  std::string big(100000, 'x');\n  int errors = 0;\n  for (int i = 0; i < 20; i++) {\n    fprintf(stderr, \"iter %d; errors %d\\n\", i, errors);\n    if (!Put(\"foo\", big).ok()) {\n      errors++;\n      DelayMilliseconds(100);\n    }\n  }\n  ASSERT_GT(errors, 0);\n  env_->non_writable_.Release_Store(NULL);\n}\n\nTEST(DBTest, WriteSyncError) {\n  // Check that log sync errors cause the DB to disallow future writes.\n\n  // (a) Cause log sync calls to fail\n  Options options = CurrentOptions();\n  options.env = env_;\n  Reopen(&options);\n  env_->data_sync_error_.Release_Store(env_);\n\n  // (b) Normal write should succeed\n  WriteOptions w;\n  ASSERT_OK(db_->Put(w, \"k1\", \"v1\"));\n  ASSERT_EQ(\"v1\", Get(\"k1\"));\n\n  // (c) Do a sync write; should fail\n  w.sync = true;\n  ASSERT_TRUE(!db_->Put(w, \"k2\", \"v2\").ok());\n  ASSERT_EQ(\"v1\", Get(\"k1\"));\n  ASSERT_EQ(\"NOT_FOUND\", Get(\"k2\"));\n\n  // (d) make sync behave normally\n  env_->data_sync_error_.Release_Store(NULL);\n\n  // (e) Do a non-sync write; should fail\n  w.sync = false;\n  ASSERT_TRUE(!db_->Put(w, \"k3\", \"v3\").ok());\n  ASSERT_EQ(\"v1\", Get(\"k1\"));\n  ASSERT_EQ(\"NOT_FOUND\", Get(\"k2\"));\n  ASSERT_EQ(\"NOT_FOUND\", Get(\"k3\"));\n}\n\nTEST(DBTest, ManifestWriteError) {\n  // Test for the following problem:\n  // (a) Compaction produces file F\n  // (b) Log record containing F is written to MANIFEST file, but Sync() fails\n  // (c) GC deletes F\n  // (d) After reopening DB, reads fail since deleted F is named in log record\n\n  // We iterate twice.  In the second iteration, everything is the\n  // same except the log record never makes it to the MANIFEST file.\n  for (int iter = 0; iter < 2; iter++) {\n    port::AtomicPointer* error_type = (iter == 0)\n        ? &env_->manifest_sync_error_\n        : &env_->manifest_write_error_;\n\n    // Insert foo=>bar mapping\n    Options options = CurrentOptions();\n    options.env = env_;\n    options.create_if_missing = true;\n    options.error_if_exists = false;\n    DestroyAndReopen(&options);\n    ASSERT_OK(Put(\"foo\", \"bar\"));\n    ASSERT_EQ(\"bar\", Get(\"foo\"));\n\n    // Memtable compaction (will succeed)\n    dbfull()->TEST_CompactMemTable();\n    ASSERT_EQ(\"bar\", Get(\"foo\"));\n    const int last = config::kMaxMemCompactLevel;\n    ASSERT_EQ(NumTableFilesAtLevel(last), 1);   // foo=>bar is now in last level\n\n    // Merging compaction (will fail)\n    error_type->Release_Store(env_);\n    dbfull()->TEST_CompactRange(last, NULL, NULL);  // Should fail\n    ASSERT_EQ(\"bar\", Get(\"foo\"));\n\n    // Recovery: should not lose data\n    error_type->Release_Store(NULL);\n    Reopen(&options);\n    ASSERT_EQ(\"bar\", Get(\"foo\"));\n  }\n}\n\nTEST(DBTest, MissingSSTFile) {\n  ASSERT_OK(Put(\"foo\", \"bar\"));\n  ASSERT_EQ(\"bar\", Get(\"foo\"));\n\n  // Dump the memtable to disk.\n  dbfull()->TEST_CompactMemTable();\n  ASSERT_EQ(\"bar\", Get(\"foo\"));\n\n  Close();\n  ASSERT_TRUE(DeleteAnSSTFile());\n  Options options = CurrentOptions();\n  options.paranoid_checks = true;\n  Status s = TryReopen(&options);\n  ASSERT_TRUE(!s.ok());\n  ASSERT_TRUE(s.ToString().find(\"issing\") != std::string::npos)\n      << s.ToString();\n}\n\nTEST(DBTest, StillReadSST) {\n  ASSERT_OK(Put(\"foo\", \"bar\"));\n  ASSERT_EQ(\"bar\", Get(\"foo\"));\n\n  // Dump the memtable to disk.\n  dbfull()->TEST_CompactMemTable();\n  ASSERT_EQ(\"bar\", Get(\"foo\"));\n  Close();\n  ASSERT_GT(RenameLDBToSST(), 0);\n  Options options = CurrentOptions();\n  options.paranoid_checks = true;\n  Status s = TryReopen(&options);\n  ASSERT_TRUE(s.ok());\n  ASSERT_EQ(\"bar\", Get(\"foo\"));\n}\n\nTEST(DBTest, FilesDeletedAfterCompaction) {\n  ASSERT_OK(Put(\"foo\", \"v2\"));\n  Compact(\"a\", \"z\");\n  const int num_files = CountFiles();\n  for (int i = 0; i < 10; i++) {\n    ASSERT_OK(Put(\"foo\", \"v2\"));\n    Compact(\"a\", \"z\");\n  }\n  ASSERT_EQ(CountFiles(), num_files);\n}\n\nTEST(DBTest, BloomFilter) {\n  env_->count_random_reads_ = true;\n  Options options = CurrentOptions();\n  options.env = env_;\n  options.block_cache = NewLRUCache(0);  // Prevent cache hits\n  options.filter_policy = NewBloomFilterPolicy(10);\n  Reopen(&options);\n\n  // Populate multiple layers\n  const int N = 10000;\n  for (int i = 0; i < N; i++) {\n    ASSERT_OK(Put(Key(i), Key(i)));\n  }\n  Compact(\"a\", \"z\");\n  for (int i = 0; i < N; i += 100) {\n    ASSERT_OK(Put(Key(i), Key(i)));\n  }\n  dbfull()->TEST_CompactMemTable();\n\n  // Prevent auto compactions triggered by seeks\n  env_->delay_data_sync_.Release_Store(env_);\n\n  // Lookup present keys.  Should rarely read from small sstable.\n  env_->random_read_counter_.Reset();\n  for (int i = 0; i < N; i++) {\n    ASSERT_EQ(Key(i), Get(Key(i)));\n  }\n  int reads = env_->random_read_counter_.Read();\n  fprintf(stderr, \"%d present => %d reads\\n\", N, reads);\n  ASSERT_GE(reads, N);\n  ASSERT_LE(reads, N + 2*N/100);\n\n  // Lookup present keys.  Should rarely read from either sstable.\n  env_->random_read_counter_.Reset();\n  for (int i = 0; i < N; i++) {\n    ASSERT_EQ(\"NOT_FOUND\", Get(Key(i) + \".missing\"));\n  }\n  reads = env_->random_read_counter_.Read();\n  fprintf(stderr, \"%d missing => %d reads\\n\", N, reads);\n  ASSERT_LE(reads, 3*N/100);\n\n  env_->delay_data_sync_.Release_Store(NULL);\n  Close();\n  delete options.block_cache;\n  delete options.filter_policy;\n}\n\n// Multi-threaded test:\nnamespace {\n\nstatic const int kNumThreads = 4;\nstatic const int kTestSeconds = 10;\nstatic const int kNumKeys = 1000;\n\nstruct MTState {\n  DBTest* test;\n  port::AtomicPointer stop;\n  port::AtomicPointer counter[kNumThreads];\n  port::AtomicPointer thread_done[kNumThreads];\n};\n\nstruct MTThread {\n  MTState* state;\n  int id;\n};\n\nstatic void MTThreadBody(void* arg) {\n  MTThread* t = reinterpret_cast<MTThread*>(arg);\n  int id = t->id;\n  DB* db = t->state->test->db_;\n  uintptr_t counter = 0;\n  fprintf(stderr, \"... starting thread %d\\n\", id);\n  Random rnd(1000 + id);\n  std::string value;\n  char valbuf[1500];\n  while (t->state->stop.Acquire_Load() == NULL) {\n    t->state->counter[id].Release_Store(reinterpret_cast<void*>(counter));\n\n    int key = rnd.Uniform(kNumKeys);\n    char keybuf[20];\n    snprintf(keybuf, sizeof(keybuf), \"%016d\", key);\n\n    if (rnd.OneIn(2)) {\n      // Write values of the form <key, my id, counter>.\n      // We add some padding for force compactions.\n      snprintf(valbuf, sizeof(valbuf), \"%d.%d.%-1000d\",\n               key, id, static_cast<int>(counter));\n      ASSERT_OK(db->Put(WriteOptions(), Slice(keybuf), Slice(valbuf)));\n    } else {\n      // Read a value and verify that it matches the pattern written above.\n      Status s = db->Get(ReadOptions(), Slice(keybuf), &value);\n      if (s.IsNotFound()) {\n        // Key has not yet been written\n      } else {\n        // Check that the writer thread counter is >= the counter in the value\n        ASSERT_OK(s);\n        int k, w, c;\n        ASSERT_EQ(3, sscanf(value.c_str(), \"%d.%d.%d\", &k, &w, &c)) << value;\n        ASSERT_EQ(k, key);\n        ASSERT_GE(w, 0);\n        ASSERT_LT(w, kNumThreads);\n        ASSERT_LE(static_cast<uintptr_t>(c), reinterpret_cast<uintptr_t>(\n            t->state->counter[w].Acquire_Load()));\n      }\n    }\n    counter++;\n  }\n  t->state->thread_done[id].Release_Store(t);\n  fprintf(stderr, \"... stopping thread %d after %d ops\\n\", id, int(counter));\n}\n\n}  // namespace\n\nTEST(DBTest, MultiThreaded) {\n  do {\n    // Initialize state\n    MTState mt;\n    mt.test = this;\n    mt.stop.Release_Store(0);\n    for (int id = 0; id < kNumThreads; id++) {\n      mt.counter[id].Release_Store(0);\n      mt.thread_done[id].Release_Store(0);\n    }\n\n    // Start threads\n    MTThread thread[kNumThreads];\n    for (int id = 0; id < kNumThreads; id++) {\n      thread[id].state = &mt;\n      thread[id].id = id;\n      env_->StartThread(MTThreadBody, &thread[id]);\n    }\n\n    // Let them run for a while\n    DelayMilliseconds(kTestSeconds * 1000);\n\n    // Stop the threads and wait for them to finish\n    mt.stop.Release_Store(&mt);\n    for (int id = 0; id < kNumThreads; id++) {\n      while (mt.thread_done[id].Acquire_Load() == NULL) {\n        DelayMilliseconds(100);\n      }\n    }\n  } while (ChangeOptions());\n}\n\nnamespace {\ntypedef std::map<std::string, std::string> KVMap;\n}\n\nclass ModelDB: public DB {\n public:\n  class ModelSnapshot : public Snapshot {\n   public:\n    KVMap map_;\n  };\n\n  explicit ModelDB(const Options& options): options_(options) { }\n  ~ModelDB() { }\n  virtual Status Put(const WriteOptions& o, const Slice& k, const Slice& v) {\n    return DB::Put(o, k, v);\n  }\n  virtual Status Delete(const WriteOptions& o, const Slice& key) {\n    return DB::Delete(o, key);\n  }\n  virtual Status Get(const ReadOptions& options,\n                     const Slice& key, std::string* value) {\n    assert(false);      // Not implemented\n    return Status::NotFound(key);\n  }\n  virtual Iterator* NewIterator(const ReadOptions& options) {\n    if (options.snapshot == NULL) {\n      KVMap* saved = new KVMap;\n      *saved = map_;\n      return new ModelIter(saved, true);\n    } else {\n      const KVMap* snapshot_state =\n          &(reinterpret_cast<const ModelSnapshot*>(options.snapshot)->map_);\n      return new ModelIter(snapshot_state, false);\n    }\n  }\n  virtual const Snapshot* GetSnapshot() {\n    ModelSnapshot* snapshot = new ModelSnapshot;\n    snapshot->map_ = map_;\n    return snapshot;\n  }\n\n  virtual void ReleaseSnapshot(const Snapshot* snapshot) {\n    delete reinterpret_cast<const ModelSnapshot*>(snapshot);\n  }\n  virtual Status Write(const WriteOptions& options, WriteBatch* batch) {\n    class Handler : public WriteBatch::Handler {\n     public:\n      KVMap* map_;\n      virtual void Put(const Slice& key, const Slice& value) {\n        (*map_)[key.ToString()] = value.ToString();\n      }\n      virtual void Delete(const Slice& key) {\n        map_->erase(key.ToString());\n      }\n    };\n    Handler handler;\n    handler.map_ = &map_;\n    return batch->Iterate(&handler);\n  }\n\n  virtual bool GetProperty(const Slice& property, std::string* value) {\n    return false;\n  }\n  virtual void GetApproximateSizes(const Range* r, int n, uint64_t* sizes) {\n    for (int i = 0; i < n; i++) {\n      sizes[i] = 0;\n    }\n  }\n  virtual void CompactRange(const Slice* start, const Slice* end) {\n  }\n\n private:\n  class ModelIter: public Iterator {\n   public:\n    ModelIter(const KVMap* map, bool owned)\n        : map_(map), owned_(owned), iter_(map_->end()) {\n    }\n    ~ModelIter() {\n      if (owned_) delete map_;\n    }\n    virtual bool Valid() const { return iter_ != map_->end(); }\n    virtual void SeekToFirst() { iter_ = map_->begin(); }\n    virtual void SeekToLast() {\n      if (map_->empty()) {\n        iter_ = map_->end();\n      } else {\n        iter_ = map_->find(map_->rbegin()->first);\n      }\n    }\n    virtual void Seek(const Slice& k) {\n      iter_ = map_->lower_bound(k.ToString());\n    }\n    virtual void Next() { ++iter_; }\n    virtual void Prev() { --iter_; }\n    virtual Slice key() const { return iter_->first; }\n    virtual Slice value() const { return iter_->second; }\n    virtual Status status() const { return Status::OK(); }\n   private:\n    const KVMap* const map_;\n    const bool owned_;  // Do we own map_\n    KVMap::const_iterator iter_;\n  };\n  const Options options_;\n  KVMap map_;\n};\n\nstatic std::string RandomKey(Random* rnd) {\n  int len = (rnd->OneIn(3)\n             ? 1                // Short sometimes to encourage collisions\n             : (rnd->OneIn(100) ? rnd->Skewed(10) : rnd->Uniform(10)));\n  return test::RandomKey(rnd, len);\n}\n\nstatic bool CompareIterators(int step,\n                             DB* model,\n                             DB* db,\n                             const Snapshot* model_snap,\n                             const Snapshot* db_snap) {\n  ReadOptions options;\n  options.snapshot = model_snap;\n  Iterator* miter = model->NewIterator(options);\n  options.snapshot = db_snap;\n  Iterator* dbiter = db->NewIterator(options);\n  bool ok = true;\n  int count = 0;\n  for (miter->SeekToFirst(), dbiter->SeekToFirst();\n       ok && miter->Valid() && dbiter->Valid();\n       miter->Next(), dbiter->Next()) {\n    count++;\n    if (miter->key().compare(dbiter->key()) != 0) {\n      fprintf(stderr, \"step %d: Key mismatch: '%s' vs. '%s'\\n\",\n              step,\n              EscapeString(miter->key()).c_str(),\n              EscapeString(dbiter->key()).c_str());\n      ok = false;\n      break;\n    }\n\n    if (miter->value().compare(dbiter->value()) != 0) {\n      fprintf(stderr, \"step %d: Value mismatch for key '%s': '%s' vs. '%s'\\n\",\n              step,\n              EscapeString(miter->key()).c_str(),\n              EscapeString(miter->value()).c_str(),\n              EscapeString(miter->value()).c_str());\n      ok = false;\n    }\n  }\n\n  if (ok) {\n    if (miter->Valid() != dbiter->Valid()) {\n      fprintf(stderr, \"step %d: Mismatch at end of iterators: %d vs. %d\\n\",\n              step, miter->Valid(), dbiter->Valid());\n      ok = false;\n    }\n  }\n  fprintf(stderr, \"%d entries compared: ok=%d\\n\", count, ok);\n  delete miter;\n  delete dbiter;\n  return ok;\n}\n\nTEST(DBTest, Randomized) {\n  Random rnd(test::RandomSeed());\n  do {\n    ModelDB model(CurrentOptions());\n    const int N = 10000;\n    const Snapshot* model_snap = NULL;\n    const Snapshot* db_snap = NULL;\n    std::string k, v;\n    for (int step = 0; step < N; step++) {\n      if (step % 100 == 0) {\n        fprintf(stderr, \"Step %d of %d\\n\", step, N);\n      }\n      // TODO(sanjay): Test Get() works\n      int p = rnd.Uniform(100);\n      if (p < 45) {                               // Put\n        k = RandomKey(&rnd);\n        v = RandomString(&rnd,\n                         rnd.OneIn(20)\n                         ? 100 + rnd.Uniform(100)\n                         : rnd.Uniform(8));\n        ASSERT_OK(model.Put(WriteOptions(), k, v));\n        ASSERT_OK(db_->Put(WriteOptions(), k, v));\n\n      } else if (p < 90) {                        // Delete\n        k = RandomKey(&rnd);\n        ASSERT_OK(model.Delete(WriteOptions(), k));\n        ASSERT_OK(db_->Delete(WriteOptions(), k));\n\n\n      } else {                                    // Multi-element batch\n        WriteBatch b;\n        const int num = rnd.Uniform(8);\n        for (int i = 0; i < num; i++) {\n          if (i == 0 || !rnd.OneIn(10)) {\n            k = RandomKey(&rnd);\n          } else {\n            // Periodically re-use the same key from the previous iter, so\n            // we have multiple entries in the write batch for the same key\n          }\n          if (rnd.OneIn(2)) {\n            v = RandomString(&rnd, rnd.Uniform(10));\n            b.Put(k, v);\n          } else {\n            b.Delete(k);\n          }\n        }\n        ASSERT_OK(model.Write(WriteOptions(), &b));\n        ASSERT_OK(db_->Write(WriteOptions(), &b));\n      }\n\n      if ((step % 100) == 0) {\n        ASSERT_TRUE(CompareIterators(step, &model, db_, NULL, NULL));\n        ASSERT_TRUE(CompareIterators(step, &model, db_, model_snap, db_snap));\n        // Save a snapshot from each DB this time that we'll use next\n        // time we compare things, to make sure the current state is\n        // preserved with the snapshot\n        if (model_snap != NULL) model.ReleaseSnapshot(model_snap);\n        if (db_snap != NULL) db_->ReleaseSnapshot(db_snap);\n\n        Reopen();\n        ASSERT_TRUE(CompareIterators(step, &model, db_, NULL, NULL));\n\n        model_snap = model.GetSnapshot();\n        db_snap = db_->GetSnapshot();\n      }\n    }\n    if (model_snap != NULL) model.ReleaseSnapshot(model_snap);\n    if (db_snap != NULL) db_->ReleaseSnapshot(db_snap);\n  } while (ChangeOptions());\n}\n\nstd::string MakeKey(unsigned int num) {\n  char buf[30];\n  snprintf(buf, sizeof(buf), \"%016u\", num);\n  return std::string(buf);\n}\n\nvoid BM_LogAndApply(int iters, int num_base_files) {\n  std::string dbname = test::TmpDir() + \"/leveldb_test_benchmark\";\n  DestroyDB(dbname, Options());\n\n  DB* db = NULL;\n  Options opts;\n  opts.create_if_missing = true;\n  Status s = DB::Open(opts, dbname, &db);\n  ASSERT_OK(s);\n  ASSERT_TRUE(db != NULL);\n\n  delete db;\n  db = NULL;\n\n  Env* env = Env::Default();\n\n  port::Mutex mu;\n  MutexLock l(&mu);\n\n  InternalKeyComparator cmp(BytewiseComparator());\n  Options options;\n  VersionSet vset(dbname, &options, NULL, &cmp);\n  bool save_manifest;\n  ASSERT_OK(vset.Recover(&save_manifest));\n  VersionEdit vbase;\n  uint64_t fnum = 1;\n  for (int i = 0; i < num_base_files; i++) {\n    InternalKey start(MakeKey(2*fnum), 1, kTypeValue);\n    InternalKey limit(MakeKey(2*fnum+1), 1, kTypeDeletion);\n    vbase.AddFile(2, fnum++, 1 /* file size */, start, limit);\n  }\n  ASSERT_OK(vset.LogAndApply(&vbase, &mu));\n\n  uint64_t start_micros = env->NowMicros();\n\n  for (int i = 0; i < iters; i++) {\n    VersionEdit vedit;\n    vedit.DeleteFile(2, fnum);\n    InternalKey start(MakeKey(2*fnum), 1, kTypeValue);\n    InternalKey limit(MakeKey(2*fnum+1), 1, kTypeDeletion);\n    vedit.AddFile(2, fnum++, 1 /* file size */, start, limit);\n    vset.LogAndApply(&vedit, &mu);\n  }\n  uint64_t stop_micros = env->NowMicros();\n  unsigned int us = stop_micros - start_micros;\n  char buf[16];\n  snprintf(buf, sizeof(buf), \"%d\", num_base_files);\n  fprintf(stderr,\n          \"BM_LogAndApply/%-6s   %8d iters : %9u us (%7.0f us / iter)\\n\",\n          buf, iters, us, ((float)us) / iters);\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  if (argc > 1 && std::string(argv[1]) == \"--benchmark\") {\n    leveldb::BM_LogAndApply(1000, 1);\n    leveldb::BM_LogAndApply(1000, 100);\n    leveldb::BM_LogAndApply(1000, 10000);\n    leveldb::BM_LogAndApply(100, 100000);\n    return 0;\n  }\n\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/db/dbformat.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include <stdio.h>\n#include \"db/dbformat.h\"\n#include \"port/port.h\"\n#include \"util/coding.h\"\n\nnamespace leveldb {\n\nstatic uint64_t PackSequenceAndType(uint64_t seq, ValueType t) {\n  assert(seq <= kMaxSequenceNumber);\n  assert(t <= kValueTypeForSeek);\n  return (seq << 8) | t;\n}\n\nvoid AppendInternalKey(std::string* result, const ParsedInternalKey& key) {\n  result->append(key.user_key.data(), key.user_key.size());\n  PutFixed64(result, PackSequenceAndType(key.sequence, key.type));\n}\n\nstd::string ParsedInternalKey::DebugString() const {\n  char buf[50];\n  snprintf(buf, sizeof(buf), \"' @ %llu : %d\",\n           (unsigned long long) sequence,\n           int(type));\n  std::string result = \"'\";\n  result += EscapeString(user_key.ToString());\n  result += buf;\n  return result;\n}\n\nstd::string InternalKey::DebugString() const {\n  std::string result;\n  ParsedInternalKey parsed;\n  if (ParseInternalKey(rep_, &parsed)) {\n    result = parsed.DebugString();\n  } else {\n    result = \"(bad)\";\n    result.append(EscapeString(rep_));\n  }\n  return result;\n}\n\nconst char* InternalKeyComparator::Name() const {\n  return \"leveldb.InternalKeyComparator\";\n}\n\nint InternalKeyComparator::Compare(const Slice& akey, const Slice& bkey) const {\n  // Order by:\n  //    increasing user key (according to user-supplied comparator)\n  //    decreasing sequence number\n  //    decreasing type (though sequence# should be enough to disambiguate)\n  int r = user_comparator_->Compare(ExtractUserKey(akey), ExtractUserKey(bkey));\n  if (r == 0) {\n    const uint64_t anum = DecodeFixed64(akey.data() + akey.size() - 8);\n    const uint64_t bnum = DecodeFixed64(bkey.data() + bkey.size() - 8);\n    if (anum > bnum) {\n      r = -1;\n    } else if (anum < bnum) {\n      r = +1;\n    }\n  }\n  return r;\n}\n\nvoid InternalKeyComparator::FindShortestSeparator(\n      std::string* start,\n      const Slice& limit) const {\n  // Attempt to shorten the user portion of the key\n  Slice user_start = ExtractUserKey(*start);\n  Slice user_limit = ExtractUserKey(limit);\n  std::string tmp(user_start.data(), user_start.size());\n  user_comparator_->FindShortestSeparator(&tmp, user_limit);\n  if (tmp.size() < user_start.size() &&\n      user_comparator_->Compare(user_start, tmp) < 0) {\n    // User key has become shorter physically, but larger logically.\n    // Tack on the earliest possible number to the shortened user key.\n    PutFixed64(&tmp, PackSequenceAndType(kMaxSequenceNumber,kValueTypeForSeek));\n    assert(this->Compare(*start, tmp) < 0);\n    assert(this->Compare(tmp, limit) < 0);\n    start->swap(tmp);\n  }\n}\n\nvoid InternalKeyComparator::FindShortSuccessor(std::string* key) const {\n  Slice user_key = ExtractUserKey(*key);\n  std::string tmp(user_key.data(), user_key.size());\n  user_comparator_->FindShortSuccessor(&tmp);\n  if (tmp.size() < user_key.size() &&\n      user_comparator_->Compare(user_key, tmp) < 0) {\n    // User key has become shorter physically, but larger logically.\n    // Tack on the earliest possible number to the shortened user key.\n    PutFixed64(&tmp, PackSequenceAndType(kMaxSequenceNumber,kValueTypeForSeek));\n    assert(this->Compare(*key, tmp) < 0);\n    key->swap(tmp);\n  }\n}\n\nconst char* InternalFilterPolicy::Name() const {\n  return user_policy_->Name();\n}\n\nvoid InternalFilterPolicy::CreateFilter(const Slice* keys, int n,\n                                        std::string* dst) const {\n  // We rely on the fact that the code in table.cc does not mind us\n  // adjusting keys[].\n  Slice* mkey = const_cast<Slice*>(keys);\n  for (int i = 0; i < n; i++) {\n    mkey[i] = ExtractUserKey(keys[i]);\n    // TODO(sanjay): Suppress dups?\n  }\n  user_policy_->CreateFilter(keys, n, dst);\n}\n\nbool InternalFilterPolicy::KeyMayMatch(const Slice& key, const Slice& f) const {\n  return user_policy_->KeyMayMatch(ExtractUserKey(key), f);\n}\n\nLookupKey::LookupKey(const Slice& user_key, SequenceNumber s) {\n  size_t usize = user_key.size();\n  size_t needed = usize + 13;  // A conservative estimate\n  char* dst;\n  if (needed <= sizeof(space_)) {\n    dst = space_;\n  } else {\n    dst = new char[needed];\n  }\n  start_ = dst;\n  dst = EncodeVarint32(dst, usize + 8);\n  kstart_ = dst;\n  memcpy(dst, user_key.data(), usize);\n  dst += usize;\n  EncodeFixed64(dst, PackSequenceAndType(s, kValueTypeForSeek));\n  dst += 8;\n  end_ = dst;\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/db/dbformat.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_DB_DBFORMAT_H_\n#define STORAGE_LEVELDB_DB_DBFORMAT_H_\n\n#include <stdio.h>\n#include \"leveldb/comparator.h\"\n#include \"leveldb/db.h\"\n#include \"leveldb/filter_policy.h\"\n#include \"leveldb/slice.h\"\n#include \"leveldb/table_builder.h\"\n#include \"util/coding.h\"\n#include \"util/logging.h\"\n\nnamespace leveldb {\n\n// Grouping of constants.  We may want to make some of these\n// parameters set via options.\nnamespace config {\nstatic const int kNumLevels = 7;\n\n// Level-0 compaction is started when we hit this many files.\nstatic const int kL0_CompactionTrigger = 4;\n\n// Soft limit on number of level-0 files.  We slow down writes at this point.\nstatic const int kL0_SlowdownWritesTrigger = 16;\n\n// Maximum number of level-0 files.  We stop writes at this point.\nstatic const int kL0_StopWritesTrigger = 64;\n\n// Maximum level to which a new compacted memtable is pushed if it\n// does not create overlap.  We try to push to level 2 to avoid the\n// relatively expensive level 0=>1 compactions and to avoid some\n// expensive manifest file operations.  We do not push all the way to\n// the largest level since that can generate a lot of wasted disk\n// space if the same key space is being repeatedly overwritten.\nstatic const int kMaxMemCompactLevel = 2;\n\n// Approximate gap in bytes between samples of data read during iteration.\nstatic const int kReadBytesPeriod = 1048576;\n\n}  // namespace config\n\nclass InternalKey;\n\n// Value types encoded as the last component of internal keys.\n// DO NOT CHANGE THESE ENUM VALUES: they are embedded in the on-disk\n// data structures.\nenum ValueType {\n  kTypeDeletion = 0x0,\n  kTypeValue = 0x1\n};\n// kValueTypeForSeek defines the ValueType that should be passed when\n// constructing a ParsedInternalKey object for seeking to a particular\n// sequence number (since we sort sequence numbers in decreasing order\n// and the value type is embedded as the low 8 bits in the sequence\n// number in internal keys, we need to use the highest-numbered\n// ValueType, not the lowest).\nstatic const ValueType kValueTypeForSeek = kTypeValue;\n\ntypedef uint64_t SequenceNumber;\n\n// We leave eight bits empty at the bottom so a type and sequence#\n// can be packed together into 64-bits.\nstatic const SequenceNumber kMaxSequenceNumber =\n    ((0x1ull << 56) - 1);\n\nstruct ParsedInternalKey {\n  Slice user_key;\n  SequenceNumber sequence;\n  ValueType type;\n\n  ParsedInternalKey() { }  // Intentionally left uninitialized (for speed)\n  ParsedInternalKey(const Slice& u, const SequenceNumber& seq, ValueType t)\n      : user_key(u), sequence(seq), type(t) { }\n  std::string DebugString() const;\n};\n\n// Return the length of the encoding of \"key\".\ninline size_t InternalKeyEncodingLength(const ParsedInternalKey& key) {\n  return key.user_key.size() + 8;\n}\n\n// Append the serialization of \"key\" to *result.\nextern void AppendInternalKey(std::string* result,\n                              const ParsedInternalKey& key);\n\n// Attempt to parse an internal key from \"internal_key\".  On success,\n// stores the parsed data in \"*result\", and returns true.\n//\n// On error, returns false, leaves \"*result\" in an undefined state.\nextern bool ParseInternalKey(const Slice& internal_key,\n                             ParsedInternalKey* result);\n\n// Returns the user key portion of an internal key.\ninline Slice ExtractUserKey(const Slice& internal_key) {\n  assert(internal_key.size() >= 8);\n  return Slice(internal_key.data(), internal_key.size() - 8);\n}\n\ninline ValueType ExtractValueType(const Slice& internal_key) {\n  assert(internal_key.size() >= 8);\n  const size_t n = internal_key.size();\n  uint64_t num = DecodeFixed64(internal_key.data() + n - 8);\n  unsigned char c = num & 0xff;\n  return static_cast<ValueType>(c);\n}\n\n// A comparator for internal keys that uses a specified comparator for\n// the user key portion and breaks ties by decreasing sequence number.\nclass InternalKeyComparator : public Comparator {\n private:\n  const Comparator* user_comparator_;\n public:\n  explicit InternalKeyComparator(const Comparator* c) : user_comparator_(c) { }\n  virtual const char* Name() const;\n  virtual int Compare(const Slice& a, const Slice& b) const;\n  virtual void FindShortestSeparator(\n      std::string* start,\n      const Slice& limit) const;\n  virtual void FindShortSuccessor(std::string* key) const;\n\n  const Comparator* user_comparator() const { return user_comparator_; }\n\n  int Compare(const InternalKey& a, const InternalKey& b) const;\n};\n\n// Filter policy wrapper that converts from internal keys to user keys\nclass InternalFilterPolicy : public FilterPolicy {\n private:\n  const FilterPolicy* const user_policy_;\n public:\n  explicit InternalFilterPolicy(const FilterPolicy* p) : user_policy_(p) { }\n  virtual const char* Name() const;\n  virtual void CreateFilter(const Slice* keys, int n, std::string* dst) const;\n  virtual bool KeyMayMatch(const Slice& key, const Slice& filter) const;\n};\n\n// Modules in this directory should keep internal keys wrapped inside\n// the following class instead of plain strings so that we do not\n// incorrectly use string comparisons instead of an InternalKeyComparator.\nclass InternalKey {\n private:\n  std::string rep_;\n public:\n  InternalKey() { }   // Leave rep_ as empty to indicate it is invalid\n  InternalKey(const Slice& user_key, SequenceNumber s, ValueType t) {\n    AppendInternalKey(&rep_, ParsedInternalKey(user_key, s, t));\n  }\n\n  void DecodeFrom(const Slice& s) { rep_.assign(s.data(), s.size()); }\n  Slice Encode() const {\n    assert(!rep_.empty());\n    return rep_;\n  }\n\n  Slice user_key() const { return ExtractUserKey(rep_); }\n\n  void SetFrom(const ParsedInternalKey& p) {\n    rep_.clear();\n    AppendInternalKey(&rep_, p);\n  }\n\n  void Clear() { rep_.clear(); }\n\n  std::string DebugString() const;\n};\n\ninline int InternalKeyComparator::Compare(\n    const InternalKey& a, const InternalKey& b) const {\n  return Compare(a.Encode(), b.Encode());\n}\n\ninline bool ParseInternalKey(const Slice& internal_key,\n                             ParsedInternalKey* result) {\n  const size_t n = internal_key.size();\n  if (n < 8) return false;\n  uint64_t num = DecodeFixed64(internal_key.data() + n - 8);\n  unsigned char c = num & 0xff;\n  result->sequence = num >> 8;\n  result->type = static_cast<ValueType>(c);\n  result->user_key = Slice(internal_key.data(), n - 8);\n  return (c <= static_cast<unsigned char>(kTypeValue));\n}\n\n// A helper class useful for DBImpl::Get()\nclass LookupKey {\n public:\n  // Initialize *this for looking up user_key at a snapshot with\n  // the specified sequence number.\n  LookupKey(const Slice& user_key, SequenceNumber sequence);\n\n  ~LookupKey();\n\n  // Return a key suitable for lookup in a MemTable.\n  Slice memtable_key() const { return Slice(start_, end_ - start_); }\n\n  // Return an internal key (suitable for passing to an internal iterator)\n  Slice internal_key() const { return Slice(kstart_, end_ - kstart_); }\n\n  // Return the user key\n  Slice user_key() const { return Slice(kstart_, end_ - kstart_ - 8); }\n\n private:\n  // We construct a char array of the form:\n  //    klength  varint32               <-- start_\n  //    userkey  char[klength]          <-- kstart_\n  //    tag      uint64\n  //                                    <-- end_\n  // The array is a suitable MemTable key.\n  // The suffix starting with \"userkey\" can be used as an InternalKey.\n  const char* start_;\n  const char* kstart_;\n  const char* end_;\n  char space_[200];      // Avoid allocation for short keys\n\n  // No copying allowed\n  LookupKey(const LookupKey&);\n  void operator=(const LookupKey&);\n};\n\ninline LookupKey::~LookupKey() {\n  if (start_ != space_) delete[] start_;\n}\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_DB_DBFORMAT_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/db/dbformat.h.bk",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_DB_DBFORMAT_H_\n#define STORAGE_LEVELDB_DB_DBFORMAT_H_\n\n#include <stdio.h>\n#include \"leveldb/comparator.h\"\n#include \"leveldb/db.h\"\n#include \"leveldb/filter_policy.h\"\n#include \"leveldb/slice.h\"\n#include \"leveldb/table_builder.h\"\n#include \"util/coding.h\"\n#include \"util/logging.h\"\n\nnamespace leveldb {\n\n// Grouping of constants.  We may want to make some of these\n// parameters set via options.\nnamespace config {\nstatic const int kNumLevels = 7;\n\n// Level-0 compaction is started when we hit this many files.\nstatic const int kL0_CompactionTrigger = 4;\n\n// Soft limit on number of level-0 files.  We slow down writes at this point.\nstatic const int kL0_SlowdownWritesTrigger = 8;\n\n// Maximum number of level-0 files.  We stop writes at this point.\nstatic const int kL0_StopWritesTrigger = 12;\n\n// Maximum level to which a new compacted memtable is pushed if it\n// does not create overlap.  We try to push to level 2 to avoid the\n// relatively expensive level 0=>1 compactions and to avoid some\n// expensive manifest file operations.  We do not push all the way to\n// the largest level since that can generate a lot of wasted disk\n// space if the same key space is being repeatedly overwritten.\nstatic const int kMaxMemCompactLevel = 2;\n\n// Approximate gap in bytes between samples of data read during iteration.\nstatic const int kReadBytesPeriod = 1048576;\n\n}  // namespace config\n\nclass InternalKey;\n\n// Value types encoded as the last component of internal keys.\n// DO NOT CHANGE THESE ENUM VALUES: they are embedded in the on-disk\n// data structures.\nenum ValueType {\n  kTypeDeletion = 0x0,\n  kTypeValue = 0x1\n};\n// kValueTypeForSeek defines the ValueType that should be passed when\n// constructing a ParsedInternalKey object for seeking to a particular\n// sequence number (since we sort sequence numbers in decreasing order\n// and the value type is embedded as the low 8 bits in the sequence\n// number in internal keys, we need to use the highest-numbered\n// ValueType, not the lowest).\nstatic const ValueType kValueTypeForSeek = kTypeValue;\n\ntypedef uint64_t SequenceNumber;\n\n// We leave eight bits empty at the bottom so a type and sequence#\n// can be packed together into 64-bits.\nstatic const SequenceNumber kMaxSequenceNumber =\n    ((0x1ull << 56) - 1);\n\nstruct ParsedInternalKey {\n  Slice user_key;\n  SequenceNumber sequence;\n  ValueType type;\n\n  ParsedInternalKey() { }  // Intentionally left uninitialized (for speed)\n  ParsedInternalKey(const Slice& u, const SequenceNumber& seq, ValueType t)\n      : user_key(u), sequence(seq), type(t) { }\n  std::string DebugString() const;\n};\n\n// Return the length of the encoding of \"key\".\ninline size_t InternalKeyEncodingLength(const ParsedInternalKey& key) {\n  return key.user_key.size() + 8;\n}\n\n// Append the serialization of \"key\" to *result.\nextern void AppendInternalKey(std::string* result,\n                              const ParsedInternalKey& key);\n\n// Attempt to parse an internal key from \"internal_key\".  On success,\n// stores the parsed data in \"*result\", and returns true.\n//\n// On error, returns false, leaves \"*result\" in an undefined state.\nextern bool ParseInternalKey(const Slice& internal_key,\n                             ParsedInternalKey* result);\n\n// Returns the user key portion of an internal key.\ninline Slice ExtractUserKey(const Slice& internal_key) {\n  assert(internal_key.size() >= 8);\n  return Slice(internal_key.data(), internal_key.size() - 8);\n}\n\ninline ValueType ExtractValueType(const Slice& internal_key) {\n  assert(internal_key.size() >= 8);\n  const size_t n = internal_key.size();\n  uint64_t num = DecodeFixed64(internal_key.data() + n - 8);\n  unsigned char c = num & 0xff;\n  return static_cast<ValueType>(c);\n}\n\n// A comparator for internal keys that uses a specified comparator for\n// the user key portion and breaks ties by decreasing sequence number.\nclass InternalKeyComparator : public Comparator {\n private:\n  const Comparator* user_comparator_;\n public:\n  explicit InternalKeyComparator(const Comparator* c) : user_comparator_(c) { }\n  virtual const char* Name() const;\n  virtual int Compare(const Slice& a, const Slice& b) const;\n  virtual void FindShortestSeparator(\n      std::string* start,\n      const Slice& limit) const;\n  virtual void FindShortSuccessor(std::string* key) const;\n\n  const Comparator* user_comparator() const { return user_comparator_; }\n\n  int Compare(const InternalKey& a, const InternalKey& b) const;\n};\n\n// Filter policy wrapper that converts from internal keys to user keys\nclass InternalFilterPolicy : public FilterPolicy {\n private:\n  const FilterPolicy* const user_policy_;\n public:\n  explicit InternalFilterPolicy(const FilterPolicy* p) : user_policy_(p) { }\n  virtual const char* Name() const;\n  virtual void CreateFilter(const Slice* keys, int n, std::string* dst) const;\n  virtual bool KeyMayMatch(const Slice& key, const Slice& filter) const;\n};\n\n// Modules in this directory should keep internal keys wrapped inside\n// the following class instead of plain strings so that we do not\n// incorrectly use string comparisons instead of an InternalKeyComparator.\nclass InternalKey {\n private:\n  std::string rep_;\n public:\n  InternalKey() { }   // Leave rep_ as empty to indicate it is invalid\n  InternalKey(const Slice& user_key, SequenceNumber s, ValueType t) {\n    AppendInternalKey(&rep_, ParsedInternalKey(user_key, s, t));\n  }\n\n  void DecodeFrom(const Slice& s) { rep_.assign(s.data(), s.size()); }\n  Slice Encode() const {\n    assert(!rep_.empty());\n    return rep_;\n  }\n\n  Slice user_key() const { return ExtractUserKey(rep_); }\n\n  void SetFrom(const ParsedInternalKey& p) {\n    rep_.clear();\n    AppendInternalKey(&rep_, p);\n  }\n\n  void Clear() { rep_.clear(); }\n\n  std::string DebugString() const;\n};\n\ninline int InternalKeyComparator::Compare(\n    const InternalKey& a, const InternalKey& b) const {\n  return Compare(a.Encode(), b.Encode());\n}\n\ninline bool ParseInternalKey(const Slice& internal_key,\n                             ParsedInternalKey* result) {\n  const size_t n = internal_key.size();\n  if (n < 8) return false;\n  uint64_t num = DecodeFixed64(internal_key.data() + n - 8);\n  unsigned char c = num & 0xff;\n  result->sequence = num >> 8;\n  result->type = static_cast<ValueType>(c);\n  result->user_key = Slice(internal_key.data(), n - 8);\n  return (c <= static_cast<unsigned char>(kTypeValue));\n}\n\n// A helper class useful for DBImpl::Get()\nclass LookupKey {\n public:\n  // Initialize *this for looking up user_key at a snapshot with\n  // the specified sequence number.\n  LookupKey(const Slice& user_key, SequenceNumber sequence);\n\n  ~LookupKey();\n\n  // Return a key suitable for lookup in a MemTable.\n  Slice memtable_key() const { return Slice(start_, end_ - start_); }\n\n  // Return an internal key (suitable for passing to an internal iterator)\n  Slice internal_key() const { return Slice(kstart_, end_ - kstart_); }\n\n  // Return the user key\n  Slice user_key() const { return Slice(kstart_, end_ - kstart_ - 8); }\n\n private:\n  // We construct a char array of the form:\n  //    klength  varint32               <-- start_\n  //    userkey  char[klength]          <-- kstart_\n  //    tag      uint64\n  //                                    <-- end_\n  // The array is a suitable MemTable key.\n  // The suffix starting with \"userkey\" can be used as an InternalKey.\n  const char* start_;\n  const char* kstart_;\n  const char* end_;\n  char space_[200];      // Avoid allocation for short keys\n\n  // No copying allowed\n  LookupKey(const LookupKey&);\n  void operator=(const LookupKey&);\n};\n\ninline LookupKey::~LookupKey() {\n  if (start_ != space_) delete[] start_;\n}\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_DB_DBFORMAT_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/db/dbformat_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/dbformat.h\"\n#include \"util/logging.h\"\n#include \"util/testharness.h\"\n\nnamespace leveldb {\n\nstatic std::string IKey(const std::string& user_key,\n                        uint64_t seq,\n                        ValueType vt) {\n  std::string encoded;\n  AppendInternalKey(&encoded, ParsedInternalKey(user_key, seq, vt));\n  return encoded;\n}\n\nstatic std::string Shorten(const std::string& s, const std::string& l) {\n  std::string result = s;\n  InternalKeyComparator(BytewiseComparator()).FindShortestSeparator(&result, l);\n  return result;\n}\n\nstatic std::string ShortSuccessor(const std::string& s) {\n  std::string result = s;\n  InternalKeyComparator(BytewiseComparator()).FindShortSuccessor(&result);\n  return result;\n}\n\nstatic void TestKey(const std::string& key,\n                    uint64_t seq,\n                    ValueType vt) {\n  std::string encoded = IKey(key, seq, vt);\n\n  Slice in(encoded);\n  ParsedInternalKey decoded(\"\", 0, kTypeValue);\n\n  ASSERT_TRUE(ParseInternalKey(in, &decoded));\n  ASSERT_EQ(key, decoded.user_key.ToString());\n  ASSERT_EQ(seq, decoded.sequence);\n  ASSERT_EQ(vt, decoded.type);\n\n  ASSERT_TRUE(!ParseInternalKey(Slice(\"bar\"), &decoded));\n}\n\nclass FormatTest { };\n\nTEST(FormatTest, InternalKey_EncodeDecode) {\n  const char* keys[] = { \"\", \"k\", \"hello\", \"longggggggggggggggggggggg\" };\n  const uint64_t seq[] = {\n    1, 2, 3,\n    (1ull << 8) - 1, 1ull << 8, (1ull << 8) + 1,\n    (1ull << 16) - 1, 1ull << 16, (1ull << 16) + 1,\n    (1ull << 32) - 1, 1ull << 32, (1ull << 32) + 1\n  };\n  for (int k = 0; k < sizeof(keys) / sizeof(keys[0]); k++) {\n    for (int s = 0; s < sizeof(seq) / sizeof(seq[0]); s++) {\n      TestKey(keys[k], seq[s], kTypeValue);\n      TestKey(\"hello\", 1, kTypeDeletion);\n    }\n  }\n}\n\nTEST(FormatTest, InternalKeyShortSeparator) {\n  // When user keys are same\n  ASSERT_EQ(IKey(\"foo\", 100, kTypeValue),\n            Shorten(IKey(\"foo\", 100, kTypeValue),\n                    IKey(\"foo\", 99, kTypeValue)));\n  ASSERT_EQ(IKey(\"foo\", 100, kTypeValue),\n            Shorten(IKey(\"foo\", 100, kTypeValue),\n                    IKey(\"foo\", 101, kTypeValue)));\n  ASSERT_EQ(IKey(\"foo\", 100, kTypeValue),\n            Shorten(IKey(\"foo\", 100, kTypeValue),\n                    IKey(\"foo\", 100, kTypeValue)));\n  ASSERT_EQ(IKey(\"foo\", 100, kTypeValue),\n            Shorten(IKey(\"foo\", 100, kTypeValue),\n                    IKey(\"foo\", 100, kTypeDeletion)));\n\n  // When user keys are misordered\n  ASSERT_EQ(IKey(\"foo\", 100, kTypeValue),\n            Shorten(IKey(\"foo\", 100, kTypeValue),\n                    IKey(\"bar\", 99, kTypeValue)));\n\n  // When user keys are different, but correctly ordered\n  ASSERT_EQ(IKey(\"g\", kMaxSequenceNumber, kValueTypeForSeek),\n            Shorten(IKey(\"foo\", 100, kTypeValue),\n                    IKey(\"hello\", 200, kTypeValue)));\n\n  // When start user key is prefix of limit user key\n  ASSERT_EQ(IKey(\"foo\", 100, kTypeValue),\n            Shorten(IKey(\"foo\", 100, kTypeValue),\n                    IKey(\"foobar\", 200, kTypeValue)));\n\n  // When limit user key is prefix of start user key\n  ASSERT_EQ(IKey(\"foobar\", 100, kTypeValue),\n            Shorten(IKey(\"foobar\", 100, kTypeValue),\n                    IKey(\"foo\", 200, kTypeValue)));\n}\n\nTEST(FormatTest, InternalKeyShortestSuccessor) {\n  ASSERT_EQ(IKey(\"g\", kMaxSequenceNumber, kValueTypeForSeek),\n            ShortSuccessor(IKey(\"foo\", 100, kTypeValue)));\n  ASSERT_EQ(IKey(\"\\xff\\xff\", 100, kTypeValue),\n            ShortSuccessor(IKey(\"\\xff\\xff\", 100, kTypeValue)));\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/db/dumpfile.cc",
    "content": "// Copyright (c) 2012 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include <stdio.h>\n#include \"db/dbformat.h\"\n#include \"db/filename.h\"\n#include \"db/log_reader.h\"\n#include \"db/version_edit.h\"\n#include \"db/write_batch_internal.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/iterator.h\"\n#include \"leveldb/options.h\"\n#include \"leveldb/status.h\"\n#include \"leveldb/table.h\"\n#include \"leveldb/write_batch.h\"\n#include \"util/logging.h\"\n\nnamespace leveldb {\n\nnamespace {\n\nbool GuessType(const std::string& fname, FileType* type) {\n  size_t pos = fname.rfind('/');\n  std::string basename;\n  if (pos == std::string::npos) {\n    basename = fname;\n  } else {\n    basename = std::string(fname.data() + pos + 1, fname.size() - pos - 1);\n  }\n  uint64_t ignored;\n  return ParseFileName(basename, &ignored, type);\n}\n\n// Notified when log reader encounters corruption.\nclass CorruptionReporter : public log::Reader::Reporter {\n public:\n  WritableFile* dst_;\n  virtual void Corruption(size_t bytes, const Status& status) {\n    std::string r = \"corruption: \";\n    AppendNumberTo(&r, bytes);\n    r += \" bytes; \";\n    r += status.ToString();\n    r.push_back('\\n');\n    dst_->Append(r);\n  }\n};\n\n// Print contents of a log file. (*func)() is called on every record.\nStatus PrintLogContents(Env* env, const std::string& fname,\n                        void (*func)(uint64_t, Slice, WritableFile*),\n                        WritableFile* dst) {\n  SequentialFile* file;\n  Status s = env->NewSequentialFile(fname, &file);\n  if (!s.ok()) {\n    return s;\n  }\n  CorruptionReporter reporter;\n  reporter.dst_ = dst;\n  log::Reader reader(file, &reporter, true, 0);\n  Slice record;\n  std::string scratch;\n  while (reader.ReadRecord(&record, &scratch)) {\n    (*func)(reader.LastRecordOffset(), record, dst);\n  }\n  delete file;\n  return Status::OK();\n}\n\n// Called on every item found in a WriteBatch.\nclass WriteBatchItemPrinter : public WriteBatch::Handler {\n public:\n  WritableFile* dst_;\n  virtual void Put(const Slice& key, const Slice& value) {\n    std::string r = \"  put '\";\n    AppendEscapedStringTo(&r, key);\n    r += \"' '\";\n    AppendEscapedStringTo(&r, value);\n    r += \"'\\n\";\n    dst_->Append(r);\n  }\n  virtual void Delete(const Slice& key) {\n    std::string r = \"  del '\";\n    AppendEscapedStringTo(&r, key);\n    r += \"'\\n\";\n    dst_->Append(r);\n  }\n};\n\n\n// Called on every log record (each one of which is a WriteBatch)\n// found in a kLogFile.\nstatic void WriteBatchPrinter(uint64_t pos, Slice record, WritableFile* dst) {\n  std::string r = \"--- offset \";\n  AppendNumberTo(&r, pos);\n  r += \"; \";\n  if (record.size() < 12) {\n    r += \"log record length \";\n    AppendNumberTo(&r, record.size());\n    r += \" is too small\\n\";\n    dst->Append(r);\n    return;\n  }\n  WriteBatch batch;\n  WriteBatchInternal::SetContents(&batch, record);\n  r += \"sequence \";\n  AppendNumberTo(&r, WriteBatchInternal::Sequence(&batch));\n  r.push_back('\\n');\n  dst->Append(r);\n  WriteBatchItemPrinter batch_item_printer;\n  batch_item_printer.dst_ = dst;\n  Status s = batch.Iterate(&batch_item_printer);\n  if (!s.ok()) {\n    dst->Append(\"  error: \" + s.ToString() + \"\\n\");\n  }\n}\n\nStatus DumpLog(Env* env, const std::string& fname, WritableFile* dst) {\n  return PrintLogContents(env, fname, WriteBatchPrinter, dst);\n}\n\n// Called on every log record (each one of which is a WriteBatch)\n// found in a kDescriptorFile.\nstatic void VersionEditPrinter(uint64_t pos, Slice record, WritableFile* dst) {\n  std::string r = \"--- offset \";\n  AppendNumberTo(&r, pos);\n  r += \"; \";\n  VersionEdit edit;\n  Status s = edit.DecodeFrom(record);\n  if (!s.ok()) {\n    r += s.ToString();\n    r.push_back('\\n');\n  } else {\n    r += edit.DebugString();\n  }\n  dst->Append(r);\n}\n\nStatus DumpDescriptor(Env* env, const std::string& fname, WritableFile* dst) {\n  return PrintLogContents(env, fname, VersionEditPrinter, dst);\n}\n\nStatus DumpTable(Env* env, const std::string& fname, WritableFile* dst) {\n  uint64_t file_size;\n  RandomAccessFile* file = NULL;\n  Table* table = NULL;\n  Status s = env->GetFileSize(fname, &file_size);\n  if (s.ok()) {\n    s = env->NewRandomAccessFile(fname, &file);\n  }\n  if (s.ok()) {\n    // We use the default comparator, which may or may not match the\n    // comparator used in this database. However this should not cause\n    // problems since we only use Table operations that do not require\n    // any comparisons.  In particular, we do not call Seek or Prev.\n    s = Table::Open(Options(), file, file_size, &table);\n  }\n  if (!s.ok()) {\n    delete table;\n    delete file;\n    return s;\n  }\n\n  ReadOptions ro;\n  ro.fill_cache = false;\n  Iterator* iter = table->NewIterator(ro);\n  std::string r;\n  for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {\n    r.clear();\n    ParsedInternalKey key;\n    if (!ParseInternalKey(iter->key(), &key)) {\n      r = \"badkey '\";\n      AppendEscapedStringTo(&r, iter->key());\n      r += \"' => '\";\n      AppendEscapedStringTo(&r, iter->value());\n      r += \"'\\n\";\n      dst->Append(r);\n    } else {\n      r = \"'\";\n      AppendEscapedStringTo(&r, key.user_key);\n      r += \"' @ \";\n      AppendNumberTo(&r, key.sequence);\n      r += \" : \";\n      if (key.type == kTypeDeletion) {\n        r += \"del\";\n      } else if (key.type == kTypeValue) {\n        r += \"val\";\n      } else {\n        AppendNumberTo(&r, key.type);\n      }\n      r += \" => '\";\n      AppendEscapedStringTo(&r, iter->value());\n      r += \"'\\n\";\n      dst->Append(r);\n    }\n  }\n  s = iter->status();\n  if (!s.ok()) {\n    dst->Append(\"iterator error: \" + s.ToString() + \"\\n\");\n  }\n\n  delete iter;\n  delete table;\n  delete file;\n  return Status::OK();\n}\n\n}  // namespace\n\nStatus DumpFile(Env* env, const std::string& fname, WritableFile* dst) {\n  FileType ftype;\n  if (!GuessType(fname, &ftype)) {\n    return Status::InvalidArgument(fname + \": unknown file type\");\n  }\n  switch (ftype) {\n    case kLogFile:         return DumpLog(env, fname, dst);\n    case kDescriptorFile:  return DumpDescriptor(env, fname, dst);\n    case kTableFile:       return DumpTable(env, fname, dst);\n    default:\n      break;\n  }\n  return Status::InvalidArgument(fname + \": not a dump-able file type\");\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/db/fault_injection_test.cc",
    "content": "// Copyright 2014 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n// This test uses a custom Env to keep track of the state of a filesystem as of\n// the last \"sync\". It then checks for data loss errors by purposely dropping\n// file data (or entire files) not protected by a \"sync\".\n\n#include \"leveldb/db.h\"\n\n#include <map>\n#include <set>\n#include \"db/db_impl.h\"\n#include \"db/filename.h\"\n#include \"db/log_format.h\"\n#include \"db/version_set.h\"\n#include \"leveldb/cache.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/table.h\"\n#include \"leveldb/write_batch.h\"\n#include \"util/logging.h\"\n#include \"util/mutexlock.h\"\n#include \"util/testharness.h\"\n#include \"util/testutil.h\"\n\nnamespace leveldb {\n\nstatic const int kValueSize = 1000;\nstatic const int kMaxNumValues = 2000;\nstatic const size_t kNumIterations = 3;\n\nclass FaultInjectionTestEnv;\n\nnamespace {\n\n// Assume a filename, and not a directory name like \"/foo/bar/\"\nstatic std::string GetDirName(const std::string filename) {\n  size_t found = filename.find_last_of(\"/\\\\\");\n  if (found == std::string::npos) {\n    return \"\";\n  } else {\n    return filename.substr(0, found);\n  }\n}\n\nStatus SyncDir(const std::string& dir) {\n  // As this is a test it isn't required to *actually* sync this directory.\n  return Status::OK();\n}\n\n// A basic file truncation function suitable for this test.\nStatus Truncate(const std::string& filename, uint64_t length) {\n  leveldb::Env* env = leveldb::Env::Default();\n\n  SequentialFile* orig_file;\n  Status s = env->NewSequentialFile(filename, &orig_file);\n  if (!s.ok())\n    return s;\n\n  char* scratch = new char[length];\n  leveldb::Slice result;\n  s = orig_file->Read(length, &result, scratch);\n  delete orig_file;\n  if (s.ok()) {\n    std::string tmp_name = GetDirName(filename) + \"/truncate.tmp\";\n    WritableFile* tmp_file;\n    s = env->NewWritableFile(tmp_name, &tmp_file);\n    if (s.ok()) {\n      s = tmp_file->Append(result);\n      delete tmp_file;\n      if (s.ok()) {\n        s = env->RenameFile(tmp_name, filename);\n      } else {\n        env->DeleteFile(tmp_name);\n      }\n    }\n  }\n\n  delete[] scratch;\n\n  return s;\n}\n\nstruct FileState {\n  std::string filename_;\n  ssize_t pos_;\n  ssize_t pos_at_last_sync_;\n  ssize_t pos_at_last_flush_;\n\n  FileState(const std::string& filename)\n      : filename_(filename),\n        pos_(-1),\n        pos_at_last_sync_(-1),\n        pos_at_last_flush_(-1) { }\n\n  FileState() : pos_(-1), pos_at_last_sync_(-1), pos_at_last_flush_(-1) {}\n\n  bool IsFullySynced() const { return pos_ <= 0 || pos_ == pos_at_last_sync_; }\n\n  Status DropUnsyncedData() const;\n};\n\n}  // anonymous namespace\n\n// A wrapper around WritableFile which informs another Env whenever this file\n// is written to or sync'ed.\nclass TestWritableFile : public WritableFile {\n public:\n  TestWritableFile(const FileState& state,\n                   WritableFile* f,\n                   FaultInjectionTestEnv* env);\n  virtual ~TestWritableFile();\n  virtual Status Append(const Slice& data);\n  virtual Status Close();\n  virtual Status Flush();\n  virtual Status Sync();\n\n private:\n  FileState state_;\n  WritableFile* target_;\n  bool writable_file_opened_;\n  FaultInjectionTestEnv* env_;\n\n  Status SyncParent();\n};\n\nclass FaultInjectionTestEnv : public EnvWrapper {\n public:\n  FaultInjectionTestEnv() : EnvWrapper(Env::Default()), filesystem_active_(true) {}\n  virtual ~FaultInjectionTestEnv() { }\n  virtual Status NewWritableFile(const std::string& fname,\n                                 WritableFile** result);\n  virtual Status NewAppendableFile(const std::string& fname,\n                                   WritableFile** result);\n  virtual Status DeleteFile(const std::string& f);\n  virtual Status RenameFile(const std::string& s, const std::string& t);\n\n  void WritableFileClosed(const FileState& state);\n  Status DropUnsyncedFileData();\n  Status DeleteFilesCreatedAfterLastDirSync();\n  void DirWasSynced();\n  bool IsFileCreatedSinceLastDirSync(const std::string& filename);\n  void ResetState();\n  void UntrackFile(const std::string& f);\n  // Setting the filesystem to inactive is the test equivalent to simulating a\n  // system reset. Setting to inactive will freeze our saved filesystem state so\n  // that it will stop being recorded. It can then be reset back to the state at\n  // the time of the reset.\n  bool IsFilesystemActive() const { return filesystem_active_; }\n  void SetFilesystemActive(bool active) { filesystem_active_ = active; }\n\n private:\n  port::Mutex mutex_;\n  std::map<std::string, FileState> db_file_state_;\n  std::set<std::string> new_files_since_last_dir_sync_;\n  bool filesystem_active_;  // Record flushes, syncs, writes\n};\n\nTestWritableFile::TestWritableFile(const FileState& state,\n                                   WritableFile* f,\n                                   FaultInjectionTestEnv* env)\n    : state_(state),\n      target_(f),\n      writable_file_opened_(true),\n      env_(env) {\n  assert(f != NULL);\n}\n\nTestWritableFile::~TestWritableFile() {\n  if (writable_file_opened_) {\n    Close();\n  }\n  delete target_;\n}\n\nStatus TestWritableFile::Append(const Slice& data) {\n  Status s = target_->Append(data);\n  if (s.ok() && env_->IsFilesystemActive()) {\n    state_.pos_ += data.size();\n  }\n  return s;\n}\n\nStatus TestWritableFile::Close() {\n  writable_file_opened_ = false;\n  Status s = target_->Close();\n  if (s.ok()) {\n    env_->WritableFileClosed(state_);\n  }\n  return s;\n}\n\nStatus TestWritableFile::Flush() {\n  Status s = target_->Flush();\n  if (s.ok() && env_->IsFilesystemActive()) {\n    state_.pos_at_last_flush_ = state_.pos_;\n  }\n  return s;\n}\n\nStatus TestWritableFile::SyncParent() {\n  Status s = SyncDir(GetDirName(state_.filename_));\n  if (s.ok()) {\n    env_->DirWasSynced();\n  }\n  return s;\n}\n\nStatus TestWritableFile::Sync() {\n  if (!env_->IsFilesystemActive()) {\n    return Status::OK();\n  }\n  // Ensure new files referred to by the manifest are in the filesystem.\n  Status s = target_->Sync();\n  if (s.ok()) {\n    state_.pos_at_last_sync_ = state_.pos_;\n  }\n  if (env_->IsFileCreatedSinceLastDirSync(state_.filename_)) {\n    Status ps = SyncParent();\n    if (s.ok() && !ps.ok()) {\n      s = ps;\n    }\n  }\n  return s;\n}\n\nStatus FaultInjectionTestEnv::NewWritableFile(const std::string& fname,\n                                              WritableFile** result) {\n  WritableFile* actual_writable_file;\n  Status s = target()->NewWritableFile(fname, &actual_writable_file);\n  if (s.ok()) {\n    FileState state(fname);\n    state.pos_ = 0;\n    *result = new TestWritableFile(state, actual_writable_file, this);\n    // NewWritableFile doesn't append to files, so if the same file is\n    // opened again then it will be truncated - so forget our saved\n    // state.\n    UntrackFile(fname);\n    MutexLock l(&mutex_);\n    new_files_since_last_dir_sync_.insert(fname);\n  }\n  return s;\n}\n\nStatus FaultInjectionTestEnv::NewAppendableFile(const std::string& fname,\n                                                WritableFile** result) {\n  WritableFile* actual_writable_file;\n  Status s = target()->NewAppendableFile(fname, &actual_writable_file);\n  if (s.ok()) {\n    FileState state(fname);\n    state.pos_ = 0;\n    {\n      MutexLock l(&mutex_);\n      if (db_file_state_.count(fname) == 0) {\n        new_files_since_last_dir_sync_.insert(fname);\n      } else {\n        state = db_file_state_[fname];\n      }\n    }\n    *result = new TestWritableFile(state, actual_writable_file, this);\n  }\n  return s;\n}\n\nStatus FaultInjectionTestEnv::DropUnsyncedFileData() {\n  Status s;\n  MutexLock l(&mutex_);\n  for (std::map<std::string, FileState>::const_iterator it =\n           db_file_state_.begin();\n       s.ok() && it != db_file_state_.end(); ++it) {\n    const FileState& state = it->second;\n    if (!state.IsFullySynced()) {\n      s = state.DropUnsyncedData();\n    }\n  }\n  return s;\n}\n\nvoid FaultInjectionTestEnv::DirWasSynced() {\n  MutexLock l(&mutex_);\n  new_files_since_last_dir_sync_.clear();\n}\n\nbool FaultInjectionTestEnv::IsFileCreatedSinceLastDirSync(\n    const std::string& filename) {\n  MutexLock l(&mutex_);\n  return new_files_since_last_dir_sync_.find(filename) !=\n         new_files_since_last_dir_sync_.end();\n}\n\nvoid FaultInjectionTestEnv::UntrackFile(const std::string& f) {\n  MutexLock l(&mutex_);\n  db_file_state_.erase(f);\n  new_files_since_last_dir_sync_.erase(f);\n}\n\nStatus FaultInjectionTestEnv::DeleteFile(const std::string& f) {\n  Status s = EnvWrapper::DeleteFile(f);\n  ASSERT_OK(s);\n  if (s.ok()) {\n    UntrackFile(f);\n  }\n  return s;\n}\n\nStatus FaultInjectionTestEnv::RenameFile(const std::string& s,\n                                         const std::string& t) {\n  Status ret = EnvWrapper::RenameFile(s, t);\n\n  if (ret.ok()) {\n    MutexLock l(&mutex_);\n    if (db_file_state_.find(s) != db_file_state_.end()) {\n      db_file_state_[t] = db_file_state_[s];\n      db_file_state_.erase(s);\n    }\n\n    if (new_files_since_last_dir_sync_.erase(s) != 0) {\n      assert(new_files_since_last_dir_sync_.find(t) ==\n             new_files_since_last_dir_sync_.end());\n      new_files_since_last_dir_sync_.insert(t);\n    }\n  }\n\n  return ret;\n}\n\nvoid FaultInjectionTestEnv::ResetState() {\n  // Since we are not destroying the database, the existing files\n  // should keep their recorded synced/flushed state. Therefore\n  // we do not reset db_file_state_ and new_files_since_last_dir_sync_.\n  MutexLock l(&mutex_);\n  SetFilesystemActive(true);\n}\n\nStatus FaultInjectionTestEnv::DeleteFilesCreatedAfterLastDirSync() {\n  // Because DeleteFile access this container make a copy to avoid deadlock\n  mutex_.Lock();\n  std::set<std::string> new_files(new_files_since_last_dir_sync_.begin(),\n                                  new_files_since_last_dir_sync_.end());\n  mutex_.Unlock();\n  Status s;\n  std::set<std::string>::const_iterator it;\n  for (it = new_files.begin(); s.ok() && it != new_files.end(); ++it) {\n    s = DeleteFile(*it);\n  }\n  return s;\n}\n\nvoid FaultInjectionTestEnv::WritableFileClosed(const FileState& state) {\n  MutexLock l(&mutex_);\n  db_file_state_[state.filename_] = state;\n}\n\nStatus FileState::DropUnsyncedData() const {\n  ssize_t sync_pos = pos_at_last_sync_ == -1 ? 0 : pos_at_last_sync_;\n  return Truncate(filename_, sync_pos);\n}\n\nclass FaultInjectionTest {\n public:\n  enum ExpectedVerifResult { VAL_EXPECT_NO_ERROR, VAL_EXPECT_ERROR };\n  enum ResetMethod { RESET_DROP_UNSYNCED_DATA, RESET_DELETE_UNSYNCED_FILES };\n\n  FaultInjectionTestEnv* env_;\n  std::string dbname_;\n  Cache* tiny_cache_;\n  Options options_;\n  DB* db_;\n\n  FaultInjectionTest()\n      : env_(new FaultInjectionTestEnv),\n        tiny_cache_(NewLRUCache(100)),\n        db_(NULL) {\n    dbname_ = test::TmpDir() + \"/fault_test\";\n    DestroyDB(dbname_, Options());  // Destroy any db from earlier run\n    options_.reuse_logs = true;\n    options_.env = env_;\n    options_.paranoid_checks = true;\n    options_.block_cache = tiny_cache_;\n    options_.create_if_missing = true;\n  }\n\n  ~FaultInjectionTest() {\n    CloseDB();\n    DestroyDB(dbname_, Options());\n    delete tiny_cache_;\n    delete env_;\n  }\n\n  void ReuseLogs(bool reuse) {\n    options_.reuse_logs = reuse;\n  }\n\n  void Build(int start_idx, int num_vals) {\n    std::string key_space, value_space;\n    WriteBatch batch;\n    for (int i = start_idx; i < start_idx + num_vals; i++) {\n      Slice key = Key(i, &key_space);\n      batch.Clear();\n      batch.Put(key, Value(i, &value_space));\n      WriteOptions options;\n      ASSERT_OK(db_->Write(options, &batch));\n    }\n  }\n\n  Status ReadValue(int i, std::string* val) const {\n    std::string key_space, value_space;\n    Slice key = Key(i, &key_space);\n    Value(i, &value_space);\n    ReadOptions options;\n    return db_->Get(options, key, val);\n  }\n\n  Status Verify(int start_idx, int num_vals,\n                ExpectedVerifResult expected) const {\n    std::string val;\n    std::string value_space;\n    Status s;\n    for (int i = start_idx; i < start_idx + num_vals && s.ok(); i++) {\n      Value(i, &value_space);\n      s = ReadValue(i, &val);\n      if (expected == VAL_EXPECT_NO_ERROR) {\n        if (s.ok()) {\n          ASSERT_EQ(value_space, val);\n        }\n      } else if (s.ok()) {\n        fprintf(stderr, \"Expected an error at %d, but was OK\\n\", i);\n        s = Status::IOError(dbname_, \"Expected value error:\");\n      } else {\n        s = Status::OK();  // An expected error\n      }\n    }\n    return s;\n  }\n\n  // Return the ith key\n  Slice Key(int i, std::string* storage) const {\n    char buf[100];\n    snprintf(buf, sizeof(buf), \"%016d\", i);\n    storage->assign(buf, strlen(buf));\n    return Slice(*storage);\n  }\n\n  // Return the value to associate with the specified key\n  Slice Value(int k, std::string* storage) const {\n    Random r(k);\n    return test::RandomString(&r, kValueSize, storage);\n  }\n\n  Status OpenDB() {\n    delete db_;\n    db_ = NULL;\n    env_->ResetState();\n    return DB::Open(options_, dbname_, &db_);\n  }\n\n  void CloseDB() {\n    delete db_;\n    db_ = NULL;\n  }\n\n  void DeleteAllData() {\n    Iterator* iter = db_->NewIterator(ReadOptions());\n    WriteOptions options;\n    for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {\n      ASSERT_OK(db_->Delete(WriteOptions(), iter->key()));\n    }\n\n    delete iter;\n  }\n\n  void ResetDBState(ResetMethod reset_method) {\n    switch (reset_method) {\n      case RESET_DROP_UNSYNCED_DATA:\n        ASSERT_OK(env_->DropUnsyncedFileData());\n        break;\n      case RESET_DELETE_UNSYNCED_FILES:\n        ASSERT_OK(env_->DeleteFilesCreatedAfterLastDirSync());\n        break;\n      default:\n        assert(false);\n    }\n  }\n\n  void PartialCompactTestPreFault(int num_pre_sync, int num_post_sync) {\n    DeleteAllData();\n    Build(0, num_pre_sync);\n    db_->CompactRange(NULL, NULL);\n    Build(num_pre_sync, num_post_sync);\n  }\n\n  void PartialCompactTestReopenWithFault(ResetMethod reset_method,\n                                         int num_pre_sync,\n                                         int num_post_sync) {\n    env_->SetFilesystemActive(false);\n    CloseDB();\n    ResetDBState(reset_method);\n    ASSERT_OK(OpenDB());\n    ASSERT_OK(Verify(0, num_pre_sync, FaultInjectionTest::VAL_EXPECT_NO_ERROR));\n    ASSERT_OK(Verify(num_pre_sync, num_post_sync, FaultInjectionTest::VAL_EXPECT_ERROR));\n  }\n\n  void NoWriteTestPreFault() {\n  }\n\n  void NoWriteTestReopenWithFault(ResetMethod reset_method) {\n    CloseDB();\n    ResetDBState(reset_method);\n    ASSERT_OK(OpenDB());\n  }\n\n  void DoTest() {\n    Random rnd(0);\n    ASSERT_OK(OpenDB());\n    for (size_t idx = 0; idx < kNumIterations; idx++) {\n      int num_pre_sync = rnd.Uniform(kMaxNumValues);\n      int num_post_sync = rnd.Uniform(kMaxNumValues);\n\n      PartialCompactTestPreFault(num_pre_sync, num_post_sync);\n      PartialCompactTestReopenWithFault(RESET_DROP_UNSYNCED_DATA,\n                                        num_pre_sync,\n                                        num_post_sync);\n\n      NoWriteTestPreFault();\n      NoWriteTestReopenWithFault(RESET_DROP_UNSYNCED_DATA);\n\n      PartialCompactTestPreFault(num_pre_sync, num_post_sync);\n      // No new files created so we expect all values since no files will be\n      // dropped.\n      PartialCompactTestReopenWithFault(RESET_DELETE_UNSYNCED_FILES,\n                                        num_pre_sync + num_post_sync,\n                                        0);\n\n      NoWriteTestPreFault();\n      NoWriteTestReopenWithFault(RESET_DELETE_UNSYNCED_FILES);\n    }\n  }\n};\n\nTEST(FaultInjectionTest, FaultTestNoLogReuse) {\n  ReuseLogs(false);\n  DoTest();\n}\n\nTEST(FaultInjectionTest, FaultTestWithLogReuse) {\n  ReuseLogs(true);\n  DoTest();\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/db/filename.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include <ctype.h>\n#include <stdio.h>\n#include \"db/filename.h\"\n#include \"db/dbformat.h\"\n#include \"leveldb/env.h\"\n#include \"util/logging.h\"\n\nnamespace leveldb {\n\n// A utility routine: write \"data\" to the named file and Sync() it.\nextern Status WriteStringToFileSync(Env* env, const Slice& data,\n                                    const std::string& fname);\n\nstatic std::string MakeFileName(const std::string& name, uint64_t number,\n                                const char* suffix) {\n  char buf[100];\n  snprintf(buf, sizeof(buf), \"/%06llu.%s\",\n           static_cast<unsigned long long>(number),\n           suffix);\n  return name + buf;\n}\n\nstd::string LogFileName(const std::string& name, uint64_t number) {\n  assert(number > 0);\n  return MakeFileName(name, number, \"log\");\n}\n\nstd::string TableFileName(const std::string& name, uint64_t number) {\n  assert(number > 0);\n  return MakeFileName(name, number, \"ldb\");\n}\n\nstd::string SSTTableFileName(const std::string& name, uint64_t number) {\n  assert(number > 0);\n  return MakeFileName(name, number, \"sst\");\n}\n\nstd::string DescriptorFileName(const std::string& dbname, uint64_t number) {\n  assert(number > 0);\n  char buf[100];\n  snprintf(buf, sizeof(buf), \"/MANIFEST-%06llu\",\n           static_cast<unsigned long long>(number));\n  return dbname + buf;\n}\n\nstd::string CurrentFileName(const std::string& dbname) {\n  return dbname + \"/CURRENT\";\n}\n\nstd::string LockFileName(const std::string& dbname) {\n  return dbname + \"/LOCK\";\n}\n\nstd::string TempFileName(const std::string& dbname, uint64_t number) {\n  assert(number > 0);\n  return MakeFileName(dbname, number, \"dbtmp\");\n}\n\nstd::string InfoLogFileName(const std::string& dbname) {\n  return dbname + \"/LOG\";\n}\n\n// Return the name of the old info log file for \"dbname\".\nstd::string OldInfoLogFileName(const std::string& dbname) {\n  return dbname + \"/LOG.old\";\n}\n\n\n// Owned filenames have the form:\n//    dbname/CURRENT\n//    dbname/LOCK\n//    dbname/LOG\n//    dbname/LOG.old\n//    dbname/MANIFEST-[0-9]+\n//    dbname/[0-9]+.(log|sst|ldb)\nbool ParseFileName(const std::string& fname,\n                   uint64_t* number,\n                   FileType* type) {\n  Slice rest(fname);\n  if (rest == \"CURRENT\") {\n    *number = 0;\n    *type = kCurrentFile;\n  } else if (rest == \"LOCK\") {\n    *number = 0;\n    *type = kDBLockFile;\n  } else if (rest == \"LOG\" || rest == \"LOG.old\") {\n    *number = 0;\n    *type = kInfoLogFile;\n  } else if (rest.starts_with(\"MANIFEST-\")) {\n    rest.remove_prefix(strlen(\"MANIFEST-\"));\n    uint64_t num;\n    if (!ConsumeDecimalNumber(&rest, &num)) {\n      return false;\n    }\n    if (!rest.empty()) {\n      return false;\n    }\n    *type = kDescriptorFile;\n    *number = num;\n  } else {\n    // Avoid strtoull() to keep filename format independent of the\n    // current locale\n    uint64_t num;\n    if (!ConsumeDecimalNumber(&rest, &num)) {\n      return false;\n    }\n    Slice suffix = rest;\n    if (suffix == Slice(\".log\")) {\n      *type = kLogFile;\n    } else if (suffix == Slice(\".sst\") || suffix == Slice(\".ldb\")) {\n      *type = kTableFile;\n    } else if (suffix == Slice(\".dbtmp\")) {\n      *type = kTempFile;\n    } else {\n      return false;\n    }\n    *number = num;\n  }\n  return true;\n}\n\nStatus SetCurrentFile(Env* env, const std::string& dbname,\n                      uint64_t descriptor_number) {\n  // Remove leading \"dbname/\" and add newline to manifest file name\n  std::string manifest = DescriptorFileName(dbname, descriptor_number);\n  Slice contents = manifest;\n  assert(contents.starts_with(dbname + \"/\"));\n  contents.remove_prefix(dbname.size() + 1);\n  std::string tmp = TempFileName(dbname, descriptor_number);\n  Status s = WriteStringToFileSync(env, contents.ToString() + \"\\n\", tmp);\n  if (s.ok()) {\n    s = env->RenameFile(tmp, CurrentFileName(dbname));\n  }\n  if (!s.ok()) {\n    env->DeleteFile(tmp);\n  }\n  return s;\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/db/filename.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// File names used by DB code\n\n#ifndef STORAGE_LEVELDB_DB_FILENAME_H_\n#define STORAGE_LEVELDB_DB_FILENAME_H_\n\n#include <stdint.h>\n#include <string>\n#include \"leveldb/slice.h\"\n#include \"leveldb/status.h\"\n#include \"port/port.h\"\n\nnamespace leveldb {\n\nclass Env;\n\nenum FileType {\n  kLogFile,\n  kDBLockFile,\n  kTableFile,\n  kDescriptorFile,\n  kCurrentFile,\n  kTempFile,\n  kInfoLogFile  // Either the current one, or an old one\n};\n\n// Return the name of the log file with the specified number\n// in the db named by \"dbname\".  The result will be prefixed with\n// \"dbname\".\nextern std::string LogFileName(const std::string& dbname, uint64_t number);\n\n// Return the name of the sstable with the specified number\n// in the db named by \"dbname\".  The result will be prefixed with\n// \"dbname\".\nextern std::string TableFileName(const std::string& dbname, uint64_t number);\n\n// Return the legacy file name for an sstable with the specified number\n// in the db named by \"dbname\". The result will be prefixed with\n// \"dbname\".\nextern std::string SSTTableFileName(const std::string& dbname, uint64_t number);\n\n// Return the name of the descriptor file for the db named by\n// \"dbname\" and the specified incarnation number.  The result will be\n// prefixed with \"dbname\".\nextern std::string DescriptorFileName(const std::string& dbname,\n                                      uint64_t number);\n\n// Return the name of the current file.  This file contains the name\n// of the current manifest file.  The result will be prefixed with\n// \"dbname\".\nextern std::string CurrentFileName(const std::string& dbname);\n\n// Return the name of the lock file for the db named by\n// \"dbname\".  The result will be prefixed with \"dbname\".\nextern std::string LockFileName(const std::string& dbname);\n\n// Return the name of a temporary file owned by the db named \"dbname\".\n// The result will be prefixed with \"dbname\".\nextern std::string TempFileName(const std::string& dbname, uint64_t number);\n\n// Return the name of the info log file for \"dbname\".\nextern std::string InfoLogFileName(const std::string& dbname);\n\n// Return the name of the old info log file for \"dbname\".\nextern std::string OldInfoLogFileName(const std::string& dbname);\n\n// If filename is a leveldb file, store the type of the file in *type.\n// The number encoded in the filename is stored in *number.  If the\n// filename was successfully parsed, returns true.  Else return false.\nextern bool ParseFileName(const std::string& filename,\n                          uint64_t* number,\n                          FileType* type);\n\n// Make the CURRENT file point to the descriptor file with the\n// specified number.\nextern Status SetCurrentFile(Env* env, const std::string& dbname,\n                             uint64_t descriptor_number);\n\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_DB_FILENAME_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/db/filename_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/filename.h\"\n\n#include \"db/dbformat.h\"\n#include \"port/port.h\"\n#include \"util/logging.h\"\n#include \"util/testharness.h\"\n\nnamespace leveldb {\n\nclass FileNameTest { };\n\nTEST(FileNameTest, Parse) {\n  Slice db;\n  FileType type;\n  uint64_t number;\n\n  // Successful parses\n  static struct {\n    const char* fname;\n    uint64_t number;\n    FileType type;\n  } cases[] = {\n    { \"100.log\",            100,   kLogFile },\n    { \"0.log\",              0,     kLogFile },\n    { \"0.sst\",              0,     kTableFile },\n    { \"0.ldb\",              0,     kTableFile },\n    { \"CURRENT\",            0,     kCurrentFile },\n    { \"LOCK\",               0,     kDBLockFile },\n    { \"MANIFEST-2\",         2,     kDescriptorFile },\n    { \"MANIFEST-7\",         7,     kDescriptorFile },\n    { \"LOG\",                0,     kInfoLogFile },\n    { \"LOG.old\",            0,     kInfoLogFile },\n    { \"18446744073709551615.log\", 18446744073709551615ull, kLogFile },\n  };\n  for (int i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {\n    std::string f = cases[i].fname;\n    ASSERT_TRUE(ParseFileName(f, &number, &type)) << f;\n    ASSERT_EQ(cases[i].type, type) << f;\n    ASSERT_EQ(cases[i].number, number) << f;\n  }\n\n  // Errors\n  static const char* errors[] = {\n    \"\",\n    \"foo\",\n    \"foo-dx-100.log\",\n    \".log\",\n    \"\",\n    \"manifest\",\n    \"CURREN\",\n    \"CURRENTX\",\n    \"MANIFES\",\n    \"MANIFEST\",\n    \"MANIFEST-\",\n    \"XMANIFEST-3\",\n    \"MANIFEST-3x\",\n    \"LOC\",\n    \"LOCKx\",\n    \"LO\",\n    \"LOGx\",\n    \"18446744073709551616.log\",\n    \"184467440737095516150.log\",\n    \"100\",\n    \"100.\",\n    \"100.lop\"\n  };\n  for (int i = 0; i < sizeof(errors) / sizeof(errors[0]); i++) {\n    std::string f = errors[i];\n    ASSERT_TRUE(!ParseFileName(f, &number, &type)) << f;\n  }\n}\n\nTEST(FileNameTest, Construction) {\n  uint64_t number;\n  FileType type;\n  std::string fname;\n\n  fname = CurrentFileName(\"foo\");\n  ASSERT_EQ(\"foo/\", std::string(fname.data(), 4));\n  ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type));\n  ASSERT_EQ(0, number);\n  ASSERT_EQ(kCurrentFile, type);\n\n  fname = LockFileName(\"foo\");\n  ASSERT_EQ(\"foo/\", std::string(fname.data(), 4));\n  ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type));\n  ASSERT_EQ(0, number);\n  ASSERT_EQ(kDBLockFile, type);\n\n  fname = LogFileName(\"foo\", 192);\n  ASSERT_EQ(\"foo/\", std::string(fname.data(), 4));\n  ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type));\n  ASSERT_EQ(192, number);\n  ASSERT_EQ(kLogFile, type);\n\n  fname = TableFileName(\"bar\", 200);\n  ASSERT_EQ(\"bar/\", std::string(fname.data(), 4));\n  ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type));\n  ASSERT_EQ(200, number);\n  ASSERT_EQ(kTableFile, type);\n\n  fname = DescriptorFileName(\"bar\", 100);\n  ASSERT_EQ(\"bar/\", std::string(fname.data(), 4));\n  ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type));\n  ASSERT_EQ(100, number);\n  ASSERT_EQ(kDescriptorFile, type);\n\n  fname = TempFileName(\"tmp\", 999);\n  ASSERT_EQ(\"tmp/\", std::string(fname.data(), 4));\n  ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type));\n  ASSERT_EQ(999, number);\n  ASSERT_EQ(kTempFile, type);\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/db/leveldbutil.cc",
    "content": "// Copyright (c) 2012 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include <stdio.h>\n#include \"leveldb/dumpfile.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/status.h\"\n\nnamespace leveldb {\nnamespace {\n\nclass StdoutPrinter : public WritableFile {\n public:\n  virtual Status Append(const Slice& data) {\n    fwrite(data.data(), 1, data.size(), stdout);\n    return Status::OK();\n  }\n  virtual Status Close() { return Status::OK(); }\n  virtual Status Flush() { return Status::OK(); }\n  virtual Status Sync() { return Status::OK(); }\n};\n\nbool HandleDumpCommand(Env* env, char** files, int num) {\n  StdoutPrinter printer;\n  bool ok = true;\n  for (int i = 0; i < num; i++) {\n    Status s = DumpFile(env, files[i], &printer);\n    if (!s.ok()) {\n      fprintf(stderr, \"%s\\n\", s.ToString().c_str());\n      ok = false;\n    }\n  }\n  return ok;\n}\n\n}  // namespace\n}  // namespace leveldb\n\nstatic void Usage() {\n  fprintf(\n      stderr,\n      \"Usage: leveldbutil command...\\n\"\n      \"   dump files...         -- dump contents of specified files\\n\"\n      );\n}\n\nint main(int argc, char** argv) {\n  leveldb::Env* env = leveldb::Env::Default();\n  bool ok = true;\n  if (argc < 2) {\n    Usage();\n    ok = false;\n  } else {\n    std::string command = argv[1];\n    if (command == \"dump\") {\n      ok = leveldb::HandleDumpCommand(env, argv+2, argc-2);\n    } else {\n      Usage();\n      ok = false;\n    }\n  }\n  return (ok ? 0 : 1);\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/db/log_format.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// Log format information shared by reader and writer.\n// See ../doc/log_format.md for more detail.\n\n#ifndef STORAGE_LEVELDB_DB_LOG_FORMAT_H_\n#define STORAGE_LEVELDB_DB_LOG_FORMAT_H_\n\nnamespace leveldb {\nnamespace log {\n\nenum RecordType {\n  // Zero is reserved for preallocated files\n  kZeroType = 0,\n\n  kFullType = 1,\n\n  // For fragments\n  kFirstType = 2,\n  kMiddleType = 3,\n  kLastType = 4\n};\nstatic const int kMaxRecordType = kLastType;\n\nstatic const int kBlockSize = 32768;\n\n// Header is checksum (4 bytes), length (2 bytes), type (1 byte).\nstatic const int kHeaderSize = 4 + 2 + 1;\n\n}  // namespace log\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_DB_LOG_FORMAT_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/db/log_reader.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/log_reader.h\"\n\n#include <stdio.h>\n#include \"leveldb/env.h\"\n#include \"util/coding.h\"\n#include \"util/crc32c.h\"\n\nnamespace leveldb {\nnamespace log {\n\nReader::Reporter::~Reporter() {\n}\n\nReader::Reader(SequentialFile* file, Reporter* reporter, bool checksum,\n               uint64_t initial_offset)\n    : file_(file),\n      reporter_(reporter),\n      checksum_(checksum),\n      backing_store_(new char[kBlockSize]),\n      buffer_(),\n      eof_(false),\n      last_record_offset_(0),\n      end_of_buffer_offset_(0),\n      initial_offset_(initial_offset),\n      resyncing_(initial_offset > 0) {\n}\n\nReader::~Reader() {\n  delete[] backing_store_;\n}\n\nbool Reader::SkipToInitialBlock() {\n  size_t offset_in_block = initial_offset_ % kBlockSize;\n  uint64_t block_start_location = initial_offset_ - offset_in_block;\n\n  // Don't search a block if we'd be in the trailer\n  if (offset_in_block > kBlockSize - 6) {\n    offset_in_block = 0;\n    block_start_location += kBlockSize;\n  }\n\n  end_of_buffer_offset_ = block_start_location;\n\n  // Skip to start of first block that can contain the initial record\n  if (block_start_location > 0) {\n    Status skip_status = file_->Skip(block_start_location);\n    if (!skip_status.ok()) {\n      ReportDrop(block_start_location, skip_status);\n      return false;\n    }\n  }\n\n  return true;\n}\n\nbool Reader::ReadRecord(Slice* record, std::string* scratch) {\n  if (last_record_offset_ < initial_offset_) {\n    if (!SkipToInitialBlock()) {\n      return false;\n    }\n  }\n\n  scratch->clear();\n  record->clear();\n  bool in_fragmented_record = false;\n  // Record offset of the logical record that we're reading\n  // 0 is a dummy value to make compilers happy\n  uint64_t prospective_record_offset = 0;\n\n  Slice fragment;\n  while (true) {\n    const unsigned int record_type = ReadPhysicalRecord(&fragment);\n\n    // ReadPhysicalRecord may have only had an empty trailer remaining in its\n    // internal buffer. Calculate the offset of the next physical record now\n    // that it has returned, properly accounting for its header size.\n    uint64_t physical_record_offset =\n        end_of_buffer_offset_ - buffer_.size() - kHeaderSize - fragment.size();\n\n    if (resyncing_) {\n      if (record_type == kMiddleType) {\n        continue;\n      } else if (record_type == kLastType) {\n        resyncing_ = false;\n        continue;\n      } else {\n        resyncing_ = false;\n      }\n    }\n\n    switch (record_type) {\n      case kFullType:\n        if (in_fragmented_record) {\n          // Handle bug in earlier versions of log::Writer where\n          // it could emit an empty kFirstType record at the tail end\n          // of a block followed by a kFullType or kFirstType record\n          // at the beginning of the next block.\n          if (scratch->empty()) {\n            in_fragmented_record = false;\n          } else {\n            ReportCorruption(scratch->size(), \"partial record without end(1)\");\n          }\n        }\n        prospective_record_offset = physical_record_offset;\n        scratch->clear();\n        *record = fragment;\n        last_record_offset_ = prospective_record_offset;\n        return true;\n\n      case kFirstType:\n        if (in_fragmented_record) {\n          // Handle bug in earlier versions of log::Writer where\n          // it could emit an empty kFirstType record at the tail end\n          // of a block followed by a kFullType or kFirstType record\n          // at the beginning of the next block.\n          if (scratch->empty()) {\n            in_fragmented_record = false;\n          } else {\n            ReportCorruption(scratch->size(), \"partial record without end(2)\");\n          }\n        }\n        prospective_record_offset = physical_record_offset;\n        scratch->assign(fragment.data(), fragment.size());\n        in_fragmented_record = true;\n        break;\n\n      case kMiddleType:\n        if (!in_fragmented_record) {\n          ReportCorruption(fragment.size(),\n                           \"missing start of fragmented record(1)\");\n        } else {\n          scratch->append(fragment.data(), fragment.size());\n        }\n        break;\n\n      case kLastType:\n        if (!in_fragmented_record) {\n          ReportCorruption(fragment.size(),\n                           \"missing start of fragmented record(2)\");\n        } else {\n          scratch->append(fragment.data(), fragment.size());\n          *record = Slice(*scratch);\n          last_record_offset_ = prospective_record_offset;\n          return true;\n        }\n        break;\n\n      case kEof:\n        if (in_fragmented_record) {\n          // This can be caused by the writer dying immediately after\n          // writing a physical record but before completing the next; don't\n          // treat it as a corruption, just ignore the entire logical record.\n          scratch->clear();\n        }\n        return false;\n\n      case kBadRecord:\n        if (in_fragmented_record) {\n          ReportCorruption(scratch->size(), \"error in middle of record\");\n          in_fragmented_record = false;\n          scratch->clear();\n        }\n        break;\n\n      default: {\n        char buf[40];\n        snprintf(buf, sizeof(buf), \"unknown record type %u\", record_type);\n        ReportCorruption(\n            (fragment.size() + (in_fragmented_record ? scratch->size() : 0)),\n            buf);\n        in_fragmented_record = false;\n        scratch->clear();\n        break;\n      }\n    }\n  }\n  return false;\n}\n\nuint64_t Reader::LastRecordOffset() {\n  return last_record_offset_;\n}\n\nvoid Reader::ReportCorruption(uint64_t bytes, const char* reason) {\n  ReportDrop(bytes, Status::Corruption(reason));\n}\n\nvoid Reader::ReportDrop(uint64_t bytes, const Status& reason) {\n  if (reporter_ != NULL &&\n      end_of_buffer_offset_ - buffer_.size() - bytes >= initial_offset_) {\n    reporter_->Corruption(static_cast<size_t>(bytes), reason);\n  }\n}\n\nunsigned int Reader::ReadPhysicalRecord(Slice* result) {\n  while (true) {\n    if (buffer_.size() < kHeaderSize) {\n      if (!eof_) {\n        // Last read was a full read, so this is a trailer to skip\n        buffer_.clear();\n        Status status = file_->Read(kBlockSize, &buffer_, backing_store_);\n        end_of_buffer_offset_ += buffer_.size();\n        if (!status.ok()) {\n          buffer_.clear();\n          ReportDrop(kBlockSize, status);\n          eof_ = true;\n          return kEof;\n        } else if (buffer_.size() < kBlockSize) {\n          eof_ = true;\n        }\n        continue;\n      } else {\n        // Note that if buffer_ is non-empty, we have a truncated header at the\n        // end of the file, which can be caused by the writer crashing in the\n        // middle of writing the header. Instead of considering this an error,\n        // just report EOF.\n        buffer_.clear();\n        return kEof;\n      }\n    }\n\n    // Parse the header\n    const char* header = buffer_.data();\n    const uint32_t a = static_cast<uint32_t>(header[4]) & 0xff;\n    const uint32_t b = static_cast<uint32_t>(header[5]) & 0xff;\n    const unsigned int type = header[6];\n    const uint32_t length = a | (b << 8);\n    if (kHeaderSize + length > buffer_.size()) {\n      size_t drop_size = buffer_.size();\n      buffer_.clear();\n      if (!eof_) {\n        ReportCorruption(drop_size, \"bad record length\");\n        return kBadRecord;\n      }\n      // If the end of the file has been reached without reading |length| bytes\n      // of payload, assume the writer died in the middle of writing the record.\n      // Don't report a corruption.\n      return kEof;\n    }\n\n    if (type == kZeroType && length == 0) {\n      // Skip zero length record without reporting any drops since\n      // such records are produced by the mmap based writing code in\n      // env_posix.cc that preallocates file regions.\n      buffer_.clear();\n      return kBadRecord;\n    }\n\n    // Check crc\n    if (checksum_) {\n      uint32_t expected_crc = crc32c::Unmask(DecodeFixed32(header));\n      uint32_t actual_crc = crc32c::Value(header + 6, 1 + length);\n      if (actual_crc != expected_crc) {\n        // Drop the rest of the buffer since \"length\" itself may have\n        // been corrupted and if we trust it, we could find some\n        // fragment of a real log record that just happens to look\n        // like a valid log record.\n        size_t drop_size = buffer_.size();\n        buffer_.clear();\n        ReportCorruption(drop_size, \"checksum mismatch\");\n        return kBadRecord;\n      }\n    }\n\n    buffer_.remove_prefix(kHeaderSize + length);\n\n    // Skip physical record that started before initial_offset_\n    if (end_of_buffer_offset_ - buffer_.size() - kHeaderSize - length <\n        initial_offset_) {\n      result->clear();\n      return kBadRecord;\n    }\n\n    *result = Slice(header + kHeaderSize, length);\n    return type;\n  }\n}\n\n}  // namespace log\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/db/log_reader.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_DB_LOG_READER_H_\n#define STORAGE_LEVELDB_DB_LOG_READER_H_\n\n#include <stdint.h>\n\n#include \"db/log_format.h\"\n#include \"leveldb/slice.h\"\n#include \"leveldb/status.h\"\n\nnamespace leveldb {\n\nclass SequentialFile;\n\nnamespace log {\n\nclass Reader {\n public:\n  // Interface for reporting errors.\n  class Reporter {\n   public:\n    virtual ~Reporter();\n\n    // Some corruption was detected.  \"size\" is the approximate number\n    // of bytes dropped due to the corruption.\n    virtual void Corruption(size_t bytes, const Status& status) = 0;\n  };\n\n  // Create a reader that will return log records from \"*file\".\n  // \"*file\" must remain live while this Reader is in use.\n  //\n  // If \"reporter\" is non-NULL, it is notified whenever some data is\n  // dropped due to a detected corruption.  \"*reporter\" must remain\n  // live while this Reader is in use.\n  //\n  // If \"checksum\" is true, verify checksums if available.\n  //\n  // The Reader will start reading at the first record located at physical\n  // position >= initial_offset within the file.\n  Reader(SequentialFile* file, Reporter* reporter, bool checksum,\n         uint64_t initial_offset);\n\n  ~Reader();\n\n  // Read the next record into *record.  Returns true if read\n  // successfully, false if we hit end of the input.  May use\n  // \"*scratch\" as temporary storage.  The contents filled in *record\n  // will only be valid until the next mutating operation on this\n  // reader or the next mutation to *scratch.\n  bool ReadRecord(Slice* record, std::string* scratch);\n\n  // Returns the physical offset of the last record returned by ReadRecord.\n  //\n  // Undefined before the first call to ReadRecord.\n  uint64_t LastRecordOffset();\n\n private:\n  SequentialFile* const file_;\n  Reporter* const reporter_;\n  bool const checksum_;\n  char* const backing_store_;\n  Slice buffer_;\n  bool eof_;   // Last Read() indicated EOF by returning < kBlockSize\n\n  // Offset of the last record returned by ReadRecord.\n  uint64_t last_record_offset_;\n  // Offset of the first location past the end of buffer_.\n  uint64_t end_of_buffer_offset_;\n\n  // Offset at which to start looking for the first record to return\n  uint64_t const initial_offset_;\n\n  // True if we are resynchronizing after a seek (initial_offset_ > 0). In\n  // particular, a run of kMiddleType and kLastType records can be silently\n  // skipped in this mode\n  bool resyncing_;\n\n  // Extend record types with the following special values\n  enum {\n    kEof = kMaxRecordType + 1,\n    // Returned whenever we find an invalid physical record.\n    // Currently there are three situations in which this happens:\n    // * The record has an invalid CRC (ReadPhysicalRecord reports a drop)\n    // * The record is a 0-length record (No drop is reported)\n    // * The record is below constructor's initial_offset (No drop is reported)\n    kBadRecord = kMaxRecordType + 2\n  };\n\n  // Skips all blocks that are completely before \"initial_offset_\".\n  //\n  // Returns true on success. Handles reporting.\n  bool SkipToInitialBlock();\n\n  // Return type, or one of the preceding special values\n  unsigned int ReadPhysicalRecord(Slice* result);\n\n  // Reports dropped bytes to the reporter.\n  // buffer_ must be updated to remove the dropped bytes prior to invocation.\n  void ReportCorruption(uint64_t bytes, const char* reason);\n  void ReportDrop(uint64_t bytes, const Status& reason);\n\n  // No copying allowed\n  Reader(const Reader&);\n  void operator=(const Reader&);\n};\n\n}  // namespace log\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_DB_LOG_READER_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/db/log_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/log_reader.h\"\n#include \"db/log_writer.h\"\n#include \"leveldb/env.h\"\n#include \"util/coding.h\"\n#include \"util/crc32c.h\"\n#include \"util/random.h\"\n#include \"util/testharness.h\"\n\nnamespace leveldb {\nnamespace log {\n\n// Construct a string of the specified length made out of the supplied\n// partial string.\nstatic std::string BigString(const std::string& partial_string, size_t n) {\n  std::string result;\n  while (result.size() < n) {\n    result.append(partial_string);\n  }\n  result.resize(n);\n  return result;\n}\n\n// Construct a string from a number\nstatic std::string NumberString(int n) {\n  char buf[50];\n  snprintf(buf, sizeof(buf), \"%d.\", n);\n  return std::string(buf);\n}\n\n// Return a skewed potentially long string\nstatic std::string RandomSkewedString(int i, Random* rnd) {\n  return BigString(NumberString(i), rnd->Skewed(17));\n}\n\nclass LogTest {\n private:\n  class StringDest : public WritableFile {\n   public:\n    std::string contents_;\n\n    virtual Status Close() { return Status::OK(); }\n    virtual Status Flush() { return Status::OK(); }\n    virtual Status Sync() { return Status::OK(); }\n    virtual Status Append(const Slice& slice) {\n      contents_.append(slice.data(), slice.size());\n      return Status::OK();\n    }\n  };\n\n  class StringSource : public SequentialFile {\n   public:\n    Slice contents_;\n    bool force_error_;\n    bool returned_partial_;\n    StringSource() : force_error_(false), returned_partial_(false) { }\n\n    virtual Status Read(size_t n, Slice* result, char* scratch) {\n      ASSERT_TRUE(!returned_partial_) << \"must not Read() after eof/error\";\n\n      if (force_error_) {\n        force_error_ = false;\n        returned_partial_ = true;\n        return Status::Corruption(\"read error\");\n      }\n\n      if (contents_.size() < n) {\n        n = contents_.size();\n        returned_partial_ = true;\n      }\n      *result = Slice(contents_.data(), n);\n      contents_.remove_prefix(n);\n      return Status::OK();\n    }\n\n    virtual Status Skip(uint64_t n) {\n      if (n > contents_.size()) {\n        contents_.clear();\n        return Status::NotFound(\"in-memory file skipped past end\");\n      }\n\n      contents_.remove_prefix(n);\n\n      return Status::OK();\n    }\n  };\n\n  class ReportCollector : public Reader::Reporter {\n   public:\n    size_t dropped_bytes_;\n    std::string message_;\n\n    ReportCollector() : dropped_bytes_(0) { }\n    virtual void Corruption(size_t bytes, const Status& status) {\n      dropped_bytes_ += bytes;\n      message_.append(status.ToString());\n    }\n  };\n\n  StringDest dest_;\n  StringSource source_;\n  ReportCollector report_;\n  bool reading_;\n  Writer* writer_;\n  Reader* reader_;\n\n  // Record metadata for testing initial offset functionality\n  static size_t initial_offset_record_sizes_[];\n  static uint64_t initial_offset_last_record_offsets_[];\n  static int num_initial_offset_records_;\n\n public:\n  LogTest() : reading_(false),\n              writer_(new Writer(&dest_)),\n              reader_(new Reader(&source_, &report_, true/*checksum*/,\n                      0/*initial_offset*/)) {\n  }\n\n  ~LogTest() {\n    delete writer_;\n    delete reader_;\n  }\n\n  void ReopenForAppend() {\n    delete writer_;\n    writer_ = new Writer(&dest_, dest_.contents_.size());\n  }\n\n  void Write(const std::string& msg) {\n    ASSERT_TRUE(!reading_) << \"Write() after starting to read\";\n    writer_->AddRecord(Slice(msg));\n  }\n\n  size_t WrittenBytes() const {\n    return dest_.contents_.size();\n  }\n\n  std::string Read() {\n    if (!reading_) {\n      reading_ = true;\n      source_.contents_ = Slice(dest_.contents_);\n    }\n    std::string scratch;\n    Slice record;\n    if (reader_->ReadRecord(&record, &scratch)) {\n      return record.ToString();\n    } else {\n      return \"EOF\";\n    }\n  }\n\n  void IncrementByte(int offset, int delta) {\n    dest_.contents_[offset] += delta;\n  }\n\n  void SetByte(int offset, char new_byte) {\n    dest_.contents_[offset] = new_byte;\n  }\n\n  void ShrinkSize(int bytes) {\n    dest_.contents_.resize(dest_.contents_.size() - bytes);\n  }\n\n  void FixChecksum(int header_offset, int len) {\n    // Compute crc of type/len/data\n    uint32_t crc = crc32c::Value(&dest_.contents_[header_offset+6], 1 + len);\n    crc = crc32c::Mask(crc);\n    EncodeFixed32(&dest_.contents_[header_offset], crc);\n  }\n\n  void ForceError() {\n    source_.force_error_ = true;\n  }\n\n  size_t DroppedBytes() const {\n    return report_.dropped_bytes_;\n  }\n\n  std::string ReportMessage() const {\n    return report_.message_;\n  }\n\n  // Returns OK iff recorded error message contains \"msg\"\n  std::string MatchError(const std::string& msg) const {\n    if (report_.message_.find(msg) == std::string::npos) {\n      return report_.message_;\n    } else {\n      return \"OK\";\n    }\n  }\n\n  void WriteInitialOffsetLog() {\n    for (int i = 0; i < num_initial_offset_records_; i++) {\n      std::string record(initial_offset_record_sizes_[i],\n                         static_cast<char>('a' + i));\n      Write(record);\n    }\n  }\n\n  void StartReadingAt(uint64_t initial_offset) {\n    delete reader_;\n    reader_ = new Reader(&source_, &report_, true/*checksum*/, initial_offset);\n  }\n\n  void CheckOffsetPastEndReturnsNoRecords(uint64_t offset_past_end) {\n    WriteInitialOffsetLog();\n    reading_ = true;\n    source_.contents_ = Slice(dest_.contents_);\n    Reader* offset_reader = new Reader(&source_, &report_, true/*checksum*/,\n                                       WrittenBytes() + offset_past_end);\n    Slice record;\n    std::string scratch;\n    ASSERT_TRUE(!offset_reader->ReadRecord(&record, &scratch));\n    delete offset_reader;\n  }\n\n  void CheckInitialOffsetRecord(uint64_t initial_offset,\n                                int expected_record_offset) {\n    WriteInitialOffsetLog();\n    reading_ = true;\n    source_.contents_ = Slice(dest_.contents_);\n    Reader* offset_reader = new Reader(&source_, &report_, true/*checksum*/,\n                                       initial_offset);\n\n    // Read all records from expected_record_offset through the last one.\n    ASSERT_LT(expected_record_offset, num_initial_offset_records_);\n    for (; expected_record_offset < num_initial_offset_records_;\n         ++expected_record_offset) {\n      Slice record;\n      std::string scratch;\n      ASSERT_TRUE(offset_reader->ReadRecord(&record, &scratch));\n      ASSERT_EQ(initial_offset_record_sizes_[expected_record_offset],\n                record.size());\n      ASSERT_EQ(initial_offset_last_record_offsets_[expected_record_offset],\n                offset_reader->LastRecordOffset());\n      ASSERT_EQ((char)('a' + expected_record_offset), record.data()[0]);\n    }\n    delete offset_reader;\n  }\n};\n\nsize_t LogTest::initial_offset_record_sizes_[] =\n    {10000,  // Two sizable records in first block\n     10000,\n     2 * log::kBlockSize - 1000,  // Span three blocks\n     1,\n     13716,  // Consume all but two bytes of block 3.\n     log::kBlockSize - kHeaderSize, // Consume the entirety of block 4.\n    };\n\nuint64_t LogTest::initial_offset_last_record_offsets_[] =\n    {0,\n     kHeaderSize + 10000,\n     2 * (kHeaderSize + 10000),\n     2 * (kHeaderSize + 10000) +\n         (2 * log::kBlockSize - 1000) + 3 * kHeaderSize,\n     2 * (kHeaderSize + 10000) +\n         (2 * log::kBlockSize - 1000) + 3 * kHeaderSize\n         + kHeaderSize + 1,\n     3 * log::kBlockSize,\n    };\n\n// LogTest::initial_offset_last_record_offsets_ must be defined before this.\nint LogTest::num_initial_offset_records_ =\n    sizeof(LogTest::initial_offset_last_record_offsets_)/sizeof(uint64_t);\n\nTEST(LogTest, Empty) {\n  ASSERT_EQ(\"EOF\", Read());\n}\n\nTEST(LogTest, ReadWrite) {\n  Write(\"foo\");\n  Write(\"bar\");\n  Write(\"\");\n  Write(\"xxxx\");\n  ASSERT_EQ(\"foo\", Read());\n  ASSERT_EQ(\"bar\", Read());\n  ASSERT_EQ(\"\", Read());\n  ASSERT_EQ(\"xxxx\", Read());\n  ASSERT_EQ(\"EOF\", Read());\n  ASSERT_EQ(\"EOF\", Read());  // Make sure reads at eof work\n}\n\nTEST(LogTest, ManyBlocks) {\n  for (int i = 0; i < 100000; i++) {\n    Write(NumberString(i));\n  }\n  for (int i = 0; i < 100000; i++) {\n    ASSERT_EQ(NumberString(i), Read());\n  }\n  ASSERT_EQ(\"EOF\", Read());\n}\n\nTEST(LogTest, Fragmentation) {\n  Write(\"small\");\n  Write(BigString(\"medium\", 50000));\n  Write(BigString(\"large\", 100000));\n  ASSERT_EQ(\"small\", Read());\n  ASSERT_EQ(BigString(\"medium\", 50000), Read());\n  ASSERT_EQ(BigString(\"large\", 100000), Read());\n  ASSERT_EQ(\"EOF\", Read());\n}\n\nTEST(LogTest, MarginalTrailer) {\n  // Make a trailer that is exactly the same length as an empty record.\n  const int n = kBlockSize - 2*kHeaderSize;\n  Write(BigString(\"foo\", n));\n  ASSERT_EQ(kBlockSize - kHeaderSize, WrittenBytes());\n  Write(\"\");\n  Write(\"bar\");\n  ASSERT_EQ(BigString(\"foo\", n), Read());\n  ASSERT_EQ(\"\", Read());\n  ASSERT_EQ(\"bar\", Read());\n  ASSERT_EQ(\"EOF\", Read());\n}\n\nTEST(LogTest, MarginalTrailer2) {\n  // Make a trailer that is exactly the same length as an empty record.\n  const int n = kBlockSize - 2*kHeaderSize;\n  Write(BigString(\"foo\", n));\n  ASSERT_EQ(kBlockSize - kHeaderSize, WrittenBytes());\n  Write(\"bar\");\n  ASSERT_EQ(BigString(\"foo\", n), Read());\n  ASSERT_EQ(\"bar\", Read());\n  ASSERT_EQ(\"EOF\", Read());\n  ASSERT_EQ(0, DroppedBytes());\n  ASSERT_EQ(\"\", ReportMessage());\n}\n\nTEST(LogTest, ShortTrailer) {\n  const int n = kBlockSize - 2*kHeaderSize + 4;\n  Write(BigString(\"foo\", n));\n  ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes());\n  Write(\"\");\n  Write(\"bar\");\n  ASSERT_EQ(BigString(\"foo\", n), Read());\n  ASSERT_EQ(\"\", Read());\n  ASSERT_EQ(\"bar\", Read());\n  ASSERT_EQ(\"EOF\", Read());\n}\n\nTEST(LogTest, AlignedEof) {\n  const int n = kBlockSize - 2*kHeaderSize + 4;\n  Write(BigString(\"foo\", n));\n  ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes());\n  ASSERT_EQ(BigString(\"foo\", n), Read());\n  ASSERT_EQ(\"EOF\", Read());\n}\n\nTEST(LogTest, OpenForAppend) {\n  Write(\"hello\");\n  ReopenForAppend();\n  Write(\"world\");\n  ASSERT_EQ(\"hello\", Read());\n  ASSERT_EQ(\"world\", Read());\n  ASSERT_EQ(\"EOF\", Read());\n}\n\nTEST(LogTest, RandomRead) {\n  const int N = 500;\n  Random write_rnd(301);\n  for (int i = 0; i < N; i++) {\n    Write(RandomSkewedString(i, &write_rnd));\n  }\n  Random read_rnd(301);\n  for (int i = 0; i < N; i++) {\n    ASSERT_EQ(RandomSkewedString(i, &read_rnd), Read());\n  }\n  ASSERT_EQ(\"EOF\", Read());\n}\n\n// Tests of all the error paths in log_reader.cc follow:\n\nTEST(LogTest, ReadError) {\n  Write(\"foo\");\n  ForceError();\n  ASSERT_EQ(\"EOF\", Read());\n  ASSERT_EQ(kBlockSize, DroppedBytes());\n  ASSERT_EQ(\"OK\", MatchError(\"read error\"));\n}\n\nTEST(LogTest, BadRecordType) {\n  Write(\"foo\");\n  // Type is stored in header[6]\n  IncrementByte(6, 100);\n  FixChecksum(0, 3);\n  ASSERT_EQ(\"EOF\", Read());\n  ASSERT_EQ(3, DroppedBytes());\n  ASSERT_EQ(\"OK\", MatchError(\"unknown record type\"));\n}\n\nTEST(LogTest, TruncatedTrailingRecordIsIgnored) {\n  Write(\"foo\");\n  ShrinkSize(4);   // Drop all payload as well as a header byte\n  ASSERT_EQ(\"EOF\", Read());\n  // Truncated last record is ignored, not treated as an error.\n  ASSERT_EQ(0, DroppedBytes());\n  ASSERT_EQ(\"\", ReportMessage());\n}\n\nTEST(LogTest, BadLength) {\n  const int kPayloadSize = kBlockSize - kHeaderSize;\n  Write(BigString(\"bar\", kPayloadSize));\n  Write(\"foo\");\n  // Least significant size byte is stored in header[4].\n  IncrementByte(4, 1);\n  ASSERT_EQ(\"foo\", Read());\n  ASSERT_EQ(kBlockSize, DroppedBytes());\n  ASSERT_EQ(\"OK\", MatchError(\"bad record length\"));\n}\n\nTEST(LogTest, BadLengthAtEndIsIgnored) {\n  Write(\"foo\");\n  ShrinkSize(1);\n  ASSERT_EQ(\"EOF\", Read());\n  ASSERT_EQ(0, DroppedBytes());\n  ASSERT_EQ(\"\", ReportMessage());\n}\n\nTEST(LogTest, ChecksumMismatch) {\n  Write(\"foo\");\n  IncrementByte(0, 10);\n  ASSERT_EQ(\"EOF\", Read());\n  ASSERT_EQ(10, DroppedBytes());\n  ASSERT_EQ(\"OK\", MatchError(\"checksum mismatch\"));\n}\n\nTEST(LogTest, UnexpectedMiddleType) {\n  Write(\"foo\");\n  SetByte(6, kMiddleType);\n  FixChecksum(0, 3);\n  ASSERT_EQ(\"EOF\", Read());\n  ASSERT_EQ(3, DroppedBytes());\n  ASSERT_EQ(\"OK\", MatchError(\"missing start\"));\n}\n\nTEST(LogTest, UnexpectedLastType) {\n  Write(\"foo\");\n  SetByte(6, kLastType);\n  FixChecksum(0, 3);\n  ASSERT_EQ(\"EOF\", Read());\n  ASSERT_EQ(3, DroppedBytes());\n  ASSERT_EQ(\"OK\", MatchError(\"missing start\"));\n}\n\nTEST(LogTest, UnexpectedFullType) {\n  Write(\"foo\");\n  Write(\"bar\");\n  SetByte(6, kFirstType);\n  FixChecksum(0, 3);\n  ASSERT_EQ(\"bar\", Read());\n  ASSERT_EQ(\"EOF\", Read());\n  ASSERT_EQ(3, DroppedBytes());\n  ASSERT_EQ(\"OK\", MatchError(\"partial record without end\"));\n}\n\nTEST(LogTest, UnexpectedFirstType) {\n  Write(\"foo\");\n  Write(BigString(\"bar\", 100000));\n  SetByte(6, kFirstType);\n  FixChecksum(0, 3);\n  ASSERT_EQ(BigString(\"bar\", 100000), Read());\n  ASSERT_EQ(\"EOF\", Read());\n  ASSERT_EQ(3, DroppedBytes());\n  ASSERT_EQ(\"OK\", MatchError(\"partial record without end\"));\n}\n\nTEST(LogTest, MissingLastIsIgnored) {\n  Write(BigString(\"bar\", kBlockSize));\n  // Remove the LAST block, including header.\n  ShrinkSize(14);\n  ASSERT_EQ(\"EOF\", Read());\n  ASSERT_EQ(\"\", ReportMessage());\n  ASSERT_EQ(0, DroppedBytes());\n}\n\nTEST(LogTest, PartialLastIsIgnored) {\n  Write(BigString(\"bar\", kBlockSize));\n  // Cause a bad record length in the LAST block.\n  ShrinkSize(1);\n  ASSERT_EQ(\"EOF\", Read());\n  ASSERT_EQ(\"\", ReportMessage());\n  ASSERT_EQ(0, DroppedBytes());\n}\n\nTEST(LogTest, SkipIntoMultiRecord) {\n  // Consider a fragmented record:\n  //    first(R1), middle(R1), last(R1), first(R2)\n  // If initial_offset points to a record after first(R1) but before first(R2)\n  // incomplete fragment errors are not actual errors, and must be suppressed\n  // until a new first or full record is encountered.\n  Write(BigString(\"foo\", 3*kBlockSize));\n  Write(\"correct\");\n  StartReadingAt(kBlockSize);\n\n  ASSERT_EQ(\"correct\", Read());\n  ASSERT_EQ(\"\", ReportMessage());\n  ASSERT_EQ(0, DroppedBytes());\n  ASSERT_EQ(\"EOF\", Read());\n}\n\nTEST(LogTest, ErrorJoinsRecords) {\n  // Consider two fragmented records:\n  //    first(R1) last(R1) first(R2) last(R2)\n  // where the middle two fragments disappear.  We do not want\n  // first(R1),last(R2) to get joined and returned as a valid record.\n\n  // Write records that span two blocks\n  Write(BigString(\"foo\", kBlockSize));\n  Write(BigString(\"bar\", kBlockSize));\n  Write(\"correct\");\n\n  // Wipe the middle block\n  for (int offset = kBlockSize; offset < 2*kBlockSize; offset++) {\n    SetByte(offset, 'x');\n  }\n\n  ASSERT_EQ(\"correct\", Read());\n  ASSERT_EQ(\"EOF\", Read());\n  const size_t dropped = DroppedBytes();\n  ASSERT_LE(dropped, 2*kBlockSize + 100);\n  ASSERT_GE(dropped, 2*kBlockSize);\n}\n\nTEST(LogTest, ReadStart) {\n  CheckInitialOffsetRecord(0, 0);\n}\n\nTEST(LogTest, ReadSecondOneOff) {\n  CheckInitialOffsetRecord(1, 1);\n}\n\nTEST(LogTest, ReadSecondTenThousand) {\n  CheckInitialOffsetRecord(10000, 1);\n}\n\nTEST(LogTest, ReadSecondStart) {\n  CheckInitialOffsetRecord(10007, 1);\n}\n\nTEST(LogTest, ReadThirdOneOff) {\n  CheckInitialOffsetRecord(10008, 2);\n}\n\nTEST(LogTest, ReadThirdStart) {\n  CheckInitialOffsetRecord(20014, 2);\n}\n\nTEST(LogTest, ReadFourthOneOff) {\n  CheckInitialOffsetRecord(20015, 3);\n}\n\nTEST(LogTest, ReadFourthFirstBlockTrailer) {\n  CheckInitialOffsetRecord(log::kBlockSize - 4, 3);\n}\n\nTEST(LogTest, ReadFourthMiddleBlock) {\n  CheckInitialOffsetRecord(log::kBlockSize + 1, 3);\n}\n\nTEST(LogTest, ReadFourthLastBlock) {\n  CheckInitialOffsetRecord(2 * log::kBlockSize + 1, 3);\n}\n\nTEST(LogTest, ReadFourthStart) {\n  CheckInitialOffsetRecord(\n      2 * (kHeaderSize + 1000) + (2 * log::kBlockSize - 1000) + 3 * kHeaderSize,\n      3);\n}\n\nTEST(LogTest, ReadInitialOffsetIntoBlockPadding) {\n  CheckInitialOffsetRecord(3 * log::kBlockSize - 3, 5);\n}\n\nTEST(LogTest, ReadEnd) {\n  CheckOffsetPastEndReturnsNoRecords(0);\n}\n\nTEST(LogTest, ReadPastEnd) {\n  CheckOffsetPastEndReturnsNoRecords(5);\n}\n\n}  // namespace log\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/db/log_writer.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/log_writer.h\"\n\n#include <stdint.h>\n#include \"leveldb/env.h\"\n#include \"util/coding.h\"\n#include \"util/crc32c.h\"\n\nnamespace leveldb {\nnamespace log {\n\nstatic void InitTypeCrc(uint32_t* type_crc) {\n  for (int i = 0; i <= kMaxRecordType; i++) {\n    char t = static_cast<char>(i);\n    type_crc[i] = crc32c::Value(&t, 1);\n  }\n}\n\nWriter::Writer(WritableFile* dest)\n    : dest_(dest),\n      block_offset_(0) {\n  InitTypeCrc(type_crc_);\n}\n\nWriter::Writer(WritableFile* dest, uint64_t dest_length)\n    : dest_(dest), block_offset_(dest_length % kBlockSize) {\n  InitTypeCrc(type_crc_);\n}\n\nWriter::~Writer() {\n}\n\nStatus Writer::AddRecord(const Slice& slice) {\n  const char* ptr = slice.data();\n  size_t left = slice.size();\n\n  // Fragment the record if necessary and emit it.  Note that if slice\n  // is empty, we still want to iterate once to emit a single\n  // zero-length record\n  Status s;\n  bool begin = true;\n  do {\n    const int leftover = kBlockSize - block_offset_;\n    assert(leftover >= 0);\n    if (leftover < kHeaderSize) {\n      // Switch to a new block\n      if (leftover > 0) {\n        // Fill the trailer (literal below relies on kHeaderSize being 7)\n        assert(kHeaderSize == 7);\n        dest_->Append(Slice(\"\\x00\\x00\\x00\\x00\\x00\\x00\", leftover));\n      }\n      block_offset_ = 0;\n    }\n\n    // Invariant: we never leave < kHeaderSize bytes in a block.\n    assert(kBlockSize - block_offset_ - kHeaderSize >= 0);\n\n    const size_t avail = kBlockSize - block_offset_ - kHeaderSize;\n    const size_t fragment_length = (left < avail) ? left : avail;\n\n    RecordType type;\n    const bool end = (left == fragment_length);\n    if (begin && end) {\n      type = kFullType;\n    } else if (begin) {\n      type = kFirstType;\n    } else if (end) {\n      type = kLastType;\n    } else {\n      type = kMiddleType;\n    }\n\n    s = EmitPhysicalRecord(type, ptr, fragment_length);\n    ptr += fragment_length;\n    left -= fragment_length;\n    begin = false;\n  } while (s.ok() && left > 0);\n  return s;\n}\n\nStatus Writer::EmitPhysicalRecord(RecordType t, const char* ptr, size_t n) {\n  assert(n <= 0xffff);  // Must fit in two bytes\n  assert(block_offset_ + kHeaderSize + n <= kBlockSize);\n\n  // Format the header\n  char buf[kHeaderSize];\n  buf[4] = static_cast<char>(n & 0xff);\n  buf[5] = static_cast<char>(n >> 8);\n  buf[6] = static_cast<char>(t);\n\n  // Compute the crc of the record type and the payload.\n  uint32_t crc = crc32c::Extend(type_crc_[t], ptr, n);\n  crc = crc32c::Mask(crc);                 // Adjust for storage\n  EncodeFixed32(buf, crc);\n\n  // Write the header and the payload\n  Status s = dest_->Append(Slice(buf, kHeaderSize));\n  if (s.ok()) {\n    s = dest_->Append(Slice(ptr, n));\n    if (s.ok()) {\n      s = dest_->Flush();\n    }\n  }\n  block_offset_ += kHeaderSize + n;\n  return s;\n}\n\n}  // namespace log\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/db/log_writer.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_DB_LOG_WRITER_H_\n#define STORAGE_LEVELDB_DB_LOG_WRITER_H_\n\n#include <stdint.h>\n#include \"db/log_format.h\"\n#include \"leveldb/slice.h\"\n#include \"leveldb/status.h\"\n\nnamespace leveldb {\n\nclass WritableFile;\n\nnamespace log {\n\nclass Writer {\n public:\n  // Create a writer that will append data to \"*dest\".\n  // \"*dest\" must be initially empty.\n  // \"*dest\" must remain live while this Writer is in use.\n  explicit Writer(WritableFile* dest);\n\n  // Create a writer that will append data to \"*dest\".\n  // \"*dest\" must have initial length \"dest_length\".\n  // \"*dest\" must remain live while this Writer is in use.\n  Writer(WritableFile* dest, uint64_t dest_length);\n\n  ~Writer();\n\n  Status AddRecord(const Slice& slice);\n\n private:\n  WritableFile* dest_;\n  int block_offset_;       // Current offset in block\n\n  // crc32c values for all supported record types.  These are\n  // pre-computed to reduce the overhead of computing the crc of the\n  // record type stored in the header.\n  uint32_t type_crc_[kMaxRecordType + 1];\n\n  Status EmitPhysicalRecord(RecordType type, const char* ptr, size_t length);\n\n  // No copying allowed\n  Writer(const Writer&);\n  void operator=(const Writer&);\n};\n\n}  // namespace log\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_DB_LOG_WRITER_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/db/memtable.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/memtable.h\"\n#include \"db/dbformat.h\"\n#include \"leveldb/comparator.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/iterator.h\"\n#include \"util/coding.h\"\n\nnamespace leveldb {\n\nstatic Slice GetLengthPrefixedSlice(const char* data) {\n  uint32_t len;\n  const char* p = data;\n  p = GetVarint32Ptr(p, p + 5, &len);  // +5: we assume \"p\" is not corrupted\n  return Slice(p, len);\n}\n\nMemTable::MemTable(const InternalKeyComparator& cmp)\n    : comparator_(cmp),\n      refs_(0),\n      table_(comparator_, &arena_) {\n}\n\nMemTable::~MemTable() {\n  assert(refs_ == 0);\n}\n\nsize_t MemTable::ApproximateMemoryUsage() { return arena_.MemoryUsage(); }\n\nint MemTable::KeyComparator::operator()(const char* aptr, const char* bptr)\n    const {\n  // Internal keys are encoded as length-prefixed strings.\n  Slice a = GetLengthPrefixedSlice(aptr);\n  Slice b = GetLengthPrefixedSlice(bptr);\n  return comparator.Compare(a, b);\n}\n\n// Encode a suitable internal key target for \"target\" and return it.\n// Uses *scratch as scratch space, and the returned pointer will point\n// into this scratch space.\nstatic const char* EncodeKey(std::string* scratch, const Slice& target) {\n  scratch->clear();\n  PutVarint32(scratch, target.size());\n  scratch->append(target.data(), target.size());\n  return scratch->data();\n}\n\nclass MemTableIterator: public Iterator {\n public:\n  explicit MemTableIterator(MemTable::Table* table) : iter_(table) { }\n\n  virtual bool Valid() const { return iter_.Valid(); }\n  virtual void Seek(const Slice& k) { iter_.Seek(EncodeKey(&tmp_, k)); }\n  virtual void SeekToFirst() { iter_.SeekToFirst(); }\n  virtual void SeekToLast() { iter_.SeekToLast(); }\n  virtual void Next() { iter_.Next(); }\n  virtual void Prev() { iter_.Prev(); }\n  virtual Slice key() const { return GetLengthPrefixedSlice(iter_.key()); }\n  virtual Slice value() const {\n    Slice key_slice = GetLengthPrefixedSlice(iter_.key());\n    return GetLengthPrefixedSlice(key_slice.data() + key_slice.size());\n  }\n\n  virtual Status status() const { return Status::OK(); }\n\n private:\n  MemTable::Table::Iterator iter_;\n  std::string tmp_;       // For passing to EncodeKey\n\n  // No copying allowed\n  MemTableIterator(const MemTableIterator&);\n  void operator=(const MemTableIterator&);\n};\n\nIterator* MemTable::NewIterator() {\n  return new MemTableIterator(&table_);\n}\n\nvoid MemTable::Add(SequenceNumber s, ValueType type,\n                   const Slice& key,\n                   const Slice& value) {\n  // Format of an entry is concatenation of:\n  //  key_size     : varint32 of internal_key.size()\n  //  key bytes    : char[internal_key.size()]\n  //  value_size   : varint32 of value.size()\n  //  value bytes  : char[value.size()]\n  size_t key_size = key.size();\n  size_t val_size = value.size();\n  size_t internal_key_size = key_size + 8;\n  const size_t encoded_len =\n      VarintLength(internal_key_size) + internal_key_size +\n      VarintLength(val_size) + val_size;\n  char* buf = arena_.Allocate(encoded_len);\n  char* p = EncodeVarint32(buf, internal_key_size);\n  memcpy(p, key.data(), key_size);\n  p += key_size;\n  EncodeFixed64(p, (s << 8) | type);\n  p += 8;\n  p = EncodeVarint32(p, val_size);\n  memcpy(p, value.data(), val_size);\n  assert((p + val_size) - buf == encoded_len);\n  table_.Insert(buf);\n}\n\nbool MemTable::Get(const LookupKey& key, std::string* value, Status* s) {\n  Slice memkey = key.memtable_key();\n  Table::Iterator iter(&table_);\n  iter.Seek(memkey.data());\n  if (iter.Valid()) {\n    // entry format is:\n    //    klength  varint32\n    //    userkey  char[klength]\n    //    tag      uint64\n    //    vlength  varint32\n    //    value    char[vlength]\n    // Check that it belongs to same user key.  We do not check the\n    // sequence number since the Seek() call above should have skipped\n    // all entries with overly large sequence numbers.\n    const char* entry = iter.key();\n    uint32_t key_length;\n    const char* key_ptr = GetVarint32Ptr(entry, entry+5, &key_length);\n    if (comparator_.comparator.user_comparator()->Compare(\n            Slice(key_ptr, key_length - 8),\n            key.user_key()) == 0) {\n      // Correct user key\n      const uint64_t tag = DecodeFixed64(key_ptr + key_length - 8);\n      switch (static_cast<ValueType>(tag & 0xff)) {\n        case kTypeValue: {\n          Slice v = GetLengthPrefixedSlice(key_ptr + key_length);\n          value->assign(v.data(), v.size());\n          return true;\n        }\n        case kTypeDeletion:\n          *s = Status::NotFound(Slice());\n          return true;\n      }\n    }\n  }\n  return false;\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/db/memtable.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_DB_MEMTABLE_H_\n#define STORAGE_LEVELDB_DB_MEMTABLE_H_\n\n#include <string>\n#include \"leveldb/db.h\"\n#include \"db/dbformat.h\"\n#include \"db/skiplist.h\"\n#include \"util/arena.h\"\n\nnamespace leveldb {\n\nclass InternalKeyComparator;\nclass Mutex;\nclass MemTableIterator;\n\nclass MemTable {\n public:\n  // MemTables are reference counted.  The initial reference count\n  // is zero and the caller must call Ref() at least once.\n  explicit MemTable(const InternalKeyComparator& comparator);\n\n  // Increase reference count.\n  void Ref() { ++refs_; }\n\n  // Drop reference count.  Delete if no more references exist.\n  void Unref() {\n    --refs_;\n    assert(refs_ >= 0);\n    if (refs_ <= 0) {\n      delete this;\n    }\n  }\n\n  // Returns an estimate of the number of bytes of data in use by this\n  // data structure. It is safe to call when MemTable is being modified.\n  size_t ApproximateMemoryUsage();\n\n  // Return an iterator that yields the contents of the memtable.\n  //\n  // The caller must ensure that the underlying MemTable remains live\n  // while the returned iterator is live.  The keys returned by this\n  // iterator are internal keys encoded by AppendInternalKey in the\n  // db/format.{h,cc} module.\n  Iterator* NewIterator();\n\n  // Add an entry into memtable that maps key to value at the\n  // specified sequence number and with the specified type.\n  // Typically value will be empty if type==kTypeDeletion.\n  void Add(SequenceNumber seq, ValueType type,\n           const Slice& key,\n           const Slice& value);\n\n  // If memtable contains a value for key, store it in *value and return true.\n  // If memtable contains a deletion for key, store a NotFound() error\n  // in *status and return true.\n  // Else, return false.\n  bool Get(const LookupKey& key, std::string* value, Status* s);\n\n private:\n  ~MemTable();  // Private since only Unref() should be used to delete it\n\n  struct KeyComparator {\n    const InternalKeyComparator comparator;\n    explicit KeyComparator(const InternalKeyComparator& c) : comparator(c) { }\n    int operator()(const char* a, const char* b) const;\n  };\n  friend class MemTableIterator;\n  friend class MemTableBackwardIterator;\n\n  typedef SkipList<const char*, KeyComparator> Table;\n\n  KeyComparator comparator_;\n  int refs_;\n  Arena arena_;\n  Table table_;\n\n  // No copying allowed\n  MemTable(const MemTable&);\n  void operator=(const MemTable&);\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_DB_MEMTABLE_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/db/recovery_test.cc",
    "content": "// Copyright (c) 2014 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/db_impl.h\"\n#include \"db/filename.h\"\n#include \"db/version_set.h\"\n#include \"db/write_batch_internal.h\"\n#include \"leveldb/db.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/write_batch.h\"\n#include \"util/logging.h\"\n#include \"util/testharness.h\"\n#include \"util/testutil.h\"\n\nnamespace leveldb {\n\nclass RecoveryTest {\n public:\n  RecoveryTest() : env_(Env::Default()), db_(NULL) {\n    dbname_ = test::TmpDir() + \"/recovery_test\";\n    DestroyDB(dbname_, Options());\n    Open();\n  }\n\n  ~RecoveryTest() {\n    Close();\n    DestroyDB(dbname_, Options());\n  }\n\n  DBImpl* dbfull() const { return reinterpret_cast<DBImpl*>(db_); }\n  Env* env() const { return env_; }\n\n  bool CanAppend() {\n    WritableFile* tmp;\n    Status s = env_->NewAppendableFile(CurrentFileName(dbname_), &tmp);\n    delete tmp;\n    if (s.IsNotSupportedError()) {\n      return false;\n    } else {\n      return true;\n    }\n  }\n\n  void Close() {\n    delete db_;\n    db_ = NULL;\n  }\n\n  Status OpenWithStatus(Options* options = NULL) {\n    Close();\n    Options opts;\n    if (options != NULL) {\n      opts = *options;\n    } else {\n      opts.reuse_logs = true;  // TODO(sanjay): test both ways\n      opts.create_if_missing = true;\n    }\n    if (opts.env == NULL) {\n      opts.env = env_;\n    }\n    return DB::Open(opts, dbname_, &db_);\n  }\n\n  void Open(Options* options = NULL) {\n    ASSERT_OK(OpenWithStatus(options));\n    ASSERT_EQ(1, NumLogs());\n  }\n\n  Status Put(const std::string& k, const std::string& v) {\n    return db_->Put(WriteOptions(), k, v);\n  }\n\n  std::string Get(const std::string& k, const Snapshot* snapshot = NULL) {\n    std::string result;\n    Status s = db_->Get(ReadOptions(), k, &result);\n    if (s.IsNotFound()) {\n      result = \"NOT_FOUND\";\n    } else if (!s.ok()) {\n      result = s.ToString();\n    }\n    return result;\n  }\n\n  std::string ManifestFileName() {\n    std::string current;\n    ASSERT_OK(ReadFileToString(env_, CurrentFileName(dbname_), &current));\n    size_t len = current.size();\n    if (len > 0 && current[len-1] == '\\n') {\n      current.resize(len - 1);\n    }\n    return dbname_ + \"/\" + current;\n  }\n\n  std::string LogName(uint64_t number) {\n    return LogFileName(dbname_, number);\n  }\n\n  size_t DeleteLogFiles() {\n    std::vector<uint64_t> logs = GetFiles(kLogFile);\n    for (size_t i = 0; i < logs.size(); i++) {\n      ASSERT_OK(env_->DeleteFile(LogName(logs[i]))) << LogName(logs[i]);\n    }\n    return logs.size();\n  }\n\n  void DeleteManifestFile() {\n    ASSERT_OK(env_->DeleteFile(ManifestFileName()));\n  }\n\n  uint64_t FirstLogFile() {\n    return GetFiles(kLogFile)[0];\n  }\n\n  std::vector<uint64_t> GetFiles(FileType t) {\n    std::vector<std::string> filenames;\n    ASSERT_OK(env_->GetChildren(dbname_, &filenames));\n    std::vector<uint64_t> result;\n    for (size_t i = 0; i < filenames.size(); i++) {\n      uint64_t number;\n      FileType type;\n      if (ParseFileName(filenames[i], &number, &type) && type == t) {\n        result.push_back(number);\n      }\n    }\n    return result;\n  }\n\n  int NumLogs() {\n    return GetFiles(kLogFile).size();\n  }\n\n  int NumTables() {\n    return GetFiles(kTableFile).size();\n  }\n\n  uint64_t FileSize(const std::string& fname) {\n    uint64_t result;\n    ASSERT_OK(env_->GetFileSize(fname, &result)) << fname;\n    return result;\n  }\n\n  void CompactMemTable() {\n    dbfull()->TEST_CompactMemTable();\n  }\n\n  // Directly construct a log file that sets key to val.\n  void MakeLogFile(uint64_t lognum, SequenceNumber seq, Slice key, Slice val) {\n    std::string fname = LogFileName(dbname_, lognum);\n    WritableFile* file;\n    ASSERT_OK(env_->NewWritableFile(fname, &file));\n    log::Writer writer(file);\n    WriteBatch batch;\n    batch.Put(key, val);\n    WriteBatchInternal::SetSequence(&batch, seq);\n    ASSERT_OK(writer.AddRecord(WriteBatchInternal::Contents(&batch)));\n    ASSERT_OK(file->Flush());\n    delete file;\n  }\n\n private:\n  std::string dbname_;\n  Env* env_;\n  DB* db_;\n};\n\nTEST(RecoveryTest, ManifestReused) {\n  if (!CanAppend()) {\n    fprintf(stderr, \"skipping test because env does not support appending\\n\");\n    return;\n  }\n  ASSERT_OK(Put(\"foo\", \"bar\"));\n  Close();\n  std::string old_manifest = ManifestFileName();\n  Open();\n  ASSERT_EQ(old_manifest, ManifestFileName());\n  ASSERT_EQ(\"bar\", Get(\"foo\"));\n  Open();\n  ASSERT_EQ(old_manifest, ManifestFileName());\n  ASSERT_EQ(\"bar\", Get(\"foo\"));\n}\n\nTEST(RecoveryTest, LargeManifestCompacted) {\n  if (!CanAppend()) {\n    fprintf(stderr, \"skipping test because env does not support appending\\n\");\n    return;\n  }\n  ASSERT_OK(Put(\"foo\", \"bar\"));\n  Close();\n  std::string old_manifest = ManifestFileName();\n\n  // Pad with zeroes to make manifest file very big.\n  {\n    uint64_t len = FileSize(old_manifest);\n    WritableFile* file;\n    ASSERT_OK(env()->NewAppendableFile(old_manifest, &file));\n    std::string zeroes(3*1048576 - static_cast<size_t>(len), 0);\n    ASSERT_OK(file->Append(zeroes));\n    ASSERT_OK(file->Flush());\n    delete file;\n  }\n\n  Open();\n  std::string new_manifest = ManifestFileName();\n  ASSERT_NE(old_manifest, new_manifest);\n  ASSERT_GT(10000, FileSize(new_manifest));\n  ASSERT_EQ(\"bar\", Get(\"foo\"));\n\n  Open();\n  ASSERT_EQ(new_manifest, ManifestFileName());\n  ASSERT_EQ(\"bar\", Get(\"foo\"));\n}\n\nTEST(RecoveryTest, NoLogFiles) {\n  ASSERT_OK(Put(\"foo\", \"bar\"));\n  ASSERT_EQ(1, DeleteLogFiles());\n  Open();\n  ASSERT_EQ(\"NOT_FOUND\", Get(\"foo\"));\n  Open();\n  ASSERT_EQ(\"NOT_FOUND\", Get(\"foo\"));\n}\n\nTEST(RecoveryTest, LogFileReuse) {\n  if (!CanAppend()) {\n    fprintf(stderr, \"skipping test because env does not support appending\\n\");\n    return;\n  }\n  for (int i = 0; i < 2; i++) {\n    ASSERT_OK(Put(\"foo\", \"bar\"));\n    if (i == 0) {\n      // Compact to ensure current log is empty\n      CompactMemTable();\n    }\n    Close();\n    ASSERT_EQ(1, NumLogs());\n    uint64_t number = FirstLogFile();\n    if (i == 0) {\n      ASSERT_EQ(0, FileSize(LogName(number)));\n    } else {\n      ASSERT_LT(0, FileSize(LogName(number)));\n    }\n    Open();\n    ASSERT_EQ(1, NumLogs());\n    ASSERT_EQ(number, FirstLogFile()) << \"did not reuse log file\";\n    ASSERT_EQ(\"bar\", Get(\"foo\"));\n    Open();\n    ASSERT_EQ(1, NumLogs());\n    ASSERT_EQ(number, FirstLogFile()) << \"did not reuse log file\";\n    ASSERT_EQ(\"bar\", Get(\"foo\"));\n  }\n}\n\nTEST(RecoveryTest, MultipleMemTables) {\n  // Make a large log.\n  const int kNum = 1000;\n  for (int i = 0; i < kNum; i++) {\n    char buf[100];\n    snprintf(buf, sizeof(buf), \"%050d\", i);\n    ASSERT_OK(Put(buf, buf));\n  }\n  ASSERT_EQ(0, NumTables());\n  Close();\n  ASSERT_EQ(0, NumTables());\n  ASSERT_EQ(1, NumLogs());\n  uint64_t old_log_file = FirstLogFile();\n\n  // Force creation of multiple memtables by reducing the write buffer size.\n  Options opt;\n  opt.reuse_logs = true;\n  opt.write_buffer_size = (kNum*100) / 2;\n  Open(&opt);\n  ASSERT_LE(2, NumTables());\n  ASSERT_EQ(1, NumLogs());\n  ASSERT_NE(old_log_file, FirstLogFile()) << \"must not reuse log\";\n  for (int i = 0; i < kNum; i++) {\n    char buf[100];\n    snprintf(buf, sizeof(buf), \"%050d\", i);\n    ASSERT_EQ(buf, Get(buf));\n  }\n}\n\nTEST(RecoveryTest, MultipleLogFiles) {\n  ASSERT_OK(Put(\"foo\", \"bar\"));\n  Close();\n  ASSERT_EQ(1, NumLogs());\n\n  // Make a bunch of uncompacted log files.\n  uint64_t old_log = FirstLogFile();\n  MakeLogFile(old_log+1, 1000, \"hello\", \"world\");\n  MakeLogFile(old_log+2, 1001, \"hi\", \"there\");\n  MakeLogFile(old_log+3, 1002, \"foo\", \"bar2\");\n\n  // Recover and check that all log files were processed.\n  Open();\n  ASSERT_LE(1, NumTables());\n  ASSERT_EQ(1, NumLogs());\n  uint64_t new_log = FirstLogFile();\n  ASSERT_LE(old_log+3, new_log);\n  ASSERT_EQ(\"bar2\", Get(\"foo\"));\n  ASSERT_EQ(\"world\", Get(\"hello\"));\n  ASSERT_EQ(\"there\", Get(\"hi\"));\n\n  // Test that previous recovery produced recoverable state.\n  Open();\n  ASSERT_LE(1, NumTables());\n  ASSERT_EQ(1, NumLogs());\n  if (CanAppend()) {\n    ASSERT_EQ(new_log, FirstLogFile());\n  }\n  ASSERT_EQ(\"bar2\", Get(\"foo\"));\n  ASSERT_EQ(\"world\", Get(\"hello\"));\n  ASSERT_EQ(\"there\", Get(\"hi\"));\n\n  // Check that introducing an older log file does not cause it to be re-read.\n  Close();\n  MakeLogFile(old_log+1, 2000, \"hello\", \"stale write\");\n  Open();\n  ASSERT_LE(1, NumTables());\n  ASSERT_EQ(1, NumLogs());\n  if (CanAppend()) {\n    ASSERT_EQ(new_log, FirstLogFile());\n  }\n  ASSERT_EQ(\"bar2\", Get(\"foo\"));\n  ASSERT_EQ(\"world\", Get(\"hello\"));\n  ASSERT_EQ(\"there\", Get(\"hi\"));\n}\n\nTEST(RecoveryTest, ManifestMissing) {\n  ASSERT_OK(Put(\"foo\", \"bar\"));\n  Close();\n  DeleteManifestFile();\n\n  Status status = OpenWithStatus();\n  ASSERT_TRUE(status.IsCorruption());\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/db/repair.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// We recover the contents of the descriptor from the other files we find.\n// (1) Any log files are first converted to tables\n// (2) We scan every table to compute\n//     (a) smallest/largest for the table\n//     (b) largest sequence number in the table\n// (3) We generate descriptor contents:\n//      - log number is set to zero\n//      - next-file-number is set to 1 + largest file number we found\n//      - last-sequence-number is set to largest sequence# found across\n//        all tables (see 2c)\n//      - compaction pointers are cleared\n//      - every table file is added at level 0\n//\n// Possible optimization 1:\n//   (a) Compute total size and use to pick appropriate max-level M\n//   (b) Sort tables by largest sequence# in the table\n//   (c) For each table: if it overlaps earlier table, place in level-0,\n//       else place in level-M.\n// Possible optimization 2:\n//   Store per-table metadata (smallest, largest, largest-seq#, ...)\n//   in the table's meta section to speed up ScanTable.\n\n#include \"db/builder.h\"\n#include \"db/db_impl.h\"\n#include \"db/dbformat.h\"\n#include \"db/filename.h\"\n#include \"db/log_reader.h\"\n#include \"db/log_writer.h\"\n#include \"db/memtable.h\"\n#include \"db/table_cache.h\"\n#include \"db/version_edit.h\"\n#include \"db/write_batch_internal.h\"\n#include \"leveldb/comparator.h\"\n#include \"leveldb/db.h\"\n#include \"leveldb/env.h\"\n\nnamespace leveldb {\n\nnamespace {\n\nclass Repairer {\n public:\n  Repairer(const std::string& dbname, const Options& options)\n      : dbname_(dbname),\n        env_(options.env),\n        icmp_(options.comparator),\n        ipolicy_(options.filter_policy),\n        options_(SanitizeOptions(dbname, &icmp_, &ipolicy_, options)),\n        owns_info_log_(options_.info_log != options.info_log),\n        owns_cache_(options_.block_cache != options.block_cache),\n        next_file_number_(1) {\n    // TableCache can be small since we expect each table to be opened once.\n    table_cache_ = new TableCache(dbname_, &options_, 10);\n  }\n\n  ~Repairer() {\n    delete table_cache_;\n    if (owns_info_log_) {\n      delete options_.info_log;\n    }\n    if (owns_cache_) {\n      delete options_.block_cache;\n    }\n  }\n\n  Status Run() {\n    Status status = FindFiles();\n    if (status.ok()) {\n      ConvertLogFilesToTables();\n      ExtractMetaData();\n      status = WriteDescriptor();\n    }\n    if (status.ok()) {\n      unsigned long long bytes = 0;\n      for (size_t i = 0; i < tables_.size(); i++) {\n        bytes += tables_[i].meta.file_size;\n      }\n      Log(options_.info_log,\n          \"**** Repaired leveldb %s; \"\n          \"recovered %d files; %llu bytes. \"\n          \"Some data may have been lost. \"\n          \"****\",\n          dbname_.c_str(),\n          static_cast<int>(tables_.size()),\n          bytes);\n    }\n    return status;\n  }\n\n private:\n  struct TableInfo {\n    FileMetaData meta;\n    SequenceNumber max_sequence;\n  };\n\n  std::string const dbname_;\n  Env* const env_;\n  InternalKeyComparator const icmp_;\n  InternalFilterPolicy const ipolicy_;\n  Options const options_;\n  bool owns_info_log_;\n  bool owns_cache_;\n  TableCache* table_cache_;\n  VersionEdit edit_;\n\n  std::vector<std::string> manifests_;\n  std::vector<uint64_t> table_numbers_;\n  std::vector<uint64_t> logs_;\n  std::vector<TableInfo> tables_;\n  uint64_t next_file_number_;\n\n  Status FindFiles() {\n    std::vector<std::string> filenames;\n    Status status = env_->GetChildren(dbname_, &filenames);\n    if (!status.ok()) {\n      return status;\n    }\n    if (filenames.empty()) {\n      return Status::IOError(dbname_, \"repair found no files\");\n    }\n\n    uint64_t number;\n    FileType type;\n    for (size_t i = 0; i < filenames.size(); i++) {\n      if (ParseFileName(filenames[i], &number, &type)) {\n        if (type == kDescriptorFile) {\n          manifests_.push_back(filenames[i]);\n        } else {\n          if (number + 1 > next_file_number_) {\n            next_file_number_ = number + 1;\n          }\n          if (type == kLogFile) {\n            logs_.push_back(number);\n          } else if (type == kTableFile) {\n            table_numbers_.push_back(number);\n          } else {\n            // Ignore other files\n          }\n        }\n      }\n    }\n    return status;\n  }\n\n  void ConvertLogFilesToTables() {\n    for (size_t i = 0; i < logs_.size(); i++) {\n      std::string logname = LogFileName(dbname_, logs_[i]);\n      Status status = ConvertLogToTable(logs_[i]);\n      if (!status.ok()) {\n        Log(options_.info_log, \"Log #%llu: ignoring conversion error: %s\",\n            (unsigned long long) logs_[i],\n            status.ToString().c_str());\n      }\n      ArchiveFile(logname);\n    }\n  }\n\n  Status ConvertLogToTable(uint64_t log) {\n    struct LogReporter : public log::Reader::Reporter {\n      Env* env;\n      Logger* info_log;\n      uint64_t lognum;\n      virtual void Corruption(size_t bytes, const Status& s) {\n        // We print error messages for corruption, but continue repairing.\n        Log(info_log, \"Log #%llu: dropping %d bytes; %s\",\n            (unsigned long long) lognum,\n            static_cast<int>(bytes),\n            s.ToString().c_str());\n      }\n    };\n\n    // Open the log file\n    std::string logname = LogFileName(dbname_, log);\n    SequentialFile* lfile;\n    Status status = env_->NewSequentialFile(logname, &lfile);\n    if (!status.ok()) {\n      return status;\n    }\n\n    // Create the log reader.\n    LogReporter reporter;\n    reporter.env = env_;\n    reporter.info_log = options_.info_log;\n    reporter.lognum = log;\n    // We intentionally make log::Reader do checksumming so that\n    // corruptions cause entire commits to be skipped instead of\n    // propagating bad information (like overly large sequence\n    // numbers).\n    log::Reader reader(lfile, &reporter, false/*do not checksum*/,\n                       0/*initial_offset*/);\n\n    // Read all the records and add to a memtable\n    std::string scratch;\n    Slice record;\n    WriteBatch batch;\n    MemTable* mem = new MemTable(icmp_);\n    mem->Ref();\n    int counter = 0;\n    while (reader.ReadRecord(&record, &scratch)) {\n      if (record.size() < 12) {\n        reporter.Corruption(\n            record.size(), Status::Corruption(\"log record too small\"));\n        continue;\n      }\n      WriteBatchInternal::SetContents(&batch, record);\n      status = WriteBatchInternal::InsertInto(&batch, mem);\n      if (status.ok()) {\n        counter += WriteBatchInternal::Count(&batch);\n      } else {\n        Log(options_.info_log, \"Log #%llu: ignoring %s\",\n            (unsigned long long) log,\n            status.ToString().c_str());\n        status = Status::OK();  // Keep going with rest of file\n      }\n    }\n    delete lfile;\n\n    // Do not record a version edit for this conversion to a Table\n    // since ExtractMetaData() will also generate edits.\n    FileMetaData meta;\n    meta.number = next_file_number_++;\n    Iterator* iter = mem->NewIterator();\n    status = BuildTable(dbname_, env_, options_, table_cache_, iter, &meta);\n    delete iter;\n    mem->Unref();\n    mem = NULL;\n    if (status.ok()) {\n      if (meta.file_size > 0) {\n        table_numbers_.push_back(meta.number);\n      }\n    }\n    Log(options_.info_log, \"Log #%llu: %d ops saved to Table #%llu %s\",\n        (unsigned long long) log,\n        counter,\n        (unsigned long long) meta.number,\n        status.ToString().c_str());\n    return status;\n  }\n\n  void ExtractMetaData() {\n    for (size_t i = 0; i < table_numbers_.size(); i++) {\n      ScanTable(table_numbers_[i]);\n    }\n  }\n\n  Iterator* NewTableIterator(const FileMetaData& meta) {\n    // Same as compaction iterators: if paranoid_checks are on, turn\n    // on checksum verification.\n    ReadOptions r;\n    r.verify_checksums = options_.paranoid_checks;\n    return table_cache_->NewIterator(r, meta.number, meta.file_size);\n  }\n\n  void ScanTable(uint64_t number) {\n    TableInfo t;\n    t.meta.number = number;\n    std::string fname = TableFileName(dbname_, number);\n    Status status = env_->GetFileSize(fname, &t.meta.file_size);\n    if (!status.ok()) {\n      // Try alternate file name.\n      fname = SSTTableFileName(dbname_, number);\n      Status s2 = env_->GetFileSize(fname, &t.meta.file_size);\n      if (s2.ok()) {\n        status = Status::OK();\n      }\n    }\n    if (!status.ok()) {\n      ArchiveFile(TableFileName(dbname_, number));\n      ArchiveFile(SSTTableFileName(dbname_, number));\n      Log(options_.info_log, \"Table #%llu: dropped: %s\",\n          (unsigned long long) t.meta.number,\n          status.ToString().c_str());\n      return;\n    }\n\n    // Extract metadata by scanning through table.\n    int counter = 0;\n    Iterator* iter = NewTableIterator(t.meta);\n    bool empty = true;\n    ParsedInternalKey parsed;\n    t.max_sequence = 0;\n    for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {\n      Slice key = iter->key();\n      if (!ParseInternalKey(key, &parsed)) {\n        Log(options_.info_log, \"Table #%llu: unparsable key %s\",\n            (unsigned long long) t.meta.number,\n            EscapeString(key).c_str());\n        continue;\n      }\n\n      counter++;\n      if (empty) {\n        empty = false;\n        t.meta.smallest.DecodeFrom(key);\n      }\n      t.meta.largest.DecodeFrom(key);\n      if (parsed.sequence > t.max_sequence) {\n        t.max_sequence = parsed.sequence;\n      }\n    }\n    if (!iter->status().ok()) {\n      status = iter->status();\n    }\n    delete iter;\n    Log(options_.info_log, \"Table #%llu: %d entries %s\",\n        (unsigned long long) t.meta.number,\n        counter,\n        status.ToString().c_str());\n\n    if (status.ok()) {\n      tables_.push_back(t);\n    } else {\n      RepairTable(fname, t);  // RepairTable archives input file.\n    }\n  }\n\n  void RepairTable(const std::string& src, TableInfo t) {\n    // We will copy src contents to a new table and then rename the\n    // new table over the source.\n\n    // Create builder.\n    std::string copy = TableFileName(dbname_, next_file_number_++);\n    WritableFile* file;\n    Status s = env_->NewWritableFile(copy, &file);\n    if (!s.ok()) {\n      return;\n    }\n    TableBuilder* builder = new TableBuilder(options_, file);\n\n    // Copy data.\n    Iterator* iter = NewTableIterator(t.meta);\n    int counter = 0;\n    for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {\n      builder->Add(iter->key(), iter->value());\n      counter++;\n    }\n    delete iter;\n\n    ArchiveFile(src);\n    if (counter == 0) {\n      builder->Abandon();  // Nothing to save\n    } else {\n      s = builder->Finish();\n      if (s.ok()) {\n        t.meta.file_size = builder->FileSize();\n      }\n    }\n    delete builder;\n    builder = NULL;\n\n    if (s.ok()) {\n      s = file->Close();\n    }\n    delete file;\n    file = NULL;\n\n    if (counter > 0 && s.ok()) {\n      std::string orig = TableFileName(dbname_, t.meta.number);\n      s = env_->RenameFile(copy, orig);\n      if (s.ok()) {\n        Log(options_.info_log, \"Table #%llu: %d entries repaired\",\n            (unsigned long long) t.meta.number, counter);\n        tables_.push_back(t);\n      }\n    }\n    if (!s.ok()) {\n      env_->DeleteFile(copy);\n    }\n  }\n\n  Status WriteDescriptor() {\n    std::string tmp = TempFileName(dbname_, 1);\n    WritableFile* file;\n    Status status = env_->NewWritableFile(tmp, &file);\n    if (!status.ok()) {\n      return status;\n    }\n\n    SequenceNumber max_sequence = 0;\n    for (size_t i = 0; i < tables_.size(); i++) {\n      if (max_sequence < tables_[i].max_sequence) {\n        max_sequence = tables_[i].max_sequence;\n      }\n    }\n\n    edit_.SetComparatorName(icmp_.user_comparator()->Name());\n    edit_.SetLogNumber(0);\n    edit_.SetNextFile(next_file_number_);\n    edit_.SetLastSequence(max_sequence);\n\n    for (size_t i = 0; i < tables_.size(); i++) {\n      // TODO(opt): separate out into multiple levels\n      const TableInfo& t = tables_[i];\n      edit_.AddFile(0, t.meta.number, t.meta.file_size,\n                    t.meta.smallest, t.meta.largest);\n    }\n\n    //fprintf(stderr, \"NewDescriptor:\\n%s\\n\", edit_.DebugString().c_str());\n    {\n      log::Writer log(file);\n      std::string record;\n      edit_.EncodeTo(&record);\n      status = log.AddRecord(record);\n    }\n    if (status.ok()) {\n      status = file->Close();\n    }\n    delete file;\n    file = NULL;\n\n    if (!status.ok()) {\n      env_->DeleteFile(tmp);\n    } else {\n      // Discard older manifests\n      for (size_t i = 0; i < manifests_.size(); i++) {\n        ArchiveFile(dbname_ + \"/\" + manifests_[i]);\n      }\n\n      // Install new manifest\n      status = env_->RenameFile(tmp, DescriptorFileName(dbname_, 1));\n      if (status.ok()) {\n        status = SetCurrentFile(env_, dbname_, 1);\n      } else {\n        env_->DeleteFile(tmp);\n      }\n    }\n    return status;\n  }\n\n  void ArchiveFile(const std::string& fname) {\n    // Move into another directory.  E.g., for\n    //    dir/foo\n    // rename to\n    //    dir/lost/foo\n    const char* slash = strrchr(fname.c_str(), '/');\n    std::string new_dir;\n    if (slash != NULL) {\n      new_dir.assign(fname.data(), slash - fname.data());\n    }\n    new_dir.append(\"/lost\");\n    env_->CreateDir(new_dir);  // Ignore error\n    std::string new_file = new_dir;\n    new_file.append(\"/\");\n    new_file.append((slash == NULL) ? fname.c_str() : slash + 1);\n    Status s = env_->RenameFile(fname, new_file);\n    Log(options_.info_log, \"Archiving %s: %s\\n\",\n        fname.c_str(), s.ToString().c_str());\n  }\n};\n}  // namespace\n\nStatus RepairDB(const std::string& dbname, const Options& options) {\n  Repairer repairer(dbname, options);\n  return repairer.Run();\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/db/skiplist.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_DB_SKIPLIST_H_\n#define STORAGE_LEVELDB_DB_SKIPLIST_H_\n\n// Thread safety\n// -------------\n//\n// Writes require external synchronization, most likely a mutex.\n// Reads require a guarantee that the SkipList will not be destroyed\n// while the read is in progress.  Apart from that, reads progress\n// without any internal locking or synchronization.\n//\n// Invariants:\n//\n// (1) Allocated nodes are never deleted until the SkipList is\n// destroyed.  This is trivially guaranteed by the code since we\n// never delete any skip list nodes.\n//\n// (2) The contents of a Node except for the next/prev pointers are\n// immutable after the Node has been linked into the SkipList.\n// Only Insert() modifies the list, and it is careful to initialize\n// a node and use release-stores to publish the nodes in one or\n// more lists.\n//\n// ... prev vs. next pointer ordering ...\n\n#include <assert.h>\n#include <stdlib.h>\n#include \"port/port.h\"\n#include \"util/arena.h\"\n#include \"util/random.h\"\n\nnamespace leveldb {\n\nclass Arena;\n\ntemplate<typename Key, class Comparator>\nclass SkipList {\n private:\n  struct Node;\n\n public:\n  // Create a new SkipList object that will use \"cmp\" for comparing keys,\n  // and will allocate memory using \"*arena\".  Objects allocated in the arena\n  // must remain allocated for the lifetime of the skiplist object.\n  explicit SkipList(Comparator cmp, Arena* arena);\n\n  // Insert key into the list.\n  // REQUIRES: nothing that compares equal to key is currently in the list.\n  void Insert(const Key& key);\n\n  // Returns true iff an entry that compares equal to key is in the list.\n  bool Contains(const Key& key) const;\n\n  // Iteration over the contents of a skip list\n  class Iterator {\n   public:\n    // Initialize an iterator over the specified list.\n    // The returned iterator is not valid.\n    explicit Iterator(const SkipList* list);\n\n    // Returns true iff the iterator is positioned at a valid node.\n    bool Valid() const;\n\n    // Returns the key at the current position.\n    // REQUIRES: Valid()\n    const Key& key() const;\n\n    // Advances to the next position.\n    // REQUIRES: Valid()\n    void Next();\n\n    // Advances to the previous position.\n    // REQUIRES: Valid()\n    void Prev();\n\n    // Advance to the first entry with a key >= target\n    void Seek(const Key& target);\n\n    // Position at the first entry in list.\n    // Final state of iterator is Valid() iff list is not empty.\n    void SeekToFirst();\n\n    // Position at the last entry in list.\n    // Final state of iterator is Valid() iff list is not empty.\n    void SeekToLast();\n\n   private:\n    const SkipList* list_;\n    Node* node_;\n    // Intentionally copyable\n  };\n\n private:\n  enum { kMaxHeight = 12 };\n\n  // Immutable after construction\n  Comparator const compare_;\n  Arena* const arena_;    // Arena used for allocations of nodes\n\n  Node* const head_;\n\n  // Modified only by Insert().  Read racily by readers, but stale\n  // values are ok.\n  port::AtomicPointer max_height_;   // Height of the entire list\n\n  inline int GetMaxHeight() const {\n    return static_cast<int>(\n        reinterpret_cast<intptr_t>(max_height_.NoBarrier_Load()));\n  }\n\n  // Read/written only by Insert().\n  Random rnd_;\n\n  Node* NewNode(const Key& key, int height);\n  int RandomHeight();\n  bool Equal(const Key& a, const Key& b) const { return (compare_(a, b) == 0); }\n\n  // Return true if key is greater than the data stored in \"n\"\n  bool KeyIsAfterNode(const Key& key, Node* n) const;\n\n  // Return the earliest node that comes at or after key.\n  // Return NULL if there is no such node.\n  //\n  // If prev is non-NULL, fills prev[level] with pointer to previous\n  // node at \"level\" for every level in [0..max_height_-1].\n  Node* FindGreaterOrEqual(const Key& key, Node** prev) const;\n\n  // Return the latest node with a key < key.\n  // Return head_ if there is no such node.\n  Node* FindLessThan(const Key& key) const;\n\n  // Return the last node in the list.\n  // Return head_ if list is empty.\n  Node* FindLast() const;\n\n  // No copying allowed\n  SkipList(const SkipList&);\n  void operator=(const SkipList&);\n};\n\n// Implementation details follow\ntemplate<typename Key, class Comparator>\nstruct SkipList<Key,Comparator>::Node {\n  explicit Node(const Key& k) : key(k) { }\n\n  Key const key;\n\n  // Accessors/mutators for links.  Wrapped in methods so we can\n  // add the appropriate barriers as necessary.\n  Node* Next(int n) {\n    assert(n >= 0);\n    // Use an 'acquire load' so that we observe a fully initialized\n    // version of the returned Node.\n    return reinterpret_cast<Node*>(next_[n].Acquire_Load());\n  }\n  void SetNext(int n, Node* x) {\n    assert(n >= 0);\n    // Use a 'release store' so that anybody who reads through this\n    // pointer observes a fully initialized version of the inserted node.\n    next_[n].Release_Store(x);\n  }\n\n  // No-barrier variants that can be safely used in a few locations.\n  Node* NoBarrier_Next(int n) {\n    assert(n >= 0);\n    return reinterpret_cast<Node*>(next_[n].NoBarrier_Load());\n  }\n  void NoBarrier_SetNext(int n, Node* x) {\n    assert(n >= 0);\n    next_[n].NoBarrier_Store(x);\n  }\n\n private:\n  // Array of length equal to the node height.  next_[0] is lowest level link.\n  port::AtomicPointer next_[1];\n};\n\ntemplate<typename Key, class Comparator>\ntypename SkipList<Key,Comparator>::Node*\nSkipList<Key,Comparator>::NewNode(const Key& key, int height) {\n  char* mem = arena_->AllocateAligned(\n      sizeof(Node) + sizeof(port::AtomicPointer) * (height - 1));\n  return new (mem) Node(key);\n}\n\ntemplate<typename Key, class Comparator>\ninline SkipList<Key,Comparator>::Iterator::Iterator(const SkipList* list) {\n  list_ = list;\n  node_ = NULL;\n}\n\ntemplate<typename Key, class Comparator>\ninline bool SkipList<Key,Comparator>::Iterator::Valid() const {\n  return node_ != NULL;\n}\n\ntemplate<typename Key, class Comparator>\ninline const Key& SkipList<Key,Comparator>::Iterator::key() const {\n  assert(Valid());\n  return node_->key;\n}\n\ntemplate<typename Key, class Comparator>\ninline void SkipList<Key,Comparator>::Iterator::Next() {\n  assert(Valid());\n  node_ = node_->Next(0);\n}\n\ntemplate<typename Key, class Comparator>\ninline void SkipList<Key,Comparator>::Iterator::Prev() {\n  // Instead of using explicit \"prev\" links, we just search for the\n  // last node that falls before key.\n  assert(Valid());\n  node_ = list_->FindLessThan(node_->key);\n  if (node_ == list_->head_) {\n    node_ = NULL;\n  }\n}\n\ntemplate<typename Key, class Comparator>\ninline void SkipList<Key,Comparator>::Iterator::Seek(const Key& target) {\n  node_ = list_->FindGreaterOrEqual(target, NULL);\n}\n\ntemplate<typename Key, class Comparator>\ninline void SkipList<Key,Comparator>::Iterator::SeekToFirst() {\n  node_ = list_->head_->Next(0);\n}\n\ntemplate<typename Key, class Comparator>\ninline void SkipList<Key,Comparator>::Iterator::SeekToLast() {\n  node_ = list_->FindLast();\n  if (node_ == list_->head_) {\n    node_ = NULL;\n  }\n}\n\ntemplate<typename Key, class Comparator>\nint SkipList<Key,Comparator>::RandomHeight() {\n  // Increase height with probability 1 in kBranching\n  static const unsigned int kBranching = 4;\n  int height = 1;\n  while (height < kMaxHeight && ((rnd_.Next() % kBranching) == 0)) {\n    height++;\n  }\n  assert(height > 0);\n  assert(height <= kMaxHeight);\n  return height;\n}\n\ntemplate<typename Key, class Comparator>\nbool SkipList<Key,Comparator>::KeyIsAfterNode(const Key& key, Node* n) const {\n  // NULL n is considered infinite\n  return (n != NULL) && (compare_(n->key, key) < 0);\n}\n\ntemplate<typename Key, class Comparator>\ntypename SkipList<Key,Comparator>::Node* SkipList<Key,Comparator>::FindGreaterOrEqual(const Key& key, Node** prev)\n    const {\n  Node* x = head_;\n  int level = GetMaxHeight() - 1;\n  while (true) {\n    Node* next = x->Next(level);\n    if (KeyIsAfterNode(key, next)) {\n      // Keep searching in this list\n      x = next;\n    } else {\n      if (prev != NULL) prev[level] = x;\n      if (level == 0) {\n        return next;\n      } else {\n        // Switch to next list\n        level--;\n      }\n    }\n  }\n}\n\ntemplate<typename Key, class Comparator>\ntypename SkipList<Key,Comparator>::Node*\nSkipList<Key,Comparator>::FindLessThan(const Key& key) const {\n  Node* x = head_;\n  int level = GetMaxHeight() - 1;\n  while (true) {\n    assert(x == head_ || compare_(x->key, key) < 0);\n    Node* next = x->Next(level);\n    if (next == NULL || compare_(next->key, key) >= 0) {\n      if (level == 0) {\n        return x;\n      } else {\n        // Switch to next list\n        level--;\n      }\n    } else {\n      x = next;\n    }\n  }\n}\n\ntemplate<typename Key, class Comparator>\ntypename SkipList<Key,Comparator>::Node* SkipList<Key,Comparator>::FindLast()\n    const {\n  Node* x = head_;\n  int level = GetMaxHeight() - 1;\n  while (true) {\n    Node* next = x->Next(level);\n    if (next == NULL) {\n      if (level == 0) {\n        return x;\n      } else {\n        // Switch to next list\n        level--;\n      }\n    } else {\n      x = next;\n    }\n  }\n}\n\ntemplate<typename Key, class Comparator>\nSkipList<Key,Comparator>::SkipList(Comparator cmp, Arena* arena)\n    : compare_(cmp),\n      arena_(arena),\n      head_(NewNode(0 /* any key will do */, kMaxHeight)),\n      max_height_(reinterpret_cast<void*>(1)),\n      rnd_(0xdeadbeef) {\n  for (int i = 0; i < kMaxHeight; i++) {\n    head_->SetNext(i, NULL);\n  }\n}\n\ntemplate<typename Key, class Comparator>\nvoid SkipList<Key,Comparator>::Insert(const Key& key) {\n  // TODO(opt): We can use a barrier-free variant of FindGreaterOrEqual()\n  // here since Insert() is externally synchronized.\n  Node* prev[kMaxHeight];\n  Node* x = FindGreaterOrEqual(key, prev);\n\n  // Our data structure does not allow duplicate insertion\n  assert(x == NULL || !Equal(key, x->key));\n\n  int height = RandomHeight();\n  if (height > GetMaxHeight()) {\n    for (int i = GetMaxHeight(); i < height; i++) {\n      prev[i] = head_;\n    }\n    //fprintf(stderr, \"Change height from %d to %d\\n\", max_height_, height);\n\n    // It is ok to mutate max_height_ without any synchronization\n    // with concurrent readers.  A concurrent reader that observes\n    // the new value of max_height_ will see either the old value of\n    // new level pointers from head_ (NULL), or a new value set in\n    // the loop below.  In the former case the reader will\n    // immediately drop to the next level since NULL sorts after all\n    // keys.  In the latter case the reader will use the new node.\n    max_height_.NoBarrier_Store(reinterpret_cast<void*>(height));\n  }\n\n  x = NewNode(key, height);\n  for (int i = 0; i < height; i++) {\n    // NoBarrier_SetNext() suffices since we will add a barrier when\n    // we publish a pointer to \"x\" in prev[i].\n    x->NoBarrier_SetNext(i, prev[i]->NoBarrier_Next(i));\n    prev[i]->SetNext(i, x);\n  }\n}\n\ntemplate<typename Key, class Comparator>\nbool SkipList<Key,Comparator>::Contains(const Key& key) const {\n  Node* x = FindGreaterOrEqual(key, NULL);\n  if (x != NULL && Equal(key, x->key)) {\n    return true;\n  } else {\n    return false;\n  }\n}\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_DB_SKIPLIST_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/db/skiplist_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/skiplist.h\"\n#include <set>\n#include \"leveldb/env.h\"\n#include \"util/arena.h\"\n#include \"util/hash.h\"\n#include \"util/random.h\"\n#include \"util/testharness.h\"\n\nnamespace leveldb {\n\ntypedef uint64_t Key;\n\nstruct Comparator {\n  int operator()(const Key& a, const Key& b) const {\n    if (a < b) {\n      return -1;\n    } else if (a > b) {\n      return +1;\n    } else {\n      return 0;\n    }\n  }\n};\n\nclass SkipTest { };\n\nTEST(SkipTest, Empty) {\n  Arena arena;\n  Comparator cmp;\n  SkipList<Key, Comparator> list(cmp, &arena);\n  ASSERT_TRUE(!list.Contains(10));\n\n  SkipList<Key, Comparator>::Iterator iter(&list);\n  ASSERT_TRUE(!iter.Valid());\n  iter.SeekToFirst();\n  ASSERT_TRUE(!iter.Valid());\n  iter.Seek(100);\n  ASSERT_TRUE(!iter.Valid());\n  iter.SeekToLast();\n  ASSERT_TRUE(!iter.Valid());\n}\n\nTEST(SkipTest, InsertAndLookup) {\n  const int N = 2000;\n  const int R = 5000;\n  Random rnd(1000);\n  std::set<Key> keys;\n  Arena arena;\n  Comparator cmp;\n  SkipList<Key, Comparator> list(cmp, &arena);\n  for (int i = 0; i < N; i++) {\n    Key key = rnd.Next() % R;\n    if (keys.insert(key).second) {\n      list.Insert(key);\n    }\n  }\n\n  for (int i = 0; i < R; i++) {\n    if (list.Contains(i)) {\n      ASSERT_EQ(keys.count(i), 1);\n    } else {\n      ASSERT_EQ(keys.count(i), 0);\n    }\n  }\n\n  // Simple iterator tests\n  {\n    SkipList<Key, Comparator>::Iterator iter(&list);\n    ASSERT_TRUE(!iter.Valid());\n\n    iter.Seek(0);\n    ASSERT_TRUE(iter.Valid());\n    ASSERT_EQ(*(keys.begin()), iter.key());\n\n    iter.SeekToFirst();\n    ASSERT_TRUE(iter.Valid());\n    ASSERT_EQ(*(keys.begin()), iter.key());\n\n    iter.SeekToLast();\n    ASSERT_TRUE(iter.Valid());\n    ASSERT_EQ(*(keys.rbegin()), iter.key());\n  }\n\n  // Forward iteration test\n  for (int i = 0; i < R; i++) {\n    SkipList<Key, Comparator>::Iterator iter(&list);\n    iter.Seek(i);\n\n    // Compare against model iterator\n    std::set<Key>::iterator model_iter = keys.lower_bound(i);\n    for (int j = 0; j < 3; j++) {\n      if (model_iter == keys.end()) {\n        ASSERT_TRUE(!iter.Valid());\n        break;\n      } else {\n        ASSERT_TRUE(iter.Valid());\n        ASSERT_EQ(*model_iter, iter.key());\n        ++model_iter;\n        iter.Next();\n      }\n    }\n  }\n\n  // Backward iteration test\n  {\n    SkipList<Key, Comparator>::Iterator iter(&list);\n    iter.SeekToLast();\n\n    // Compare against model iterator\n    for (std::set<Key>::reverse_iterator model_iter = keys.rbegin();\n         model_iter != keys.rend();\n         ++model_iter) {\n      ASSERT_TRUE(iter.Valid());\n      ASSERT_EQ(*model_iter, iter.key());\n      iter.Prev();\n    }\n    ASSERT_TRUE(!iter.Valid());\n  }\n}\n\n// We want to make sure that with a single writer and multiple\n// concurrent readers (with no synchronization other than when a\n// reader's iterator is created), the reader always observes all the\n// data that was present in the skip list when the iterator was\n// constructor.  Because insertions are happening concurrently, we may\n// also observe new values that were inserted since the iterator was\n// constructed, but we should never miss any values that were present\n// at iterator construction time.\n//\n// We generate multi-part keys:\n//     <key,gen,hash>\n// where:\n//     key is in range [0..K-1]\n//     gen is a generation number for key\n//     hash is hash(key,gen)\n//\n// The insertion code picks a random key, sets gen to be 1 + the last\n// generation number inserted for that key, and sets hash to Hash(key,gen).\n//\n// At the beginning of a read, we snapshot the last inserted\n// generation number for each key.  We then iterate, including random\n// calls to Next() and Seek().  For every key we encounter, we\n// check that it is either expected given the initial snapshot or has\n// been concurrently added since the iterator started.\nclass ConcurrentTest {\n private:\n  static const uint32_t K = 4;\n\n  static uint64_t key(Key key) { return (key >> 40); }\n  static uint64_t gen(Key key) { return (key >> 8) & 0xffffffffu; }\n  static uint64_t hash(Key key) { return key & 0xff; }\n\n  static uint64_t HashNumbers(uint64_t k, uint64_t g) {\n    uint64_t data[2] = { k, g };\n    return Hash(reinterpret_cast<char*>(data), sizeof(data), 0);\n  }\n\n  static Key MakeKey(uint64_t k, uint64_t g) {\n    assert(sizeof(Key) == sizeof(uint64_t));\n    assert(k <= K);  // We sometimes pass K to seek to the end of the skiplist\n    assert(g <= 0xffffffffu);\n    return ((k << 40) | (g << 8) | (HashNumbers(k, g) & 0xff));\n  }\n\n  static bool IsValidKey(Key k) {\n    return hash(k) == (HashNumbers(key(k), gen(k)) & 0xff);\n  }\n\n  static Key RandomTarget(Random* rnd) {\n    switch (rnd->Next() % 10) {\n      case 0:\n        // Seek to beginning\n        return MakeKey(0, 0);\n      case 1:\n        // Seek to end\n        return MakeKey(K, 0);\n      default:\n        // Seek to middle\n        return MakeKey(rnd->Next() % K, 0);\n    }\n  }\n\n  // Per-key generation\n  struct State {\n    port::AtomicPointer generation[K];\n    void Set(int k, intptr_t v) {\n      generation[k].Release_Store(reinterpret_cast<void*>(v));\n    }\n    intptr_t Get(int k) {\n      return reinterpret_cast<intptr_t>(generation[k].Acquire_Load());\n    }\n\n    State() {\n      for (int k = 0; k < K; k++) {\n        Set(k, 0);\n      }\n    }\n  };\n\n  // Current state of the test\n  State current_;\n\n  Arena arena_;\n\n  // SkipList is not protected by mu_.  We just use a single writer\n  // thread to modify it.\n  SkipList<Key, Comparator> list_;\n\n public:\n  ConcurrentTest() : list_(Comparator(), &arena_) { }\n\n  // REQUIRES: External synchronization\n  void WriteStep(Random* rnd) {\n    const uint32_t k = rnd->Next() % K;\n    const intptr_t g = current_.Get(k) + 1;\n    const Key key = MakeKey(k, g);\n    list_.Insert(key);\n    current_.Set(k, g);\n  }\n\n  void ReadStep(Random* rnd) {\n    // Remember the initial committed state of the skiplist.\n    State initial_state;\n    for (int k = 0; k < K; k++) {\n      initial_state.Set(k, current_.Get(k));\n    }\n\n    Key pos = RandomTarget(rnd);\n    SkipList<Key, Comparator>::Iterator iter(&list_);\n    iter.Seek(pos);\n    while (true) {\n      Key current;\n      if (!iter.Valid()) {\n        current = MakeKey(K, 0);\n      } else {\n        current = iter.key();\n        ASSERT_TRUE(IsValidKey(current)) << current;\n      }\n      ASSERT_LE(pos, current) << \"should not go backwards\";\n\n      // Verify that everything in [pos,current) was not present in\n      // initial_state.\n      while (pos < current) {\n        ASSERT_LT(key(pos), K) << pos;\n\n        // Note that generation 0 is never inserted, so it is ok if\n        // <*,0,*> is missing.\n        ASSERT_TRUE((gen(pos) == 0) ||\n                    (gen(pos) > static_cast<Key>(initial_state.Get(key(pos))))\n                    ) << \"key: \" << key(pos)\n                      << \"; gen: \" << gen(pos)\n                      << \"; initgen: \"\n                      << initial_state.Get(key(pos));\n\n        // Advance to next key in the valid key space\n        if (key(pos) < key(current)) {\n          pos = MakeKey(key(pos) + 1, 0);\n        } else {\n          pos = MakeKey(key(pos), gen(pos) + 1);\n        }\n      }\n\n      if (!iter.Valid()) {\n        break;\n      }\n\n      if (rnd->Next() % 2) {\n        iter.Next();\n        pos = MakeKey(key(pos), gen(pos) + 1);\n      } else {\n        Key new_target = RandomTarget(rnd);\n        if (new_target > pos) {\n          pos = new_target;\n          iter.Seek(new_target);\n        }\n      }\n    }\n  }\n};\nconst uint32_t ConcurrentTest::K;\n\n// Simple test that does single-threaded testing of the ConcurrentTest\n// scaffolding.\nTEST(SkipTest, ConcurrentWithoutThreads) {\n  ConcurrentTest test;\n  Random rnd(test::RandomSeed());\n  for (int i = 0; i < 10000; i++) {\n    test.ReadStep(&rnd);\n    test.WriteStep(&rnd);\n  }\n}\n\nclass TestState {\n public:\n  ConcurrentTest t_;\n  int seed_;\n  port::AtomicPointer quit_flag_;\n\n  enum ReaderState {\n    STARTING,\n    RUNNING,\n    DONE\n  };\n\n  explicit TestState(int s)\n      : seed_(s),\n        quit_flag_(NULL),\n        state_(STARTING),\n        state_cv_(&mu_) {}\n\n  void Wait(ReaderState s) {\n    mu_.Lock();\n    while (state_ != s) {\n      state_cv_.Wait();\n    }\n    mu_.Unlock();\n  }\n\n  void Change(ReaderState s) {\n    mu_.Lock();\n    state_ = s;\n    state_cv_.Signal();\n    mu_.Unlock();\n  }\n\n private:\n  port::Mutex mu_;\n  ReaderState state_;\n  port::CondVar state_cv_;\n};\n\nstatic void ConcurrentReader(void* arg) {\n  TestState* state = reinterpret_cast<TestState*>(arg);\n  Random rnd(state->seed_);\n  int64_t reads = 0;\n  state->Change(TestState::RUNNING);\n  while (!state->quit_flag_.Acquire_Load()) {\n    state->t_.ReadStep(&rnd);\n    ++reads;\n  }\n  state->Change(TestState::DONE);\n}\n\nstatic void RunConcurrent(int run) {\n  const int seed = test::RandomSeed() + (run * 100);\n  Random rnd(seed);\n  const int N = 1000;\n  const int kSize = 1000;\n  for (int i = 0; i < N; i++) {\n    if ((i % 100) == 0) {\n      fprintf(stderr, \"Run %d of %d\\n\", i, N);\n    }\n    TestState state(seed + 1);\n    Env::Default()->Schedule(ConcurrentReader, &state);\n    state.Wait(TestState::RUNNING);\n    for (int i = 0; i < kSize; i++) {\n      state.t_.WriteStep(&rnd);\n    }\n    state.quit_flag_.Release_Store(&state);  // Any non-NULL arg will do\n    state.Wait(TestState::DONE);\n  }\n}\n\nTEST(SkipTest, Concurrent1) { RunConcurrent(1); }\nTEST(SkipTest, Concurrent2) { RunConcurrent(2); }\nTEST(SkipTest, Concurrent3) { RunConcurrent(3); }\nTEST(SkipTest, Concurrent4) { RunConcurrent(4); }\nTEST(SkipTest, Concurrent5) { RunConcurrent(5); }\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/db/snapshot.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_DB_SNAPSHOT_H_\n#define STORAGE_LEVELDB_DB_SNAPSHOT_H_\n\n#include \"db/dbformat.h\"\n#include \"leveldb/db.h\"\n\nnamespace leveldb {\n\nclass SnapshotList;\n\n// Snapshots are kept in a doubly-linked list in the DB.\n// Each SnapshotImpl corresponds to a particular sequence number.\nclass SnapshotImpl : public Snapshot {\n public:\n  SequenceNumber number_;  // const after creation\n\n private:\n  friend class SnapshotList;\n\n  // SnapshotImpl is kept in a doubly-linked circular list\n  SnapshotImpl* prev_;\n  SnapshotImpl* next_;\n\n  SnapshotList* list_;                 // just for sanity checks\n};\n\nclass SnapshotList {\n public:\n  SnapshotList() {\n    list_.prev_ = &list_;\n    list_.next_ = &list_;\n  }\n\n  bool empty() const { return list_.next_ == &list_; }\n  SnapshotImpl* oldest() const { assert(!empty()); return list_.next_; }\n  SnapshotImpl* newest() const { assert(!empty()); return list_.prev_; }\n\n  const SnapshotImpl* New(SequenceNumber seq) {\n    SnapshotImpl* s = new SnapshotImpl;\n    s->number_ = seq;\n    s->list_ = this;\n    s->next_ = &list_;\n    s->prev_ = list_.prev_;\n    s->prev_->next_ = s;\n    s->next_->prev_ = s;\n    return s;\n  }\n\n  void Delete(const SnapshotImpl* s) {\n    assert(s->list_ == this);\n    s->prev_->next_ = s->next_;\n    s->next_->prev_ = s->prev_;\n    delete s;\n  }\n\n private:\n  // Dummy head of doubly-linked list of snapshots\n  SnapshotImpl list_;\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_DB_SNAPSHOT_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/db/table_cache.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/table_cache.h\"\n\n#include \"db/filename.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/table.h\"\n#include \"util/coding.h\"\n\nnamespace leveldb {\n\nstruct TableAndFile {\n  RandomAccessFile* file;\n  Table* table;\n};\n\nstatic void DeleteEntry(const Slice& key, void* value) {\n  TableAndFile* tf = reinterpret_cast<TableAndFile*>(value);\n  delete tf->table;\n  delete tf->file;\n  delete tf;\n}\n\nstatic void UnrefEntry(void* arg1, void* arg2) {\n  Cache* cache = reinterpret_cast<Cache*>(arg1);\n  Cache::Handle* h = reinterpret_cast<Cache::Handle*>(arg2);\n  cache->Release(h);\n}\n\nTableCache::TableCache(const std::string& dbname,\n                       const Options* options,\n                       int entries)\n    : env_(options->env),\n      dbname_(dbname),\n      options_(options),\n      cache_(NewLRUCache(entries)) {\n}\n\nTableCache::~TableCache() {\n  delete cache_;\n}\n\nStatus TableCache::FindTable(uint64_t file_number, uint64_t file_size,\n                             Cache::Handle** handle) {\n  Status s;\n  char buf[sizeof(file_number)];\n  EncodeFixed64(buf, file_number);\n  Slice key(buf, sizeof(buf));\n  *handle = cache_->Lookup(key);\n  if (*handle == NULL) {\n    std::string fname = TableFileName(dbname_, file_number);\n    RandomAccessFile* file = NULL;\n    Table* table = NULL;\n    s = env_->NewRandomAccessFile(fname, &file);\n    if (!s.ok()) {\n      std::string old_fname = SSTTableFileName(dbname_, file_number);\n      if (env_->NewRandomAccessFile(old_fname, &file).ok()) {\n        s = Status::OK();\n      }\n    }\n    if (s.ok()) {\n      s = Table::Open(*options_, file, file_size, &table);\n    }\n\n    if (!s.ok()) {\n      assert(table == NULL);\n      delete file;\n      // We do not cache error results so that if the error is transient,\n      // or somebody repairs the file, we recover automatically.\n    } else {\n      TableAndFile* tf = new TableAndFile;\n      tf->file = file;\n      tf->table = table;\n      *handle = cache_->Insert(key, tf, 1, &DeleteEntry);\n    }\n  }\n  return s;\n}\n\nIterator* TableCache::NewIterator(const ReadOptions& options,\n                                  uint64_t file_number,\n                                  uint64_t file_size,\n                                  Table** tableptr) {\n  if (tableptr != NULL) {\n    *tableptr = NULL;\n  }\n\n  Cache::Handle* handle = NULL;\n  Status s = FindTable(file_number, file_size, &handle);\n  if (!s.ok()) {\n    return NewErrorIterator(s);\n  }\n\n  Table* table = reinterpret_cast<TableAndFile*>(cache_->Value(handle))->table;\n  Iterator* result = table->NewIterator(options);\n  result->RegisterCleanup(&UnrefEntry, cache_, handle);\n  if (tableptr != NULL) {\n    *tableptr = table;\n  }\n  return result;\n}\n\nStatus TableCache::Get(const ReadOptions& options,\n                       uint64_t file_number,\n                       uint64_t file_size,\n                       const Slice& k,\n                       void* arg,\n                       void (*saver)(void*, const Slice&, const Slice&)) {\n  Cache::Handle* handle = NULL;\n  Status s = FindTable(file_number, file_size, &handle);\n  if (s.ok()) {\n    Table* t = reinterpret_cast<TableAndFile*>(cache_->Value(handle))->table;\n    s = t->InternalGet(options, k, arg, saver);\n    cache_->Release(handle);\n  }\n  return s;\n}\n\nvoid TableCache::Evict(uint64_t file_number) {\n  char buf[sizeof(file_number)];\n  EncodeFixed64(buf, file_number);\n  cache_->Erase(Slice(buf, sizeof(buf)));\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/db/table_cache.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// Thread-safe (provides internal synchronization)\n\n#ifndef STORAGE_LEVELDB_DB_TABLE_CACHE_H_\n#define STORAGE_LEVELDB_DB_TABLE_CACHE_H_\n\n#include <string>\n#include <stdint.h>\n#include \"db/dbformat.h\"\n#include \"leveldb/cache.h\"\n#include \"leveldb/table.h\"\n#include \"port/port.h\"\n\nnamespace leveldb {\n\nclass Env;\n\nclass TableCache {\n public:\n  TableCache(const std::string& dbname, const Options* options, int entries);\n  ~TableCache();\n\n  // Return an iterator for the specified file number (the corresponding\n  // file length must be exactly \"file_size\" bytes).  If \"tableptr\" is\n  // non-NULL, also sets \"*tableptr\" to point to the Table object\n  // underlying the returned iterator, or NULL if no Table object underlies\n  // the returned iterator.  The returned \"*tableptr\" object is owned by\n  // the cache and should not be deleted, and is valid for as long as the\n  // returned iterator is live.\n  Iterator* NewIterator(const ReadOptions& options,\n                        uint64_t file_number,\n                        uint64_t file_size,\n                        Table** tableptr = NULL);\n\n  // If a seek to internal key \"k\" in specified file finds an entry,\n  // call (*handle_result)(arg, found_key, found_value).\n  Status Get(const ReadOptions& options,\n             uint64_t file_number,\n             uint64_t file_size,\n             const Slice& k,\n             void* arg,\n             void (*handle_result)(void*, const Slice&, const Slice&));\n\n  // Evict any entry for the specified file number\n  void Evict(uint64_t file_number);\n\n private:\n  Env* const env_;\n  const std::string dbname_;\n  const Options* options_;\n  Cache* cache_;\n\n  Status FindTable(uint64_t file_number, uint64_t file_size, Cache::Handle**);\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_DB_TABLE_CACHE_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/db/version_edit.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/version_edit.h\"\n\n#include \"db/version_set.h\"\n#include \"util/coding.h\"\n\nnamespace leveldb {\n\n// Tag numbers for serialized VersionEdit.  These numbers are written to\n// disk and should not be changed.\nenum Tag {\n  kComparator           = 1,\n  kLogNumber            = 2,\n  kNextFileNumber       = 3,\n  kLastSequence         = 4,\n  kCompactPointer       = 5,\n  kDeletedFile          = 6,\n  kNewFile              = 7,\n  // 8 was used for large value refs\n  kPrevLogNumber        = 9\n};\n\nvoid VersionEdit::Clear() {\n  comparator_.clear();\n  log_number_ = 0;\n  prev_log_number_ = 0;\n  last_sequence_ = 0;\n  next_file_number_ = 0;\n  has_comparator_ = false;\n  has_log_number_ = false;\n  has_prev_log_number_ = false;\n  has_next_file_number_ = false;\n  has_last_sequence_ = false;\n  deleted_files_.clear();\n  new_files_.clear();\n}\n\nvoid VersionEdit::EncodeTo(std::string* dst) const {\n  if (has_comparator_) {\n    PutVarint32(dst, kComparator);\n    PutLengthPrefixedSlice(dst, comparator_);\n  }\n  if (has_log_number_) {\n    PutVarint32(dst, kLogNumber);\n    PutVarint64(dst, log_number_);\n  }\n  if (has_prev_log_number_) {\n    PutVarint32(dst, kPrevLogNumber);\n    PutVarint64(dst, prev_log_number_);\n  }\n  if (has_next_file_number_) {\n    PutVarint32(dst, kNextFileNumber);\n    PutVarint64(dst, next_file_number_);\n  }\n  if (has_last_sequence_) {\n    PutVarint32(dst, kLastSequence);\n    PutVarint64(dst, last_sequence_);\n  }\n\n  for (size_t i = 0; i < compact_pointers_.size(); i++) {\n    PutVarint32(dst, kCompactPointer);\n    PutVarint32(dst, compact_pointers_[i].first);  // level\n    PutLengthPrefixedSlice(dst, compact_pointers_[i].second.Encode());\n  }\n\n  for (DeletedFileSet::const_iterator iter = deleted_files_.begin();\n       iter != deleted_files_.end();\n       ++iter) {\n    PutVarint32(dst, kDeletedFile);\n    PutVarint32(dst, iter->first);   // level\n    PutVarint64(dst, iter->second);  // file number\n  }\n\n  for (size_t i = 0; i < new_files_.size(); i++) {\n    const FileMetaData& f = new_files_[i].second;\n    PutVarint32(dst, kNewFile);\n    PutVarint32(dst, new_files_[i].first);  // level\n    PutVarint64(dst, f.number);\n    PutVarint64(dst, f.file_size);\n    PutLengthPrefixedSlice(dst, f.smallest.Encode());\n    PutLengthPrefixedSlice(dst, f.largest.Encode());\n  }\n}\n\nstatic bool GetInternalKey(Slice* input, InternalKey* dst) {\n  Slice str;\n  if (GetLengthPrefixedSlice(input, &str)) {\n    dst->DecodeFrom(str);\n    return true;\n  } else {\n    return false;\n  }\n}\n\nstatic bool GetLevel(Slice* input, int* level) {\n  uint32_t v;\n  if (GetVarint32(input, &v) &&\n      v < config::kNumLevels) {\n    *level = v;\n    return true;\n  } else {\n    return false;\n  }\n}\n\nStatus VersionEdit::DecodeFrom(const Slice& src) {\n  Clear();\n  Slice input = src;\n  const char* msg = NULL;\n  uint32_t tag;\n\n  // Temporary storage for parsing\n  int level;\n  uint64_t number;\n  FileMetaData f;\n  Slice str;\n  InternalKey key;\n\n  while (msg == NULL && GetVarint32(&input, &tag)) {\n    switch (tag) {\n      case kComparator:\n        if (GetLengthPrefixedSlice(&input, &str)) {\n          comparator_ = str.ToString();\n          has_comparator_ = true;\n        } else {\n          msg = \"comparator name\";\n        }\n        break;\n\n      case kLogNumber:\n        if (GetVarint64(&input, &log_number_)) {\n          has_log_number_ = true;\n        } else {\n          msg = \"log number\";\n        }\n        break;\n\n      case kPrevLogNumber:\n        if (GetVarint64(&input, &prev_log_number_)) {\n          has_prev_log_number_ = true;\n        } else {\n          msg = \"previous log number\";\n        }\n        break;\n\n      case kNextFileNumber:\n        if (GetVarint64(&input, &next_file_number_)) {\n          has_next_file_number_ = true;\n        } else {\n          msg = \"next file number\";\n        }\n        break;\n\n      case kLastSequence:\n        if (GetVarint64(&input, &last_sequence_)) {\n          has_last_sequence_ = true;\n        } else {\n          msg = \"last sequence number\";\n        }\n        break;\n\n      case kCompactPointer:\n        if (GetLevel(&input, &level) &&\n            GetInternalKey(&input, &key)) {\n          compact_pointers_.push_back(std::make_pair(level, key));\n        } else {\n          msg = \"compaction pointer\";\n        }\n        break;\n\n      case kDeletedFile:\n        if (GetLevel(&input, &level) &&\n            GetVarint64(&input, &number)) {\n          deleted_files_.insert(std::make_pair(level, number));\n        } else {\n          msg = \"deleted file\";\n        }\n        break;\n\n      case kNewFile:\n        if (GetLevel(&input, &level) &&\n            GetVarint64(&input, &f.number) &&\n            GetVarint64(&input, &f.file_size) &&\n            GetInternalKey(&input, &f.smallest) &&\n            GetInternalKey(&input, &f.largest)) {\n          new_files_.push_back(std::make_pair(level, f));\n        } else {\n          msg = \"new-file entry\";\n        }\n        break;\n\n      default:\n        msg = \"unknown tag\";\n        break;\n    }\n  }\n\n  if (msg == NULL && !input.empty()) {\n    msg = \"invalid tag\";\n  }\n\n  Status result;\n  if (msg != NULL) {\n    result = Status::Corruption(\"VersionEdit\", msg);\n  }\n  return result;\n}\n\nstd::string VersionEdit::DebugString() const {\n  std::string r;\n  r.append(\"VersionEdit {\");\n  if (has_comparator_) {\n    r.append(\"\\n  Comparator: \");\n    r.append(comparator_);\n  }\n  if (has_log_number_) {\n    r.append(\"\\n  LogNumber: \");\n    AppendNumberTo(&r, log_number_);\n  }\n  if (has_prev_log_number_) {\n    r.append(\"\\n  PrevLogNumber: \");\n    AppendNumberTo(&r, prev_log_number_);\n  }\n  if (has_next_file_number_) {\n    r.append(\"\\n  NextFile: \");\n    AppendNumberTo(&r, next_file_number_);\n  }\n  if (has_last_sequence_) {\n    r.append(\"\\n  LastSeq: \");\n    AppendNumberTo(&r, last_sequence_);\n  }\n  for (size_t i = 0; i < compact_pointers_.size(); i++) {\n    r.append(\"\\n  CompactPointer: \");\n    AppendNumberTo(&r, compact_pointers_[i].first);\n    r.append(\" \");\n    r.append(compact_pointers_[i].second.DebugString());\n  }\n  for (DeletedFileSet::const_iterator iter = deleted_files_.begin();\n       iter != deleted_files_.end();\n       ++iter) {\n    r.append(\"\\n  DeleteFile: \");\n    AppendNumberTo(&r, iter->first);\n    r.append(\" \");\n    AppendNumberTo(&r, iter->second);\n  }\n  for (size_t i = 0; i < new_files_.size(); i++) {\n    const FileMetaData& f = new_files_[i].second;\n    r.append(\"\\n  AddFile: \");\n    AppendNumberTo(&r, new_files_[i].first);\n    r.append(\" \");\n    AppendNumberTo(&r, f.number);\n    r.append(\" \");\n    AppendNumberTo(&r, f.file_size);\n    r.append(\" \");\n    r.append(f.smallest.DebugString());\n    r.append(\" .. \");\n    r.append(f.largest.DebugString());\n  }\n  r.append(\"\\n}\\n\");\n  return r;\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/db/version_edit.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_DB_VERSION_EDIT_H_\n#define STORAGE_LEVELDB_DB_VERSION_EDIT_H_\n\n#include <set>\n#include <utility>\n#include <vector>\n#include \"db/dbformat.h\"\n\nnamespace leveldb {\n\nclass VersionSet;\n\nstruct FileMetaData {\n  int refs;\n  int allowed_seeks;          // Seeks allowed until compaction\n  uint64_t number;\n  uint64_t file_size;         // File size in bytes\n  InternalKey smallest;       // Smallest internal key served by table\n  InternalKey largest;        // Largest internal key served by table\n\n  FileMetaData() : refs(0), allowed_seeks(1 << 30), file_size(0) { }\n};\n\nclass VersionEdit {\n public:\n  VersionEdit() { Clear(); }\n  ~VersionEdit() { }\n\n  void Clear();\n\n  void SetComparatorName(const Slice& name) {\n    has_comparator_ = true;\n    comparator_ = name.ToString();\n  }\n  void SetLogNumber(uint64_t num) {\n    has_log_number_ = true;\n    log_number_ = num;\n  }\n  void SetPrevLogNumber(uint64_t num) {\n    has_prev_log_number_ = true;\n    prev_log_number_ = num;\n  }\n  void SetNextFile(uint64_t num) {\n    has_next_file_number_ = true;\n    next_file_number_ = num;\n  }\n  void SetLastSequence(SequenceNumber seq) {\n    has_last_sequence_ = true;\n    last_sequence_ = seq;\n  }\n  void SetCompactPointer(int level, const InternalKey& key) {\n    compact_pointers_.push_back(std::make_pair(level, key));\n  }\n\n  // Add the specified file at the specified number.\n  // REQUIRES: This version has not been saved (see VersionSet::SaveTo)\n  // REQUIRES: \"smallest\" and \"largest\" are smallest and largest keys in file\n  void AddFile(int level, uint64_t file,\n               uint64_t file_size,\n               const InternalKey& smallest,\n               const InternalKey& largest) {\n    FileMetaData f;\n    f.number = file;\n    f.file_size = file_size;\n    f.smallest = smallest;\n    f.largest = largest;\n    new_files_.push_back(std::make_pair(level, f));\n  }\n\n  // Delete the specified \"file\" from the specified \"level\".\n  void DeleteFile(int level, uint64_t file) {\n    deleted_files_.insert(std::make_pair(level, file));\n  }\n\n  void EncodeTo(std::string* dst) const;\n  Status DecodeFrom(const Slice& src);\n\n  std::string DebugString() const;\n\n private:\n  friend class VersionSet;\n\n  typedef std::set< std::pair<int, uint64_t> > DeletedFileSet;\n\n  std::string comparator_;\n  uint64_t log_number_;\n  uint64_t prev_log_number_;\n  uint64_t next_file_number_;\n  SequenceNumber last_sequence_;\n  bool has_comparator_;\n  bool has_log_number_;\n  bool has_prev_log_number_;\n  bool has_next_file_number_;\n  bool has_last_sequence_;\n\n  std::vector< std::pair<int, InternalKey> > compact_pointers_;\n  DeletedFileSet deleted_files_;\n  std::vector< std::pair<int, FileMetaData> > new_files_;\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_DB_VERSION_EDIT_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/db/version_edit_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/version_edit.h\"\n#include \"util/testharness.h\"\n\nnamespace leveldb {\n\nstatic void TestEncodeDecode(const VersionEdit& edit) {\n  std::string encoded, encoded2;\n  edit.EncodeTo(&encoded);\n  VersionEdit parsed;\n  Status s = parsed.DecodeFrom(encoded);\n  ASSERT_TRUE(s.ok()) << s.ToString();\n  parsed.EncodeTo(&encoded2);\n  ASSERT_EQ(encoded, encoded2);\n}\n\nclass VersionEditTest { };\n\nTEST(VersionEditTest, EncodeDecode) {\n  static const uint64_t kBig = 1ull << 50;\n\n  VersionEdit edit;\n  for (int i = 0; i < 4; i++) {\n    TestEncodeDecode(edit);\n    edit.AddFile(3, kBig + 300 + i, kBig + 400 + i,\n                 InternalKey(\"foo\", kBig + 500 + i, kTypeValue),\n                 InternalKey(\"zoo\", kBig + 600 + i, kTypeDeletion));\n    edit.DeleteFile(4, kBig + 700 + i);\n    edit.SetCompactPointer(i, InternalKey(\"x\", kBig + 900 + i, kTypeValue));\n  }\n\n  edit.SetComparatorName(\"foo\");\n  edit.SetLogNumber(kBig + 100);\n  edit.SetNextFile(kBig + 200);\n  edit.SetLastSequence(kBig + 1000);\n  TestEncodeDecode(edit);\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/db/version_set.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/version_set.h\"\n\n#include <algorithm>\n#include <stdio.h>\n#include \"db/filename.h\"\n#include \"db/log_reader.h\"\n#include \"db/log_writer.h\"\n#include \"db/memtable.h\"\n#include \"db/table_cache.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/table_builder.h\"\n#include \"table/merger.h\"\n#include \"table/two_level_iterator.h\"\n#include \"util/coding.h\"\n#include \"util/logging.h\"\n\nnamespace leveldb {\n\nstatic int TargetFileSize(const Options* options) {\n  return options->max_file_size;\n}\n\n// Maximum bytes of overlaps in grandparent (i.e., level+2) before we\n// stop building a single file in a level->level+1 compaction.\nstatic int64_t MaxGrandParentOverlapBytes(const Options* options) {\n  return 10 * TargetFileSize(options);\n}\n\n// Maximum number of bytes in all compacted files.  We avoid expanding\n// the lower level file set of a compaction if it would make the\n// total compaction cover more than this many bytes.\nstatic int64_t ExpandedCompactionByteSizeLimit(const Options* options) {\n  return 25 * TargetFileSize(options);\n}\n\nstatic double MaxBytesForLevel(const Options* options, int level) {\n  // Note: the result for level zero is not really used since we set\n  // the level-0 compaction threshold based on number of files.\n\n  // Result for both level-0 and level-1\n  double result = 10. * 1048576.0;\n  while (level > 1) {\n    result *= 10;\n    level--;\n  }\n  return result;\n}\n\nstatic uint64_t MaxFileSizeForLevel(const Options* options, int level) {\n  // We could vary per level to reduce number of files?\n  return TargetFileSize(options);\n}\n\nstatic int64_t TotalFileSize(const std::vector<FileMetaData*>& files) {\n  int64_t sum = 0;\n  for (size_t i = 0; i < files.size(); i++) {\n    sum += files[i]->file_size;\n  }\n  return sum;\n}\n\nVersion::~Version() {\n  assert(refs_ == 0);\n\n  // Remove from linked list\n  prev_->next_ = next_;\n  next_->prev_ = prev_;\n\n  // Drop references to files\n  for (int level = 0; level < config::kNumLevels; level++) {\n    for (size_t i = 0; i < files_[level].size(); i++) {\n      FileMetaData* f = files_[level][i];\n      assert(f->refs > 0);\n      f->refs--;\n      if (f->refs <= 0) {\n        delete f;\n      }\n    }\n  }\n}\n\nint FindFile(const InternalKeyComparator& icmp,\n             const std::vector<FileMetaData*>& files,\n             const Slice& key) {\n  uint32_t left = 0;\n  uint32_t right = files.size();\n  while (left < right) {\n    uint32_t mid = (left + right) / 2;\n    const FileMetaData* f = files[mid];\n    if (icmp.InternalKeyComparator::Compare(f->largest.Encode(), key) < 0) {\n      // Key at \"mid.largest\" is < \"target\".  Therefore all\n      // files at or before \"mid\" are uninteresting.\n      left = mid + 1;\n    } else {\n      // Key at \"mid.largest\" is >= \"target\".  Therefore all files\n      // after \"mid\" are uninteresting.\n      right = mid;\n    }\n  }\n  return right;\n}\n\nstatic bool AfterFile(const Comparator* ucmp,\n                      const Slice* user_key, const FileMetaData* f) {\n  // NULL user_key occurs before all keys and is therefore never after *f\n  return (user_key != NULL &&\n          ucmp->Compare(*user_key, f->largest.user_key()) > 0);\n}\n\nstatic bool BeforeFile(const Comparator* ucmp,\n                       const Slice* user_key, const FileMetaData* f) {\n  // NULL user_key occurs after all keys and is therefore never before *f\n  return (user_key != NULL &&\n          ucmp->Compare(*user_key, f->smallest.user_key()) < 0);\n}\n\nbool SomeFileOverlapsRange(\n    const InternalKeyComparator& icmp,\n    bool disjoint_sorted_files,\n    const std::vector<FileMetaData*>& files,\n    const Slice* smallest_user_key,\n    const Slice* largest_user_key) {\n  const Comparator* ucmp = icmp.user_comparator();\n  if (!disjoint_sorted_files) {\n    // Need to check against all files\n    for (size_t i = 0; i < files.size(); i++) {\n      const FileMetaData* f = files[i];\n      if (AfterFile(ucmp, smallest_user_key, f) ||\n          BeforeFile(ucmp, largest_user_key, f)) {\n        // No overlap\n      } else {\n        return true;  // Overlap\n      }\n    }\n    return false;\n  }\n\n  // Binary search over file list\n  uint32_t index = 0;\n  if (smallest_user_key != NULL) {\n    // Find the earliest possible internal key for smallest_user_key\n    InternalKey small(*smallest_user_key, kMaxSequenceNumber,kValueTypeForSeek);\n    index = FindFile(icmp, files, small.Encode());\n  }\n\n  if (index >= files.size()) {\n    // beginning of range is after all files, so no overlap.\n    return false;\n  }\n\n  return !BeforeFile(ucmp, largest_user_key, files[index]);\n}\n\n// An internal iterator.  For a given version/level pair, yields\n// information about the files in the level.  For a given entry, key()\n// is the largest key that occurs in the file, and value() is an\n// 16-byte value containing the file number and file size, both\n// encoded using EncodeFixed64.\nclass Version::LevelFileNumIterator : public Iterator {\n public:\n  LevelFileNumIterator(const InternalKeyComparator& icmp,\n                       const std::vector<FileMetaData*>* flist)\n      : icmp_(icmp),\n        flist_(flist),\n        index_(flist->size()) {        // Marks as invalid\n  }\n  virtual bool Valid() const {\n    return index_ < flist_->size();\n  }\n  virtual void Seek(const Slice& target) {\n    index_ = FindFile(icmp_, *flist_, target);\n  }\n  virtual void SeekToFirst() { index_ = 0; }\n  virtual void SeekToLast() {\n    index_ = flist_->empty() ? 0 : flist_->size() - 1;\n  }\n  virtual void Next() {\n    assert(Valid());\n    index_++;\n  }\n  virtual void Prev() {\n    assert(Valid());\n    if (index_ == 0) {\n      index_ = flist_->size();  // Marks as invalid\n    } else {\n      index_--;\n    }\n  }\n  Slice key() const {\n    assert(Valid());\n    return (*flist_)[index_]->largest.Encode();\n  }\n  Slice value() const {\n    assert(Valid());\n    EncodeFixed64(value_buf_, (*flist_)[index_]->number);\n    EncodeFixed64(value_buf_+8, (*flist_)[index_]->file_size);\n    return Slice(value_buf_, sizeof(value_buf_));\n  }\n  virtual Status status() const { return Status::OK(); }\n private:\n  const InternalKeyComparator icmp_;\n  const std::vector<FileMetaData*>* const flist_;\n  uint32_t index_;\n\n  // Backing store for value().  Holds the file number and size.\n  mutable char value_buf_[16];\n};\n\nstatic Iterator* GetFileIterator(void* arg,\n                                 const ReadOptions& options,\n                                 const Slice& file_value) {\n  TableCache* cache = reinterpret_cast<TableCache*>(arg);\n  if (file_value.size() != 16) {\n    return NewErrorIterator(\n        Status::Corruption(\"FileReader invoked with unexpected value\"));\n  } else {\n    return cache->NewIterator(options,\n                              DecodeFixed64(file_value.data()),\n                              DecodeFixed64(file_value.data() + 8));\n  }\n}\n\nIterator* Version::NewConcatenatingIterator(const ReadOptions& options,\n                                            int level) const {\n  return NewTwoLevelIterator(\n      new LevelFileNumIterator(vset_->icmp_, &files_[level]),\n      &GetFileIterator, vset_->table_cache_, options);\n}\n\nvoid Version::AddIterators(const ReadOptions& options,\n                           std::vector<Iterator*>* iters) {\n  // Merge all level zero files together since they may overlap\n  for (size_t i = 0; i < files_[0].size(); i++) {\n    iters->push_back(\n        vset_->table_cache_->NewIterator(\n            options, files_[0][i]->number, files_[0][i]->file_size));\n  }\n\n  // For levels > 0, we can use a concatenating iterator that sequentially\n  // walks through the non-overlapping files in the level, opening them\n  // lazily.\n  for (int level = 1; level < config::kNumLevels; level++) {\n    if (!files_[level].empty()) {\n      iters->push_back(NewConcatenatingIterator(options, level));\n    }\n  }\n}\n\n// Callback from TableCache::Get()\nnamespace {\nenum SaverState {\n  kNotFound,\n  kFound,\n  kDeleted,\n  kCorrupt,\n};\nstruct Saver {\n  SaverState state;\n  const Comparator* ucmp;\n  Slice user_key;\n  std::string* value;\n};\n}\nstatic void SaveValue(void* arg, const Slice& ikey, const Slice& v) {\n  Saver* s = reinterpret_cast<Saver*>(arg);\n  ParsedInternalKey parsed_key;\n  if (!ParseInternalKey(ikey, &parsed_key)) {\n    s->state = kCorrupt;\n  } else {\n    if (s->ucmp->Compare(parsed_key.user_key, s->user_key) == 0) {\n      s->state = (parsed_key.type == kTypeValue) ? kFound : kDeleted;\n      if (s->state == kFound) {\n        s->value->assign(v.data(), v.size());\n      }\n    }\n  }\n}\n\nstatic bool NewestFirst(FileMetaData* a, FileMetaData* b) {\n  return a->number > b->number;\n}\n\nvoid Version::ForEachOverlapping(Slice user_key, Slice internal_key,\n                                 void* arg,\n                                 bool (*func)(void*, int, FileMetaData*)) {\n  // TODO(sanjay): Change Version::Get() to use this function.\n  const Comparator* ucmp = vset_->icmp_.user_comparator();\n\n  // Search level-0 in order from newest to oldest.\n  std::vector<FileMetaData*> tmp;\n  tmp.reserve(files_[0].size());\n  for (uint32_t i = 0; i < files_[0].size(); i++) {\n    FileMetaData* f = files_[0][i];\n    if (ucmp->Compare(user_key, f->smallest.user_key()) >= 0 &&\n        ucmp->Compare(user_key, f->largest.user_key()) <= 0) {\n      tmp.push_back(f);\n    }\n  }\n  if (!tmp.empty()) {\n    std::sort(tmp.begin(), tmp.end(), NewestFirst);\n    for (uint32_t i = 0; i < tmp.size(); i++) {\n      if (!(*func)(arg, 0, tmp[i])) {\n        return;\n      }\n    }\n  }\n\n  // Search other levels.\n  for (int level = 1; level < config::kNumLevels; level++) {\n    size_t num_files = files_[level].size();\n    if (num_files == 0) continue;\n\n    // Binary search to find earliest index whose largest key >= internal_key.\n    uint32_t index = FindFile(vset_->icmp_, files_[level], internal_key);\n    if (index < num_files) {\n      FileMetaData* f = files_[level][index];\n      if (ucmp->Compare(user_key, f->smallest.user_key()) < 0) {\n        // All of \"f\" is past any data for user_key\n      } else {\n        if (!(*func)(arg, level, f)) {\n          return;\n        }\n      }\n    }\n  }\n}\n\nStatus Version::Get(const ReadOptions& options,\n                    const LookupKey& k,\n                    std::string* value,\n                    GetStats* stats) {\n  Slice ikey = k.internal_key();\n  Slice user_key = k.user_key();\n  const Comparator* ucmp = vset_->icmp_.user_comparator();\n  Status s;\n\n  stats->seek_file = NULL;\n  stats->seek_file_level = -1;\n  FileMetaData* last_file_read = NULL;\n  int last_file_read_level = -1;\n\n  // We can search level-by-level since entries never hop across\n  // levels.  Therefore we are guaranteed that if we find data\n  // in an smaller level, later levels are irrelevant.\n  std::vector<FileMetaData*> tmp;\n  FileMetaData* tmp2;\n  for (int level = 0; level < config::kNumLevels; level++) {\n    size_t num_files = files_[level].size();\n    if (num_files == 0) continue;\n\n    // Get the list of files to search in this level\n    FileMetaData* const* files = &files_[level][0];\n    if (level == 0) {\n      // Level-0 files may overlap each other.  Find all files that\n      // overlap user_key and process them in order from newest to oldest.\n      tmp.reserve(num_files);\n      for (uint32_t i = 0; i < num_files; i++) {\n        FileMetaData* f = files[i];\n        if (ucmp->Compare(user_key, f->smallest.user_key()) >= 0 &&\n            ucmp->Compare(user_key, f->largest.user_key()) <= 0) {\n          tmp.push_back(f);\n        }\n      }\n      if (tmp.empty()) continue;\n\n      std::sort(tmp.begin(), tmp.end(), NewestFirst);\n      files = &tmp[0];\n      num_files = tmp.size();\n    } else {\n      // Binary search to find earliest index whose largest key >= ikey.\n      uint32_t index = FindFile(vset_->icmp_, files_[level], ikey);\n      if (index >= num_files) {\n        files = NULL;\n        num_files = 0;\n      } else {\n        tmp2 = files[index];\n        if (ucmp->Compare(user_key, tmp2->smallest.user_key()) < 0) {\n          // All of \"tmp2\" is past any data for user_key\n          files = NULL;\n          num_files = 0;\n        } else {\n          files = &tmp2;\n          num_files = 1;\n        }\n      }\n    }\n\n    for (uint32_t i = 0; i < num_files; ++i) {\n      if (last_file_read != NULL && stats->seek_file == NULL) {\n        // We have had more than one seek for this read.  Charge the 1st file.\n        stats->seek_file = last_file_read;\n        stats->seek_file_level = last_file_read_level;\n      }\n\n      FileMetaData* f = files[i];\n      last_file_read = f;\n      last_file_read_level = level;\n\n      Saver saver;\n      saver.state = kNotFound;\n      saver.ucmp = ucmp;\n      saver.user_key = user_key;\n      saver.value = value;\n      s = vset_->table_cache_->Get(options, f->number, f->file_size,\n                                   ikey, &saver, SaveValue);\n      if (!s.ok()) {\n        return s;\n      }\n      switch (saver.state) {\n        case kNotFound:\n          break;      // Keep searching in other files\n        case kFound:\n          return s;\n        case kDeleted:\n          s = Status::NotFound(Slice());  // Use empty error message for speed\n          return s;\n        case kCorrupt:\n          s = Status::Corruption(\"corrupted key for \", user_key);\n          return s;\n      }\n    }\n  }\n\n  return Status::NotFound(Slice());  // Use an empty error message for speed\n}\n\nbool Version::UpdateStats(const GetStats& stats) {\n  FileMetaData* f = stats.seek_file;\n  if (f != NULL) {\n    f->allowed_seeks--;\n    if (f->allowed_seeks <= 0 && file_to_compact_ == NULL) {\n      file_to_compact_ = f;\n      file_to_compact_level_ = stats.seek_file_level;\n      return true;\n    }\n  }\n  return false;\n}\n\nbool Version::RecordReadSample(Slice internal_key) {\n  ParsedInternalKey ikey;\n  if (!ParseInternalKey(internal_key, &ikey)) {\n    return false;\n  }\n\n  struct State {\n    GetStats stats;  // Holds first matching file\n    int matches;\n\n    static bool Match(void* arg, int level, FileMetaData* f) {\n      State* state = reinterpret_cast<State*>(arg);\n      state->matches++;\n      if (state->matches == 1) {\n        // Remember first match.\n        state->stats.seek_file = f;\n        state->stats.seek_file_level = level;\n      }\n      // We can stop iterating once we have a second match.\n      return state->matches < 2;\n    }\n  };\n\n  State state;\n  state.matches = 0;\n  ForEachOverlapping(ikey.user_key, internal_key, &state, &State::Match);\n\n  // Must have at least two matches since we want to merge across\n  // files. But what if we have a single file that contains many\n  // overwrites and deletions?  Should we have another mechanism for\n  // finding such files?\n  if (state.matches >= 2) {\n    // 1MB cost is about 1 seek (see comment in Builder::Apply).\n    return UpdateStats(state.stats);\n  }\n  return false;\n}\n\nvoid Version::Ref() {\n  ++refs_;\n}\n\nvoid Version::Unref() {\n  assert(this != &vset_->dummy_versions_);\n  assert(refs_ >= 1);\n  --refs_;\n  if (refs_ == 0) {\n    delete this;\n  }\n}\n\nbool Version::OverlapInLevel(int level,\n                             const Slice* smallest_user_key,\n                             const Slice* largest_user_key) {\n  return SomeFileOverlapsRange(vset_->icmp_, (level > 0), files_[level],\n                               smallest_user_key, largest_user_key);\n}\n\nint Version::PickLevelForMemTableOutput(\n    const Slice& smallest_user_key,\n    const Slice& largest_user_key) {\n  int level = 0;\n  if (!OverlapInLevel(0, &smallest_user_key, &largest_user_key)) {\n    // Push to next level if there is no overlap in next level,\n    // and the #bytes overlapping in the level after that are limited.\n    InternalKey start(smallest_user_key, kMaxSequenceNumber, kValueTypeForSeek);\n    InternalKey limit(largest_user_key, 0, static_cast<ValueType>(0));\n    std::vector<FileMetaData*> overlaps;\n    while (level < config::kMaxMemCompactLevel) {\n      if (OverlapInLevel(level + 1, &smallest_user_key, &largest_user_key)) {\n        break;\n      }\n      if (level + 2 < config::kNumLevels) {\n        // Check that file does not overlap too many grandparent bytes.\n        GetOverlappingInputs(level + 2, &start, &limit, &overlaps);\n        const int64_t sum = TotalFileSize(overlaps);\n        if (sum > MaxGrandParentOverlapBytes(vset_->options_)) {\n          break;\n        }\n      }\n      level++;\n    }\n  }\n  return level;\n}\n\n// Store in \"*inputs\" all files in \"level\" that overlap [begin,end]\nvoid Version::GetOverlappingInputs(\n    int level,\n    const InternalKey* begin,\n    const InternalKey* end,\n    std::vector<FileMetaData*>* inputs) {\n  assert(level >= 0);\n  assert(level < config::kNumLevels);\n  inputs->clear();\n  Slice user_begin, user_end;\n  if (begin != NULL) {\n    user_begin = begin->user_key();\n  }\n  if (end != NULL) {\n    user_end = end->user_key();\n  }\n  const Comparator* user_cmp = vset_->icmp_.user_comparator();\n  for (size_t i = 0; i < files_[level].size(); ) {\n    FileMetaData* f = files_[level][i++];\n    const Slice file_start = f->smallest.user_key();\n    const Slice file_limit = f->largest.user_key();\n    if (begin != NULL && user_cmp->Compare(file_limit, user_begin) < 0) {\n      // \"f\" is completely before specified range; skip it\n    } else if (end != NULL && user_cmp->Compare(file_start, user_end) > 0) {\n      // \"f\" is completely after specified range; skip it\n    } else {\n      inputs->push_back(f);\n      if (level == 0) {\n        // Level-0 files may overlap each other.  So check if the newly\n        // added file has expanded the range.  If so, restart search.\n        if (begin != NULL && user_cmp->Compare(file_start, user_begin) < 0) {\n          user_begin = file_start;\n          inputs->clear();\n          i = 0;\n        } else if (end != NULL && user_cmp->Compare(file_limit, user_end) > 0) {\n          user_end = file_limit;\n          inputs->clear();\n          i = 0;\n        }\n      }\n    }\n  }\n}\n\nstd::string Version::DebugString() const {\n  std::string r;\n  for (int level = 0; level < config::kNumLevels; level++) {\n    // E.g.,\n    //   --- level 1 ---\n    //   17:123['a' .. 'd']\n    //   20:43['e' .. 'g']\n    r.append(\"--- level \");\n    AppendNumberTo(&r, level);\n    r.append(\" ---\\n\");\n    const std::vector<FileMetaData*>& files = files_[level];\n    for (size_t i = 0; i < files.size(); i++) {\n      r.push_back(' ');\n      AppendNumberTo(&r, files[i]->number);\n      r.push_back(':');\n      AppendNumberTo(&r, files[i]->file_size);\n      r.append(\"[\");\n      r.append(files[i]->smallest.DebugString());\n      r.append(\" .. \");\n      r.append(files[i]->largest.DebugString());\n      r.append(\"]\\n\");\n    }\n  }\n  return r;\n}\n\n// A helper class so we can efficiently apply a whole sequence\n// of edits to a particular state without creating intermediate\n// Versions that contain full copies of the intermediate state.\nclass VersionSet::Builder {\n private:\n  // Helper to sort by v->files_[file_number].smallest\n  struct BySmallestKey {\n    const InternalKeyComparator* internal_comparator;\n\n    bool operator()(FileMetaData* f1, FileMetaData* f2) const {\n      int r = internal_comparator->Compare(f1->smallest, f2->smallest);\n      if (r != 0) {\n        return (r < 0);\n      } else {\n        // Break ties by file number\n        return (f1->number < f2->number);\n      }\n    }\n  };\n\n  typedef std::set<FileMetaData*, BySmallestKey> FileSet;\n  struct LevelState {\n    std::set<uint64_t> deleted_files;\n    FileSet* added_files;\n  };\n\n  VersionSet* vset_;\n  Version* base_;\n  LevelState levels_[config::kNumLevels];\n\n public:\n  // Initialize a builder with the files from *base and other info from *vset\n  Builder(VersionSet* vset, Version* base)\n      : vset_(vset),\n        base_(base) {\n    base_->Ref();\n    BySmallestKey cmp;\n    cmp.internal_comparator = &vset_->icmp_;\n    for (int level = 0; level < config::kNumLevels; level++) {\n      levels_[level].added_files = new FileSet(cmp);\n    }\n  }\n\n  ~Builder() {\n    for (int level = 0; level < config::kNumLevels; level++) {\n      const FileSet* added = levels_[level].added_files;\n      std::vector<FileMetaData*> to_unref;\n      to_unref.reserve(added->size());\n      for (FileSet::const_iterator it = added->begin();\n          it != added->end(); ++it) {\n        to_unref.push_back(*it);\n      }\n      delete added;\n      for (uint32_t i = 0; i < to_unref.size(); i++) {\n        FileMetaData* f = to_unref[i];\n        f->refs--;\n        if (f->refs <= 0) {\n          delete f;\n        }\n      }\n    }\n    base_->Unref();\n  }\n\n  // Apply all of the edits in *edit to the current state.\n  void Apply(VersionEdit* edit) {\n    // Update compaction pointers\n    for (size_t i = 0; i < edit->compact_pointers_.size(); i++) {\n      const int level = edit->compact_pointers_[i].first;\n      vset_->compact_pointer_[level] =\n          edit->compact_pointers_[i].second.Encode().ToString();\n    }\n\n    // Delete files\n    const VersionEdit::DeletedFileSet& del = edit->deleted_files_;\n    for (VersionEdit::DeletedFileSet::const_iterator iter = del.begin();\n         iter != del.end();\n         ++iter) {\n      const int level = iter->first;\n      const uint64_t number = iter->second;\n      levels_[level].deleted_files.insert(number);\n    }\n\n    // Add new files\n    for (size_t i = 0; i < edit->new_files_.size(); i++) {\n      const int level = edit->new_files_[i].first;\n      FileMetaData* f = new FileMetaData(edit->new_files_[i].second);\n      f->refs = 1;\n\n      // We arrange to automatically compact this file after\n      // a certain number of seeks.  Let's assume:\n      //   (1) One seek costs 10ms\n      //   (2) Writing or reading 1MB costs 10ms (100MB/s)\n      //   (3) A compaction of 1MB does 25MB of IO:\n      //         1MB read from this level\n      //         10-12MB read from next level (boundaries may be misaligned)\n      //         10-12MB written to next level\n      // This implies that 25 seeks cost the same as the compaction\n      // of 1MB of data.  I.e., one seek costs approximately the\n      // same as the compaction of 40KB of data.  We are a little\n      // conservative and allow approximately one seek for every 16KB\n      // of data before triggering a compaction.\n      f->allowed_seeks = (f->file_size / 16384);\n      if (f->allowed_seeks < 100) f->allowed_seeks = 100;\n\n      levels_[level].deleted_files.erase(f->number);\n      levels_[level].added_files->insert(f);\n    }\n  }\n\n  // Save the current state in *v.\n  void SaveTo(Version* v) {\n    BySmallestKey cmp;\n    cmp.internal_comparator = &vset_->icmp_;\n    for (int level = 0; level < config::kNumLevels; level++) {\n      // Merge the set of added files with the set of pre-existing files.\n      // Drop any deleted files.  Store the result in *v.\n      const std::vector<FileMetaData*>& base_files = base_->files_[level];\n      std::vector<FileMetaData*>::const_iterator base_iter = base_files.begin();\n      std::vector<FileMetaData*>::const_iterator base_end = base_files.end();\n      const FileSet* added = levels_[level].added_files;\n      v->files_[level].reserve(base_files.size() + added->size());\n      for (FileSet::const_iterator added_iter = added->begin();\n           added_iter != added->end();\n           ++added_iter) {\n        // Add all smaller files listed in base_\n        for (std::vector<FileMetaData*>::const_iterator bpos\n                 = std::upper_bound(base_iter, base_end, *added_iter, cmp);\n             base_iter != bpos;\n             ++base_iter) {\n          MaybeAddFile(v, level, *base_iter);\n        }\n\n        MaybeAddFile(v, level, *added_iter);\n      }\n\n      // Add remaining base files\n      for (; base_iter != base_end; ++base_iter) {\n        MaybeAddFile(v, level, *base_iter);\n      }\n\n#ifndef NDEBUG\n      // Make sure there is no overlap in levels > 0\n      if (level > 0) {\n        for (uint32_t i = 1; i < v->files_[level].size(); i++) {\n          const InternalKey& prev_end = v->files_[level][i-1]->largest;\n          const InternalKey& this_begin = v->files_[level][i]->smallest;\n          if (vset_->icmp_.Compare(prev_end, this_begin) >= 0) {\n            fprintf(stderr, \"overlapping ranges in same level %s vs. %s\\n\",\n                    prev_end.DebugString().c_str(),\n                    this_begin.DebugString().c_str());\n            abort();\n          }\n        }\n      }\n#endif\n    }\n  }\n\n  void MaybeAddFile(Version* v, int level, FileMetaData* f) {\n    if (levels_[level].deleted_files.count(f->number) > 0) {\n      // File is deleted: do nothing\n    } else {\n      std::vector<FileMetaData*>* files = &v->files_[level];\n      if (level > 0 && !files->empty()) {\n        // Must not overlap\n        assert(vset_->icmp_.Compare((*files)[files->size()-1]->largest,\n                                    f->smallest) < 0);\n      }\n      f->refs++;\n      files->push_back(f);\n    }\n  }\n};\n\nVersionSet::VersionSet(const std::string& dbname,\n                       const Options* options,\n                       TableCache* table_cache,\n                       const InternalKeyComparator* cmp)\n    : env_(options->env),\n      dbname_(dbname),\n      options_(options),\n      table_cache_(table_cache),\n      icmp_(*cmp),\n      next_file_number_(2),\n      manifest_file_number_(0),  // Filled by Recover()\n      last_sequence_(0),\n      log_number_(0),\n      prev_log_number_(0),\n      descriptor_file_(NULL),\n      descriptor_log_(NULL),\n      dummy_versions_(this),\n      current_(NULL) {\n  AppendVersion(new Version(this));\n}\n\nVersionSet::~VersionSet() {\n  current_->Unref();\n  assert(dummy_versions_.next_ == &dummy_versions_);  // List must be empty\n  delete descriptor_log_;\n  delete descriptor_file_;\n}\n\nvoid VersionSet::AppendVersion(Version* v) {\n  // Make \"v\" current\n  assert(v->refs_ == 0);\n  assert(v != current_);\n  if (current_ != NULL) {\n    current_->Unref();\n  }\n  current_ = v;\n  v->Ref();\n\n  // Append to linked list\n  v->prev_ = dummy_versions_.prev_;\n  v->next_ = &dummy_versions_;\n  v->prev_->next_ = v;\n  v->next_->prev_ = v;\n}\n\nStatus VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu) {\n  if (edit->has_log_number_) {\n    assert(edit->log_number_ >= log_number_);\n    assert(edit->log_number_ < next_file_number_);\n  } else {\n    edit->SetLogNumber(log_number_);\n  }\n\n  if (!edit->has_prev_log_number_) {\n    edit->SetPrevLogNumber(prev_log_number_);\n  }\n\n  edit->SetNextFile(next_file_number_);\n  edit->SetLastSequence(last_sequence_);\n\n  Version* v = new Version(this);\n  {\n    Builder builder(this, current_);\n    builder.Apply(edit);\n    builder.SaveTo(v);\n  }\n  Finalize(v);\n\n  // Initialize new descriptor log file if necessary by creating\n  // a temporary file that contains a snapshot of the current version.\n  std::string new_manifest_file;\n  Status s;\n  if (descriptor_log_ == NULL) {\n    // No reason to unlock *mu here since we only hit this path in the\n    // first call to LogAndApply (when opening the database).\n    assert(descriptor_file_ == NULL);\n    new_manifest_file = DescriptorFileName(dbname_, manifest_file_number_);\n    edit->SetNextFile(next_file_number_);\n    s = env_->NewWritableFile(new_manifest_file, &descriptor_file_);\n    if (s.ok()) {\n      descriptor_log_ = new log::Writer(descriptor_file_);\n      s = WriteSnapshot(descriptor_log_);\n    }\n  }\n\n  // Unlock during expensive MANIFEST log write\n  {\n    mu->Unlock();\n\n    // Write new record to MANIFEST log\n    if (s.ok()) {\n      std::string record;\n      edit->EncodeTo(&record);\n      s = descriptor_log_->AddRecord(record);\n      if (s.ok()) {\n        s = descriptor_file_->Sync();\n      }\n      if (!s.ok()) {\n        Log(options_->info_log, \"MANIFEST write: %s\\n\", s.ToString().c_str());\n      }\n    }\n\n    // If we just created a new descriptor file, install it by writing a\n    // new CURRENT file that points to it.\n    if (s.ok() && !new_manifest_file.empty()) {\n      s = SetCurrentFile(env_, dbname_, manifest_file_number_);\n    }\n\n    mu->Lock();\n  }\n\n  // Install the new version\n  if (s.ok()) {\n    AppendVersion(v);\n    log_number_ = edit->log_number_;\n    prev_log_number_ = edit->prev_log_number_;\n  } else {\n    delete v;\n    if (!new_manifest_file.empty()) {\n      delete descriptor_log_;\n      delete descriptor_file_;\n      descriptor_log_ = NULL;\n      descriptor_file_ = NULL;\n      env_->DeleteFile(new_manifest_file);\n    }\n  }\n\n  return s;\n}\n\nStatus VersionSet::Recover(bool *save_manifest) {\n  struct LogReporter : public log::Reader::Reporter {\n    Status* status;\n    virtual void Corruption(size_t bytes, const Status& s) {\n      if (this->status->ok()) *this->status = s;\n    }\n  };\n\n  // Read \"CURRENT\" file, which contains a pointer to the current manifest file\n  std::string current;\n  Status s = ReadFileToString(env_, CurrentFileName(dbname_), &current);\n  if (!s.ok()) {\n    return s;\n  }\n  if (current.empty() || current[current.size()-1] != '\\n') {\n    return Status::Corruption(\"CURRENT file does not end with newline\");\n  }\n  current.resize(current.size() - 1);\n\n  std::string dscname = dbname_ + \"/\" + current;\n  SequentialFile* file;\n  s = env_->NewSequentialFile(dscname, &file);\n  if (!s.ok()) {\n    if (s.IsNotFound()) {\n      return Status::Corruption(\n            \"CURRENT points to a non-existent file\", s.ToString());\n    }\n    return s;\n  }\n\n  bool have_log_number = false;\n  bool have_prev_log_number = false;\n  bool have_next_file = false;\n  bool have_last_sequence = false;\n  uint64_t next_file = 0;\n  uint64_t last_sequence = 0;\n  uint64_t log_number = 0;\n  uint64_t prev_log_number = 0;\n  Builder builder(this, current_);\n\n  {\n    LogReporter reporter;\n    reporter.status = &s;\n    log::Reader reader(file, &reporter, true/*checksum*/, 0/*initial_offset*/);\n    Slice record;\n    std::string scratch;\n    while (reader.ReadRecord(&record, &scratch) && s.ok()) {\n      VersionEdit edit;\n      s = edit.DecodeFrom(record);\n      if (s.ok()) {\n        if (edit.has_comparator_ &&\n            edit.comparator_ != icmp_.user_comparator()->Name()) {\n          s = Status::InvalidArgument(\n              edit.comparator_ + \" does not match existing comparator \",\n              icmp_.user_comparator()->Name());\n        }\n      }\n\n      if (s.ok()) {\n        builder.Apply(&edit);\n      }\n\n      if (edit.has_log_number_) {\n        log_number = edit.log_number_;\n        have_log_number = true;\n      }\n\n      if (edit.has_prev_log_number_) {\n        prev_log_number = edit.prev_log_number_;\n        have_prev_log_number = true;\n      }\n\n      if (edit.has_next_file_number_) {\n        next_file = edit.next_file_number_;\n        have_next_file = true;\n      }\n\n      if (edit.has_last_sequence_) {\n        last_sequence = edit.last_sequence_;\n        have_last_sequence = true;\n      }\n    }\n  }\n  delete file;\n  file = NULL;\n\n  if (s.ok()) {\n    if (!have_next_file) {\n      s = Status::Corruption(\"no meta-nextfile entry in descriptor\");\n    } else if (!have_log_number) {\n      s = Status::Corruption(\"no meta-lognumber entry in descriptor\");\n    } else if (!have_last_sequence) {\n      s = Status::Corruption(\"no last-sequence-number entry in descriptor\");\n    }\n\n    if (!have_prev_log_number) {\n      prev_log_number = 0;\n    }\n\n    MarkFileNumberUsed(prev_log_number);\n    MarkFileNumberUsed(log_number);\n  }\n\n  if (s.ok()) {\n    Version* v = new Version(this);\n    builder.SaveTo(v);\n    // Install recovered version\n    Finalize(v);\n    AppendVersion(v);\n    manifest_file_number_ = next_file;\n    next_file_number_ = next_file + 1;\n    last_sequence_ = last_sequence;\n    log_number_ = log_number;\n    prev_log_number_ = prev_log_number;\n\n    // See if we can reuse the existing MANIFEST file.\n    if (ReuseManifest(dscname, current)) {\n      // No need to save new manifest\n    } else {\n      *save_manifest = true;\n    }\n  }\n\n  return s;\n}\n\nbool VersionSet::ReuseManifest(const std::string& dscname,\n                               const std::string& dscbase) {\n  if (!options_->reuse_logs) {\n    return false;\n  }\n  FileType manifest_type;\n  uint64_t manifest_number;\n  uint64_t manifest_size;\n  if (!ParseFileName(dscbase, &manifest_number, &manifest_type) ||\n      manifest_type != kDescriptorFile ||\n      !env_->GetFileSize(dscname, &manifest_size).ok() ||\n      // Make new compacted MANIFEST if old one is too big\n      manifest_size >= TargetFileSize(options_)) {\n    return false;\n  }\n\n  assert(descriptor_file_ == NULL);\n  assert(descriptor_log_ == NULL);\n  Status r = env_->NewAppendableFile(dscname, &descriptor_file_);\n  if (!r.ok()) {\n    Log(options_->info_log, \"Reuse MANIFEST: %s\\n\", r.ToString().c_str());\n    assert(descriptor_file_ == NULL);\n    return false;\n  }\n\n  Log(options_->info_log, \"Reusing MANIFEST %s\\n\", dscname.c_str());\n  descriptor_log_ = new log::Writer(descriptor_file_, manifest_size);\n  manifest_file_number_ = manifest_number;\n  return true;\n}\n\nvoid VersionSet::MarkFileNumberUsed(uint64_t number) {\n  if (next_file_number_ <= number) {\n    next_file_number_ = number + 1;\n  }\n}\n\nvoid VersionSet::Finalize(Version* v) {\n  // Precomputed best level for next compaction\n  int best_level = -1;\n  double best_score = -1;\n\n  for (int level = 0; level < config::kNumLevels-1; level++) {\n    double score;\n    if (level == 0) {\n      // We treat level-0 specially by bounding the number of files\n      // instead of number of bytes for two reasons:\n      //\n      // (1) With larger write-buffer sizes, it is nice not to do too\n      // many level-0 compactions.\n      //\n      // (2) The files in level-0 are merged on every read and\n      // therefore we wish to avoid too many files when the individual\n      // file size is small (perhaps because of a small write-buffer\n      // setting, or very high compression ratios, or lots of\n      // overwrites/deletions).\n      score = v->files_[level].size() /\n          static_cast<double>(config::kL0_CompactionTrigger);\n    } else {\n      // Compute the ratio of current size to size limit.\n      const uint64_t level_bytes = TotalFileSize(v->files_[level]);\n      score =\n          static_cast<double>(level_bytes) / MaxBytesForLevel(options_, level);\n    }\n\n    if (score > best_score) {\n      best_level = level;\n      best_score = score;\n    }\n  }\n\n  v->compaction_level_ = best_level;\n  v->compaction_score_ = best_score;\n}\n\nStatus VersionSet::WriteSnapshot(log::Writer* log) {\n  // TODO: Break up into multiple records to reduce memory usage on recovery?\n\n  // Save metadata\n  VersionEdit edit;\n  edit.SetComparatorName(icmp_.user_comparator()->Name());\n\n  // Save compaction pointers\n  for (int level = 0; level < config::kNumLevels; level++) {\n    if (!compact_pointer_[level].empty()) {\n      InternalKey key;\n      key.DecodeFrom(compact_pointer_[level]);\n      edit.SetCompactPointer(level, key);\n    }\n  }\n\n  // Save files\n  for (int level = 0; level < config::kNumLevels; level++) {\n    const std::vector<FileMetaData*>& files = current_->files_[level];\n    for (size_t i = 0; i < files.size(); i++) {\n      const FileMetaData* f = files[i];\n      edit.AddFile(level, f->number, f->file_size, f->smallest, f->largest);\n    }\n  }\n\n  std::string record;\n  edit.EncodeTo(&record);\n  return log->AddRecord(record);\n}\n\nint VersionSet::NumLevelFiles(int level) const {\n  assert(level >= 0);\n  assert(level < config::kNumLevels);\n  return current_->files_[level].size();\n}\n\nconst char* VersionSet::LevelSummary(LevelSummaryStorage* scratch) const {\n  // Update code if kNumLevels changes\n  assert(config::kNumLevels == 7);\n  snprintf(scratch->buffer, sizeof(scratch->buffer),\n           \"files[ %d %d %d %d %d %d %d ]\",\n           int(current_->files_[0].size()),\n           int(current_->files_[1].size()),\n           int(current_->files_[2].size()),\n           int(current_->files_[3].size()),\n           int(current_->files_[4].size()),\n           int(current_->files_[5].size()),\n           int(current_->files_[6].size()));\n  return scratch->buffer;\n}\n\nuint64_t VersionSet::ApproximateOffsetOf(Version* v, const InternalKey& ikey) {\n  uint64_t result = 0;\n  for (int level = 0; level < config::kNumLevels; level++) {\n    const std::vector<FileMetaData*>& files = v->files_[level];\n    for (size_t i = 0; i < files.size(); i++) {\n      if (icmp_.Compare(files[i]->largest, ikey) <= 0) {\n        // Entire file is before \"ikey\", so just add the file size\n        result += files[i]->file_size;\n      } else if (icmp_.Compare(files[i]->smallest, ikey) > 0) {\n        // Entire file is after \"ikey\", so ignore\n        if (level > 0) {\n          // Files other than level 0 are sorted by meta->smallest, so\n          // no further files in this level will contain data for\n          // \"ikey\".\n          break;\n        }\n      } else {\n        // \"ikey\" falls in the range for this table.  Add the\n        // approximate offset of \"ikey\" within the table.\n        Table* tableptr;\n        Iterator* iter = table_cache_->NewIterator(\n            ReadOptions(), files[i]->number, files[i]->file_size, &tableptr);\n        if (tableptr != NULL) {\n          result += tableptr->ApproximateOffsetOf(ikey.Encode());\n        }\n        delete iter;\n      }\n    }\n  }\n  return result;\n}\n\nvoid VersionSet::AddLiveFiles(std::set<uint64_t>* live) {\n  for (Version* v = dummy_versions_.next_;\n       v != &dummy_versions_;\n       v = v->next_) {\n    for (int level = 0; level < config::kNumLevels; level++) {\n      const std::vector<FileMetaData*>& files = v->files_[level];\n      for (size_t i = 0; i < files.size(); i++) {\n        live->insert(files[i]->number);\n      }\n    }\n  }\n}\n\nint64_t VersionSet::NumLevelBytes(int level) const {\n  assert(level >= 0);\n  assert(level < config::kNumLevels);\n  return TotalFileSize(current_->files_[level]);\n}\n\nint64_t VersionSet::MaxNextLevelOverlappingBytes() {\n  int64_t result = 0;\n  std::vector<FileMetaData*> overlaps;\n  for (int level = 1; level < config::kNumLevels - 1; level++) {\n    for (size_t i = 0; i < current_->files_[level].size(); i++) {\n      const FileMetaData* f = current_->files_[level][i];\n      current_->GetOverlappingInputs(level+1, &f->smallest, &f->largest,\n                                     &overlaps);\n      const int64_t sum = TotalFileSize(overlaps);\n      if (sum > result) {\n        result = sum;\n      }\n    }\n  }\n  return result;\n}\n\n// Stores the minimal range that covers all entries in inputs in\n// *smallest, *largest.\n// REQUIRES: inputs is not empty\nvoid VersionSet::GetRange(const std::vector<FileMetaData*>& inputs,\n                          InternalKey* smallest,\n                          InternalKey* largest) {\n  assert(!inputs.empty());\n  smallest->Clear();\n  largest->Clear();\n  for (size_t i = 0; i < inputs.size(); i++) {\n    FileMetaData* f = inputs[i];\n    if (i == 0) {\n      *smallest = f->smallest;\n      *largest = f->largest;\n    } else {\n      if (icmp_.Compare(f->smallest, *smallest) < 0) {\n        *smallest = f->smallest;\n      }\n      if (icmp_.Compare(f->largest, *largest) > 0) {\n        *largest = f->largest;\n      }\n    }\n  }\n}\n\n// Stores the minimal range that covers all entries in inputs1 and inputs2\n// in *smallest, *largest.\n// REQUIRES: inputs is not empty\nvoid VersionSet::GetRange2(const std::vector<FileMetaData*>& inputs1,\n                           const std::vector<FileMetaData*>& inputs2,\n                           InternalKey* smallest,\n                           InternalKey* largest) {\n  std::vector<FileMetaData*> all = inputs1;\n  all.insert(all.end(), inputs2.begin(), inputs2.end());\n  GetRange(all, smallest, largest);\n}\n\nIterator* VersionSet::MakeInputIterator(Compaction* c) {\n  ReadOptions options;\n  options.verify_checksums = options_->paranoid_checks;\n  options.fill_cache = false;\n\n  // Level-0 files have to be merged together.  For other levels,\n  // we will make a concatenating iterator per level.\n  // TODO(opt): use concatenating iterator for level-0 if there is no overlap\n  const int space = (c->level() == 0 ? c->inputs_[0].size() + 1 : 2);\n  Iterator** list = new Iterator*[space];\n  int num = 0;\n  for (int which = 0; which < 2; which++) {\n    if (!c->inputs_[which].empty()) {\n      if (c->level() + which == 0) {\n        const std::vector<FileMetaData*>& files = c->inputs_[which];\n        for (size_t i = 0; i < files.size(); i++) {\n          list[num++] = table_cache_->NewIterator(\n              options, files[i]->number, files[i]->file_size);\n        }\n      } else {\n        // Create concatenating iterator for the files from this level\n        list[num++] = NewTwoLevelIterator(\n            new Version::LevelFileNumIterator(icmp_, &c->inputs_[which]),\n            &GetFileIterator, table_cache_, options);\n      }\n    }\n  }\n  assert(num <= space);\n  Iterator* result = NewMergingIterator(&icmp_, list, num);\n  delete[] list;\n  return result;\n}\n\nCompaction* VersionSet::PickCompaction() {\n  Compaction* c;\n  int level;\n\n  // We prefer compactions triggered by too much data in a level over\n  // the compactions triggered by seeks.\n  const bool size_compaction = (current_->compaction_score_ >= 1);\n  const bool seek_compaction = (current_->file_to_compact_ != NULL);\n  if (size_compaction) {\n    level = current_->compaction_level_;\n    assert(level >= 0);\n    assert(level+1 < config::kNumLevels);\n    c = new Compaction(options_, level);\n\n    // Pick the first file that comes after compact_pointer_[level]\n    for (size_t i = 0; i < current_->files_[level].size(); i++) {\n      FileMetaData* f = current_->files_[level][i];\n      if (compact_pointer_[level].empty() ||\n          icmp_.Compare(f->largest.Encode(), compact_pointer_[level]) > 0) {\n        c->inputs_[0].push_back(f);\n        break;\n      }\n    }\n    if (c->inputs_[0].empty()) {\n      // Wrap-around to the beginning of the key space\n      c->inputs_[0].push_back(current_->files_[level][0]);\n    }\n  } else if (seek_compaction) {\n    level = current_->file_to_compact_level_;\n    c = new Compaction(options_, level);\n    c->inputs_[0].push_back(current_->file_to_compact_);\n  } else {\n    return NULL;\n  }\n\n  c->input_version_ = current_;\n  c->input_version_->Ref();\n\n  // Files in level 0 may overlap each other, so pick up all overlapping ones\n  if (level == 0) {\n    InternalKey smallest, largest;\n    GetRange(c->inputs_[0], &smallest, &largest);\n    // Note that the next call will discard the file we placed in\n    // c->inputs_[0] earlier and replace it with an overlapping set\n    // which will include the picked file.\n    current_->GetOverlappingInputs(0, &smallest, &largest, &c->inputs_[0]);\n    assert(!c->inputs_[0].empty());\n  }\n\n  SetupOtherInputs(c);\n\n  return c;\n}\n\nvoid VersionSet::SetupOtherInputs(Compaction* c) {\n  const int level = c->level();\n  InternalKey smallest, largest;\n  GetRange(c->inputs_[0], &smallest, &largest);\n\n  current_->GetOverlappingInputs(level+1, &smallest, &largest, &c->inputs_[1]);\n\n  // Get entire range covered by compaction\n  InternalKey all_start, all_limit;\n  GetRange2(c->inputs_[0], c->inputs_[1], &all_start, &all_limit);\n\n  // See if we can grow the number of inputs in \"level\" without\n  // changing the number of \"level+1\" files we pick up.\n  if (!c->inputs_[1].empty()) {\n    std::vector<FileMetaData*> expanded0;\n    current_->GetOverlappingInputs(level, &all_start, &all_limit, &expanded0);\n    const int64_t inputs0_size = TotalFileSize(c->inputs_[0]);\n    const int64_t inputs1_size = TotalFileSize(c->inputs_[1]);\n    const int64_t expanded0_size = TotalFileSize(expanded0);\n    if (expanded0.size() > c->inputs_[0].size() &&\n        inputs1_size + expanded0_size <\n            ExpandedCompactionByteSizeLimit(options_)) {\n      InternalKey new_start, new_limit;\n      GetRange(expanded0, &new_start, &new_limit);\n      std::vector<FileMetaData*> expanded1;\n      current_->GetOverlappingInputs(level+1, &new_start, &new_limit,\n                                     &expanded1);\n      if (expanded1.size() == c->inputs_[1].size()) {\n        Log(options_->info_log,\n            \"Expanding@%d %d+%d (%ld+%ld bytes) to %d+%d (%ld+%ld bytes)\\n\",\n            level,\n            int(c->inputs_[0].size()),\n            int(c->inputs_[1].size()),\n            long(inputs0_size), long(inputs1_size),\n            int(expanded0.size()),\n            int(expanded1.size()),\n            long(expanded0_size), long(inputs1_size));\n        smallest = new_start;\n        largest = new_limit;\n        c->inputs_[0] = expanded0;\n        c->inputs_[1] = expanded1;\n        GetRange2(c->inputs_[0], c->inputs_[1], &all_start, &all_limit);\n      }\n    }\n  }\n\n  // Compute the set of grandparent files that overlap this compaction\n  // (parent == level+1; grandparent == level+2)\n  if (level + 2 < config::kNumLevels) {\n    current_->GetOverlappingInputs(level + 2, &all_start, &all_limit,\n                                   &c->grandparents_);\n  }\n\n  // Update the place where we will do the next compaction for this level.\n  // We update this immediately instead of waiting for the VersionEdit\n  // to be applied so that if the compaction fails, we will try a different\n  // key range next time.\n  compact_pointer_[level] = largest.Encode().ToString();\n  c->edit_.SetCompactPointer(level, largest);\n}\n\nCompaction* VersionSet::CompactRange(\n    int level,\n    const InternalKey* begin,\n    const InternalKey* end) {\n  std::vector<FileMetaData*> inputs;\n  current_->GetOverlappingInputs(level, begin, end, &inputs);\n  if (inputs.empty()) {\n    return NULL;\n  }\n\n  // Avoid compacting too much in one shot in case the range is large.\n  // But we cannot do this for level-0 since level-0 files can overlap\n  // and we must not pick one file and drop another older file if the\n  // two files overlap.\n  if (level > 0) {\n    const uint64_t limit = MaxFileSizeForLevel(options_, level);\n    uint64_t total = 0;\n    for (size_t i = 0; i < inputs.size(); i++) {\n      uint64_t s = inputs[i]->file_size;\n      total += s;\n      if (total >= limit) {\n        inputs.resize(i + 1);\n        break;\n      }\n    }\n  }\n\n  Compaction* c = new Compaction(options_, level);\n  c->input_version_ = current_;\n  c->input_version_->Ref();\n  c->inputs_[0] = inputs;\n  SetupOtherInputs(c);\n  return c;\n}\n\nCompaction::Compaction(const Options* options, int level)\n    : level_(level),\n      max_output_file_size_(MaxFileSizeForLevel(options, level)),\n      input_version_(NULL),\n      grandparent_index_(0),\n      seen_key_(false),\n      overlapped_bytes_(0) {\n  for (int i = 0; i < config::kNumLevels; i++) {\n    level_ptrs_[i] = 0;\n  }\n}\n\nCompaction::~Compaction() {\n  if (input_version_ != NULL) {\n    input_version_->Unref();\n  }\n}\n\nbool Compaction::IsTrivialMove() const {\n  const VersionSet* vset = input_version_->vset_;\n  // Avoid a move if there is lots of overlapping grandparent data.\n  // Otherwise, the move could create a parent file that will require\n  // a very expensive merge later on.\n  return (num_input_files(0) == 1 && num_input_files(1) == 0 &&\n          TotalFileSize(grandparents_) <=\n              MaxGrandParentOverlapBytes(vset->options_));\n}\n\nvoid Compaction::AddInputDeletions(VersionEdit* edit) {\n  for (int which = 0; which < 2; which++) {\n    for (size_t i = 0; i < inputs_[which].size(); i++) {\n      edit->DeleteFile(level_ + which, inputs_[which][i]->number);\n    }\n  }\n}\n\nbool Compaction::IsBaseLevelForKey(const Slice& user_key) {\n  // Maybe use binary search to find right entry instead of linear search?\n  const Comparator* user_cmp = input_version_->vset_->icmp_.user_comparator();\n  for (int lvl = level_ + 2; lvl < config::kNumLevels; lvl++) {\n    const std::vector<FileMetaData*>& files = input_version_->files_[lvl];\n    for (; level_ptrs_[lvl] < files.size(); ) {\n      FileMetaData* f = files[level_ptrs_[lvl]];\n      if (user_cmp->Compare(user_key, f->largest.user_key()) <= 0) {\n        // We've advanced far enough\n        if (user_cmp->Compare(user_key, f->smallest.user_key()) >= 0) {\n          // Key falls in this file's range, so definitely not base level\n          return false;\n        }\n        break;\n      }\n      level_ptrs_[lvl]++;\n    }\n  }\n  return true;\n}\n\nbool Compaction::ShouldStopBefore(const Slice& internal_key) {\n  const VersionSet* vset = input_version_->vset_;\n  // Scan to find earliest grandparent file that contains key.\n  const InternalKeyComparator* icmp = &vset->icmp_;\n  while (grandparent_index_ < grandparents_.size() &&\n      icmp->Compare(internal_key,\n                    grandparents_[grandparent_index_]->largest.Encode()) > 0) {\n    if (seen_key_) {\n      overlapped_bytes_ += grandparents_[grandparent_index_]->file_size;\n    }\n    grandparent_index_++;\n  }\n  seen_key_ = true;\n\n  if (overlapped_bytes_ > MaxGrandParentOverlapBytes(vset->options_)) {\n    // Too much overlap for current output; start new output\n    overlapped_bytes_ = 0;\n    return true;\n  } else {\n    return false;\n  }\n}\n\nvoid Compaction::ReleaseInputs() {\n  if (input_version_ != NULL) {\n    input_version_->Unref();\n    input_version_ = NULL;\n  }\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/db/version_set.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// The representation of a DBImpl consists of a set of Versions.  The\n// newest version is called \"current\".  Older versions may be kept\n// around to provide a consistent view to live iterators.\n//\n// Each Version keeps track of a set of Table files per level.  The\n// entire set of versions is maintained in a VersionSet.\n//\n// Version,VersionSet are thread-compatible, but require external\n// synchronization on all accesses.\n\n#ifndef STORAGE_LEVELDB_DB_VERSION_SET_H_\n#define STORAGE_LEVELDB_DB_VERSION_SET_H_\n\n#include <map>\n#include <set>\n#include <vector>\n#include \"db/dbformat.h\"\n#include \"db/version_edit.h\"\n#include \"port/port.h\"\n#include \"port/thread_annotations.h\"\n\nnamespace leveldb {\n\nnamespace log { class Writer; }\n\nclass Compaction;\nclass Iterator;\nclass MemTable;\nclass TableBuilder;\nclass TableCache;\nclass Version;\nclass VersionSet;\nclass WritableFile;\n\n// Return the smallest index i such that files[i]->largest >= key.\n// Return files.size() if there is no such file.\n// REQUIRES: \"files\" contains a sorted list of non-overlapping files.\nextern int FindFile(const InternalKeyComparator& icmp,\n                    const std::vector<FileMetaData*>& files,\n                    const Slice& key);\n\n// Returns true iff some file in \"files\" overlaps the user key range\n// [*smallest,*largest].\n// smallest==NULL represents a key smaller than all keys in the DB.\n// largest==NULL represents a key largest than all keys in the DB.\n// REQUIRES: If disjoint_sorted_files, files[] contains disjoint ranges\n//           in sorted order.\nextern bool SomeFileOverlapsRange(\n    const InternalKeyComparator& icmp,\n    bool disjoint_sorted_files,\n    const std::vector<FileMetaData*>& files,\n    const Slice* smallest_user_key,\n    const Slice* largest_user_key);\n\nclass Version {\n public:\n  // Append to *iters a sequence of iterators that will\n  // yield the contents of this Version when merged together.\n  // REQUIRES: This version has been saved (see VersionSet::SaveTo)\n  void AddIterators(const ReadOptions&, std::vector<Iterator*>* iters);\n\n  // Lookup the value for key.  If found, store it in *val and\n  // return OK.  Else return a non-OK status.  Fills *stats.\n  // REQUIRES: lock is not held\n  struct GetStats {\n    FileMetaData* seek_file;\n    int seek_file_level;\n  };\n  Status Get(const ReadOptions&, const LookupKey& key, std::string* val,\n             GetStats* stats);\n\n  // Adds \"stats\" into the current state.  Returns true if a new\n  // compaction may need to be triggered, false otherwise.\n  // REQUIRES: lock is held\n  bool UpdateStats(const GetStats& stats);\n\n  // Record a sample of bytes read at the specified internal key.\n  // Samples are taken approximately once every config::kReadBytesPeriod\n  // bytes.  Returns true if a new compaction may need to be triggered.\n  // REQUIRES: lock is held\n  bool RecordReadSample(Slice key);\n\n  // Reference count management (so Versions do not disappear out from\n  // under live iterators)\n  void Ref();\n  void Unref();\n\n  void GetOverlappingInputs(\n      int level,\n      const InternalKey* begin,         // NULL means before all keys\n      const InternalKey* end,           // NULL means after all keys\n      std::vector<FileMetaData*>* inputs);\n\n  // Returns true iff some file in the specified level overlaps\n  // some part of [*smallest_user_key,*largest_user_key].\n  // smallest_user_key==NULL represents a key smaller than all keys in the DB.\n  // largest_user_key==NULL represents a key largest than all keys in the DB.\n  bool OverlapInLevel(int level,\n                      const Slice* smallest_user_key,\n                      const Slice* largest_user_key);\n\n  // Return the level at which we should place a new memtable compaction\n  // result that covers the range [smallest_user_key,largest_user_key].\n  int PickLevelForMemTableOutput(const Slice& smallest_user_key,\n                                 const Slice& largest_user_key);\n\n  int NumFiles(int level) const { return files_[level].size(); }\n\n  // Return a human readable string that describes this version's contents.\n  std::string DebugString() const;\n\n private:\n  friend class Compaction;\n  friend class VersionSet;\n\n  class LevelFileNumIterator;\n  Iterator* NewConcatenatingIterator(const ReadOptions&, int level) const;\n\n  // Call func(arg, level, f) for every file that overlaps user_key in\n  // order from newest to oldest.  If an invocation of func returns\n  // false, makes no more calls.\n  //\n  // REQUIRES: user portion of internal_key == user_key.\n  void ForEachOverlapping(Slice user_key, Slice internal_key,\n                          void* arg,\n                          bool (*func)(void*, int, FileMetaData*));\n\n  VersionSet* vset_;            // VersionSet to which this Version belongs\n  Version* next_;               // Next version in linked list\n  Version* prev_;               // Previous version in linked list\n  int refs_;                    // Number of live refs to this version\n\n  // List of files per level\n  std::vector<FileMetaData*> files_[config::kNumLevels];\n\n  // Next file to compact based on seek stats.\n  FileMetaData* file_to_compact_;\n  int file_to_compact_level_;\n\n  // Level that should be compacted next and its compaction score.\n  // Score < 1 means compaction is not strictly needed.  These fields\n  // are initialized by Finalize().\n  double compaction_score_;\n  int compaction_level_;\n\n  explicit Version(VersionSet* vset)\n      : vset_(vset), next_(this), prev_(this), refs_(0),\n        file_to_compact_(NULL),\n        file_to_compact_level_(-1),\n        compaction_score_(-1),\n        compaction_level_(-1) {\n  }\n\n  ~Version();\n\n  // No copying allowed\n  Version(const Version&);\n  void operator=(const Version&);\n};\n\nclass VersionSet {\n public:\n  VersionSet(const std::string& dbname,\n             const Options* options,\n             TableCache* table_cache,\n             const InternalKeyComparator*);\n  ~VersionSet();\n\n  // Apply *edit to the current version to form a new descriptor that\n  // is both saved to persistent state and installed as the new\n  // current version.  Will release *mu while actually writing to the file.\n  // REQUIRES: *mu is held on entry.\n  // REQUIRES: no other thread concurrently calls LogAndApply()\n  Status LogAndApply(VersionEdit* edit, port::Mutex* mu)\n      EXCLUSIVE_LOCKS_REQUIRED(mu);\n\n  // Recover the last saved descriptor from persistent storage.\n  Status Recover(bool *save_manifest);\n\n  // Return the current version.\n  Version* current() const { return current_; }\n\n  // Return the current manifest file number\n  uint64_t ManifestFileNumber() const { return manifest_file_number_; }\n\n  // Allocate and return a new file number\n  uint64_t NewFileNumber() { return next_file_number_++; }\n\n  // Arrange to reuse \"file_number\" unless a newer file number has\n  // already been allocated.\n  // REQUIRES: \"file_number\" was returned by a call to NewFileNumber().\n  void ReuseFileNumber(uint64_t file_number) {\n    if (next_file_number_ == file_number + 1) {\n      next_file_number_ = file_number;\n    }\n  }\n\n  // Return the number of Table files at the specified level.\n  int NumLevelFiles(int level) const;\n\n  // Return the combined file size of all files at the specified level.\n  int64_t NumLevelBytes(int level) const;\n\n  // Return the last sequence number.\n  uint64_t LastSequence() const { return last_sequence_; }\n\n  // Set the last sequence number to s.\n  void SetLastSequence(uint64_t s) {\n    assert(s >= last_sequence_);\n    last_sequence_ = s;\n  }\n\n  // Mark the specified file number as used.\n  void MarkFileNumberUsed(uint64_t number);\n\n  // Return the current log file number.\n  uint64_t LogNumber() const { return log_number_; }\n\n  // Return the log file number for the log file that is currently\n  // being compacted, or zero if there is no such log file.\n  uint64_t PrevLogNumber() const { return prev_log_number_; }\n\n  // Pick level and inputs for a new compaction.\n  // Returns NULL if there is no compaction to be done.\n  // Otherwise returns a pointer to a heap-allocated object that\n  // describes the compaction.  Caller should delete the result.\n  Compaction* PickCompaction();\n\n  // Return a compaction object for compacting the range [begin,end] in\n  // the specified level.  Returns NULL if there is nothing in that\n  // level that overlaps the specified range.  Caller should delete\n  // the result.\n  Compaction* CompactRange(\n      int level,\n      const InternalKey* begin,\n      const InternalKey* end);\n\n  // Return the maximum overlapping data (in bytes) at next level for any\n  // file at a level >= 1.\n  int64_t MaxNextLevelOverlappingBytes();\n\n  // Create an iterator that reads over the compaction inputs for \"*c\".\n  // The caller should delete the iterator when no longer needed.\n  Iterator* MakeInputIterator(Compaction* c);\n\n  // Returns true iff some level needs a compaction.\n  bool NeedsCompaction() const {\n    Version* v = current_;\n    return (v->compaction_score_ >= 1) || (v->file_to_compact_ != NULL);\n  }\n\n  // Add all files listed in any live version to *live.\n  // May also mutate some internal state.\n  void AddLiveFiles(std::set<uint64_t>* live);\n\n  // Return the approximate offset in the database of the data for\n  // \"key\" as of version \"v\".\n  uint64_t ApproximateOffsetOf(Version* v, const InternalKey& key);\n\n  // Return a human-readable short (single-line) summary of the number\n  // of files per level.  Uses *scratch as backing store.\n  struct LevelSummaryStorage {\n    char buffer[100];\n  };\n  const char* LevelSummary(LevelSummaryStorage* scratch) const;\n\n private:\n  class Builder;\n\n  friend class Compaction;\n  friend class Version;\n\n  bool ReuseManifest(const std::string& dscname, const std::string& dscbase);\n\n  void Finalize(Version* v);\n\n  void GetRange(const std::vector<FileMetaData*>& inputs,\n                InternalKey* smallest,\n                InternalKey* largest);\n\n  void GetRange2(const std::vector<FileMetaData*>& inputs1,\n                 const std::vector<FileMetaData*>& inputs2,\n                 InternalKey* smallest,\n                 InternalKey* largest);\n\n  void SetupOtherInputs(Compaction* c);\n\n  // Save current contents to *log\n  Status WriteSnapshot(log::Writer* log);\n\n  void AppendVersion(Version* v);\n\n  Env* const env_;\n  const std::string dbname_;\n  const Options* const options_;\n  TableCache* const table_cache_;\n  const InternalKeyComparator icmp_;\n  uint64_t next_file_number_;\n  uint64_t manifest_file_number_;\n  uint64_t last_sequence_;\n  uint64_t log_number_;\n  uint64_t prev_log_number_;  // 0 or backing store for memtable being compacted\n\n  // Opened lazily\n  WritableFile* descriptor_file_;\n  log::Writer* descriptor_log_;\n  Version dummy_versions_;  // Head of circular doubly-linked list of versions.\n  Version* current_;        // == dummy_versions_.prev_\n\n  // Per-level key at which the next compaction at that level should start.\n  // Either an empty string, or a valid InternalKey.\n  std::string compact_pointer_[config::kNumLevels];\n\n  // No copying allowed\n  VersionSet(const VersionSet&);\n  void operator=(const VersionSet&);\n};\n\n// A Compaction encapsulates information about a compaction.\nclass Compaction {\n public:\n  ~Compaction();\n\n  // Return the level that is being compacted.  Inputs from \"level\"\n  // and \"level+1\" will be merged to produce a set of \"level+1\" files.\n  int level() const { return level_; }\n\n  // Return the object that holds the edits to the descriptor done\n  // by this compaction.\n  VersionEdit* edit() { return &edit_; }\n\n  // \"which\" must be either 0 or 1\n  int num_input_files(int which) const { return inputs_[which].size(); }\n\n  // Return the ith input file at \"level()+which\" (\"which\" must be 0 or 1).\n  FileMetaData* input(int which, int i) const { return inputs_[which][i]; }\n\n  // Maximum size of files to build during this compaction.\n  uint64_t MaxOutputFileSize() const { return max_output_file_size_; }\n\n  // Is this a trivial compaction that can be implemented by just\n  // moving a single input file to the next level (no merging or splitting)\n  bool IsTrivialMove() const;\n\n  // Add all inputs to this compaction as delete operations to *edit.\n  void AddInputDeletions(VersionEdit* edit);\n\n  // Returns true if the information we have available guarantees that\n  // the compaction is producing data in \"level+1\" for which no data exists\n  // in levels greater than \"level+1\".\n  bool IsBaseLevelForKey(const Slice& user_key);\n\n  // Returns true iff we should stop building the current output\n  // before processing \"internal_key\".\n  bool ShouldStopBefore(const Slice& internal_key);\n\n  // Release the input version for the compaction, once the compaction\n  // is successful.\n  void ReleaseInputs();\n\n private:\n  friend class Version;\n  friend class VersionSet;\n\n  Compaction(const Options* options, int level);\n\n  int level_;\n  uint64_t max_output_file_size_;\n  Version* input_version_;\n  VersionEdit edit_;\n\n  // Each compaction reads inputs from \"level_\" and \"level_+1\"\n  std::vector<FileMetaData*> inputs_[2];      // The two sets of inputs\n\n  // State used to check for number of of overlapping grandparent files\n  // (parent == level_ + 1, grandparent == level_ + 2)\n  std::vector<FileMetaData*> grandparents_;\n  size_t grandparent_index_;  // Index in grandparent_starts_\n  bool seen_key_;             // Some output key has been seen\n  int64_t overlapped_bytes_;  // Bytes of overlap between current output\n                              // and grandparent files\n\n  // State for implementing IsBaseLevelForKey\n\n  // level_ptrs_ holds indices into input_version_->levels_: our state\n  // is that we are positioned at one of the file ranges for each\n  // higher level than the ones involved in this compaction (i.e. for\n  // all L >= level_ + 2).\n  size_t level_ptrs_[config::kNumLevels];\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_DB_VERSION_SET_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/db/version_set_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"db/version_set.h\"\n#include \"util/logging.h\"\n#include \"util/testharness.h\"\n#include \"util/testutil.h\"\n\nnamespace leveldb {\n\nclass FindFileTest {\n public:\n  std::vector<FileMetaData*> files_;\n  bool disjoint_sorted_files_;\n\n  FindFileTest() : disjoint_sorted_files_(true) { }\n\n  ~FindFileTest() {\n    for (int i = 0; i < files_.size(); i++) {\n      delete files_[i];\n    }\n  }\n\n  void Add(const char* smallest, const char* largest,\n           SequenceNumber smallest_seq = 100,\n           SequenceNumber largest_seq = 100) {\n    FileMetaData* f = new FileMetaData;\n    f->number = files_.size() + 1;\n    f->smallest = InternalKey(smallest, smallest_seq, kTypeValue);\n    f->largest = InternalKey(largest, largest_seq, kTypeValue);\n    files_.push_back(f);\n  }\n\n  int Find(const char* key) {\n    InternalKey target(key, 100, kTypeValue);\n    InternalKeyComparator cmp(BytewiseComparator());\n    return FindFile(cmp, files_, target.Encode());\n  }\n\n  bool Overlaps(const char* smallest, const char* largest) {\n    InternalKeyComparator cmp(BytewiseComparator());\n    Slice s(smallest != NULL ? smallest : \"\");\n    Slice l(largest != NULL ? largest : \"\");\n    return SomeFileOverlapsRange(cmp, disjoint_sorted_files_, files_,\n                                 (smallest != NULL ? &s : NULL),\n                                 (largest != NULL ? &l : NULL));\n  }\n};\n\nTEST(FindFileTest, Empty) {\n  ASSERT_EQ(0, Find(\"foo\"));\n  ASSERT_TRUE(! Overlaps(\"a\", \"z\"));\n  ASSERT_TRUE(! Overlaps(NULL, \"z\"));\n  ASSERT_TRUE(! Overlaps(\"a\", NULL));\n  ASSERT_TRUE(! Overlaps(NULL, NULL));\n}\n\nTEST(FindFileTest, Single) {\n  Add(\"p\", \"q\");\n  ASSERT_EQ(0, Find(\"a\"));\n  ASSERT_EQ(0, Find(\"p\"));\n  ASSERT_EQ(0, Find(\"p1\"));\n  ASSERT_EQ(0, Find(\"q\"));\n  ASSERT_EQ(1, Find(\"q1\"));\n  ASSERT_EQ(1, Find(\"z\"));\n\n  ASSERT_TRUE(! Overlaps(\"a\", \"b\"));\n  ASSERT_TRUE(! Overlaps(\"z1\", \"z2\"));\n  ASSERT_TRUE(Overlaps(\"a\", \"p\"));\n  ASSERT_TRUE(Overlaps(\"a\", \"q\"));\n  ASSERT_TRUE(Overlaps(\"a\", \"z\"));\n  ASSERT_TRUE(Overlaps(\"p\", \"p1\"));\n  ASSERT_TRUE(Overlaps(\"p\", \"q\"));\n  ASSERT_TRUE(Overlaps(\"p\", \"z\"));\n  ASSERT_TRUE(Overlaps(\"p1\", \"p2\"));\n  ASSERT_TRUE(Overlaps(\"p1\", \"z\"));\n  ASSERT_TRUE(Overlaps(\"q\", \"q\"));\n  ASSERT_TRUE(Overlaps(\"q\", \"q1\"));\n\n  ASSERT_TRUE(! Overlaps(NULL, \"j\"));\n  ASSERT_TRUE(! Overlaps(\"r\", NULL));\n  ASSERT_TRUE(Overlaps(NULL, \"p\"));\n  ASSERT_TRUE(Overlaps(NULL, \"p1\"));\n  ASSERT_TRUE(Overlaps(\"q\", NULL));\n  ASSERT_TRUE(Overlaps(NULL, NULL));\n}\n\n\nTEST(FindFileTest, Multiple) {\n  Add(\"150\", \"200\");\n  Add(\"200\", \"250\");\n  Add(\"300\", \"350\");\n  Add(\"400\", \"450\");\n  ASSERT_EQ(0, Find(\"100\"));\n  ASSERT_EQ(0, Find(\"150\"));\n  ASSERT_EQ(0, Find(\"151\"));\n  ASSERT_EQ(0, Find(\"199\"));\n  ASSERT_EQ(0, Find(\"200\"));\n  ASSERT_EQ(1, Find(\"201\"));\n  ASSERT_EQ(1, Find(\"249\"));\n  ASSERT_EQ(1, Find(\"250\"));\n  ASSERT_EQ(2, Find(\"251\"));\n  ASSERT_EQ(2, Find(\"299\"));\n  ASSERT_EQ(2, Find(\"300\"));\n  ASSERT_EQ(2, Find(\"349\"));\n  ASSERT_EQ(2, Find(\"350\"));\n  ASSERT_EQ(3, Find(\"351\"));\n  ASSERT_EQ(3, Find(\"400\"));\n  ASSERT_EQ(3, Find(\"450\"));\n  ASSERT_EQ(4, Find(\"451\"));\n\n  ASSERT_TRUE(! Overlaps(\"100\", \"149\"));\n  ASSERT_TRUE(! Overlaps(\"251\", \"299\"));\n  ASSERT_TRUE(! Overlaps(\"451\", \"500\"));\n  ASSERT_TRUE(! Overlaps(\"351\", \"399\"));\n\n  ASSERT_TRUE(Overlaps(\"100\", \"150\"));\n  ASSERT_TRUE(Overlaps(\"100\", \"200\"));\n  ASSERT_TRUE(Overlaps(\"100\", \"300\"));\n  ASSERT_TRUE(Overlaps(\"100\", \"400\"));\n  ASSERT_TRUE(Overlaps(\"100\", \"500\"));\n  ASSERT_TRUE(Overlaps(\"375\", \"400\"));\n  ASSERT_TRUE(Overlaps(\"450\", \"450\"));\n  ASSERT_TRUE(Overlaps(\"450\", \"500\"));\n}\n\nTEST(FindFileTest, MultipleNullBoundaries) {\n  Add(\"150\", \"200\");\n  Add(\"200\", \"250\");\n  Add(\"300\", \"350\");\n  Add(\"400\", \"450\");\n  ASSERT_TRUE(! Overlaps(NULL, \"149\"));\n  ASSERT_TRUE(! Overlaps(\"451\", NULL));\n  ASSERT_TRUE(Overlaps(NULL, NULL));\n  ASSERT_TRUE(Overlaps(NULL, \"150\"));\n  ASSERT_TRUE(Overlaps(NULL, \"199\"));\n  ASSERT_TRUE(Overlaps(NULL, \"200\"));\n  ASSERT_TRUE(Overlaps(NULL, \"201\"));\n  ASSERT_TRUE(Overlaps(NULL, \"400\"));\n  ASSERT_TRUE(Overlaps(NULL, \"800\"));\n  ASSERT_TRUE(Overlaps(\"100\", NULL));\n  ASSERT_TRUE(Overlaps(\"200\", NULL));\n  ASSERT_TRUE(Overlaps(\"449\", NULL));\n  ASSERT_TRUE(Overlaps(\"450\", NULL));\n}\n\nTEST(FindFileTest, OverlapSequenceChecks) {\n  Add(\"200\", \"200\", 5000, 3000);\n  ASSERT_TRUE(! Overlaps(\"199\", \"199\"));\n  ASSERT_TRUE(! Overlaps(\"201\", \"300\"));\n  ASSERT_TRUE(Overlaps(\"200\", \"200\"));\n  ASSERT_TRUE(Overlaps(\"190\", \"200\"));\n  ASSERT_TRUE(Overlaps(\"200\", \"210\"));\n}\n\nTEST(FindFileTest, OverlappingFiles) {\n  Add(\"150\", \"600\");\n  Add(\"400\", \"500\");\n  disjoint_sorted_files_ = false;\n  ASSERT_TRUE(! Overlaps(\"100\", \"149\"));\n  ASSERT_TRUE(! Overlaps(\"601\", \"700\"));\n  ASSERT_TRUE(Overlaps(\"100\", \"150\"));\n  ASSERT_TRUE(Overlaps(\"100\", \"200\"));\n  ASSERT_TRUE(Overlaps(\"100\", \"300\"));\n  ASSERT_TRUE(Overlaps(\"100\", \"400\"));\n  ASSERT_TRUE(Overlaps(\"100\", \"500\"));\n  ASSERT_TRUE(Overlaps(\"375\", \"400\"));\n  ASSERT_TRUE(Overlaps(\"450\", \"450\"));\n  ASSERT_TRUE(Overlaps(\"450\", \"500\"));\n  ASSERT_TRUE(Overlaps(\"450\", \"700\"));\n  ASSERT_TRUE(Overlaps(\"600\", \"700\"));\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/db/write_batch.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// WriteBatch::rep_ :=\n//    sequence: fixed64\n//    count: fixed32\n//    data: record[count]\n// record :=\n//    kTypeValue varstring varstring         |\n//    kTypeDeletion varstring\n// varstring :=\n//    len: varint32\n//    data: uint8[len]\n\n#include \"leveldb/write_batch.h\"\n\n#include \"leveldb/db.h\"\n#include \"db/dbformat.h\"\n#include \"db/memtable.h\"\n#include \"db/write_batch_internal.h\"\n#include \"util/coding.h\"\n\nnamespace leveldb {\n\n// WriteBatch header has an 8-byte sequence number followed by a 4-byte count.\nstatic const size_t kHeader = 12;\n\nWriteBatch::WriteBatch() {\n  Clear();\n}\n\nWriteBatch::~WriteBatch() { }\n\nWriteBatch::Handler::~Handler() { }\n\nvoid WriteBatch::Clear() {\n  rep_.clear();\n  rep_.resize(kHeader);\n}\n\nsize_t WriteBatch::ApproximateSize() {\n  return rep_.size();\n}\n\nStatus WriteBatch::Iterate(Handler* handler) const {\n  Slice input(rep_);\n  if (input.size() < kHeader) {\n    return Status::Corruption(\"malformed WriteBatch (too small)\");\n  }\n\n  input.remove_prefix(kHeader);\n  Slice key, value;\n  int found = 0;\n  while (!input.empty()) {\n    found++;\n    char tag = input[0];\n    input.remove_prefix(1);\n    switch (tag) {\n      case kTypeValue:\n        if (GetLengthPrefixedSlice(&input, &key) &&\n            GetLengthPrefixedSlice(&input, &value)) {\n          handler->Put(key, value);\n        } else {\n          return Status::Corruption(\"bad WriteBatch Put\");\n        }\n        break;\n      case kTypeDeletion:\n        if (GetLengthPrefixedSlice(&input, &key)) {\n          handler->Delete(key);\n        } else {\n          return Status::Corruption(\"bad WriteBatch Delete\");\n        }\n        break;\n      default:\n        return Status::Corruption(\"unknown WriteBatch tag\");\n    }\n  }\n  if (found != WriteBatchInternal::Count(this)) {\n    return Status::Corruption(\"WriteBatch has wrong count\");\n  } else {\n    return Status::OK();\n  }\n}\n\nint WriteBatchInternal::Count(const WriteBatch* b) {\n  return DecodeFixed32(b->rep_.data() + 8);\n}\n\nvoid WriteBatchInternal::SetCount(WriteBatch* b, int n) {\n  EncodeFixed32(&b->rep_[8], n);\n}\n\nSequenceNumber WriteBatchInternal::Sequence(const WriteBatch* b) {\n  return SequenceNumber(DecodeFixed64(b->rep_.data()));\n}\n\nvoid WriteBatchInternal::SetSequence(WriteBatch* b, SequenceNumber seq) {\n  EncodeFixed64(&b->rep_[0], seq);\n}\n\nvoid WriteBatch::Put(const Slice& key, const Slice& value) {\n  WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);\n  rep_.push_back(static_cast<char>(kTypeValue));\n  PutLengthPrefixedSlice(&rep_, key);\n  PutLengthPrefixedSlice(&rep_, value);\n}\n\nvoid WriteBatch::Delete(const Slice& key) {\n  WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);\n  rep_.push_back(static_cast<char>(kTypeDeletion));\n  PutLengthPrefixedSlice(&rep_, key);\n}\n\nnamespace {\nclass MemTableInserter : public WriteBatch::Handler {\n public:\n  SequenceNumber sequence_;\n  MemTable* mem_;\n\n  virtual void Put(const Slice& key, const Slice& value) {\n    mem_->Add(sequence_, kTypeValue, key, value);\n    sequence_++;\n  }\n  virtual void Delete(const Slice& key) {\n    mem_->Add(sequence_, kTypeDeletion, key, Slice());\n    sequence_++;\n  }\n};\n}  // namespace\n\nStatus WriteBatchInternal::InsertInto(const WriteBatch* b,\n                                      MemTable* memtable) {\n  MemTableInserter inserter;\n  inserter.sequence_ = WriteBatchInternal::Sequence(b);\n  inserter.mem_ = memtable;\n  return b->Iterate(&inserter);\n}\n\nvoid WriteBatchInternal::SetContents(WriteBatch* b, const Slice& contents) {\n  assert(contents.size() >= kHeader);\n  b->rep_.assign(contents.data(), contents.size());\n}\n\nvoid WriteBatchInternal::Append(WriteBatch* dst, const WriteBatch* src) {\n  SetCount(dst, Count(dst) + Count(src));\n  assert(src->rep_.size() >= kHeader);\n  dst->rep_.append(src->rep_.data() + kHeader, src->rep_.size() - kHeader);\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/db/write_batch_internal.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_\n#define STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_\n\n#include \"db/dbformat.h\"\n#include \"leveldb/write_batch.h\"\n\nnamespace leveldb {\n\nclass MemTable;\n\n// WriteBatchInternal provides static methods for manipulating a\n// WriteBatch that we don't want in the public WriteBatch interface.\nclass WriteBatchInternal {\n public:\n  // Return the number of entries in the batch.\n  static int Count(const WriteBatch* batch);\n\n  // Set the count for the number of entries in the batch.\n  static void SetCount(WriteBatch* batch, int n);\n\n  // Return the sequence number for the start of this batch.\n  static SequenceNumber Sequence(const WriteBatch* batch);\n\n  // Store the specified number as the sequence number for the start of\n  // this batch.\n  static void SetSequence(WriteBatch* batch, SequenceNumber seq);\n\n  static Slice Contents(const WriteBatch* batch) {\n    return Slice(batch->rep_);\n  }\n\n  static size_t ByteSize(const WriteBatch* batch) {\n    return batch->rep_.size();\n  }\n\n  static void SetContents(WriteBatch* batch, const Slice& contents);\n\n  static Status InsertInto(const WriteBatch* batch, MemTable* memtable);\n\n  static void Append(WriteBatch* dst, const WriteBatch* src);\n};\n\n}  // namespace leveldb\n\n\n#endif  // STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/db/write_batch_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/db.h\"\n\n#include \"db/memtable.h\"\n#include \"db/write_batch_internal.h\"\n#include \"leveldb/env.h\"\n#include \"util/logging.h\"\n#include \"util/testharness.h\"\n\nnamespace leveldb {\n\nstatic std::string PrintContents(WriteBatch* b) {\n  InternalKeyComparator cmp(BytewiseComparator());\n  MemTable* mem = new MemTable(cmp);\n  mem->Ref();\n  std::string state;\n  Status s = WriteBatchInternal::InsertInto(b, mem);\n  int count = 0;\n  Iterator* iter = mem->NewIterator();\n  for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {\n    ParsedInternalKey ikey;\n    ASSERT_TRUE(ParseInternalKey(iter->key(), &ikey));\n    switch (ikey.type) {\n      case kTypeValue:\n        state.append(\"Put(\");\n        state.append(ikey.user_key.ToString());\n        state.append(\", \");\n        state.append(iter->value().ToString());\n        state.append(\")\");\n        count++;\n        break;\n      case kTypeDeletion:\n        state.append(\"Delete(\");\n        state.append(ikey.user_key.ToString());\n        state.append(\")\");\n        count++;\n        break;\n    }\n    state.append(\"@\");\n    state.append(NumberToString(ikey.sequence));\n  }\n  delete iter;\n  if (!s.ok()) {\n    state.append(\"ParseError()\");\n  } else if (count != WriteBatchInternal::Count(b)) {\n    state.append(\"CountMismatch()\");\n  }\n  mem->Unref();\n  return state;\n}\n\nclass WriteBatchTest { };\n\nTEST(WriteBatchTest, Empty) {\n  WriteBatch batch;\n  ASSERT_EQ(\"\", PrintContents(&batch));\n  ASSERT_EQ(0, WriteBatchInternal::Count(&batch));\n}\n\nTEST(WriteBatchTest, Multiple) {\n  WriteBatch batch;\n  batch.Put(Slice(\"foo\"), Slice(\"bar\"));\n  batch.Delete(Slice(\"box\"));\n  batch.Put(Slice(\"baz\"), Slice(\"boo\"));\n  WriteBatchInternal::SetSequence(&batch, 100);\n  ASSERT_EQ(100, WriteBatchInternal::Sequence(&batch));\n  ASSERT_EQ(3, WriteBatchInternal::Count(&batch));\n  ASSERT_EQ(\"Put(baz, boo)@102\"\n            \"Delete(box)@101\"\n            \"Put(foo, bar)@100\",\n            PrintContents(&batch));\n}\n\nTEST(WriteBatchTest, Corruption) {\n  WriteBatch batch;\n  batch.Put(Slice(\"foo\"), Slice(\"bar\"));\n  batch.Delete(Slice(\"box\"));\n  WriteBatchInternal::SetSequence(&batch, 200);\n  Slice contents = WriteBatchInternal::Contents(&batch);\n  WriteBatchInternal::SetContents(&batch,\n                                  Slice(contents.data(),contents.size()-1));\n  ASSERT_EQ(\"Put(foo, bar)@200\"\n            \"ParseError()\",\n            PrintContents(&batch));\n}\n\nTEST(WriteBatchTest, Append) {\n  WriteBatch b1, b2;\n  WriteBatchInternal::SetSequence(&b1, 200);\n  WriteBatchInternal::SetSequence(&b2, 300);\n  WriteBatchInternal::Append(&b1, &b2);\n  ASSERT_EQ(\"\",\n            PrintContents(&b1));\n  b2.Put(\"a\", \"va\");\n  WriteBatchInternal::Append(&b1, &b2);\n  ASSERT_EQ(\"Put(a, va)@200\",\n            PrintContents(&b1));\n  b2.Clear();\n  b2.Put(\"b\", \"vb\");\n  WriteBatchInternal::Append(&b1, &b2);\n  ASSERT_EQ(\"Put(a, va)@200\"\n            \"Put(b, vb)@201\",\n            PrintContents(&b1));\n  b2.Delete(\"foo\");\n  WriteBatchInternal::Append(&b1, &b2);\n  ASSERT_EQ(\"Put(a, va)@200\"\n            \"Put(b, vb)@202\"\n            \"Put(b, vb)@201\"\n            \"Delete(foo)@203\",\n            PrintContents(&b1));\n}\n\nTEST(WriteBatchTest, ApproximateSize) {\n  WriteBatch batch;\n  size_t empty_size = batch.ApproximateSize();\n\n  batch.Put(Slice(\"foo\"), Slice(\"bar\"));\n  size_t one_key_size = batch.ApproximateSize();\n  ASSERT_LT(empty_size, one_key_size);\n\n  batch.Put(Slice(\"baz\"), Slice(\"boo\"));\n  size_t two_keys_size = batch.ApproximateSize();\n  ASSERT_LT(one_key_size, two_keys_size);\n\n  batch.Delete(Slice(\"box\"));\n  size_t post_delete_size = batch.ApproximateSize();\n  ASSERT_LT(two_keys_size, post_delete_size);\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/doc/bench/db_bench_sqlite3.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <sqlite3.h>\n#include \"util/histogram.h\"\n#include \"util/random.h\"\n#include \"util/testutil.h\"\n\n// Comma-separated list of operations to run in the specified order\n//   Actual benchmarks:\n//\n//   fillseq       -- write N values in sequential key order in async mode\n//   fillseqsync   -- write N/100 values in sequential key order in sync mode\n//   fillseqbatch  -- batch write N values in sequential key order in async mode\n//   fillrandom    -- write N values in random key order in async mode\n//   fillrandsync  -- write N/100 values in random key order in sync mode\n//   fillrandbatch -- batch write N values in sequential key order in async mode\n//   overwrite     -- overwrite N values in random key order in async mode\n//   fillrand100K  -- write N/1000 100K values in random order in async mode\n//   fillseq100K   -- write N/1000 100K values in sequential order in async mode\n//   readseq       -- read N times sequentially\n//   readrandom    -- read N times in random order\n//   readrand100K  -- read N/1000 100K values in sequential order in async mode\nstatic const char* FLAGS_benchmarks =\n    \"fillseq,\"\n    \"fillseqsync,\"\n    \"fillseqbatch,\"\n    \"fillrandom,\"\n    \"fillrandsync,\"\n    \"fillrandbatch,\"\n    \"overwrite,\"\n    \"overwritebatch,\"\n    \"readrandom,\"\n    \"readseq,\"\n    \"fillrand100K,\"\n    \"fillseq100K,\"\n    \"readseq,\"\n    \"readrand100K,\"\n    ;\n\n// Number of key/values to place in database\nstatic int FLAGS_num = 1000000;\n\n// Number of read operations to do.  If negative, do FLAGS_num reads.\nstatic int FLAGS_reads = -1;\n\n// Size of each value\nstatic int FLAGS_value_size = 100;\n\n// Print histogram of operation timings\nstatic bool FLAGS_histogram = false;\n\n// Arrange to generate values that shrink to this fraction of\n// their original size after compression\nstatic double FLAGS_compression_ratio = 0.5;\n\n// Page size. Default 1 KB.\nstatic int FLAGS_page_size = 1024;\n\n// Number of pages.\n// Default cache size = FLAGS_page_size * FLAGS_num_pages = 4 MB.\nstatic int FLAGS_num_pages = 4096;\n\n// If true, do not destroy the existing database.  If you set this\n// flag and also specify a benchmark that wants a fresh database, that\n// benchmark will fail.\nstatic bool FLAGS_use_existing_db = false;\n\n// If true, we allow batch writes to occur\nstatic bool FLAGS_transaction = true;\n\n// If true, we enable Write-Ahead Logging\nstatic bool FLAGS_WAL_enabled = true;\n\n// Use the db with the following name.\nstatic const char* FLAGS_db = NULL;\n\ninline\nstatic void ExecErrorCheck(int status, char *err_msg) {\n  if (status != SQLITE_OK) {\n    fprintf(stderr, \"SQL error: %s\\n\", err_msg);\n    sqlite3_free(err_msg);\n    exit(1);\n  }\n}\n\ninline\nstatic void StepErrorCheck(int status) {\n  if (status != SQLITE_DONE) {\n    fprintf(stderr, \"SQL step error: status = %d\\n\", status);\n    exit(1);\n  }\n}\n\ninline\nstatic void ErrorCheck(int status) {\n  if (status != SQLITE_OK) {\n    fprintf(stderr, \"sqlite3 error: status = %d\\n\", status);\n    exit(1);\n  }\n}\n\ninline\nstatic void WalCheckpoint(sqlite3* db_) {\n  // Flush all writes to disk\n  if (FLAGS_WAL_enabled) {\n    sqlite3_wal_checkpoint_v2(db_, NULL, SQLITE_CHECKPOINT_FULL, NULL, NULL);\n  }\n}\n\nnamespace leveldb {\n\n// Helper for quickly generating random data.\nnamespace {\nclass RandomGenerator {\n private:\n  std::string data_;\n  int pos_;\n\n public:\n  RandomGenerator() {\n    // We use a limited amount of data over and over again and ensure\n    // that it is larger than the compression window (32KB), and also\n    // large enough to serve all typical value sizes we want to write.\n    Random rnd(301);\n    std::string piece;\n    while (data_.size() < 1048576) {\n      // Add a short fragment that is as compressible as specified\n      // by FLAGS_compression_ratio.\n      test::CompressibleString(&rnd, FLAGS_compression_ratio, 100, &piece);\n      data_.append(piece);\n    }\n    pos_ = 0;\n  }\n\n  Slice Generate(int len) {\n    if (pos_ + len > data_.size()) {\n      pos_ = 0;\n      assert(len < data_.size());\n    }\n    pos_ += len;\n    return Slice(data_.data() + pos_ - len, len);\n  }\n};\n\nstatic Slice TrimSpace(Slice s) {\n  int start = 0;\n  while (start < s.size() && isspace(s[start])) {\n    start++;\n  }\n  int limit = s.size();\n  while (limit > start && isspace(s[limit-1])) {\n    limit--;\n  }\n  return Slice(s.data() + start, limit - start);\n}\n\n}  // namespace\n\nclass Benchmark {\n private:\n  sqlite3* db_;\n  int db_num_;\n  int num_;\n  int reads_;\n  double start_;\n  double last_op_finish_;\n  int64_t bytes_;\n  std::string message_;\n  Histogram hist_;\n  RandomGenerator gen_;\n  Random rand_;\n\n  // State kept for progress messages\n  int done_;\n  int next_report_;     // When to report next\n\n  void PrintHeader() {\n    const int kKeySize = 16;\n    PrintEnvironment();\n    fprintf(stdout, \"Keys:       %d bytes each\\n\", kKeySize);\n    fprintf(stdout, \"Values:     %d bytes each\\n\", FLAGS_value_size);\n    fprintf(stdout, \"Entries:    %d\\n\", num_);\n    fprintf(stdout, \"RawSize:    %.1f MB (estimated)\\n\",\n            ((static_cast<int64_t>(kKeySize + FLAGS_value_size) * num_)\n             / 1048576.0));\n    PrintWarnings();\n    fprintf(stdout, \"------------------------------------------------\\n\");\n  }\n\n  void PrintWarnings() {\n#if defined(__GNUC__) && !defined(__OPTIMIZE__)\n    fprintf(stdout,\n            \"WARNING: Optimization is disabled: benchmarks unnecessarily slow\\n\"\n            );\n#endif\n#ifndef NDEBUG\n    fprintf(stdout,\n            \"WARNING: Assertions are enabled; benchmarks unnecessarily slow\\n\");\n#endif\n  }\n\n  void PrintEnvironment() {\n    fprintf(stderr, \"SQLite:     version %s\\n\", SQLITE_VERSION);\n\n#if defined(__linux)\n    time_t now = time(NULL);\n    fprintf(stderr, \"Date:       %s\", ctime(&now));  // ctime() adds newline\n\n    FILE* cpuinfo = fopen(\"/proc/cpuinfo\", \"r\");\n    if (cpuinfo != NULL) {\n      char line[1000];\n      int num_cpus = 0;\n      std::string cpu_type;\n      std::string cache_size;\n      while (fgets(line, sizeof(line), cpuinfo) != NULL) {\n        const char* sep = strchr(line, ':');\n        if (sep == NULL) {\n          continue;\n        }\n        Slice key = TrimSpace(Slice(line, sep - 1 - line));\n        Slice val = TrimSpace(Slice(sep + 1));\n        if (key == \"model name\") {\n          ++num_cpus;\n          cpu_type = val.ToString();\n        } else if (key == \"cache size\") {\n          cache_size = val.ToString();\n        }\n      }\n      fclose(cpuinfo);\n      fprintf(stderr, \"CPU:        %d * %s\\n\", num_cpus, cpu_type.c_str());\n      fprintf(stderr, \"CPUCache:   %s\\n\", cache_size.c_str());\n    }\n#endif\n  }\n\n  void Start() {\n    start_ = Env::Default()->NowMicros() * 1e-6;\n    bytes_ = 0;\n    message_.clear();\n    last_op_finish_ = start_;\n    hist_.Clear();\n    done_ = 0;\n    next_report_ = 100;\n  }\n\n  void FinishedSingleOp() {\n    if (FLAGS_histogram) {\n      double now = Env::Default()->NowMicros() * 1e-6;\n      double micros = (now - last_op_finish_) * 1e6;\n      hist_.Add(micros);\n      if (micros > 20000) {\n        fprintf(stderr, \"long op: %.1f micros%30s\\r\", micros, \"\");\n        fflush(stderr);\n      }\n      last_op_finish_ = now;\n    }\n\n    done_++;\n    if (done_ >= next_report_) {\n      if      (next_report_ < 1000)   next_report_ += 100;\n      else if (next_report_ < 5000)   next_report_ += 500;\n      else if (next_report_ < 10000)  next_report_ += 1000;\n      else if (next_report_ < 50000)  next_report_ += 5000;\n      else if (next_report_ < 100000) next_report_ += 10000;\n      else if (next_report_ < 500000) next_report_ += 50000;\n      else                            next_report_ += 100000;\n      fprintf(stderr, \"... finished %d ops%30s\\r\", done_, \"\");\n      fflush(stderr);\n    }\n  }\n\n  void Stop(const Slice& name) {\n    double finish = Env::Default()->NowMicros() * 1e-6;\n\n    // Pretend at least one op was done in case we are running a benchmark\n    // that does not call FinishedSingleOp().\n    if (done_ < 1) done_ = 1;\n\n    if (bytes_ > 0) {\n      char rate[100];\n      snprintf(rate, sizeof(rate), \"%6.1f MB/s\",\n               (bytes_ / 1048576.0) / (finish - start_));\n      if (!message_.empty()) {\n        message_  = std::string(rate) + \" \" + message_;\n      } else {\n        message_ = rate;\n      }\n    }\n\n    fprintf(stdout, \"%-12s : %11.3f micros/op;%s%s\\n\",\n            name.ToString().c_str(),\n            (finish - start_) * 1e6 / done_,\n            (message_.empty() ? \"\" : \" \"),\n            message_.c_str());\n    if (FLAGS_histogram) {\n      fprintf(stdout, \"Microseconds per op:\\n%s\\n\", hist_.ToString().c_str());\n    }\n    fflush(stdout);\n  }\n\n public:\n  enum Order {\n    SEQUENTIAL,\n    RANDOM\n  };\n  enum DBState {\n    FRESH,\n    EXISTING\n  };\n\n  Benchmark()\n  : db_(NULL),\n    db_num_(0),\n    num_(FLAGS_num),\n    reads_(FLAGS_reads < 0 ? FLAGS_num : FLAGS_reads),\n    bytes_(0),\n    rand_(301) {\n    std::vector<std::string> files;\n    std::string test_dir;\n    Env::Default()->GetTestDirectory(&test_dir);\n    Env::Default()->GetChildren(test_dir, &files);\n    if (!FLAGS_use_existing_db) {\n      for (int i = 0; i < files.size(); i++) {\n        if (Slice(files[i]).starts_with(\"dbbench_sqlite3\")) {\n          std::string file_name(test_dir);\n          file_name += \"/\";\n          file_name += files[i];\n          Env::Default()->DeleteFile(file_name.c_str());\n        }\n      }\n    }\n  }\n\n  ~Benchmark() {\n    int status = sqlite3_close(db_);\n    ErrorCheck(status);\n  }\n\n  void Run() {\n    PrintHeader();\n    Open();\n\n    const char* benchmarks = FLAGS_benchmarks;\n    while (benchmarks != NULL) {\n      const char* sep = strchr(benchmarks, ',');\n      Slice name;\n      if (sep == NULL) {\n        name = benchmarks;\n        benchmarks = NULL;\n      } else {\n        name = Slice(benchmarks, sep - benchmarks);\n        benchmarks = sep + 1;\n      }\n\n      bytes_ = 0;\n      Start();\n\n      bool known = true;\n      bool write_sync = false;\n      if (name == Slice(\"fillseq\")) {\n        Write(write_sync, SEQUENTIAL, FRESH, num_, FLAGS_value_size, 1);\n        WalCheckpoint(db_);\n      } else if (name == Slice(\"fillseqbatch\")) {\n        Write(write_sync, SEQUENTIAL, FRESH, num_, FLAGS_value_size, 1000);\n        WalCheckpoint(db_);\n      } else if (name == Slice(\"fillrandom\")) {\n        Write(write_sync, RANDOM, FRESH, num_, FLAGS_value_size, 1);\n        WalCheckpoint(db_);\n      } else if (name == Slice(\"fillrandbatch\")) {\n        Write(write_sync, RANDOM, FRESH, num_, FLAGS_value_size, 1000);\n        WalCheckpoint(db_);\n      } else if (name == Slice(\"overwrite\")) {\n        Write(write_sync, RANDOM, EXISTING, num_, FLAGS_value_size, 1);\n        WalCheckpoint(db_);\n      } else if (name == Slice(\"overwritebatch\")) {\n        Write(write_sync, RANDOM, EXISTING, num_, FLAGS_value_size, 1000);\n        WalCheckpoint(db_);\n      } else if (name == Slice(\"fillrandsync\")) {\n        write_sync = true;\n        Write(write_sync, RANDOM, FRESH, num_ / 100, FLAGS_value_size, 1);\n        WalCheckpoint(db_);\n      } else if (name == Slice(\"fillseqsync\")) {\n        write_sync = true;\n        Write(write_sync, SEQUENTIAL, FRESH, num_ / 100, FLAGS_value_size, 1);\n        WalCheckpoint(db_);\n      } else if (name == Slice(\"fillrand100K\")) {\n        Write(write_sync, RANDOM, FRESH, num_ / 1000, 100 * 1000, 1);\n        WalCheckpoint(db_);\n      } else if (name == Slice(\"fillseq100K\")) {\n        Write(write_sync, SEQUENTIAL, FRESH, num_ / 1000, 100 * 1000, 1);\n        WalCheckpoint(db_);\n      } else if (name == Slice(\"readseq\")) {\n        ReadSequential();\n      } else if (name == Slice(\"readrandom\")) {\n        Read(RANDOM, 1);\n      } else if (name == Slice(\"readrand100K\")) {\n        int n = reads_;\n        reads_ /= 1000;\n        Read(RANDOM, 1);\n        reads_ = n;\n      } else {\n        known = false;\n        if (name != Slice()) {  // No error message for empty name\n          fprintf(stderr, \"unknown benchmark '%s'\\n\", name.ToString().c_str());\n        }\n      }\n      if (known) {\n        Stop(name);\n      }\n    }\n  }\n\n  void Open() {\n    assert(db_ == NULL);\n\n    int status;\n    char file_name[100];\n    char* err_msg = NULL;\n    db_num_++;\n\n    // Open database\n    std::string tmp_dir;\n    Env::Default()->GetTestDirectory(&tmp_dir);\n    snprintf(file_name, sizeof(file_name),\n             \"%s/dbbench_sqlite3-%d.db\",\n             tmp_dir.c_str(),\n             db_num_);\n    status = sqlite3_open(file_name, &db_);\n    if (status) {\n      fprintf(stderr, \"open error: %s\\n\", sqlite3_errmsg(db_));\n      exit(1);\n    }\n\n    // Change SQLite cache size\n    char cache_size[100];\n    snprintf(cache_size, sizeof(cache_size), \"PRAGMA cache_size = %d\",\n             FLAGS_num_pages);\n    status = sqlite3_exec(db_, cache_size, NULL, NULL, &err_msg);\n    ExecErrorCheck(status, err_msg);\n\n    // FLAGS_page_size is defaulted to 1024\n    if (FLAGS_page_size != 1024) {\n      char page_size[100];\n      snprintf(page_size, sizeof(page_size), \"PRAGMA page_size = %d\",\n               FLAGS_page_size);\n      status = sqlite3_exec(db_, page_size, NULL, NULL, &err_msg);\n      ExecErrorCheck(status, err_msg);\n    }\n\n    // Change journal mode to WAL if WAL enabled flag is on\n    if (FLAGS_WAL_enabled) {\n      std::string WAL_stmt = \"PRAGMA journal_mode = WAL\";\n\n      // LevelDB's default cache size is a combined 4 MB\n      std::string WAL_checkpoint = \"PRAGMA wal_autocheckpoint = 4096\";\n      status = sqlite3_exec(db_, WAL_stmt.c_str(), NULL, NULL, &err_msg);\n      ExecErrorCheck(status, err_msg);\n      status = sqlite3_exec(db_, WAL_checkpoint.c_str(), NULL, NULL, &err_msg);\n      ExecErrorCheck(status, err_msg);\n    }\n\n    // Change locking mode to exclusive and create tables/index for database\n    std::string locking_stmt = \"PRAGMA locking_mode = EXCLUSIVE\";\n    std::string create_stmt =\n          \"CREATE TABLE test (key blob, value blob, PRIMARY KEY(key))\";\n    std::string stmt_array[] = { locking_stmt, create_stmt };\n    int stmt_array_length = sizeof(stmt_array) / sizeof(std::string);\n    for (int i = 0; i < stmt_array_length; i++) {\n      status = sqlite3_exec(db_, stmt_array[i].c_str(), NULL, NULL, &err_msg);\n      ExecErrorCheck(status, err_msg);\n    }\n  }\n\n  void Write(bool write_sync, Order order, DBState state,\n             int num_entries, int value_size, int entries_per_batch) {\n    // Create new database if state == FRESH\n    if (state == FRESH) {\n      if (FLAGS_use_existing_db) {\n        message_ = \"skipping (--use_existing_db is true)\";\n        return;\n      }\n      sqlite3_close(db_);\n      db_ = NULL;\n      Open();\n      Start();\n    }\n\n    if (num_entries != num_) {\n      char msg[100];\n      snprintf(msg, sizeof(msg), \"(%d ops)\", num_entries);\n      message_ = msg;\n    }\n\n    char* err_msg = NULL;\n    int status;\n\n    sqlite3_stmt *replace_stmt, *begin_trans_stmt, *end_trans_stmt;\n    std::string replace_str = \"REPLACE INTO test (key, value) VALUES (?, ?)\";\n    std::string begin_trans_str = \"BEGIN TRANSACTION;\";\n    std::string end_trans_str = \"END TRANSACTION;\";\n\n    // Check for synchronous flag in options\n    std::string sync_stmt = (write_sync) ? \"PRAGMA synchronous = FULL\" :\n                                           \"PRAGMA synchronous = OFF\";\n    status = sqlite3_exec(db_, sync_stmt.c_str(), NULL, NULL, &err_msg);\n    ExecErrorCheck(status, err_msg);\n\n    // Preparing sqlite3 statements\n    status = sqlite3_prepare_v2(db_, replace_str.c_str(), -1,\n                                &replace_stmt, NULL);\n    ErrorCheck(status);\n    status = sqlite3_prepare_v2(db_, begin_trans_str.c_str(), -1,\n                                &begin_trans_stmt, NULL);\n    ErrorCheck(status);\n    status = sqlite3_prepare_v2(db_, end_trans_str.c_str(), -1,\n                                &end_trans_stmt, NULL);\n    ErrorCheck(status);\n\n    bool transaction = (entries_per_batch > 1);\n    for (int i = 0; i < num_entries; i += entries_per_batch) {\n      // Begin write transaction\n      if (FLAGS_transaction && transaction) {\n        status = sqlite3_step(begin_trans_stmt);\n        StepErrorCheck(status);\n        status = sqlite3_reset(begin_trans_stmt);\n        ErrorCheck(status);\n      }\n\n      // Create and execute SQL statements\n      for (int j = 0; j < entries_per_batch; j++) {\n        const char* value = gen_.Generate(value_size).data();\n\n        // Create values for key-value pair\n        const int k = (order == SEQUENTIAL) ? i + j :\n                      (rand_.Next() % num_entries);\n        char key[100];\n        snprintf(key, sizeof(key), \"%016d\", k);\n\n        // Bind KV values into replace_stmt\n        status = sqlite3_bind_blob(replace_stmt, 1, key, 16, SQLITE_STATIC);\n        ErrorCheck(status);\n        status = sqlite3_bind_blob(replace_stmt, 2, value,\n                                   value_size, SQLITE_STATIC);\n        ErrorCheck(status);\n\n        // Execute replace_stmt\n        bytes_ += value_size + strlen(key);\n        status = sqlite3_step(replace_stmt);\n        StepErrorCheck(status);\n\n        // Reset SQLite statement for another use\n        status = sqlite3_clear_bindings(replace_stmt);\n        ErrorCheck(status);\n        status = sqlite3_reset(replace_stmt);\n        ErrorCheck(status);\n\n        FinishedSingleOp();\n      }\n\n      // End write transaction\n      if (FLAGS_transaction && transaction) {\n        status = sqlite3_step(end_trans_stmt);\n        StepErrorCheck(status);\n        status = sqlite3_reset(end_trans_stmt);\n        ErrorCheck(status);\n      }\n    }\n\n    status = sqlite3_finalize(replace_stmt);\n    ErrorCheck(status);\n    status = sqlite3_finalize(begin_trans_stmt);\n    ErrorCheck(status);\n    status = sqlite3_finalize(end_trans_stmt);\n    ErrorCheck(status);\n  }\n\n  void Read(Order order, int entries_per_batch) {\n    int status;\n    sqlite3_stmt *read_stmt, *begin_trans_stmt, *end_trans_stmt;\n\n    std::string read_str = \"SELECT * FROM test WHERE key = ?\";\n    std::string begin_trans_str = \"BEGIN TRANSACTION;\";\n    std::string end_trans_str = \"END TRANSACTION;\";\n\n    // Preparing sqlite3 statements\n    status = sqlite3_prepare_v2(db_, begin_trans_str.c_str(), -1,\n                                &begin_trans_stmt, NULL);\n    ErrorCheck(status);\n    status = sqlite3_prepare_v2(db_, end_trans_str.c_str(), -1,\n                                &end_trans_stmt, NULL);\n    ErrorCheck(status);\n    status = sqlite3_prepare_v2(db_, read_str.c_str(), -1, &read_stmt, NULL);\n    ErrorCheck(status);\n\n    bool transaction = (entries_per_batch > 1);\n    for (int i = 0; i < reads_; i += entries_per_batch) {\n      // Begin read transaction\n      if (FLAGS_transaction && transaction) {\n        status = sqlite3_step(begin_trans_stmt);\n        StepErrorCheck(status);\n        status = sqlite3_reset(begin_trans_stmt);\n        ErrorCheck(status);\n      }\n\n      // Create and execute SQL statements\n      for (int j = 0; j < entries_per_batch; j++) {\n        // Create key value\n        char key[100];\n        int k = (order == SEQUENTIAL) ? i + j : (rand_.Next() % reads_);\n        snprintf(key, sizeof(key), \"%016d\", k);\n\n        // Bind key value into read_stmt\n        status = sqlite3_bind_blob(read_stmt, 1, key, 16, SQLITE_STATIC);\n        ErrorCheck(status);\n\n        // Execute read statement\n        while ((status = sqlite3_step(read_stmt)) == SQLITE_ROW) {}\n        StepErrorCheck(status);\n\n        // Reset SQLite statement for another use\n        status = sqlite3_clear_bindings(read_stmt);\n        ErrorCheck(status);\n        status = sqlite3_reset(read_stmt);\n        ErrorCheck(status);\n        FinishedSingleOp();\n      }\n\n      // End read transaction\n      if (FLAGS_transaction && transaction) {\n        status = sqlite3_step(end_trans_stmt);\n        StepErrorCheck(status);\n        status = sqlite3_reset(end_trans_stmt);\n        ErrorCheck(status);\n      }\n    }\n\n    status = sqlite3_finalize(read_stmt);\n    ErrorCheck(status);\n    status = sqlite3_finalize(begin_trans_stmt);\n    ErrorCheck(status);\n    status = sqlite3_finalize(end_trans_stmt);\n    ErrorCheck(status);\n  }\n\n  void ReadSequential() {\n    int status;\n    sqlite3_stmt *pStmt;\n    std::string read_str = \"SELECT * FROM test ORDER BY key\";\n\n    status = sqlite3_prepare_v2(db_, read_str.c_str(), -1, &pStmt, NULL);\n    ErrorCheck(status);\n    for (int i = 0; i < reads_ && SQLITE_ROW == sqlite3_step(pStmt); i++) {\n      bytes_ += sqlite3_column_bytes(pStmt, 1) + sqlite3_column_bytes(pStmt, 2);\n      FinishedSingleOp();\n    }\n\n    status = sqlite3_finalize(pStmt);\n    ErrorCheck(status);\n  }\n\n};\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  std::string default_db_path;\n  for (int i = 1; i < argc; i++) {\n    double d;\n    int n;\n    char junk;\n    if (leveldb::Slice(argv[i]).starts_with(\"--benchmarks=\")) {\n      FLAGS_benchmarks = argv[i] + strlen(\"--benchmarks=\");\n    } else if (sscanf(argv[i], \"--histogram=%d%c\", &n, &junk) == 1 &&\n               (n == 0 || n == 1)) {\n      FLAGS_histogram = n;\n    } else if (sscanf(argv[i], \"--compression_ratio=%lf%c\", &d, &junk) == 1) {\n      FLAGS_compression_ratio = d;\n    } else if (sscanf(argv[i], \"--use_existing_db=%d%c\", &n, &junk) == 1 &&\n               (n == 0 || n == 1)) {\n      FLAGS_use_existing_db = n;\n    } else if (sscanf(argv[i], \"--num=%d%c\", &n, &junk) == 1) {\n      FLAGS_num = n;\n    } else if (sscanf(argv[i], \"--reads=%d%c\", &n, &junk) == 1) {\n      FLAGS_reads = n;\n    } else if (sscanf(argv[i], \"--value_size=%d%c\", &n, &junk) == 1) {\n      FLAGS_value_size = n;\n    } else if (leveldb::Slice(argv[i]) == leveldb::Slice(\"--no_transaction\")) {\n      FLAGS_transaction = false;\n    } else if (sscanf(argv[i], \"--page_size=%d%c\", &n, &junk) == 1) {\n      FLAGS_page_size = n;\n    } else if (sscanf(argv[i], \"--num_pages=%d%c\", &n, &junk) == 1) {\n      FLAGS_num_pages = n;\n    } else if (sscanf(argv[i], \"--WAL_enabled=%d%c\", &n, &junk) == 1 &&\n               (n == 0 || n == 1)) {\n      FLAGS_WAL_enabled = n;\n    } else if (strncmp(argv[i], \"--db=\", 5) == 0) {\n      FLAGS_db = argv[i] + 5;\n    } else {\n      fprintf(stderr, \"Invalid flag '%s'\\n\", argv[i]);\n      exit(1);\n    }\n  }\n\n  // Choose a location for the test database if none given with --db=<path>\n  if (FLAGS_db == NULL) {\n      leveldb::Env::Default()->GetTestDirectory(&default_db_path);\n      default_db_path += \"/dbbench\";\n      FLAGS_db = default_db_path.c_str();\n  }\n\n  leveldb::Benchmark benchmark;\n  benchmark.Run();\n  return 0;\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/doc/bench/db_bench_tree_db.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <kcpolydb.h>\n#include \"util/histogram.h\"\n#include \"util/random.h\"\n#include \"util/testutil.h\"\n\n// Comma-separated list of operations to run in the specified order\n//   Actual benchmarks:\n//\n//   fillseq       -- write N values in sequential key order in async mode\n//   fillrandom    -- write N values in random key order in async mode\n//   overwrite     -- overwrite N values in random key order in async mode\n//   fillseqsync   -- write N/100 values in sequential key order in sync mode\n//   fillrandsync  -- write N/100 values in random key order in sync mode\n//   fillrand100K  -- write N/1000 100K values in random order in async mode\n//   fillseq100K   -- write N/1000 100K values in seq order in async mode\n//   readseq       -- read N times sequentially\n//   readseq100K   -- read N/1000 100K values in sequential order in async mode\n//   readrand100K  -- read N/1000 100K values in sequential order in async mode\n//   readrandom    -- read N times in random order\nstatic const char* FLAGS_benchmarks =\n    \"fillseq,\"\n    \"fillseqsync,\"\n    \"fillrandsync,\"\n    \"fillrandom,\"\n    \"overwrite,\"\n    \"readrandom,\"\n    \"readseq,\"\n    \"fillrand100K,\"\n    \"fillseq100K,\"\n    \"readseq100K,\"\n    \"readrand100K,\"\n    ;\n\n// Number of key/values to place in database\nstatic int FLAGS_num = 1000000;\n\n// Number of read operations to do.  If negative, do FLAGS_num reads.\nstatic int FLAGS_reads = -1;\n\n// Size of each value\nstatic int FLAGS_value_size = 100;\n\n// Arrange to generate values that shrink to this fraction of\n// their original size after compression\nstatic double FLAGS_compression_ratio = 0.5;\n\n// Print histogram of operation timings\nstatic bool FLAGS_histogram = false;\n\n// Cache size. Default 4 MB\nstatic int FLAGS_cache_size = 4194304;\n\n// Page size. Default 1 KB\nstatic int FLAGS_page_size = 1024;\n\n// If true, do not destroy the existing database.  If you set this\n// flag and also specify a benchmark that wants a fresh database, that\n// benchmark will fail.\nstatic bool FLAGS_use_existing_db = false;\n\n// Compression flag. If true, compression is on. If false, compression\n// is off.\nstatic bool FLAGS_compression = true;\n\n// Use the db with the following name.\nstatic const char* FLAGS_db = NULL;\n\ninline\nstatic void DBSynchronize(kyotocabinet::TreeDB* db_)\n{\n  // Synchronize will flush writes to disk\n  if (!db_->synchronize()) {\n    fprintf(stderr, \"synchronize error: %s\\n\", db_->error().name());\n  }\n}\n\nnamespace leveldb {\n\n// Helper for quickly generating random data.\nnamespace {\nclass RandomGenerator {\n private:\n  std::string data_;\n  int pos_;\n\n public:\n  RandomGenerator() {\n    // We use a limited amount of data over and over again and ensure\n    // that it is larger than the compression window (32KB), and also\n    // large enough to serve all typical value sizes we want to write.\n    Random rnd(301);\n    std::string piece;\n    while (data_.size() < 1048576) {\n      // Add a short fragment that is as compressible as specified\n      // by FLAGS_compression_ratio.\n      test::CompressibleString(&rnd, FLAGS_compression_ratio, 100, &piece);\n      data_.append(piece);\n    }\n    pos_ = 0;\n  }\n\n  Slice Generate(int len) {\n    if (pos_ + len > data_.size()) {\n      pos_ = 0;\n      assert(len < data_.size());\n    }\n    pos_ += len;\n    return Slice(data_.data() + pos_ - len, len);\n  }\n};\n\nstatic Slice TrimSpace(Slice s) {\n  int start = 0;\n  while (start < s.size() && isspace(s[start])) {\n    start++;\n  }\n  int limit = s.size();\n  while (limit > start && isspace(s[limit-1])) {\n    limit--;\n  }\n  return Slice(s.data() + start, limit - start);\n}\n\n}  // namespace\n\nclass Benchmark {\n private:\n  kyotocabinet::TreeDB* db_;\n  int db_num_;\n  int num_;\n  int reads_;\n  double start_;\n  double last_op_finish_;\n  int64_t bytes_;\n  std::string message_;\n  Histogram hist_;\n  RandomGenerator gen_;\n  Random rand_;\n  kyotocabinet::LZOCompressor<kyotocabinet::LZO::RAW> comp_;\n\n  // State kept for progress messages\n  int done_;\n  int next_report_;     // When to report next\n\n  void PrintHeader() {\n    const int kKeySize = 16;\n    PrintEnvironment();\n    fprintf(stdout, \"Keys:       %d bytes each\\n\", kKeySize);\n    fprintf(stdout, \"Values:     %d bytes each (%d bytes after compression)\\n\",\n            FLAGS_value_size,\n            static_cast<int>(FLAGS_value_size * FLAGS_compression_ratio + 0.5));\n    fprintf(stdout, \"Entries:    %d\\n\", num_);\n    fprintf(stdout, \"RawSize:    %.1f MB (estimated)\\n\",\n            ((static_cast<int64_t>(kKeySize + FLAGS_value_size) * num_)\n             / 1048576.0));\n    fprintf(stdout, \"FileSize:   %.1f MB (estimated)\\n\",\n            (((kKeySize + FLAGS_value_size * FLAGS_compression_ratio) * num_)\n             / 1048576.0));\n    PrintWarnings();\n    fprintf(stdout, \"------------------------------------------------\\n\");\n  }\n\n  void PrintWarnings() {\n#if defined(__GNUC__) && !defined(__OPTIMIZE__)\n    fprintf(stdout,\n            \"WARNING: Optimization is disabled: benchmarks unnecessarily slow\\n\"\n            );\n#endif\n#ifndef NDEBUG\n    fprintf(stdout,\n            \"WARNING: Assertions are enabled; benchmarks unnecessarily slow\\n\");\n#endif\n  }\n\n  void PrintEnvironment() {\n    fprintf(stderr, \"Kyoto Cabinet:    version %s, lib ver %d, lib rev %d\\n\",\n            kyotocabinet::VERSION, kyotocabinet::LIBVER, kyotocabinet::LIBREV);\n\n#if defined(__linux)\n    time_t now = time(NULL);\n    fprintf(stderr, \"Date:           %s\", ctime(&now));  // ctime() adds newline\n\n    FILE* cpuinfo = fopen(\"/proc/cpuinfo\", \"r\");\n    if (cpuinfo != NULL) {\n      char line[1000];\n      int num_cpus = 0;\n      std::string cpu_type;\n      std::string cache_size;\n      while (fgets(line, sizeof(line), cpuinfo) != NULL) {\n        const char* sep = strchr(line, ':');\n        if (sep == NULL) {\n          continue;\n        }\n        Slice key = TrimSpace(Slice(line, sep - 1 - line));\n        Slice val = TrimSpace(Slice(sep + 1));\n        if (key == \"model name\") {\n          ++num_cpus;\n          cpu_type = val.ToString();\n        } else if (key == \"cache size\") {\n          cache_size = val.ToString();\n        }\n      }\n      fclose(cpuinfo);\n      fprintf(stderr, \"CPU:            %d * %s\\n\", num_cpus, cpu_type.c_str());\n      fprintf(stderr, \"CPUCache:       %s\\n\", cache_size.c_str());\n    }\n#endif\n  }\n\n  void Start() {\n    start_ = Env::Default()->NowMicros() * 1e-6;\n    bytes_ = 0;\n    message_.clear();\n    last_op_finish_ = start_;\n    hist_.Clear();\n    done_ = 0;\n    next_report_ = 100;\n  }\n\n  void FinishedSingleOp() {\n    if (FLAGS_histogram) {\n      double now = Env::Default()->NowMicros() * 1e-6;\n      double micros = (now - last_op_finish_) * 1e6;\n      hist_.Add(micros);\n      if (micros > 20000) {\n        fprintf(stderr, \"long op: %.1f micros%30s\\r\", micros, \"\");\n        fflush(stderr);\n      }\n      last_op_finish_ = now;\n    }\n\n    done_++;\n    if (done_ >= next_report_) {\n      if      (next_report_ < 1000)   next_report_ += 100;\n      else if (next_report_ < 5000)   next_report_ += 500;\n      else if (next_report_ < 10000)  next_report_ += 1000;\n      else if (next_report_ < 50000)  next_report_ += 5000;\n      else if (next_report_ < 100000) next_report_ += 10000;\n      else if (next_report_ < 500000) next_report_ += 50000;\n      else                            next_report_ += 100000;\n      fprintf(stderr, \"... finished %d ops%30s\\r\", done_, \"\");\n      fflush(stderr);\n    }\n  }\n\n  void Stop(const Slice& name) {\n    double finish = Env::Default()->NowMicros() * 1e-6;\n\n    // Pretend at least one op was done in case we are running a benchmark\n    // that does not call FinishedSingleOp().\n    if (done_ < 1) done_ = 1;\n\n    if (bytes_ > 0) {\n      char rate[100];\n      snprintf(rate, sizeof(rate), \"%6.1f MB/s\",\n               (bytes_ / 1048576.0) / (finish - start_));\n      if (!message_.empty()) {\n        message_  = std::string(rate) + \" \" + message_;\n      } else {\n        message_ = rate;\n      }\n    }\n\n    fprintf(stdout, \"%-12s : %11.3f micros/op;%s%s\\n\",\n            name.ToString().c_str(),\n            (finish - start_) * 1e6 / done_,\n            (message_.empty() ? \"\" : \" \"),\n            message_.c_str());\n    if (FLAGS_histogram) {\n      fprintf(stdout, \"Microseconds per op:\\n%s\\n\", hist_.ToString().c_str());\n    }\n    fflush(stdout);\n  }\n\n public:\n  enum Order {\n    SEQUENTIAL,\n    RANDOM\n  };\n  enum DBState {\n    FRESH,\n    EXISTING\n  };\n\n  Benchmark()\n  : db_(NULL),\n    num_(FLAGS_num),\n    reads_(FLAGS_reads < 0 ? FLAGS_num : FLAGS_reads),\n    bytes_(0),\n    rand_(301) {\n    std::vector<std::string> files;\n    std::string test_dir;\n    Env::Default()->GetTestDirectory(&test_dir);\n    Env::Default()->GetChildren(test_dir.c_str(), &files);\n    if (!FLAGS_use_existing_db) {\n      for (int i = 0; i < files.size(); i++) {\n        if (Slice(files[i]).starts_with(\"dbbench_polyDB\")) {\n          std::string file_name(test_dir);\n          file_name += \"/\";\n          file_name += files[i];\n          Env::Default()->DeleteFile(file_name.c_str());\n        }\n      }\n    }\n  }\n\n  ~Benchmark() {\n    if (!db_->close()) {\n      fprintf(stderr, \"close error: %s\\n\", db_->error().name());\n    }\n  }\n\n  void Run() {\n    PrintHeader();\n    Open(false);\n\n    const char* benchmarks = FLAGS_benchmarks;\n    while (benchmarks != NULL) {\n      const char* sep = strchr(benchmarks, ',');\n      Slice name;\n      if (sep == NULL) {\n        name = benchmarks;\n        benchmarks = NULL;\n      } else {\n        name = Slice(benchmarks, sep - benchmarks);\n        benchmarks = sep + 1;\n      }\n\n      Start();\n\n      bool known = true;\n      bool write_sync = false;\n      if (name == Slice(\"fillseq\")) {\n        Write(write_sync, SEQUENTIAL, FRESH, num_, FLAGS_value_size, 1);\n        DBSynchronize(db_);\n      } else if (name == Slice(\"fillrandom\")) {\n        Write(write_sync, RANDOM, FRESH, num_, FLAGS_value_size, 1);\n        DBSynchronize(db_);\n      } else if (name == Slice(\"overwrite\")) {\n        Write(write_sync, RANDOM, EXISTING, num_, FLAGS_value_size, 1);\n        DBSynchronize(db_);\n      } else if (name == Slice(\"fillrandsync\")) {\n        write_sync = true;\n        Write(write_sync, RANDOM, FRESH, num_ / 100, FLAGS_value_size, 1);\n        DBSynchronize(db_);\n      } else if (name == Slice(\"fillseqsync\")) {\n        write_sync = true;\n        Write(write_sync, SEQUENTIAL, FRESH, num_ / 100, FLAGS_value_size, 1);\n        DBSynchronize(db_);\n      } else if (name == Slice(\"fillrand100K\")) {\n        Write(write_sync, RANDOM, FRESH, num_ / 1000, 100 * 1000, 1);\n        DBSynchronize(db_);\n      } else if (name == Slice(\"fillseq100K\")) {\n        Write(write_sync, SEQUENTIAL, FRESH, num_ / 1000, 100 * 1000, 1);\n        DBSynchronize(db_);\n      } else if (name == Slice(\"readseq\")) {\n        ReadSequential();\n      } else if (name == Slice(\"readrandom\")) {\n        ReadRandom();\n      } else if (name == Slice(\"readrand100K\")) {\n        int n = reads_;\n        reads_ /= 1000;\n        ReadRandom();\n        reads_ = n;\n      } else if (name == Slice(\"readseq100K\")) {\n        int n = reads_;\n        reads_ /= 1000;\n        ReadSequential();\n        reads_ = n;\n      } else {\n        known = false;\n        if (name != Slice()) {  // No error message for empty name\n          fprintf(stderr, \"unknown benchmark '%s'\\n\", name.ToString().c_str());\n        }\n      }\n      if (known) {\n        Stop(name);\n      }\n    }\n  }\n\n private:\n    void Open(bool sync) {\n    assert(db_ == NULL);\n\n    // Initialize db_\n    db_ = new kyotocabinet::TreeDB();\n    char file_name[100];\n    db_num_++;\n    std::string test_dir;\n    Env::Default()->GetTestDirectory(&test_dir);\n    snprintf(file_name, sizeof(file_name),\n             \"%s/dbbench_polyDB-%d.kct\",\n             test_dir.c_str(),\n             db_num_);\n\n    // Create tuning options and open the database\n    int open_options = kyotocabinet::PolyDB::OWRITER |\n                       kyotocabinet::PolyDB::OCREATE;\n    int tune_options = kyotocabinet::TreeDB::TSMALL |\n        kyotocabinet::TreeDB::TLINEAR;\n    if (FLAGS_compression) {\n      tune_options |= kyotocabinet::TreeDB::TCOMPRESS;\n      db_->tune_compressor(&comp_);\n    }\n    db_->tune_options(tune_options);\n    db_->tune_page_cache(FLAGS_cache_size);\n    db_->tune_page(FLAGS_page_size);\n    db_->tune_map(256LL<<20);\n    if (sync) {\n      open_options |= kyotocabinet::PolyDB::OAUTOSYNC;\n    }\n    if (!db_->open(file_name, open_options)) {\n      fprintf(stderr, \"open error: %s\\n\", db_->error().name());\n    }\n  }\n\n  void Write(bool sync, Order order, DBState state,\n             int num_entries, int value_size, int entries_per_batch) {\n    // Create new database if state == FRESH\n    if (state == FRESH) {\n      if (FLAGS_use_existing_db) {\n        message_ = \"skipping (--use_existing_db is true)\";\n        return;\n      }\n      delete db_;\n      db_ = NULL;\n      Open(sync);\n      Start();  // Do not count time taken to destroy/open\n    }\n\n    if (num_entries != num_) {\n      char msg[100];\n      snprintf(msg, sizeof(msg), \"(%d ops)\", num_entries);\n      message_ = msg;\n    }\n\n    // Write to database\n    for (int i = 0; i < num_entries; i++)\n    {\n      const int k = (order == SEQUENTIAL) ? i : (rand_.Next() % num_entries);\n      char key[100];\n      snprintf(key, sizeof(key), \"%016d\", k);\n      bytes_ += value_size + strlen(key);\n      std::string cpp_key = key;\n      if (!db_->set(cpp_key, gen_.Generate(value_size).ToString())) {\n        fprintf(stderr, \"set error: %s\\n\", db_->error().name());\n      }\n      FinishedSingleOp();\n    }\n  }\n\n  void ReadSequential() {\n    kyotocabinet::DB::Cursor* cur = db_->cursor();\n    cur->jump();\n    std::string ckey, cvalue;\n    while (cur->get(&ckey, &cvalue, true)) {\n      bytes_ += ckey.size() + cvalue.size();\n      FinishedSingleOp();\n    }\n    delete cur;\n  }\n\n  void ReadRandom() {\n    std::string value;\n    for (int i = 0; i < reads_; i++) {\n      char key[100];\n      const int k = rand_.Next() % reads_;\n      snprintf(key, sizeof(key), \"%016d\", k);\n      db_->get(key, &value);\n      FinishedSingleOp();\n    }\n  }\n};\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  std::string default_db_path;\n  for (int i = 1; i < argc; i++) {\n    double d;\n    int n;\n    char junk;\n    if (leveldb::Slice(argv[i]).starts_with(\"--benchmarks=\")) {\n      FLAGS_benchmarks = argv[i] + strlen(\"--benchmarks=\");\n    } else if (sscanf(argv[i], \"--compression_ratio=%lf%c\", &d, &junk) == 1) {\n      FLAGS_compression_ratio = d;\n    } else if (sscanf(argv[i], \"--histogram=%d%c\", &n, &junk) == 1 &&\n               (n == 0 || n == 1)) {\n      FLAGS_histogram = n;\n    } else if (sscanf(argv[i], \"--num=%d%c\", &n, &junk) == 1) {\n      FLAGS_num = n;\n    } else if (sscanf(argv[i], \"--reads=%d%c\", &n, &junk) == 1) {\n      FLAGS_reads = n;\n    } else if (sscanf(argv[i], \"--value_size=%d%c\", &n, &junk) == 1) {\n      FLAGS_value_size = n;\n    } else if (sscanf(argv[i], \"--cache_size=%d%c\", &n, &junk) == 1) {\n      FLAGS_cache_size = n;\n    } else if (sscanf(argv[i], \"--page_size=%d%c\", &n, &junk) == 1) {\n      FLAGS_page_size = n;\n    } else if (sscanf(argv[i], \"--compression=%d%c\", &n, &junk) == 1 &&\n               (n == 0 || n == 1)) {\n      FLAGS_compression = (n == 1) ? true : false;\n    } else if (strncmp(argv[i], \"--db=\", 5) == 0) {\n      FLAGS_db = argv[i] + 5;\n    } else {\n      fprintf(stderr, \"Invalid flag '%s'\\n\", argv[i]);\n      exit(1);\n    }\n  }\n\n  // Choose a location for the test database if none given with --db=<path>\n  if (FLAGS_db == NULL) {\n      leveldb::Env::Default()->GetTestDirectory(&default_db_path);\n      default_db_path += \"/dbbench\";\n      FLAGS_db = default_db_path.c_str();\n  }\n\n  leveldb::Benchmark benchmark;\n  benchmark.Run();\n  return 0;\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/doc/benchmark.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>LevelDB Benchmarks</title>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n<style>\nbody {\n  font-family:Helvetica,sans-serif;\n  padding:20px;\n}\n\nh2 {\n  padding-top:30px;\n}\n\ntable.bn {\n  width:800px;\n  border-collapse:collapse;\n  border:0;\n  padding:0;\n}\n\ntable.bnbase {\n  width:650px;\n}\n\ntable.bn td {\n  padding:2px 0;\n}\n\ntable.bn td.c1 {\n  font-weight:bold;\n  width:150px;\n}\n\ntable.bn td.c1 div.e {\n  float:right;\n  font-weight:normal;\n}\n\ntable.bn td.c2 {\n  width:150px;\n  text-align:right;\n  padding:2px;\n}\n\ntable.bn td.c3 {\n  width:350px;\n}\n\ntable.bn td.c4 {\n  width:150px;\n  font-size:small;\n  padding-left:4px;\n}\n\n/* chart bars */\ndiv.bldb {\n  background-color:#0255df;\n}\n\ndiv.bkct {\n  background-color:#df5555;\n}\n\ndiv.bsql {\n  background-color:#aadf55;\n}\n\n.code {\n  font-family:monospace;\n  font-size:large;\n}\n\n.todo {\n  color: red;\n}\n\n</style>\n</head>\n<body>\n<h1>LevelDB Benchmarks</h1>\n<p>Google, July 2011</p>\n<hr>\n\n<p>In order to test LevelDB's performance, we benchmark it against other well-established database implementations. We compare LevelDB (revision 39) against <a href=\"http://www.sqlite.org/\">SQLite3</a> (version 3.7.6.3) and <a href=\"http://fallabs.com/kyotocabinet/spex.html\">Kyoto Cabinet's</a> (version 1.2.67) TreeDB (a B+Tree based key-value store). We would like to acknowledge Scott Hess and Mikio Hirabayashi for their suggestions and contributions to the SQLite3 and Kyoto Cabinet benchmarks, respectively.</p>\n\n<p>Benchmarks were all performed on a six-core Intel(R) Xeon(R) CPU X5650 @ 2.67GHz, with 12288 KB of total L3 cache and 12 GB of DDR3 RAM at 1333 MHz. (Note that LevelDB uses at most two CPUs since the benchmarks are single threaded: one to run the benchmark, and one for background compactions.) We ran the benchmarks on two machines (with identical processors), one with an Ext3 file system and one with an Ext4 file system. The machine with the Ext3 file system has a SATA Hitachi HDS721050CLA362 hard drive. The machine with the Ext4 file system has a SATA Samsung HD502HJ hard drive. Both hard drives spin at 7200 RPM and have hard drive write-caching enabled (using `hdparm -W 1 [device]`). The numbers reported below are the median of three measurements.</p>\n\n<h4>Benchmark Source Code</h4>\n<p>We wrote benchmark tools for SQLite and Kyoto TreeDB based on LevelDB's <span class=\"code\">db_bench</span>. The code for each of the benchmarks resides here:</p>\n<ul>\n\t<li> <b>LevelDB:</b> <a href=\"http://code.google.com/p/leveldb/source/browse/trunk/db/db_bench.cc\">db/db_bench.cc</a>.</li>\n\t<li> <b>SQLite:</b> <a href=\"http://code.google.com/p/leveldb/source/browse/#svn%2Ftrunk%2Fdoc%2Fbench%2Fdb_bench_sqlite3.cc\">doc/bench/db_bench_sqlite3.cc</a>.</li>\n\t<li> <b>Kyoto TreeDB:</b> <a href=\"http://code.google.com/p/leveldb/source/browse/#svn%2Ftrunk%2Fdoc%2Fbench%2Fdb_bench_tree_db.cc\">doc/bench/db_bench_tree_db.cc</a>.</li>\n</ul>\n\n<h4>Custom Build Specifications</h4>\n<ul>\n<li>LevelDB: LevelDB was compiled with the <a href=\"http://code.google.com/p/google-perftools\">tcmalloc</a> library and the <a href=\"http://code.google.com/p/snappy/\">Snappy</a> compression library (revision 33).  Assertions were disabled.</li>\n<li>TreeDB: TreeDB was compiled using the <a href=\"http://www.oberhumer.com/opensource/lzo/\">LZO</a> compression library (version 2.03). Furthermore, we enabled the TSMALL and TLINEAR options when opening the database in order to reduce the footprint of each record.</li>\n<li>SQLite: We tuned SQLite's performance, by setting its locking mode to exclusive.  We also enabled SQLite's <a href=\"http://www.sqlite.org/draft/wal.html\">write-ahead logging</a>.</li>\n</ul>\n\n<h2>1. Baseline Performance</h2>\n<p>This section gives the baseline performance of all the\ndatabases.  Following sections show how performance changes as various\nparameters are varied.  For the baseline:</p>\n<ul>\n\t<li> Each database is allowed 4 MB of cache memory.</li>\n        <li> Databases are opened in <em>asynchronous</em> write mode.\n             (LevelDB's sync option, TreeDB's OAUTOSYNC option, and\n             SQLite3's synchronous options are all turned off).  I.e.,\n             every write is pushed to the operating system, but the\n             benchmark does not wait for the write to reach the disk.</li>\n\t<li> Keys are 16 bytes each.</li>\n        <li> Value are 100 bytes each (with enough redundancy so that\n             a simple compressor shrinks them to 50% of their original\n             size).</li>\n\t<li> Sequential reads/writes traverse the key space in increasing order.</li>\n\t<li> Random reads/writes traverse the key space in random order.</li>\n</ul>\n\n<h3>A. Sequential Reads</h3>\n<table class=\"bn bnbase\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">4,030,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:350px\">&nbsp;</div></td>\n<tr><td class=\"c1\">Kyoto TreeDB</td>\n    <td class=\"c2\">1,010,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bkct\" style=\"width:95px\">&nbsp;</div></td>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">383,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:33px\">&nbsp;</div></td>\n</table>\n<h3>B. Random Reads</h3>\n<table class=\"bn bnbase\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">129,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:298px\">&nbsp;</div></td>\n<tr><td class=\"c1\">Kyoto TreeDB</td>\n    <td class=\"c2\">151,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bkct\" style=\"width:350px\">&nbsp;</div></td>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">134,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:310px\">&nbsp;</div></td>\n</table>\n<h3>C. Sequential Writes</h3>\n<table class=\"bn bnbase\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">779,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:350px\">&nbsp;</div></td>\n<tr><td class=\"c1\">Kyoto TreeDB</td>\n    <td class=\"c2\">342,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bkct\" style=\"width:154px\">&nbsp;</div></td>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">48,600 ops/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:22px\">&nbsp;</div></td>\n</table>\n<h3>D. Random Writes</h3>\n<table class=\"bn bnbase\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">164,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:350px\">&nbsp;</div></td>\n<tr><td class=\"c1\">Kyoto TreeDB</td>\n    <td class=\"c2\">88,500 ops/sec</td>\n    <td class=\"c3\"><div class=\"bkct\" style=\"width:188px\">&nbsp;</div></td>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">9,860 ops/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:21px\">&nbsp;</div></td>\n</table>\n\n<p>LevelDB outperforms both SQLite3 and TreeDB in sequential and random write operations and sequential read operations. Kyoto Cabinet has the fastest random read operations.</p>\n\n<h2>2. Write Performance under Different Configurations</h2>\n<h3>A. Large Values </h3>\n<p>For this benchmark, we start with an empty database, and write 100,000 byte values (~50% compressible). To keep the benchmark running time reasonable, we stop after writing 1000 values.</p>\n<h4>Sequential Writes</h4>\n<table class=\"bn bnbase\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">1,100 ops/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:234px\">&nbsp;</div></td></tr>\n<tr><td class=\"c1\">Kyoto TreeDB</td>\n    <td class=\"c2\">1,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bkct\" style=\"width:224px\">&nbsp;</div></td></tr>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">1,600 ops/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:350px\">&nbsp;</div></td></tr>\n</table>\n<h4>Random Writes</h4>\n<table class=\"bn bnbase\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">480 ops/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:105px\">&nbsp;</div></td></tr>\n<tr><td class=\"c1\">Kyoto TreeDB</td>\n    <td class=\"c2\">1,100 ops/sec</td>\n    <td class=\"c3\"><div class=\"bkct\" style=\"width:240px\">&nbsp;</div></td></tr>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">1,600 ops/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:350px\">&nbsp;</div></td></tr>\n</table>\n<p>LevelDB doesn't perform as well with large values of 100,000 bytes each. This is because LevelDB writes keys and values at least twice: first time to the transaction log, and second time (during a compaction) to a sorted file.\nWith larger values, LevelDB's per-operation efficiency is swamped by the\ncost of extra copies of large values.</p>\n<h3>B. Batch Writes</h3>\n<p>A batch write is a set of writes that are applied atomically to the underlying database. A single batch of N writes may be significantly faster than N individual writes. The following benchmark writes one thousand batches where each batch contains one thousand 100-byte values. TreeDB does not support batch writes and is omitted from this benchmark.</p>\n<h4>Sequential Writes</h4>\n<table class=\"bn\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">840,000 entries/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:350px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.08x baseline)</td></tr>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">124,000 entries/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:52px\">&nbsp;</div></td>\n    <td class=\"c4\">(2.55x baseline)</td></tr>\n</table>\n<h4>Random Writes</h4>\n<table class=\"bn\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">221,000 entries/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:350px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.35x baseline)</td></tr>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">22,000 entries/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:34px\">&nbsp;</div></td>\n    <td class=\"c4\">(2.23x baseline)</td></tr>\n</table>\n\n<p>Because of the way LevelDB persistent storage is organized, batches of\nrandom writes are not much slower (only a factor of 4x) than batches\nof sequential writes.</p>\n\n<h3>C. Synchronous Writes</h3>\n<p>In the following benchmark, we enable the synchronous writing modes\nof all of the databases.  Since this change significantly slows down the\nbenchmark, we stop after 10,000 writes. For synchronous write tests, we've\ndisabled hard drive write-caching (using `hdparm -W 0 [device]`).</p>\n<ul>\n    <li>For LevelDB, we set WriteOptions.sync = true.</li>\n    <li>In TreeDB, we enabled TreeDB's OAUTOSYNC option.</li>\n    <li>For SQLite3, we set \"PRAGMA synchronous = FULL\".</li>\n</ul>\n<h4>Sequential Writes</h4>\n<table class=\"bn\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">100 ops/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:350px\">&nbsp;</div></td>\n    <td class=\"c4\">(0.003x baseline)</td></tr>\n<tr><td class=\"c1\">Kyoto TreeDB</td>\n    <td class=\"c2\">7 ops/sec</td>\n    <td class=\"c3\"><div class=\"bkct\" style=\"width:27px\">&nbsp;</div></td>\n    <td class=\"c4\">(0.0004x baseline)</td></tr>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">88 ops/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:315px\">&nbsp;</div></td>\n    <td class=\"c4\">(0.002x baseline)</td></tr>\n</table>\n<h4>Random Writes</h4>\n<table class=\"bn\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">100 ops/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:350px\">&nbsp;</div></td>\n    <td class=\"c4\">(0.015x baseline)</td></tr>\n<tr><td class=\"c1\">Kyoto TreeDB</td>\n    <td class=\"c2\">8 ops/sec</td>\n    <td class=\"c3\"><div class=\"bkct\" style=\"width:29px\">&nbsp;</div></td>\n    <td class=\"c4\">(0.001x baseline)</td></tr>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">88 ops/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:314px\">&nbsp;</div></td>\n    <td class=\"c4\">(0.009x baseline)</td></tr>\n</table>\n\n<p>Also see the <code>ext4</code> performance numbers below\nsince synchronous writes behave significantly differently\non <code>ext3</code> and <code>ext4</code>.</p>\n\n<h3>D. Turning Compression Off</h3>\n\n<p>In the baseline measurements, LevelDB and TreeDB were using\nlight-weight compression\n(<a href=\"http://code.google.com/p/snappy/\">Snappy</a> for LevelDB,\nand <a href=\"http://www.oberhumer.com/opensource/lzo/\">LZO</a> for\nTreeDB). SQLite3, by default does not use compression.  The\nexperiments below show what happens when compression is disabled in\nall of the databases (the SQLite3 numbers are just a copy of\nits baseline measurements):</p>\n\n<h4>Sequential Writes</h4>\n<table class=\"bn\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">594,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:350px\">&nbsp;</div></td>\n    <td class=\"c4\">(0.76x baseline)</td></tr>\n<tr><td class=\"c1\">Kyoto TreeDB</td>\n    <td class=\"c2\">485,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bkct\" style=\"width:239px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.42x baseline)</td></tr>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">48,600 ops/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:29px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.00x baseline)</td></tr>\n</table>\n<h4>Random Writes</h4>\n<table class=\"bn\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">135,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:296px\">&nbsp;</div></td>\n    <td class=\"c4\">(0.82x baseline)</td></tr>\n<tr><td class=\"c1\">Kyoto TreeDB</td>\n    <td class=\"c2\">159,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bkct\" style=\"width:350px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.80x baseline)</td></tr>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">9,860 ops/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:22px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.00x baseline)</td></tr>\n</table>\n\n<p>LevelDB's write performance is better with compression than without\nsince compression decreases the amount of data that has to be written\nto disk.  Therefore LevelDB users can leave compression enabled in\nmost scenarios without having worry about a tradeoff between space\nusage and performance.  TreeDB's performance on the other hand is\nbetter without compression than with compression.  Presumably this is\nbecause TreeDB's compression library (LZO) is more expensive than\nLevelDB's compression library (Snappy).<p>\n\n<h3>E. Using More Memory</h3>\n<p>We increased the overall cache size for each database to 128 MB. For LevelDB, we partitioned 128 MB into a 120 MB write buffer and 8 MB of cache (up from 2 MB of write buffer and 2 MB of cache). For SQLite3, we kept the page size at 1024 bytes, but increased the number of pages to 131,072 (up from 4096). For TreeDB, we also kept the page size at 1024 bytes, but increased the cache size to 128 MB (up from 4 MB).</p>\n<h4>Sequential Writes</h4>\n<table class=\"bn\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">812,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:350px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.04x baseline)</td></tr>\n<tr><td class=\"c1\">Kyoto TreeDB</td>\n    <td class=\"c2\">321,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bkct\" style=\"width:138px\">&nbsp;</div></td>\n    <td class=\"c4\">(0.94x baseline)</td></tr>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">48,500 ops/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:21px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.00x baseline)</td></tr>\n</table>\n<h4>Random Writes</h4>\n<table class=\"bn\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">355,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:350px\">&nbsp;</div></td>\n    <td class=\"c4\">(2.16x baseline)</td></tr>\n<tr><td class=\"c1\">Kyoto TreeDB</td>\n    <td class=\"c2\">284,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bkct\" style=\"width:280px\">&nbsp;</div></td>\n    <td class=\"c4\">(3.21x baseline)</td></tr>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">9,670 ops/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:10px\">&nbsp;</div></td>\n    <td class=\"c4\">(0.98x baseline)</td></tr>\n</table>\n\n<p>SQLite's performance does not change substantially when compared to\nthe baseline, but the random write performance for both LevelDB and\nTreeDB increases significantly.  LevelDB's performance improves\nbecause a larger write buffer reduces the need to merge sorted files\n(since it creates a smaller number of larger sorted files).  TreeDB's\nperformance goes up because the entire database is available in memory\nfor fast in-place updates.</p>\n\n  <h2>3. Read Performance under Different Configurations</h2>\n<h3>A. Larger Caches</h3>\n<p>We increased the overall memory usage to 128 MB for each database.\nFor LevelDB, we allocated 8 MB to LevelDB's write buffer and 120 MB\nto LevelDB's cache. The other databases don't differentiate between a\nwrite buffer and a cache, so we simply set their cache size to 128\nMB.</p>\n<h4>Sequential Reads</h4>\n<table class=\"bn\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">5,210,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:350px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.29x baseline)</td></tr>\n<tr><td class=\"c1\">Kyoto TreeDB</td>\n    <td class=\"c2\">1,070,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bkct\" style=\"width:72px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.06x baseline)</td></tr>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">609,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:41px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.59x baseline)</td></tr>\n</table>\n\n<h4>Random Reads</h4>\n<table class=\"bn\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">190,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:144px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.47x baseline)</td></tr>\n<tr><td class=\"c1\">Kyoto TreeDB</td>\n    <td class=\"c2\">463,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bkct\" style=\"width:350px\">&nbsp;</div></td>\n    <td class=\"c4\">(3.07x baseline)</td></tr>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">186,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:141px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.39x baseline)</td></tr>\n</table>\n\n<p>As expected, the read performance of all of the databases increases\nwhen the caches are enlarged.  In particular, TreeDB seems to make\nvery effective use of a cache that is large enough to hold the entire\ndatabase.</p>\n\n<h3>B. No Compression Reads </h3>\n<p>For this benchmark, we populated a database with 1 million entries consisting of 16 byte keys and 100 byte values. We compiled LevelDB and Kyoto Cabinet without compression support, so results that are read out from the database are already uncompressed. We've listed the SQLite3 baseline read performance as a point of comparison.</p>\n<h4>Sequential Reads</h4>\n<table class=\"bn\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">4,880,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:350px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.21x baseline)</td></tr>\n<tr><td class=\"c1\">Kyoto TreeDB</td>\n    <td class=\"c2\">1,230,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bkct\" style=\"width:88px\">&nbsp;</div></td>\n    <td class=\"c4\">(3.60x baseline)</td></tr>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">383,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:27px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.00x baseline)</td></tr>\n</table>\n<h4>Random Reads</h4>\n<table class=\"bn\">\n<tr><td class=\"c1\">LevelDB</td>\n    <td class=\"c2\">149,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bldb\" style=\"width:300px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.16x baseline)</td></tr>\n<tr><td class=\"c1\">Kyoto TreeDB</td>\n    <td class=\"c2\">175,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bkct\" style=\"width:350px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.16x baseline)</td></tr>\n<tr><td class=\"c1\">SQLite3</td>\n    <td class=\"c2\">134,000 ops/sec</td>\n    <td class=\"c3\"><div class=\"bsql\" style=\"width:268px\">&nbsp;</div></td>\n    <td class=\"c4\">(1.00x baseline)</td></tr>\n</table>\n\n<p>Performance of both LevelDB and TreeDB improves a small amount when\ncompression is disabled.  Note however that under different workloads,\nperformance may very well be better with compression if it allows more\nof the working set to fit in memory.</p>\n\n<h2>Note about Ext4 Filesystems</h2>\n<p>The preceding numbers are for an ext3 file system. Synchronous writes are much slower under <a href=\"http://en.wikipedia.org/wiki/Ext4\">ext4</a> (LevelDB drops to ~31 writes / second and TreeDB drops to ~5 writes / second; SQLite3's synchronous writes do not noticeably drop) due to ext4's different handling of <span class=\"code\">fsync</span> / <span class=\"code\">msync</span> calls. Even LevelDB's asynchronous write performance drops somewhat since it spreads its storage across multiple files and issues <span class=\"code\">fsync</span> calls when switching to a new file.</p>\n\n<h2>Acknowledgements</h2>\n<p>Jeff Dean and Sanjay Ghemawat wrote LevelDB. Kevin Tseng wrote and compiled these benchmarks. Mikio Hirabayashi, Scott Hess, and Gabor Cselle provided help and advice.</p>\n</body>\n</html>\n"
  },
  {
    "path": "deps/leveldb-1.20/doc/impl.md",
    "content": "## Files\n\nThe implementation of leveldb is similar in spirit to the representation of a\nsingle [Bigtable tablet (section 5.3)](http://research.google.com/archive/bigtable.html).\nHowever the organization of the files that make up the representation is\nsomewhat different and is explained below.\n\nEach database is represented by a set of files stored in a directory. There are\nseveral different types of files as documented below:\n\n### Log files\n\nA log file (*.log) stores a sequence of recent updates. Each update is appended\nto the current log file. When the log file reaches a pre-determined size\n(approximately 4MB by default), it is converted to a sorted table (see below)\nand a new log file is created for future updates.\n\nA copy of the current log file is kept in an in-memory structure (the\n`memtable`). This copy is consulted on every read so that read operations\nreflect all logged updates.\n\n## Sorted tables\n\nA sorted table (*.ldb) stores a sequence of entries sorted by key. Each entry is\neither a value for the key, or a deletion marker for the key. (Deletion markers\nare kept around to hide obsolete values present in older sorted tables).\n\nThe set of sorted tables are organized into a sequence of levels. The sorted\ntable generated from a log file is placed in a special **young** level (also\ncalled level-0). When the number of young files exceeds a certain threshold\n(currently four), all of the young files are merged together with all of the\noverlapping level-1 files to produce a sequence of new level-1 files (we create\na new level-1 file for every 2MB of data.)\n\nFiles in the young level may contain overlapping keys. However files in other\nlevels have distinct non-overlapping key ranges. Consider level number L where\nL >= 1. When the combined size of files in level-L exceeds (10^L) MB (i.e., 10MB\nfor level-1, 100MB for level-2, ...), one file in level-L, and all of the\noverlapping files in level-(L+1) are merged to form a set of new files for\nlevel-(L+1). These merges have the effect of gradually migrating new updates\nfrom the young level to the largest level using only bulk reads and writes\n(i.e., minimizing expensive seeks).\n\n### Manifest\n\nA MANIFEST file lists the set of sorted tables that make up each level, the\ncorresponding key ranges, and other important metadata. A new MANIFEST file\n(with a new number embedded in the file name) is created whenever the database\nis reopened. The MANIFEST file is formatted as a log, and changes made to the\nserving state (as files are added or removed) are appended to this log.\n\n### Current\n\nCURRENT is a simple text file that contains the name of the latest MANIFEST\nfile.\n\n### Info logs\n\nInformational messages are printed to files named LOG and LOG.old.\n\n### Others\n\nOther files used for miscellaneous purposes may also be present (LOCK, *.dbtmp).\n\n## Level 0\n\nWhen the log file grows above a certain size (1MB by default):\nCreate a brand new memtable and log file and direct future updates here\nIn the background:\nWrite the contents of the previous memtable to an sstable\nDiscard the memtable\nDelete the old log file and the old memtable\nAdd the new sstable to the young (level-0) level.\n\n## Compactions\n\nWhen the size of level L exceeds its limit, we compact it in a background\nthread. The compaction picks a file from level L and all overlapping files from\nthe next level L+1. Note that if a level-L file overlaps only part of a\nlevel-(L+1) file, the entire file at level-(L+1) is used as an input to the\ncompaction and will be discarded after the compaction.  Aside: because level-0\nis special (files in it may overlap each other), we treat compactions from\nlevel-0 to level-1 specially: a level-0 compaction may pick more than one\nlevel-0 file in case some of these files overlap each other.\n\nA compaction merges the contents of the picked files to produce a sequence of\nlevel-(L+1) files. We switch to producing a new level-(L+1) file after the\ncurrent output file has reached the target file size (2MB). We also switch to a\nnew output file when the key range of the current output file has grown enough\nto overlap more than ten level-(L+2) files.  This last rule ensures that a later\ncompaction of a level-(L+1) file will not pick up too much data from\nlevel-(L+2).\n\nThe old files are discarded and the new files are added to the serving state.\n\nCompactions for a particular level rotate through the key space. In more detail,\nfor each level L, we remember the ending key of the last compaction at level L.\nThe next compaction for level L will pick the first file that starts after this\nkey (wrapping around to the beginning of the key space if there is no such\nfile).\n\nCompactions drop overwritten values. They also drop deletion markers if there\nare no higher numbered levels that contain a file whose range overlaps the\ncurrent key.\n\n### Timing\n\nLevel-0 compactions will read up to four 1MB files from level-0, and at worst\nall the level-1 files (10MB). I.e., we will read 14MB and write 14MB.\n\nOther than the special level-0 compactions, we will pick one 2MB file from level\nL. In the worst case, this will overlap ~ 12 files from level L+1 (10 because\nlevel-(L+1) is ten times the size of level-L, and another two at the boundaries\nsince the file ranges at level-L will usually not be aligned with the file\nranges at level-L+1). The compaction will therefore read 26MB and write 26MB.\nAssuming a disk IO rate of 100MB/s (ballpark range for modern drives), the worst\ncompaction cost will be approximately 0.5 second.\n\nIf we throttle the background writing to something small, say 10% of the full\n100MB/s speed, a compaction may take up to 5 seconds. If the user is writing at\n10MB/s, we might build up lots of level-0 files (~50 to hold the 5*10MB). This\nmay significantly increase the cost of reads due to the overhead of merging more\nfiles together on every read.\n\nSolution 1: To reduce this problem, we might want to increase the log switching\nthreshold when the number of level-0 files is large. Though the downside is that\nthe larger this threshold, the more memory we will need to hold the\ncorresponding memtable.\n\nSolution 2: We might want to decrease write rate artificially when the number of\nlevel-0 files goes up.\n\nSolution 3: We work on reducing the cost of very wide merges. Perhaps most of\nthe level-0 files will have their blocks sitting uncompressed in the cache and\nwe will only need to worry about the O(N) complexity in the merging iterator.\n\n### Number of files\n\nInstead of always making 2MB files, we could make larger files for larger levels\nto reduce the total file count, though at the expense of more bursty\ncompactions.  Alternatively, we could shard the set of files into multiple\ndirectories.\n\nAn experiment on an ext3 filesystem on Feb 04, 2011 shows the following timings\nto do 100K file opens in directories with varying number of files:\n\n\n| Files in directory | Microseconds to open a file |\n|-------------------:|----------------------------:|\n|               1000 |                           9 |\n|              10000 |                          10 |\n|             100000 |                          16 |\n\nSo maybe even the sharding is not necessary on modern filesystems?\n\n## Recovery\n\n* Read CURRENT to find name of the latest committed MANIFEST\n* Read the named MANIFEST file\n* Clean up stale files\n* We could open all sstables here, but it is probably better to be lazy...\n* Convert log chunk to a new level-0 sstable\n* Start directing new writes to a new log file with recovered sequence#\n\n## Garbage collection of files\n\n`DeleteObsoleteFiles()` is called at the end of every compaction and at the end\nof recovery. It finds the names of all files in the database. It deletes all log\nfiles that are not the current log file. It deletes all table files that are not\nreferenced from some level and are not the output of an active compaction.\n"
  },
  {
    "path": "deps/leveldb-1.20/doc/index.md",
    "content": "leveldb\n=======\n\n_Jeff Dean, Sanjay Ghemawat_\n\nThe leveldb library provides a persistent key value store. Keys and values are\narbitrary byte arrays.  The keys are ordered within the key value store\naccording to a user-specified comparator function.\n\n## Opening A Database\n\nA leveldb database has a name which corresponds to a file system directory. All\nof the contents of database are stored in this directory. The following example\nshows how to open a database, creating it if necessary:\n\n```c++\n#include <cassert>\n#include \"leveldb/db.h\"\n\nleveldb::DB* db;\nleveldb::Options options;\noptions.create_if_missing = true;\nleveldb::Status status = leveldb::DB::Open(options, \"/tmp/testdb\", &db);\nassert(status.ok());\n...\n```\n\nIf you want to raise an error if the database already exists, add the following\nline before the `leveldb::DB::Open` call:\n\n```c++\noptions.error_if_exists = true;\n```\n\n## Status\n\nYou may have noticed the `leveldb::Status` type above. Values of this type are\nreturned by most functions in leveldb that may encounter an error. You can check\nif such a result is ok, and also print an associated error message:\n\n```c++\nleveldb::Status s = ...;\nif (!s.ok()) cerr << s.ToString() << endl;\n```\n\n## Closing A Database\n\nWhen you are done with a database, just delete the database object. Example:\n\n```c++\n... open the db as described above ...\n... do something with db ...\ndelete db;\n```\n\n## Reads And Writes\n\nThe database provides Put, Delete, and Get methods to modify/query the database.\nFor example, the following code moves the value stored under key1 to key2.\n\n```c++\nstd::string value;\nleveldb::Status s = db->Get(leveldb::ReadOptions(), key1, &value);\nif (s.ok()) s = db->Put(leveldb::WriteOptions(), key2, value);\nif (s.ok()) s = db->Delete(leveldb::WriteOptions(), key1);\n```\n\n## Atomic Updates\n\nNote that if the process dies after the Put of key2 but before the delete of\nkey1, the same value may be left stored under multiple keys. Such problems can\nbe avoided by using the `WriteBatch` class to atomically apply a set of updates:\n\n```c++\n#include \"leveldb/write_batch.h\"\n...\nstd::string value;\nleveldb::Status s = db->Get(leveldb::ReadOptions(), key1, &value);\nif (s.ok()) {\n  leveldb::WriteBatch batch;\n  batch.Delete(key1);\n  batch.Put(key2, value);\n  s = db->Write(leveldb::WriteOptions(), &batch);\n}\n```\n\nThe `WriteBatch` holds a sequence of edits to be made to the database, and these\nedits within the batch are applied in order. Note that we called Delete before\nPut so that if key1 is identical to key2, we do not end up erroneously dropping\nthe value entirely.\n\nApart from its atomicity benefits, `WriteBatch` may also be used to speed up\nbulk updates by placing lots of individual mutations into the same batch.\n\n## Synchronous Writes\n\nBy default, each write to leveldb is asynchronous: it returns after pushing the\nwrite from the process into the operating system. The transfer from operating\nsystem memory to the underlying persistent storage happens asynchronously. The\nsync flag can be turned on for a particular write to make the write operation\nnot return until the data being written has been pushed all the way to\npersistent storage. (On Posix systems, this is implemented by calling either\n`fsync(...)` or `fdatasync(...)` or `msync(..., MS_SYNC)` before the write\noperation returns.)\n\n```c++\nleveldb::WriteOptions write_options;\nwrite_options.sync = true;\ndb->Put(write_options, ...);\n```\n\nAsynchronous writes are often more than a thousand times as fast as synchronous\nwrites. The downside of asynchronous writes is that a crash of the machine may\ncause the last few updates to be lost. Note that a crash of just the writing\nprocess (i.e., not a reboot) will not cause any loss since even when sync is\nfalse, an update is pushed from the process memory into the operating system\nbefore it is considered done.\n\nAsynchronous writes can often be used safely. For example, when loading a large\namount of data into the database you can handle lost updates by restarting the\nbulk load after a crash. A hybrid scheme is also possible where every Nth write\nis synchronous, and in the event of a crash, the bulk load is restarted just\nafter the last synchronous write finished by the previous run. (The synchronous\nwrite can update a marker that describes where to restart on a crash.)\n\n`WriteBatch` provides an alternative to asynchronous writes. Multiple updates\nmay be placed in the same WriteBatch and applied together using a synchronous\nwrite (i.e., `write_options.sync` is set to true). The extra cost of the\nsynchronous write will be amortized across all of the writes in the batch.\n\n## Concurrency\n\nA database may only be opened by one process at a time. The leveldb\nimplementation acquires a lock from the operating system to prevent misuse.\nWithin a single process, the same `leveldb::DB` object may be safely shared by\nmultiple concurrent threads. I.e., different threads may write into or fetch\niterators or call Get on the same database without any external synchronization\n(the leveldb implementation will automatically do the required synchronization).\nHowever other objects (like Iterator and `WriteBatch`) may require external\nsynchronization. If two threads share such an object, they must protect access\nto it using their own locking protocol. More details are available in the public\nheader files.\n\n## Iteration\n\nThe following example demonstrates how to print all key,value pairs in a\ndatabase.\n\n```c++\nleveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());\nfor (it->SeekToFirst(); it->Valid(); it->Next()) {\n  cout << it->key().ToString() << \": \"  << it->value().ToString() << endl;\n}\nassert(it->status().ok());  // Check for any errors found during the scan\ndelete it;\n```\n\nThe following variation shows how to process just the keys in the range\n[start,limit):\n\n```c++\nfor (it->Seek(start);\n   it->Valid() && it->key().ToString() < limit;\n   it->Next()) {\n  ...\n}\n```\n\nYou can also process entries in reverse order. (Caveat: reverse iteration may be\nsomewhat slower than forward iteration.)\n\n```c++\nfor (it->SeekToLast(); it->Valid(); it->Prev()) {\n  ...\n}\n```\n\n## Snapshots\n\nSnapshots provide consistent read-only views over the entire state of the\nkey-value store.  `ReadOptions::snapshot` may be non-NULL to indicate that a\nread should operate on a particular version of the DB state. If\n`ReadOptions::snapshot` is NULL, the read will operate on an implicit snapshot\nof the current state.\n\nSnapshots are created by the `DB::GetSnapshot()` method:\n\n```c++\nleveldb::ReadOptions options;\noptions.snapshot = db->GetSnapshot();\n... apply some updates to db ...\nleveldb::Iterator* iter = db->NewIterator(options);\n... read using iter to view the state when the snapshot was created ...\ndelete iter;\ndb->ReleaseSnapshot(options.snapshot);\n```\n\nNote that when a snapshot is no longer needed, it should be released using the\n`DB::ReleaseSnapshot` interface. This allows the implementation to get rid of\nstate that was being maintained just to support reading as of that snapshot.\n\n## Slice\n\nThe return value of the `it->key()` and `it->value()` calls above are instances\nof the `leveldb::Slice` type. Slice is a simple structure that contains a length\nand a pointer to an external byte array. Returning a Slice is a cheaper\nalternative to returning a `std::string` since we do not need to copy\npotentially large keys and values. In addition, leveldb methods do not return\nnull-terminated C-style strings since leveldb keys and values are allowed to\ncontain `'\\0'` bytes.\n\nC++ strings and null-terminated C-style strings can be easily converted to a\nSlice:\n\n```c++\nleveldb::Slice s1 = \"hello\";\n\nstd::string str(\"world\");\nleveldb::Slice s2 = str;\n```\n\nA Slice can be easily converted back to a C++ string:\n\n```c++\nstd::string str = s1.ToString();\nassert(str == std::string(\"hello\"));\n```\n\nBe careful when using Slices since it is up to the caller to ensure that the\nexternal byte array into which the Slice points remains live while the Slice is\nin use. For example, the following is buggy:\n\n```c++\nleveldb::Slice slice;\nif (...) {\n  std::string str = ...;\n  slice = str;\n}\nUse(slice);\n```\n\nWhen the if statement goes out of scope, str will be destroyed and the backing\nstorage for slice will disappear.\n\n## Comparators\n\nThe preceding examples used the default ordering function for key, which orders\nbytes lexicographically. You can however supply a custom comparator when opening\na database.  For example, suppose each database key consists of two numbers and\nwe should sort by the first number, breaking ties by the second number. First,\ndefine a proper subclass of `leveldb::Comparator` that expresses these rules:\n\n```c++\nclass TwoPartComparator : public leveldb::Comparator {\n public:\n  // Three-way comparison function:\n  //   if a < b: negative result\n  //   if a > b: positive result\n  //   else: zero result\n  int Compare(const leveldb::Slice& a, const leveldb::Slice& b) const {\n    int a1, a2, b1, b2;\n    ParseKey(a, &a1, &a2);\n    ParseKey(b, &b1, &b2);\n    if (a1 < b1) return -1;\n    if (a1 > b1) return +1;\n    if (a2 < b2) return -1;\n    if (a2 > b2) return +1;\n    return 0;\n  }\n\n  // Ignore the following methods for now:\n  const char* Name() const { return \"TwoPartComparator\"; }\n  void FindShortestSeparator(std::string*, const leveldb::Slice&) const {}\n  void FindShortSuccessor(std::string*) const {}\n};\n```\n\nNow create a database using this custom comparator:\n\n```c++\nTwoPartComparator cmp;\nleveldb::DB* db;\nleveldb::Options options;\noptions.create_if_missing = true;\noptions.comparator = &cmp;\nleveldb::Status status = leveldb::DB::Open(options, \"/tmp/testdb\", &db);\n...\n```\n\n### Backwards compatibility\n\nThe result of the comparator's Name method is attached to the database when it\nis created, and is checked on every subsequent database open. If the name\nchanges, the `leveldb::DB::Open` call will fail. Therefore, change the name if\nand only if the new key format and comparison function are incompatible with\nexisting databases, and it is ok to discard the contents of all existing\ndatabases.\n\nYou can however still gradually evolve your key format over time with a little\nbit of pre-planning. For example, you could store a version number at the end of\neach key (one byte should suffice for most uses). When you wish to switch to a\nnew key format (e.g., adding an optional third part to the keys processed by\n`TwoPartComparator`), (a) keep the same comparator name (b) increment the\nversion number for new keys (c) change the comparator function so it uses the\nversion numbers found in the keys to decide how to interpret them.\n\n## Performance\n\nPerformance can be tuned by changing the default values of the types defined in\n`include/leveldb/options.h`.\n\n### Block size\n\nleveldb groups adjacent keys together into the same block and such a block is\nthe unit of transfer to and from persistent storage. The default block size is\napproximately 4096 uncompressed bytes.  Applications that mostly do bulk scans\nover the contents of the database may wish to increase this size. Applications\nthat do a lot of point reads of small values may wish to switch to a smaller\nblock size if performance measurements indicate an improvement. There isn't much\nbenefit in using blocks smaller than one kilobyte, or larger than a few\nmegabytes. Also note that compression will be more effective with larger block\nsizes.\n\n### Compression\n\nEach block is individually compressed before being written to persistent\nstorage. Compression is on by default since the default compression method is\nvery fast, and is automatically disabled for uncompressible data. In rare cases,\napplications may want to disable compression entirely, but should only do so if\nbenchmarks show a performance improvement:\n\n```c++\nleveldb::Options options;\noptions.compression = leveldb::kNoCompression;\n... leveldb::DB::Open(options, name, ...) ....\n```\n\n### Cache\n\nThe contents of the database are stored in a set of files in the filesystem and\neach file stores a sequence of compressed blocks. If options.cache is non-NULL,\nit is used to cache frequently used uncompressed block contents.\n\n```c++\n#include \"leveldb/cache.h\"\n\nleveldb::Options options;\noptions.cache = leveldb::NewLRUCache(100 * 1048576);  // 100MB cache\nleveldb::DB* db;\nleveldb::DB::Open(options, name, &db);\n... use the db ...\ndelete db\ndelete options.cache;\n```\n\nNote that the cache holds uncompressed data, and therefore it should be sized\naccording to application level data sizes, without any reduction from\ncompression. (Caching of compressed blocks is left to the operating system\nbuffer cache, or any custom Env implementation provided by the client.)\n\nWhen performing a bulk read, the application may wish to disable caching so that\nthe data processed by the bulk read does not end up displacing most of the\ncached contents. A per-iterator option can be used to achieve this:\n\n```c++\nleveldb::ReadOptions options;\noptions.fill_cache = false;\nleveldb::Iterator* it = db->NewIterator(options);\nfor (it->SeekToFirst(); it->Valid(); it->Next()) {\n  ...\n}\n```\n\n### Key Layout\n\nNote that the unit of disk transfer and caching is a block. Adjacent keys\n(according to the database sort order) will usually be placed in the same block.\nTherefore the application can improve its performance by placing keys that are\naccessed together near each other and placing infrequently used keys in a\nseparate region of the key space.\n\nFor example, suppose we are implementing a simple file system on top of leveldb.\nThe types of entries we might wish to store are:\n\n    filename -> permission-bits, length, list of file_block_ids\n    file_block_id -> data\n\nWe might want to prefix filename keys with one letter (say '/') and the\n`file_block_id` keys with a different letter (say '0') so that scans over just\nthe metadata do not force us to fetch and cache bulky file contents.\n\n### Filters\n\nBecause of the way leveldb data is organized on disk, a single `Get()` call may\ninvolve multiple reads from disk. The optional FilterPolicy mechanism can be\nused to reduce the number of disk reads substantially.\n\n```c++\nleveldb::Options options;\noptions.filter_policy = NewBloomFilterPolicy(10);\nleveldb::DB* db;\nleveldb::DB::Open(options, \"/tmp/testdb\", &db);\n... use the database ...\ndelete db;\ndelete options.filter_policy;\n```\n\nThe preceding code associates a Bloom filter based filtering policy with the\ndatabase.  Bloom filter based filtering relies on keeping some number of bits of\ndata in memory per key (in this case 10 bits per key since that is the argument\nwe passed to `NewBloomFilterPolicy`). This filter will reduce the number of\nunnecessary disk reads needed for Get() calls by a factor of approximately\na 100. Increasing the bits per key will lead to a larger reduction at the cost\nof more memory usage. We recommend that applications whose working set does not\nfit in memory and that do a lot of random reads set a filter policy.\n\nIf you are using a custom comparator, you should ensure that the filter policy\nyou are using is compatible with your comparator. For example, consider a\ncomparator that ignores trailing spaces when comparing keys.\n`NewBloomFilterPolicy` must not be used with such a comparator. Instead, the\napplication should provide a custom filter policy that also ignores trailing\nspaces. For example:\n\n```c++\nclass CustomFilterPolicy : public leveldb::FilterPolicy {\n private:\n  FilterPolicy* builtin_policy_;\n\n public:\n  CustomFilterPolicy() : builtin_policy_(NewBloomFilterPolicy(10)) {}\n  ~CustomFilterPolicy() { delete builtin_policy_; }\n\n  const char* Name() const { return \"IgnoreTrailingSpacesFilter\"; }\n\n  void CreateFilter(const Slice* keys, int n, std::string* dst) const {\n    // Use builtin bloom filter code after removing trailing spaces\n    std::vector<Slice> trimmed(n);\n    for (int i = 0; i < n; i++) {\n      trimmed[i] = RemoveTrailingSpaces(keys[i]);\n    }\n    return builtin_policy_->CreateFilter(&trimmed[i], n, dst);\n  }\n};\n```\n\nAdvanced applications may provide a filter policy that does not use a bloom\nfilter but uses some other mechanism for summarizing a set of keys. See\n`leveldb/filter_policy.h` for detail.\n\n## Checksums\n\nleveldb associates checksums with all data it stores in the file system. There\nare two separate controls provided over how aggressively these checksums are\nverified:\n\n`ReadOptions::verify_checksums` may be set to true to force checksum\nverification of all data that is read from the file system on behalf of a\nparticular read.  By default, no such verification is done.\n\n`Options::paranoid_checks` may be set to true before opening a database to make\nthe database implementation raise an error as soon as it detects an internal\ncorruption. Depending on which portion of the database has been corrupted, the\nerror may be raised when the database is opened, or later by another database\noperation. By default, paranoid checking is off so that the database can be used\neven if parts of its persistent storage have been corrupted.\n\nIf a database is corrupted (perhaps it cannot be opened when paranoid checking\nis turned on), the `leveldb::RepairDB` function may be used to recover as much\nof the data as possible\n\n## Approximate Sizes\n\nThe `GetApproximateSizes` method can used to get the approximate number of bytes\nof file system space used by one or more key ranges.\n\n```c++\nleveldb::Range ranges[2];\nranges[0] = leveldb::Range(\"a\", \"c\");\nranges[1] = leveldb::Range(\"x\", \"z\");\nuint64_t sizes[2];\nleveldb::Status s = db->GetApproximateSizes(ranges, 2, sizes);\n```\n\nThe preceding call will set `sizes[0]` to the approximate number of bytes of\nfile system space used by the key range `[a..c)` and `sizes[1]` to the\napproximate number of bytes used by the key range `[x..z)`.\n\n## Environment\n\nAll file operations (and other operating system calls) issued by the leveldb\nimplementation are routed through a `leveldb::Env` object. Sophisticated clients\nmay wish to provide their own Env implementation to get better control.\nFor example, an application may introduce artificial delays in the file IO\npaths to limit the impact of leveldb on other activities in the system.\n\n```c++\nclass SlowEnv : public leveldb::Env {\n  ... implementation of the Env interface ...\n};\n\nSlowEnv env;\nleveldb::Options options;\noptions.env = &env;\nStatus s = leveldb::DB::Open(options, ...);\n```\n\n## Porting\n\nleveldb may be ported to a new platform by providing platform specific\nimplementations of the types/methods/functions exported by\n`leveldb/port/port.h`.  See `leveldb/port/port_example.h` for more details.\n\nIn addition, the new platform may need a new default `leveldb::Env`\nimplementation.  See `leveldb/util/env_posix.h` for an example.\n\n## Other Information\n\nDetails about the leveldb implementation may be found in the following\ndocuments:\n\n1. [Implementation notes](impl.md)\n2. [Format of an immutable Table file](table_format.md)\n3. [Format of a log file](log_format.md)\n"
  },
  {
    "path": "deps/leveldb-1.20/doc/log_format.md",
    "content": "leveldb Log format\n==================\nThe log file contents are a sequence of 32KB blocks.  The only exception is that\nthe tail of the file may contain a partial block.\n\nEach block consists of a sequence of records:\n\n    block := record* trailer?\n    record :=\n      checksum: uint32     // crc32c of type and data[] ; little-endian\n      length: uint16       // little-endian\n      type: uint8          // One of FULL, FIRST, MIDDLE, LAST\n      data: uint8[length]\n\nA record never starts within the last six bytes of a block (since it won't fit).\nAny leftover bytes here form the trailer, which must consist entirely of zero\nbytes and must be skipped by readers.\n\nAside: if exactly seven bytes are left in the current block, and a new non-zero\nlength record is added, the writer must emit a FIRST record (which contains zero\nbytes of user data) to fill up the trailing seven bytes of the block and then\nemit all of the user data in subsequent blocks.\n\nMore types may be added in the future.  Some Readers may skip record types they\ndo not understand, others may report that some data was skipped.\n\n    FULL == 1\n    FIRST == 2\n    MIDDLE == 3\n    LAST == 4\n\nThe FULL record contains the contents of an entire user record.\n\nFIRST, MIDDLE, LAST are types used for user records that have been split into\nmultiple fragments (typically because of block boundaries).  FIRST is the type\nof the first fragment of a user record, LAST is the type of the last fragment of\na user record, and MIDDLE is the type of all interior fragments of a user\nrecord.\n\nExample: consider a sequence of user records:\n\n    A: length 1000\n    B: length 97270\n    C: length 8000\n\n**A** will be stored as a FULL record in the first block.\n\n**B** will be split into three fragments: first fragment occupies the rest of\nthe first block, second fragment occupies the entirety of the second block, and\nthe third fragment occupies a prefix of the third block.  This will leave six\nbytes free in the third block, which will be left empty as the trailer.\n\n**C** will be stored as a FULL record in the fourth block.\n\n----\n\n## Some benefits over the recordio format:\n\n1. We do not need any heuristics for resyncing - just go to next block boundary\n   and scan.  If there is a corruption, skip to the next block.  As a\n   side-benefit, we do not get confused when part of the contents of one log\n   file are embedded as a record inside another log file.\n\n2. Splitting at approximate boundaries (e.g., for mapreduce) is simple: find the\n   next block boundary and skip records until we hit a FULL or FIRST record.\n\n3. We do not need extra buffering for large records.\n\n## Some downsides compared to recordio format:\n\n1. No packing of tiny records.  This could be fixed by adding a new record type,\n   so it is a shortcoming of the current implementation, not necessarily the\n   format.\n\n2. No compression.  Again, this could be fixed by adding new record types.\n"
  },
  {
    "path": "deps/leveldb-1.20/doc/table_format.md",
    "content": "leveldb File format\n===================\n\n    <beginning_of_file>\n    [data block 1]\n    [data block 2]\n    ...\n    [data block N]\n    [meta block 1]\n    ...\n    [meta block K]\n    [metaindex block]\n    [index block]\n    [Footer]        (fixed size; starts at file_size - sizeof(Footer))\n    <end_of_file>\n\nThe file contains internal pointers.  Each such pointer is called\na BlockHandle and contains the following information:\n\n    offset:   varint64\n    size:     varint64\n\nSee [varints](https://developers.google.com/protocol-buffers/docs/encoding#varints)\nfor an explanation of varint64 format.\n\n1.  The sequence of key/value pairs in the file are stored in sorted\norder and partitioned into a sequence of data blocks.  These blocks\ncome one after another at the beginning of the file.  Each data block\nis formatted according to the code in `block_builder.cc`, and then\noptionally compressed.\n\n2. After the data blocks we store a bunch of meta blocks.  The\nsupported meta block types are described below.  More meta block types\nmay be added in the future.  Each meta block is again formatted using\n`block_builder.cc` and then optionally compressed.\n\n3. A \"metaindex\" block.  It contains one entry for every other meta\nblock where the key is the name of the meta block and the value is a\nBlockHandle pointing to that meta block.\n\n4. An \"index\" block.  This block contains one entry per data block,\nwhere the key is a string >= last key in that data block and before\nthe first key in the successive data block.  The value is the\nBlockHandle for the data block.\n\n5. At the very end of the file is a fixed length footer that contains\nthe BlockHandle of the metaindex and index blocks as well as a magic number.\n\n        metaindex_handle: char[p];     // Block handle for metaindex\n        index_handle:     char[q];     // Block handle for index\n        padding:          char[40-p-q];// zeroed bytes to make fixed length\n                                       // (40==2*BlockHandle::kMaxEncodedLength)\n        magic:            fixed64;     // == 0xdb4775248b80fb57 (little-endian)\n\n## \"filter\" Meta Block\n\nIf a `FilterPolicy` was specified when the database was opened, a\nfilter block is stored in each table.  The \"metaindex\" block contains\nan entry that maps from `filter.<N>` to the BlockHandle for the filter\nblock where `<N>` is the string returned by the filter policy's\n`Name()` method.\n\nThe filter block stores a sequence of filters, where filter i contains\nthe output of `FilterPolicy::CreateFilter()` on all keys that are stored\nin a block whose file offset falls within the range\n\n    [ i*base ... (i+1)*base-1 ]\n\nCurrently, \"base\" is 2KB.  So for example, if blocks X and Y start in\nthe range `[ 0KB .. 2KB-1 ]`, all of the keys in X and Y will be\nconverted to a filter by calling `FilterPolicy::CreateFilter()`, and the\nresulting filter will be stored as the first filter in the filter\nblock.\n\nThe filter block is formatted as follows:\n\n    [filter 0]\n    [filter 1]\n    [filter 2]\n    ...\n    [filter N-1]\n\n    [offset of filter 0]                  : 4 bytes\n    [offset of filter 1]                  : 4 bytes\n    [offset of filter 2]                  : 4 bytes\n    ...\n    [offset of filter N-1]                : 4 bytes\n\n    [offset of beginning of offset array] : 4 bytes\n    lg(base)                              : 1 byte\n\nThe offset array at the end of the filter block allows efficient\nmapping from a data block offset to the corresponding filter.\n\n## \"stats\" Meta Block\n\nThis meta block contains a bunch of stats.  The key is the name\nof the statistic.  The value contains the statistic.\n\nTODO(postrelease): record following stats.\n\n    data size\n    index size\n    key size (uncompressed)\n    value size (uncompressed)\n    number of entries\n    number of data blocks\n"
  },
  {
    "path": "deps/leveldb-1.20/helpers/memenv/memenv.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"helpers/memenv/memenv.h\"\n\n#include \"leveldb/env.h\"\n#include \"leveldb/status.h\"\n#include \"port/port.h\"\n#include \"util/mutexlock.h\"\n#include <map>\n#include <string.h>\n#include <string>\n#include <vector>\n\nnamespace leveldb {\n\nnamespace {\n\nclass FileState {\n public:\n  // FileStates are reference counted. The initial reference count is zero\n  // and the caller must call Ref() at least once.\n  FileState() : refs_(0), size_(0) {}\n\n  // Increase the reference count.\n  void Ref() {\n    MutexLock lock(&refs_mutex_);\n    ++refs_;\n  }\n\n  // Decrease the reference count. Delete if this is the last reference.\n  void Unref() {\n    bool do_delete = false;\n\n    {\n      MutexLock lock(&refs_mutex_);\n      --refs_;\n      assert(refs_ >= 0);\n      if (refs_ <= 0) {\n        do_delete = true;\n      }\n    }\n\n    if (do_delete) {\n      delete this;\n    }\n  }\n\n  uint64_t Size() const { return size_; }\n\n  Status Read(uint64_t offset, size_t n, Slice* result, char* scratch) const {\n    if (offset > size_) {\n      return Status::IOError(\"Offset greater than file size.\");\n    }\n    const uint64_t available = size_ - offset;\n    if (n > available) {\n      n = static_cast<size_t>(available);\n    }\n    if (n == 0) {\n      *result = Slice();\n      return Status::OK();\n    }\n\n    assert(offset / kBlockSize <= SIZE_MAX);\n    size_t block = static_cast<size_t>(offset / kBlockSize);\n    size_t block_offset = offset % kBlockSize;\n\n    if (n <= kBlockSize - block_offset) {\n      // The requested bytes are all in the first block.\n      *result = Slice(blocks_[block] + block_offset, n);\n      return Status::OK();\n    }\n\n    size_t bytes_to_copy = n;\n    char* dst = scratch;\n\n    while (bytes_to_copy > 0) {\n      size_t avail = kBlockSize - block_offset;\n      if (avail > bytes_to_copy) {\n        avail = bytes_to_copy;\n      }\n      memcpy(dst, blocks_[block] + block_offset, avail);\n\n      bytes_to_copy -= avail;\n      dst += avail;\n      block++;\n      block_offset = 0;\n    }\n\n    *result = Slice(scratch, n);\n    return Status::OK();\n  }\n\n  Status Append(const Slice& data) {\n    const char* src = data.data();\n    size_t src_len = data.size();\n\n    while (src_len > 0) {\n      size_t avail;\n      size_t offset = size_ % kBlockSize;\n\n      if (offset != 0) {\n        // There is some room in the last block.\n        avail = kBlockSize - offset;\n      } else {\n        // No room in the last block; push new one.\n        blocks_.push_back(new char[kBlockSize]);\n        avail = kBlockSize;\n      }\n\n      if (avail > src_len) {\n        avail = src_len;\n      }\n      memcpy(blocks_.back() + offset, src, avail);\n      src_len -= avail;\n      src += avail;\n      size_ += avail;\n    }\n\n    return Status::OK();\n  }\n\n private:\n  // Private since only Unref() should be used to delete it.\n  ~FileState() {\n    for (std::vector<char*>::iterator i = blocks_.begin(); i != blocks_.end();\n         ++i) {\n      delete [] *i;\n    }\n  }\n\n  // No copying allowed.\n  FileState(const FileState&);\n  void operator=(const FileState&);\n\n  port::Mutex refs_mutex_;\n  int refs_;  // Protected by refs_mutex_;\n\n  // The following fields are not protected by any mutex. They are only mutable\n  // while the file is being written, and concurrent access is not allowed\n  // to writable files.\n  std::vector<char*> blocks_;\n  uint64_t size_;\n\n  enum { kBlockSize = 8 * 1024 };\n};\n\nclass SequentialFileImpl : public SequentialFile {\n public:\n  explicit SequentialFileImpl(FileState* file) : file_(file), pos_(0) {\n    file_->Ref();\n  }\n\n  ~SequentialFileImpl() {\n    file_->Unref();\n  }\n\n  virtual Status Read(size_t n, Slice* result, char* scratch) {\n    Status s = file_->Read(pos_, n, result, scratch);\n    if (s.ok()) {\n      pos_ += result->size();\n    }\n    return s;\n  }\n\n  virtual Status Skip(uint64_t n) {\n    if (pos_ > file_->Size()) {\n      return Status::IOError(\"pos_ > file_->Size()\");\n    }\n    const uint64_t available = file_->Size() - pos_;\n    if (n > available) {\n      n = available;\n    }\n    pos_ += n;\n    return Status::OK();\n  }\n\n private:\n  FileState* file_;\n  uint64_t pos_;\n};\n\nclass RandomAccessFileImpl : public RandomAccessFile {\n public:\n  explicit RandomAccessFileImpl(FileState* file) : file_(file) {\n    file_->Ref();\n  }\n\n  ~RandomAccessFileImpl() {\n    file_->Unref();\n  }\n\n  virtual Status Read(uint64_t offset, size_t n, Slice* result,\n                      char* scratch) const {\n    return file_->Read(offset, n, result, scratch);\n  }\n\n private:\n  FileState* file_;\n};\n\nclass WritableFileImpl : public WritableFile {\n public:\n  WritableFileImpl(FileState* file) : file_(file) {\n    file_->Ref();\n  }\n\n  ~WritableFileImpl() {\n    file_->Unref();\n  }\n\n  virtual Status Append(const Slice& data) {\n    return file_->Append(data);\n  }\n\n  virtual Status Close() { return Status::OK(); }\n  virtual Status Flush() { return Status::OK(); }\n  virtual Status Sync() { return Status::OK(); }\n\n private:\n  FileState* file_;\n};\n\nclass NoOpLogger : public Logger {\n public:\n  virtual void Logv(const char* format, va_list ap) { }\n};\n\nclass InMemoryEnv : public EnvWrapper {\n public:\n  explicit InMemoryEnv(Env* base_env) : EnvWrapper(base_env) { }\n\n  virtual ~InMemoryEnv() {\n    for (FileSystem::iterator i = file_map_.begin(); i != file_map_.end(); ++i){\n      i->second->Unref();\n    }\n  }\n\n  // Partial implementation of the Env interface.\n  virtual Status NewSequentialFile(const std::string& fname,\n                                   SequentialFile** result) {\n    MutexLock lock(&mutex_);\n    if (file_map_.find(fname) == file_map_.end()) {\n      *result = NULL;\n      return Status::IOError(fname, \"File not found\");\n    }\n\n    *result = new SequentialFileImpl(file_map_[fname]);\n    return Status::OK();\n  }\n\n  virtual Status NewRandomAccessFile(const std::string& fname,\n                                     RandomAccessFile** result) {\n    MutexLock lock(&mutex_);\n    if (file_map_.find(fname) == file_map_.end()) {\n      *result = NULL;\n      return Status::IOError(fname, \"File not found\");\n    }\n\n    *result = new RandomAccessFileImpl(file_map_[fname]);\n    return Status::OK();\n  }\n\n  virtual Status NewWritableFile(const std::string& fname,\n                                 WritableFile** result) {\n    MutexLock lock(&mutex_);\n    if (file_map_.find(fname) != file_map_.end()) {\n      DeleteFileInternal(fname);\n    }\n\n    FileState* file = new FileState();\n    file->Ref();\n    file_map_[fname] = file;\n\n    *result = new WritableFileImpl(file);\n    return Status::OK();\n  }\n\n  virtual Status NewAppendableFile(const std::string& fname,\n                                   WritableFile** result) {\n    MutexLock lock(&mutex_);\n    FileState** sptr = &file_map_[fname];\n    FileState* file = *sptr;\n    if (file == NULL) {\n      file = new FileState();\n      file->Ref();\n    }\n    *result = new WritableFileImpl(file);\n    return Status::OK();\n  }\n\n  virtual bool FileExists(const std::string& fname) {\n    MutexLock lock(&mutex_);\n    return file_map_.find(fname) != file_map_.end();\n  }\n\n  virtual Status GetChildren(const std::string& dir,\n                             std::vector<std::string>* result) {\n    MutexLock lock(&mutex_);\n    result->clear();\n\n    for (FileSystem::iterator i = file_map_.begin(); i != file_map_.end(); ++i){\n      const std::string& filename = i->first;\n\n      if (filename.size() >= dir.size() + 1 && filename[dir.size()] == '/' &&\n          Slice(filename).starts_with(Slice(dir))) {\n        result->push_back(filename.substr(dir.size() + 1));\n      }\n    }\n\n    return Status::OK();\n  }\n\n  void DeleteFileInternal(const std::string& fname) {\n    if (file_map_.find(fname) == file_map_.end()) {\n      return;\n    }\n\n    file_map_[fname]->Unref();\n    file_map_.erase(fname);\n  }\n\n  virtual Status DeleteFile(const std::string& fname) {\n    MutexLock lock(&mutex_);\n    if (file_map_.find(fname) == file_map_.end()) {\n      return Status::IOError(fname, \"File not found\");\n    }\n\n    DeleteFileInternal(fname);\n    return Status::OK();\n  }\n\n  virtual Status CreateDir(const std::string& dirname) {\n    return Status::OK();\n  }\n\n  virtual Status DeleteDir(const std::string& dirname) {\n    return Status::OK();\n  }\n\n  virtual Status GetFileSize(const std::string& fname, uint64_t* file_size) {\n    MutexLock lock(&mutex_);\n    if (file_map_.find(fname) == file_map_.end()) {\n      return Status::IOError(fname, \"File not found\");\n    }\n\n    *file_size = file_map_[fname]->Size();\n    return Status::OK();\n  }\n\n  virtual Status RenameFile(const std::string& src,\n                            const std::string& target) {\n    MutexLock lock(&mutex_);\n    if (file_map_.find(src) == file_map_.end()) {\n      return Status::IOError(src, \"File not found\");\n    }\n\n    DeleteFileInternal(target);\n    file_map_[target] = file_map_[src];\n    file_map_.erase(src);\n    return Status::OK();\n  }\n\n  virtual Status LockFile(const std::string& fname, FileLock** lock) {\n    *lock = new FileLock;\n    return Status::OK();\n  }\n\n  virtual Status UnlockFile(FileLock* lock) {\n    delete lock;\n    return Status::OK();\n  }\n\n  virtual Status GetTestDirectory(std::string* path) {\n    *path = \"/test\";\n    return Status::OK();\n  }\n\n  virtual Status NewLogger(const std::string& fname, Logger** result) {\n    *result = new NoOpLogger;\n    return Status::OK();\n  }\n\n private:\n  // Map from filenames to FileState objects, representing a simple file system.\n  typedef std::map<std::string, FileState*> FileSystem;\n  port::Mutex mutex_;\n  FileSystem file_map_;  // Protected by mutex_.\n};\n\n}  // namespace\n\nEnv* NewMemEnv(Env* base_env) {\n  return new InMemoryEnv(base_env);\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/helpers/memenv/memenv.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_HELPERS_MEMENV_MEMENV_H_\n#define STORAGE_LEVELDB_HELPERS_MEMENV_MEMENV_H_\n\nnamespace leveldb {\n\nclass Env;\n\n// Returns a new environment that stores its data in memory and delegates\n// all non-file-storage tasks to base_env. The caller must delete the result\n// when it is no longer needed.\n// *base_env must remain live while the result is in use.\nEnv* NewMemEnv(Env* base_env);\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_HELPERS_MEMENV_MEMENV_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/helpers/memenv/memenv_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"helpers/memenv/memenv.h\"\n\n#include \"db/db_impl.h\"\n#include \"leveldb/db.h\"\n#include \"leveldb/env.h\"\n#include \"util/testharness.h\"\n#include <string>\n#include <vector>\n\nnamespace leveldb {\n\nclass MemEnvTest {\n public:\n  Env* env_;\n\n  MemEnvTest()\n      : env_(NewMemEnv(Env::Default())) {\n  }\n  ~MemEnvTest() {\n    delete env_;\n  }\n};\n\nTEST(MemEnvTest, Basics) {\n  uint64_t file_size;\n  WritableFile* writable_file;\n  std::vector<std::string> children;\n\n  ASSERT_OK(env_->CreateDir(\"/dir\"));\n\n  // Check that the directory is empty.\n  ASSERT_TRUE(!env_->FileExists(\"/dir/non_existent\"));\n  ASSERT_TRUE(!env_->GetFileSize(\"/dir/non_existent\", &file_size).ok());\n  ASSERT_OK(env_->GetChildren(\"/dir\", &children));\n  ASSERT_EQ(0, children.size());\n\n  // Create a file.\n  ASSERT_OK(env_->NewWritableFile(\"/dir/f\", &writable_file));\n  ASSERT_OK(env_->GetFileSize(\"/dir/f\", &file_size));\n  ASSERT_EQ(0, file_size);\n  delete writable_file;\n\n  // Check that the file exists.\n  ASSERT_TRUE(env_->FileExists(\"/dir/f\"));\n  ASSERT_OK(env_->GetFileSize(\"/dir/f\", &file_size));\n  ASSERT_EQ(0, file_size);\n  ASSERT_OK(env_->GetChildren(\"/dir\", &children));\n  ASSERT_EQ(1, children.size());\n  ASSERT_EQ(\"f\", children[0]);\n\n  // Write to the file.\n  ASSERT_OK(env_->NewWritableFile(\"/dir/f\", &writable_file));\n  ASSERT_OK(writable_file->Append(\"abc\"));\n  delete writable_file;\n\n  // Check that append works.\n  ASSERT_OK(env_->NewAppendableFile(\"/dir/f\", &writable_file));\n  ASSERT_OK(env_->GetFileSize(\"/dir/f\", &file_size));\n  ASSERT_EQ(3, file_size);\n  ASSERT_OK(writable_file->Append(\"hello\"));\n  delete writable_file;\n\n  // Check for expected size.\n  ASSERT_OK(env_->GetFileSize(\"/dir/f\", &file_size));\n  ASSERT_EQ(8, file_size);\n\n  // Check that renaming works.\n  ASSERT_TRUE(!env_->RenameFile(\"/dir/non_existent\", \"/dir/g\").ok());\n  ASSERT_OK(env_->RenameFile(\"/dir/f\", \"/dir/g\"));\n  ASSERT_TRUE(!env_->FileExists(\"/dir/f\"));\n  ASSERT_TRUE(env_->FileExists(\"/dir/g\"));\n  ASSERT_OK(env_->GetFileSize(\"/dir/g\", &file_size));\n  ASSERT_EQ(8, file_size);\n\n  // Check that opening non-existent file fails.\n  SequentialFile* seq_file;\n  RandomAccessFile* rand_file;\n  ASSERT_TRUE(!env_->NewSequentialFile(\"/dir/non_existent\", &seq_file).ok());\n  ASSERT_TRUE(!seq_file);\n  ASSERT_TRUE(!env_->NewRandomAccessFile(\"/dir/non_existent\", &rand_file).ok());\n  ASSERT_TRUE(!rand_file);\n\n  // Check that deleting works.\n  ASSERT_TRUE(!env_->DeleteFile(\"/dir/non_existent\").ok());\n  ASSERT_OK(env_->DeleteFile(\"/dir/g\"));\n  ASSERT_TRUE(!env_->FileExists(\"/dir/g\"));\n  ASSERT_OK(env_->GetChildren(\"/dir\", &children));\n  ASSERT_EQ(0, children.size());\n  ASSERT_OK(env_->DeleteDir(\"/dir\"));\n}\n\nTEST(MemEnvTest, ReadWrite) {\n  WritableFile* writable_file;\n  SequentialFile* seq_file;\n  RandomAccessFile* rand_file;\n  Slice result;\n  char scratch[100];\n\n  ASSERT_OK(env_->CreateDir(\"/dir\"));\n\n  ASSERT_OK(env_->NewWritableFile(\"/dir/f\", &writable_file));\n  ASSERT_OK(writable_file->Append(\"hello \"));\n  ASSERT_OK(writable_file->Append(\"world\"));\n  delete writable_file;\n\n  // Read sequentially.\n  ASSERT_OK(env_->NewSequentialFile(\"/dir/f\", &seq_file));\n  ASSERT_OK(seq_file->Read(5, &result, scratch)); // Read \"hello\".\n  ASSERT_EQ(0, result.compare(\"hello\"));\n  ASSERT_OK(seq_file->Skip(1));\n  ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Read \"world\".\n  ASSERT_EQ(0, result.compare(\"world\"));\n  ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Try reading past EOF.\n  ASSERT_EQ(0, result.size());\n  ASSERT_OK(seq_file->Skip(100)); // Try to skip past end of file.\n  ASSERT_OK(seq_file->Read(1000, &result, scratch));\n  ASSERT_EQ(0, result.size());\n  delete seq_file;\n\n  // Random reads.\n  ASSERT_OK(env_->NewRandomAccessFile(\"/dir/f\", &rand_file));\n  ASSERT_OK(rand_file->Read(6, 5, &result, scratch)); // Read \"world\".\n  ASSERT_EQ(0, result.compare(\"world\"));\n  ASSERT_OK(rand_file->Read(0, 5, &result, scratch)); // Read \"hello\".\n  ASSERT_EQ(0, result.compare(\"hello\"));\n  ASSERT_OK(rand_file->Read(10, 100, &result, scratch)); // Read \"d\".\n  ASSERT_EQ(0, result.compare(\"d\"));\n\n  // Too high offset.\n  ASSERT_TRUE(!rand_file->Read(1000, 5, &result, scratch).ok());\n  delete rand_file;\n}\n\nTEST(MemEnvTest, Locks) {\n  FileLock* lock;\n\n  // These are no-ops, but we test they return success.\n  ASSERT_OK(env_->LockFile(\"some file\", &lock));\n  ASSERT_OK(env_->UnlockFile(lock));\n}\n\nTEST(MemEnvTest, Misc) {\n  std::string test_dir;\n  ASSERT_OK(env_->GetTestDirectory(&test_dir));\n  ASSERT_TRUE(!test_dir.empty());\n\n  WritableFile* writable_file;\n  ASSERT_OK(env_->NewWritableFile(\"/a/b\", &writable_file));\n\n  // These are no-ops, but we test they return success.\n  ASSERT_OK(writable_file->Sync());\n  ASSERT_OK(writable_file->Flush());\n  ASSERT_OK(writable_file->Close());\n  delete writable_file;\n}\n\nTEST(MemEnvTest, LargeWrite) {\n  const size_t kWriteSize = 300 * 1024;\n  char* scratch = new char[kWriteSize * 2];\n\n  std::string write_data;\n  for (size_t i = 0; i < kWriteSize; ++i) {\n    write_data.append(1, static_cast<char>(i));\n  }\n\n  WritableFile* writable_file;\n  ASSERT_OK(env_->NewWritableFile(\"/dir/f\", &writable_file));\n  ASSERT_OK(writable_file->Append(\"foo\"));\n  ASSERT_OK(writable_file->Append(write_data));\n  delete writable_file;\n\n  SequentialFile* seq_file;\n  Slice result;\n  ASSERT_OK(env_->NewSequentialFile(\"/dir/f\", &seq_file));\n  ASSERT_OK(seq_file->Read(3, &result, scratch)); // Read \"foo\".\n  ASSERT_EQ(0, result.compare(\"foo\"));\n\n  size_t read = 0;\n  std::string read_data;\n  while (read < kWriteSize) {\n    ASSERT_OK(seq_file->Read(kWriteSize - read, &result, scratch));\n    read_data.append(result.data(), result.size());\n    read += result.size();\n  }\n  ASSERT_TRUE(write_data == read_data);\n  delete seq_file;\n  delete [] scratch;\n}\n\nTEST(MemEnvTest, DBTest) {\n  Options options;\n  options.create_if_missing = true;\n  options.env = env_;\n  DB* db;\n\n  const Slice keys[] = {Slice(\"aaa\"), Slice(\"bbb\"), Slice(\"ccc\")};\n  const Slice vals[] = {Slice(\"foo\"), Slice(\"bar\"), Slice(\"baz\")};\n\n  ASSERT_OK(DB::Open(options, \"/dir/db\", &db));\n  for (size_t i = 0; i < 3; ++i) {\n    ASSERT_OK(db->Put(WriteOptions(), keys[i], vals[i]));\n  }\n\n  for (size_t i = 0; i < 3; ++i) {\n    std::string res;\n    ASSERT_OK(db->Get(ReadOptions(), keys[i], &res));\n    ASSERT_TRUE(res == vals[i]);\n  }\n\n  Iterator* iterator = db->NewIterator(ReadOptions());\n  iterator->SeekToFirst();\n  for (size_t i = 0; i < 3; ++i) {\n    ASSERT_TRUE(iterator->Valid());\n    ASSERT_TRUE(keys[i] == iterator->key());\n    ASSERT_TRUE(vals[i] == iterator->value());\n    iterator->Next();\n  }\n  ASSERT_TRUE(!iterator->Valid());\n  delete iterator;\n\n  DBImpl* dbi = reinterpret_cast<DBImpl*>(db);\n  ASSERT_OK(dbi->TEST_CompactMemTable());\n\n  for (size_t i = 0; i < 3; ++i) {\n    std::string res;\n    ASSERT_OK(db->Get(ReadOptions(), keys[i], &res));\n    ASSERT_TRUE(res == vals[i]);\n  }\n\n  delete db;\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/include/leveldb/c.h",
    "content": "/* Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n  Use of this source code is governed by a BSD-style license that can be\n  found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n  C bindings for leveldb.  May be useful as a stable ABI that can be\n  used by programs that keep leveldb in a shared library, or for\n  a JNI api.\n\n  Does not support:\n  . getters for the option types\n  . custom comparators that implement key shortening\n  . custom iter, db, env, cache implementations using just the C bindings\n\n  Some conventions:\n\n  (1) We expose just opaque struct pointers and functions to clients.\n  This allows us to change internal representations without having to\n  recompile clients.\n\n  (2) For simplicity, there is no equivalent to the Slice type.  Instead,\n  the caller has to pass the pointer and length as separate\n  arguments.\n\n  (3) Errors are represented by a null-terminated c string.  NULL\n  means no error.  All operations that can raise an error are passed\n  a \"char** errptr\" as the last argument.  One of the following must\n  be true on entry:\n     *errptr == NULL\n     *errptr points to a malloc()ed null-terminated error message\n       (On Windows, *errptr must have been malloc()-ed by this library.)\n  On success, a leveldb routine leaves *errptr unchanged.\n  On failure, leveldb frees the old value of *errptr and\n  set *errptr to a malloc()ed error message.\n\n  (4) Bools have the type unsigned char (0 == false; rest == true)\n\n  (5) All of the pointer arguments must be non-NULL.\n*/\n\n#ifndef STORAGE_LEVELDB_INCLUDE_C_H_\n#define STORAGE_LEVELDB_INCLUDE_C_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdarg.h>\n#include <stddef.h>\n#include <stdint.h>\n\n/* Exported types */\n\ntypedef struct leveldb_t               leveldb_t;\ntypedef struct leveldb_cache_t         leveldb_cache_t;\ntypedef struct leveldb_comparator_t    leveldb_comparator_t;\ntypedef struct leveldb_env_t           leveldb_env_t;\ntypedef struct leveldb_filelock_t      leveldb_filelock_t;\ntypedef struct leveldb_filterpolicy_t  leveldb_filterpolicy_t;\ntypedef struct leveldb_iterator_t      leveldb_iterator_t;\ntypedef struct leveldb_logger_t        leveldb_logger_t;\ntypedef struct leveldb_options_t       leveldb_options_t;\ntypedef struct leveldb_randomfile_t    leveldb_randomfile_t;\ntypedef struct leveldb_readoptions_t   leveldb_readoptions_t;\ntypedef struct leveldb_seqfile_t       leveldb_seqfile_t;\ntypedef struct leveldb_snapshot_t      leveldb_snapshot_t;\ntypedef struct leveldb_writablefile_t  leveldb_writablefile_t;\ntypedef struct leveldb_writebatch_t    leveldb_writebatch_t;\ntypedef struct leveldb_writeoptions_t  leveldb_writeoptions_t;\n\n/* DB operations */\n\nextern leveldb_t* leveldb_open(\n    const leveldb_options_t* options,\n    const char* name,\n    char** errptr);\n\nextern void leveldb_close(leveldb_t* db);\n\nextern void leveldb_put(\n    leveldb_t* db,\n    const leveldb_writeoptions_t* options,\n    const char* key, size_t keylen,\n    const char* val, size_t vallen,\n    char** errptr);\n\nextern void leveldb_delete(\n    leveldb_t* db,\n    const leveldb_writeoptions_t* options,\n    const char* key, size_t keylen,\n    char** errptr);\n\nextern void leveldb_write(\n    leveldb_t* db,\n    const leveldb_writeoptions_t* options,\n    leveldb_writebatch_t* batch,\n    char** errptr);\n\n/* Returns NULL if not found.  A malloc()ed array otherwise.\n   Stores the length of the array in *vallen. */\nextern char* leveldb_get(\n    leveldb_t* db,\n    const leveldb_readoptions_t* options,\n    const char* key, size_t keylen,\n    size_t* vallen,\n    char** errptr);\n\nextern leveldb_iterator_t* leveldb_create_iterator(\n    leveldb_t* db,\n    const leveldb_readoptions_t* options);\n\nextern const leveldb_snapshot_t* leveldb_create_snapshot(\n    leveldb_t* db);\n\nextern void leveldb_release_snapshot(\n    leveldb_t* db,\n    const leveldb_snapshot_t* snapshot);\n\n/* Returns NULL if property name is unknown.\n   Else returns a pointer to a malloc()-ed null-terminated value. */\nextern char* leveldb_property_value(\n    leveldb_t* db,\n    const char* propname);\n\nextern void leveldb_approximate_sizes(\n    leveldb_t* db,\n    int num_ranges,\n    const char* const* range_start_key, const size_t* range_start_key_len,\n    const char* const* range_limit_key, const size_t* range_limit_key_len,\n    uint64_t* sizes);\n\nextern void leveldb_compact_range(\n    leveldb_t* db,\n    const char* start_key, size_t start_key_len,\n    const char* limit_key, size_t limit_key_len);\n\n/* Management operations */\n\nextern void leveldb_destroy_db(\n    const leveldb_options_t* options,\n    const char* name,\n    char** errptr);\n\nextern void leveldb_repair_db(\n    const leveldb_options_t* options,\n    const char* name,\n    char** errptr);\n\n/* Iterator */\n\nextern void leveldb_iter_destroy(leveldb_iterator_t*);\nextern unsigned char leveldb_iter_valid(const leveldb_iterator_t*);\nextern void leveldb_iter_seek_to_first(leveldb_iterator_t*);\nextern void leveldb_iter_seek_to_last(leveldb_iterator_t*);\nextern void leveldb_iter_seek(leveldb_iterator_t*, const char* k, size_t klen);\nextern void leveldb_iter_next(leveldb_iterator_t*);\nextern void leveldb_iter_prev(leveldb_iterator_t*);\nextern const char* leveldb_iter_key(const leveldb_iterator_t*, size_t* klen);\nextern const char* leveldb_iter_value(const leveldb_iterator_t*, size_t* vlen);\nextern void leveldb_iter_get_error(const leveldb_iterator_t*, char** errptr);\n\n/* Write batch */\n\nextern leveldb_writebatch_t* leveldb_writebatch_create();\nextern void leveldb_writebatch_destroy(leveldb_writebatch_t*);\nextern void leveldb_writebatch_clear(leveldb_writebatch_t*);\nextern void leveldb_writebatch_put(\n    leveldb_writebatch_t*,\n    const char* key, size_t klen,\n    const char* val, size_t vlen);\nextern void leveldb_writebatch_delete(\n    leveldb_writebatch_t*,\n    const char* key, size_t klen);\nextern void leveldb_writebatch_iterate(\n    leveldb_writebatch_t*,\n    void* state,\n    void (*put)(void*, const char* k, size_t klen, const char* v, size_t vlen),\n    void (*deleted)(void*, const char* k, size_t klen));\n\n/* Options */\n\nextern leveldb_options_t* leveldb_options_create();\nextern void leveldb_options_destroy(leveldb_options_t*);\nextern void leveldb_options_set_comparator(\n    leveldb_options_t*,\n    leveldb_comparator_t*);\nextern void leveldb_options_set_filter_policy(\n    leveldb_options_t*,\n    leveldb_filterpolicy_t*);\nextern void leveldb_options_set_create_if_missing(\n    leveldb_options_t*, unsigned char);\nextern void leveldb_options_set_error_if_exists(\n    leveldb_options_t*, unsigned char);\nextern void leveldb_options_set_paranoid_checks(\n    leveldb_options_t*, unsigned char);\nextern void leveldb_options_set_env(leveldb_options_t*, leveldb_env_t*);\nextern void leveldb_options_set_info_log(leveldb_options_t*, leveldb_logger_t*);\nextern void leveldb_options_set_write_buffer_size(leveldb_options_t*, size_t);\nextern void leveldb_options_set_max_open_files(leveldb_options_t*, int);\nextern void leveldb_options_set_cache(leveldb_options_t*, leveldb_cache_t*);\nextern void leveldb_options_set_block_size(leveldb_options_t*, size_t);\nextern void leveldb_options_set_block_restart_interval(leveldb_options_t*, int);\n\nenum {\n  leveldb_no_compression = 0,\n  leveldb_snappy_compression = 1\n};\nextern void leveldb_options_set_compression(leveldb_options_t*, int);\n\n/* Comparator */\n\nextern leveldb_comparator_t* leveldb_comparator_create(\n    void* state,\n    void (*destructor)(void*),\n    int (*compare)(\n        void*,\n        const char* a, size_t alen,\n        const char* b, size_t blen),\n    const char* (*name)(void*));\nextern void leveldb_comparator_destroy(leveldb_comparator_t*);\n\n/* Filter policy */\n\nextern leveldb_filterpolicy_t* leveldb_filterpolicy_create(\n    void* state,\n    void (*destructor)(void*),\n    char* (*create_filter)(\n        void*,\n        const char* const* key_array, const size_t* key_length_array,\n        int num_keys,\n        size_t* filter_length),\n    unsigned char (*key_may_match)(\n        void*,\n        const char* key, size_t length,\n        const char* filter, size_t filter_length),\n    const char* (*name)(void*));\nextern void leveldb_filterpolicy_destroy(leveldb_filterpolicy_t*);\n\nextern leveldb_filterpolicy_t* leveldb_filterpolicy_create_bloom(\n    int bits_per_key);\n\n/* Read options */\n\nextern leveldb_readoptions_t* leveldb_readoptions_create();\nextern void leveldb_readoptions_destroy(leveldb_readoptions_t*);\nextern void leveldb_readoptions_set_verify_checksums(\n    leveldb_readoptions_t*,\n    unsigned char);\nextern void leveldb_readoptions_set_fill_cache(\n    leveldb_readoptions_t*, unsigned char);\nextern void leveldb_readoptions_set_snapshot(\n    leveldb_readoptions_t*,\n    const leveldb_snapshot_t*);\n\n/* Write options */\n\nextern leveldb_writeoptions_t* leveldb_writeoptions_create();\nextern void leveldb_writeoptions_destroy(leveldb_writeoptions_t*);\nextern void leveldb_writeoptions_set_sync(\n    leveldb_writeoptions_t*, unsigned char);\n\n/* Cache */\n\nextern leveldb_cache_t* leveldb_cache_create_lru(size_t capacity);\nextern void leveldb_cache_destroy(leveldb_cache_t* cache);\n\n/* Env */\n\nextern leveldb_env_t* leveldb_create_default_env();\nextern void leveldb_env_destroy(leveldb_env_t*);\n\n/* Utility */\n\n/* Calls free(ptr).\n   REQUIRES: ptr was malloc()-ed and returned by one of the routines\n   in this file.  Note that in certain cases (typically on Windows), you\n   may need to call this routine instead of free(ptr) to dispose of\n   malloc()-ed memory returned by this library. */\nextern void leveldb_free(void* ptr);\n\n/* Return the major version number for this release. */\nextern int leveldb_major_version();\n\n/* Return the minor version number for this release. */\nextern int leveldb_minor_version();\n\n#ifdef __cplusplus\n}  /* end extern \"C\" */\n#endif\n\n#endif  /* STORAGE_LEVELDB_INCLUDE_C_H_ */\n"
  },
  {
    "path": "deps/leveldb-1.20/include/leveldb/cache.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// A Cache is an interface that maps keys to values.  It has internal\n// synchronization and may be safely accessed concurrently from\n// multiple threads.  It may automatically evict entries to make room\n// for new entries.  Values have a specified charge against the cache\n// capacity.  For example, a cache where the values are variable\n// length strings, may use the length of the string as the charge for\n// the string.\n//\n// A builtin cache implementation with a least-recently-used eviction\n// policy is provided.  Clients may use their own implementations if\n// they want something more sophisticated (like scan-resistance, a\n// custom eviction policy, variable cache sizing, etc.)\n\n#ifndef STORAGE_LEVELDB_INCLUDE_CACHE_H_\n#define STORAGE_LEVELDB_INCLUDE_CACHE_H_\n\n#include <stdint.h>\n#include \"leveldb/slice.h\"\n\nnamespace leveldb {\n\nclass Cache;\n\n// Create a new cache with a fixed size capacity.  This implementation\n// of Cache uses a least-recently-used eviction policy.\nextern Cache* NewLRUCache(size_t capacity);\n\nclass Cache {\n public:\n  Cache() { }\n\n  // Destroys all existing entries by calling the \"deleter\"\n  // function that was passed to the constructor.\n  virtual ~Cache();\n\n  // Opaque handle to an entry stored in the cache.\n  struct Handle { };\n\n  // Insert a mapping from key->value into the cache and assign it\n  // the specified charge against the total cache capacity.\n  //\n  // Returns a handle that corresponds to the mapping.  The caller\n  // must call this->Release(handle) when the returned mapping is no\n  // longer needed.\n  //\n  // When the inserted entry is no longer needed, the key and\n  // value will be passed to \"deleter\".\n  virtual Handle* Insert(const Slice& key, void* value, size_t charge,\n                         void (*deleter)(const Slice& key, void* value)) = 0;\n\n  // If the cache has no mapping for \"key\", returns NULL.\n  //\n  // Else return a handle that corresponds to the mapping.  The caller\n  // must call this->Release(handle) when the returned mapping is no\n  // longer needed.\n  virtual Handle* Lookup(const Slice& key) = 0;\n\n  // Release a mapping returned by a previous Lookup().\n  // REQUIRES: handle must not have been released yet.\n  // REQUIRES: handle must have been returned by a method on *this.\n  virtual void Release(Handle* handle) = 0;\n\n  // Return the value encapsulated in a handle returned by a\n  // successful Lookup().\n  // REQUIRES: handle must not have been released yet.\n  // REQUIRES: handle must have been returned by a method on *this.\n  virtual void* Value(Handle* handle) = 0;\n\n  // If the cache contains entry for key, erase it.  Note that the\n  // underlying entry will be kept around until all existing handles\n  // to it have been released.\n  virtual void Erase(const Slice& key) = 0;\n\n  // Return a new numeric id.  May be used by multiple clients who are\n  // sharing the same cache to partition the key space.  Typically the\n  // client will allocate a new id at startup and prepend the id to\n  // its cache keys.\n  virtual uint64_t NewId() = 0;\n\n  // Remove all cache entries that are not actively in use.  Memory-constrained\n  // applications may wish to call this method to reduce memory usage.\n  // Default implementation of Prune() does nothing.  Subclasses are strongly\n  // encouraged to override the default implementation.  A future release of\n  // leveldb may change Prune() to a pure abstract method.\n  virtual void Prune() {}\n\n  // Return an estimate of the combined charges of all elements stored in the\n  // cache.\n  virtual size_t TotalCharge() const = 0;\n\n private:\n  void LRU_Remove(Handle* e);\n  void LRU_Append(Handle* e);\n  void Unref(Handle* e);\n\n  struct Rep;\n  Rep* rep_;\n\n  // No copying allowed\n  Cache(const Cache&);\n  void operator=(const Cache&);\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_INCLUDE_CACHE_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/include/leveldb/comparator.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_INCLUDE_COMPARATOR_H_\n#define STORAGE_LEVELDB_INCLUDE_COMPARATOR_H_\n\n#include <string>\n\nnamespace leveldb {\n\nclass Slice;\n\n// A Comparator object provides a total order across slices that are\n// used as keys in an sstable or a database.  A Comparator implementation\n// must be thread-safe since leveldb may invoke its methods concurrently\n// from multiple threads.\nclass Comparator {\n public:\n  virtual ~Comparator();\n\n  // Three-way comparison.  Returns value:\n  //   < 0 iff \"a\" < \"b\",\n  //   == 0 iff \"a\" == \"b\",\n  //   > 0 iff \"a\" > \"b\"\n  virtual int Compare(const Slice& a, const Slice& b) const = 0;\n\n  // The name of the comparator.  Used to check for comparator\n  // mismatches (i.e., a DB created with one comparator is\n  // accessed using a different comparator.\n  //\n  // The client of this package should switch to a new name whenever\n  // the comparator implementation changes in a way that will cause\n  // the relative ordering of any two keys to change.\n  //\n  // Names starting with \"leveldb.\" are reserved and should not be used\n  // by any clients of this package.\n  virtual const char* Name() const = 0;\n\n  // Advanced functions: these are used to reduce the space requirements\n  // for internal data structures like index blocks.\n\n  // If *start < limit, changes *start to a short string in [start,limit).\n  // Simple comparator implementations may return with *start unchanged,\n  // i.e., an implementation of this method that does nothing is correct.\n  virtual void FindShortestSeparator(\n      std::string* start,\n      const Slice& limit) const = 0;\n\n  // Changes *key to a short string >= *key.\n  // Simple comparator implementations may return with *key unchanged,\n  // i.e., an implementation of this method that does nothing is correct.\n  virtual void FindShortSuccessor(std::string* key) const = 0;\n};\n\n// Return a builtin comparator that uses lexicographic byte-wise\n// ordering.  The result remains the property of this module and\n// must not be deleted.\nextern const Comparator* BytewiseComparator();\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_INCLUDE_COMPARATOR_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/include/leveldb/db.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_INCLUDE_DB_H_\n#define STORAGE_LEVELDB_INCLUDE_DB_H_\n\n#include <stdint.h>\n#include <stdio.h>\n#include \"leveldb/iterator.h\"\n#include \"leveldb/options.h\"\n\nnamespace leveldb {\n\n// Update Makefile if you change these\nstatic const int kMajorVersion = 1;\nstatic const int kMinorVersion = 20;\n\nstruct Options;\nstruct ReadOptions;\nstruct WriteOptions;\nclass WriteBatch;\n\n// Abstract handle to particular state of a DB.\n// A Snapshot is an immutable object and can therefore be safely\n// accessed from multiple threads without any external synchronization.\nclass Snapshot {\n protected:\n  virtual ~Snapshot();\n};\n\n// A range of keys\nstruct Range {\n  Slice start;          // Included in the range\n  Slice limit;          // Not included in the range\n\n  Range() { }\n  Range(const Slice& s, const Slice& l) : start(s), limit(l) { }\n};\n\n// A DB is a persistent ordered map from keys to values.\n// A DB is safe for concurrent access from multiple threads without\n// any external synchronization.\nclass DB {\n public:\n  // Open the database with the specified \"name\".\n  // Stores a pointer to a heap-allocated database in *dbptr and returns\n  // OK on success.\n  // Stores NULL in *dbptr and returns a non-OK status on error.\n  // Caller should delete *dbptr when it is no longer needed.\n  static Status Open(const Options& options,\n                     const std::string& name,\n                     DB** dbptr);\n\n  DB() { }\n  virtual ~DB();\n\n  // Set the database entry for \"key\" to \"value\".  Returns OK on success,\n  // and a non-OK status on error.\n  // Note: consider setting options.sync = true.\n  virtual Status Put(const WriteOptions& options,\n                     const Slice& key,\n                     const Slice& value) = 0;\n\n  // Remove the database entry (if any) for \"key\".  Returns OK on\n  // success, and a non-OK status on error.  It is not an error if \"key\"\n  // did not exist in the database.\n  // Note: consider setting options.sync = true.\n  virtual Status Delete(const WriteOptions& options, const Slice& key) = 0;\n\n  // Apply the specified updates to the database.\n  // Returns OK on success, non-OK on failure.\n  // Note: consider setting options.sync = true.\n  virtual Status Write(const WriteOptions& options, WriteBatch* updates) = 0;\n\n  // If the database contains an entry for \"key\" store the\n  // corresponding value in *value and return OK.\n  //\n  // If there is no entry for \"key\" leave *value unchanged and return\n  // a status for which Status::IsNotFound() returns true.\n  //\n  // May return some other Status on an error.\n  virtual Status Get(const ReadOptions& options,\n                     const Slice& key, std::string* value) = 0;\n\n  // Return a heap-allocated iterator over the contents of the database.\n  // The result of NewIterator() is initially invalid (caller must\n  // call one of the Seek methods on the iterator before using it).\n  //\n  // Caller should delete the iterator when it is no longer needed.\n  // The returned iterator should be deleted before this db is deleted.\n  virtual Iterator* NewIterator(const ReadOptions& options) = 0;\n\n  // Return a handle to the current DB state.  Iterators created with\n  // this handle will all observe a stable snapshot of the current DB\n  // state.  The caller must call ReleaseSnapshot(result) when the\n  // snapshot is no longer needed.\n  virtual const Snapshot* GetSnapshot() = 0;\n\n  // Release a previously acquired snapshot.  The caller must not\n  // use \"snapshot\" after this call.\n  virtual void ReleaseSnapshot(const Snapshot* snapshot) = 0;\n\n  // DB implementations can export properties about their state\n  // via this method.  If \"property\" is a valid property understood by this\n  // DB implementation, fills \"*value\" with its current value and returns\n  // true.  Otherwise returns false.\n  //\n  //\n  // Valid property names include:\n  //\n  //  \"leveldb.num-files-at-level<N>\" - return the number of files at level <N>,\n  //     where <N> is an ASCII representation of a level number (e.g. \"0\").\n  //  \"leveldb.stats\" - returns a multi-line string that describes statistics\n  //     about the internal operation of the DB.\n  //  \"leveldb.sstables\" - returns a multi-line string that describes all\n  //     of the sstables that make up the db contents.\n  //  \"leveldb.approximate-memory-usage\" - returns the approximate number of\n  //     bytes of memory in use by the DB.\n  virtual bool GetProperty(const Slice& property, std::string* value) = 0;\n\n  // For each i in [0,n-1], store in \"sizes[i]\", the approximate\n  // file system space used by keys in \"[range[i].start .. range[i].limit)\".\n  //\n  // Note that the returned sizes measure file system space usage, so\n  // if the user data compresses by a factor of ten, the returned\n  // sizes will be one-tenth the size of the corresponding user data size.\n  //\n  // The results may not include the sizes of recently written data.\n  virtual void GetApproximateSizes(const Range* range, int n,\n                                   uint64_t* sizes) = 0;\n\n  // Compact the underlying storage for the key range [*begin,*end].\n  // In particular, deleted and overwritten versions are discarded,\n  // and the data is rearranged to reduce the cost of operations\n  // needed to access the data.  This operation should typically only\n  // be invoked by users who understand the underlying implementation.\n  //\n  // begin==NULL is treated as a key before all keys in the database.\n  // end==NULL is treated as a key after all keys in the database.\n  // Therefore the following call will compact the entire database:\n  //    db->CompactRange(NULL, NULL);\n  virtual void CompactRange(const Slice* begin, const Slice* end) = 0;\n\n private:\n  // No copying allowed\n  DB(const DB&);\n  void operator=(const DB&);\n};\n\n// Destroy the contents of the specified database.\n// Be very careful using this method.\nStatus DestroyDB(const std::string& name, const Options& options);\n\n// If a DB cannot be opened, you may attempt to call this method to\n// resurrect as much of the contents of the database as possible.\n// Some data may be lost, so be careful when calling this function\n// on a database that contains important information.\nStatus RepairDB(const std::string& dbname, const Options& options);\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_INCLUDE_DB_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/include/leveldb/dumpfile.h",
    "content": "// Copyright (c) 2014 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_\n#define STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_\n\n#include <string>\n#include \"leveldb/env.h\"\n#include \"leveldb/status.h\"\n\nnamespace leveldb {\n\n// Dump the contents of the file named by fname in text format to\n// *dst.  Makes a sequence of dst->Append() calls; each call is passed\n// the newline-terminated text corresponding to a single item found\n// in the file.\n//\n// Returns a non-OK result if fname does not name a leveldb storage\n// file, or if the file cannot be read.\nStatus DumpFile(Env* env, const std::string& fname, WritableFile* dst);\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/include/leveldb/env.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// An Env is an interface used by the leveldb implementation to access\n// operating system functionality like the filesystem etc.  Callers\n// may wish to provide a custom Env object when opening a database to\n// get fine gain control; e.g., to rate limit file system operations.\n//\n// All Env implementations are safe for concurrent access from\n// multiple threads without any external synchronization.\n\n#ifndef STORAGE_LEVELDB_INCLUDE_ENV_H_\n#define STORAGE_LEVELDB_INCLUDE_ENV_H_\n\n#include <string>\n#include <vector>\n#include <stdarg.h>\n#include <stdint.h>\n#include \"leveldb/status.h\"\n\nnamespace leveldb {\n\nclass FileLock;\nclass Logger;\nclass RandomAccessFile;\nclass SequentialFile;\nclass Slice;\nclass WritableFile;\n\nclass Env {\n public:\n  Env() { }\n  virtual ~Env();\n\n  // Return a default environment suitable for the current operating\n  // system.  Sophisticated users may wish to provide their own Env\n  // implementation instead of relying on this default environment.\n  //\n  // The result of Default() belongs to leveldb and must never be deleted.\n  static Env* Default();\n\n  // Create a brand new sequentially-readable file with the specified name.\n  // On success, stores a pointer to the new file in *result and returns OK.\n  // On failure stores NULL in *result and returns non-OK.  If the file does\n  // not exist, returns a non-OK status.  Implementations should return a\n  // NotFound status when the file does not exist.\n  //\n  // The returned file will only be accessed by one thread at a time.\n  virtual Status NewSequentialFile(const std::string& fname,\n                                   SequentialFile** result) = 0;\n\n  // Create a brand new random access read-only file with the\n  // specified name.  On success, stores a pointer to the new file in\n  // *result and returns OK.  On failure stores NULL in *result and\n  // returns non-OK.  If the file does not exist, returns a non-OK\n  // status.  Implementations should return a NotFound status when the file does\n  // not exist.\n  //\n  // The returned file may be concurrently accessed by multiple threads.\n  virtual Status NewRandomAccessFile(const std::string& fname,\n                                     RandomAccessFile** result) = 0;\n\n  // Create an object that writes to a new file with the specified\n  // name.  Deletes any existing file with the same name and creates a\n  // new file.  On success, stores a pointer to the new file in\n  // *result and returns OK.  On failure stores NULL in *result and\n  // returns non-OK.\n  //\n  // The returned file will only be accessed by one thread at a time.\n  virtual Status NewWritableFile(const std::string& fname,\n                                 WritableFile** result) = 0;\n\n  // Create an object that either appends to an existing file, or\n  // writes to a new file (if the file does not exist to begin with).\n  // On success, stores a pointer to the new file in *result and\n  // returns OK.  On failure stores NULL in *result and returns\n  // non-OK.\n  //\n  // The returned file will only be accessed by one thread at a time.\n  //\n  // May return an IsNotSupportedError error if this Env does\n  // not allow appending to an existing file.  Users of Env (including\n  // the leveldb implementation) must be prepared to deal with\n  // an Env that does not support appending.\n  virtual Status NewAppendableFile(const std::string& fname,\n                                   WritableFile** result);\n\n  // Returns true iff the named file exists.\n  virtual bool FileExists(const std::string& fname) = 0;\n\n  // Store in *result the names of the children of the specified directory.\n  // The names are relative to \"dir\".\n  // Original contents of *results are dropped.\n  virtual Status GetChildren(const std::string& dir,\n                             std::vector<std::string>* result) = 0;\n\n  // Delete the named file.\n  virtual Status DeleteFile(const std::string& fname) = 0;\n\n  // Create the specified directory.\n  virtual Status CreateDir(const std::string& dirname) = 0;\n\n  // Delete the specified directory.\n  virtual Status DeleteDir(const std::string& dirname) = 0;\n\n  // Store the size of fname in *file_size.\n  virtual Status GetFileSize(const std::string& fname, uint64_t* file_size) = 0;\n\n  // Rename file src to target.\n  virtual Status RenameFile(const std::string& src,\n                            const std::string& target) = 0;\n\n  // Lock the specified file.  Used to prevent concurrent access to\n  // the same db by multiple processes.  On failure, stores NULL in\n  // *lock and returns non-OK.\n  //\n  // On success, stores a pointer to the object that represents the\n  // acquired lock in *lock and returns OK.  The caller should call\n  // UnlockFile(*lock) to release the lock.  If the process exits,\n  // the lock will be automatically released.\n  //\n  // If somebody else already holds the lock, finishes immediately\n  // with a failure.  I.e., this call does not wait for existing locks\n  // to go away.\n  //\n  // May create the named file if it does not already exist.\n  virtual Status LockFile(const std::string& fname, FileLock** lock) = 0;\n\n  // Release the lock acquired by a previous successful call to LockFile.\n  // REQUIRES: lock was returned by a successful LockFile() call\n  // REQUIRES: lock has not already been unlocked.\n  virtual Status UnlockFile(FileLock* lock) = 0;\n\n  // Arrange to run \"(*function)(arg)\" once in a background thread.\n  //\n  // \"function\" may run in an unspecified thread.  Multiple functions\n  // added to the same Env may run concurrently in different threads.\n  // I.e., the caller may not assume that background work items are\n  // serialized.\n  virtual void Schedule(\n      void (*function)(void* arg),\n      void* arg) = 0;\n\n  // Start a new thread, invoking \"function(arg)\" within the new thread.\n  // When \"function(arg)\" returns, the thread will be destroyed.\n  virtual void StartThread(void (*function)(void* arg), void* arg) = 0;\n\n  // *path is set to a temporary directory that can be used for testing. It may\n  // or many not have just been created. The directory may or may not differ\n  // between runs of the same process, but subsequent calls will return the\n  // same directory.\n  virtual Status GetTestDirectory(std::string* path) = 0;\n\n  // Create and return a log file for storing informational messages.\n  virtual Status NewLogger(const std::string& fname, Logger** result) = 0;\n\n  // Returns the number of micro-seconds since some fixed point in time. Only\n  // useful for computing deltas of time.\n  virtual uint64_t NowMicros() = 0;\n\n  // Sleep/delay the thread for the prescribed number of micro-seconds.\n  virtual void SleepForMicroseconds(int micros) = 0;\n\n private:\n  // No copying allowed\n  Env(const Env&);\n  void operator=(const Env&);\n};\n\n// A file abstraction for reading sequentially through a file\nclass SequentialFile {\n public:\n  SequentialFile() { }\n  virtual ~SequentialFile();\n\n  // Read up to \"n\" bytes from the file.  \"scratch[0..n-1]\" may be\n  // written by this routine.  Sets \"*result\" to the data that was\n  // read (including if fewer than \"n\" bytes were successfully read).\n  // May set \"*result\" to point at data in \"scratch[0..n-1]\", so\n  // \"scratch[0..n-1]\" must be live when \"*result\" is used.\n  // If an error was encountered, returns a non-OK status.\n  //\n  // REQUIRES: External synchronization\n  virtual Status Read(size_t n, Slice* result, char* scratch) = 0;\n\n  // Skip \"n\" bytes from the file. This is guaranteed to be no\n  // slower that reading the same data, but may be faster.\n  //\n  // If end of file is reached, skipping will stop at the end of the\n  // file, and Skip will return OK.\n  //\n  // REQUIRES: External synchronization\n  virtual Status Skip(uint64_t n) = 0;\n\n private:\n  // No copying allowed\n  SequentialFile(const SequentialFile&);\n  void operator=(const SequentialFile&);\n};\n\n// A file abstraction for randomly reading the contents of a file.\nclass RandomAccessFile {\n public:\n  RandomAccessFile() { }\n  virtual ~RandomAccessFile();\n\n  // Read up to \"n\" bytes from the file starting at \"offset\".\n  // \"scratch[0..n-1]\" may be written by this routine.  Sets \"*result\"\n  // to the data that was read (including if fewer than \"n\" bytes were\n  // successfully read).  May set \"*result\" to point at data in\n  // \"scratch[0..n-1]\", so \"scratch[0..n-1]\" must be live when\n  // \"*result\" is used.  If an error was encountered, returns a non-OK\n  // status.\n  //\n  // Safe for concurrent use by multiple threads.\n  virtual Status Read(uint64_t offset, size_t n, Slice* result,\n                      char* scratch) const = 0;\n\n private:\n  // No copying allowed\n  RandomAccessFile(const RandomAccessFile&);\n  void operator=(const RandomAccessFile&);\n};\n\n// A file abstraction for sequential writing.  The implementation\n// must provide buffering since callers may append small fragments\n// at a time to the file.\nclass WritableFile {\n public:\n  WritableFile() { }\n  virtual ~WritableFile();\n\n  virtual Status Append(const Slice& data) = 0;\n  virtual Status Close() = 0;\n  virtual Status Flush() = 0;\n  virtual Status Sync() = 0;\n\n private:\n  // No copying allowed\n  WritableFile(const WritableFile&);\n  void operator=(const WritableFile&);\n};\n\n// An interface for writing log messages.\nclass Logger {\n public:\n  Logger() { }\n  virtual ~Logger();\n\n  // Write an entry to the log file with the specified format.\n  virtual void Logv(const char* format, va_list ap) = 0;\n\n private:\n  // No copying allowed\n  Logger(const Logger&);\n  void operator=(const Logger&);\n};\n\n\n// Identifies a locked file.\nclass FileLock {\n public:\n  FileLock() { }\n  virtual ~FileLock();\n private:\n  // No copying allowed\n  FileLock(const FileLock&);\n  void operator=(const FileLock&);\n};\n\n// Log the specified data to *info_log if info_log is non-NULL.\nextern void Log(Logger* info_log, const char* format, ...)\n#   if defined(__GNUC__) || defined(__clang__)\n    __attribute__((__format__ (__printf__, 2, 3)))\n#   endif\n    ;\n\n// A utility routine: write \"data\" to the named file.\nextern Status WriteStringToFile(Env* env, const Slice& data,\n                                const std::string& fname);\n\n// A utility routine: read contents of named file into *data\nextern Status ReadFileToString(Env* env, const std::string& fname,\n                               std::string* data);\n\n// An implementation of Env that forwards all calls to another Env.\n// May be useful to clients who wish to override just part of the\n// functionality of another Env.\nclass EnvWrapper : public Env {\n public:\n  // Initialize an EnvWrapper that delegates all calls to *t\n  explicit EnvWrapper(Env* t) : target_(t) { }\n  virtual ~EnvWrapper();\n\n  // Return the target to which this Env forwards all calls\n  Env* target() const { return target_; }\n\n  // The following text is boilerplate that forwards all methods to target()\n  Status NewSequentialFile(const std::string& f, SequentialFile** r) {\n    return target_->NewSequentialFile(f, r);\n  }\n  Status NewRandomAccessFile(const std::string& f, RandomAccessFile** r) {\n    return target_->NewRandomAccessFile(f, r);\n  }\n  Status NewWritableFile(const std::string& f, WritableFile** r) {\n    return target_->NewWritableFile(f, r);\n  }\n  Status NewAppendableFile(const std::string& f, WritableFile** r) {\n    return target_->NewAppendableFile(f, r);\n  }\n  bool FileExists(const std::string& f) { return target_->FileExists(f); }\n  Status GetChildren(const std::string& dir, std::vector<std::string>* r) {\n    return target_->GetChildren(dir, r);\n  }\n  Status DeleteFile(const std::string& f) { return target_->DeleteFile(f); }\n  Status CreateDir(const std::string& d) { return target_->CreateDir(d); }\n  Status DeleteDir(const std::string& d) { return target_->DeleteDir(d); }\n  Status GetFileSize(const std::string& f, uint64_t* s) {\n    return target_->GetFileSize(f, s);\n  }\n  Status RenameFile(const std::string& s, const std::string& t) {\n    return target_->RenameFile(s, t);\n  }\n  Status LockFile(const std::string& f, FileLock** l) {\n    return target_->LockFile(f, l);\n  }\n  Status UnlockFile(FileLock* l) { return target_->UnlockFile(l); }\n  void Schedule(void (*f)(void*), void* a) {\n    return target_->Schedule(f, a);\n  }\n  void StartThread(void (*f)(void*), void* a) {\n    return target_->StartThread(f, a);\n  }\n  virtual Status GetTestDirectory(std::string* path) {\n    return target_->GetTestDirectory(path);\n  }\n  virtual Status NewLogger(const std::string& fname, Logger** result) {\n    return target_->NewLogger(fname, result);\n  }\n  uint64_t NowMicros() {\n    return target_->NowMicros();\n  }\n  void SleepForMicroseconds(int micros) {\n    target_->SleepForMicroseconds(micros);\n  }\n private:\n  Env* target_;\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_INCLUDE_ENV_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/include/leveldb/filter_policy.h",
    "content": "// Copyright (c) 2012 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// A database can be configured with a custom FilterPolicy object.\n// This object is responsible for creating a small filter from a set\n// of keys.  These filters are stored in leveldb and are consulted\n// automatically by leveldb to decide whether or not to read some\n// information from disk. In many cases, a filter can cut down the\n// number of disk seeks form a handful to a single disk seek per\n// DB::Get() call.\n//\n// Most people will want to use the builtin bloom filter support (see\n// NewBloomFilterPolicy() below).\n\n#ifndef STORAGE_LEVELDB_INCLUDE_FILTER_POLICY_H_\n#define STORAGE_LEVELDB_INCLUDE_FILTER_POLICY_H_\n\n#include <string>\n\nnamespace leveldb {\n\nclass Slice;\n\nclass FilterPolicy {\n public:\n  virtual ~FilterPolicy();\n\n  // Return the name of this policy.  Note that if the filter encoding\n  // changes in an incompatible way, the name returned by this method\n  // must be changed.  Otherwise, old incompatible filters may be\n  // passed to methods of this type.\n  virtual const char* Name() const = 0;\n\n  // keys[0,n-1] contains a list of keys (potentially with duplicates)\n  // that are ordered according to the user supplied comparator.\n  // Append a filter that summarizes keys[0,n-1] to *dst.\n  //\n  // Warning: do not change the initial contents of *dst.  Instead,\n  // append the newly constructed filter to *dst.\n  virtual void CreateFilter(const Slice* keys, int n, std::string* dst)\n      const = 0;\n\n  // \"filter\" contains the data appended by a preceding call to\n  // CreateFilter() on this class.  This method must return true if\n  // the key was in the list of keys passed to CreateFilter().\n  // This method may return true or false if the key was not on the\n  // list, but it should aim to return false with a high probability.\n  virtual bool KeyMayMatch(const Slice& key, const Slice& filter) const = 0;\n};\n\n// Return a new filter policy that uses a bloom filter with approximately\n// the specified number of bits per key.  A good value for bits_per_key\n// is 10, which yields a filter with ~ 1% false positive rate.\n//\n// Callers must delete the result after any database that is using the\n// result has been closed.\n//\n// Note: if you are using a custom comparator that ignores some parts\n// of the keys being compared, you must not use NewBloomFilterPolicy()\n// and must provide your own FilterPolicy that also ignores the\n// corresponding parts of the keys.  For example, if the comparator\n// ignores trailing spaces, it would be incorrect to use a\n// FilterPolicy (like NewBloomFilterPolicy) that does not ignore\n// trailing spaces in keys.\nextern const FilterPolicy* NewBloomFilterPolicy(int bits_per_key);\n\n}\n\n#endif  // STORAGE_LEVELDB_INCLUDE_FILTER_POLICY_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/include/leveldb/iterator.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// An iterator yields a sequence of key/value pairs from a source.\n// The following class defines the interface.  Multiple implementations\n// are provided by this library.  In particular, iterators are provided\n// to access the contents of a Table or a DB.\n//\n// Multiple threads can invoke const methods on an Iterator without\n// external synchronization, but if any of the threads may call a\n// non-const method, all threads accessing the same Iterator must use\n// external synchronization.\n\n#ifndef STORAGE_LEVELDB_INCLUDE_ITERATOR_H_\n#define STORAGE_LEVELDB_INCLUDE_ITERATOR_H_\n\n#include \"leveldb/slice.h\"\n#include \"leveldb/status.h\"\n\nnamespace leveldb {\n\nclass Iterator {\n public:\n  Iterator();\n  virtual ~Iterator();\n\n  // An iterator is either positioned at a key/value pair, or\n  // not valid.  This method returns true iff the iterator is valid.\n  virtual bool Valid() const = 0;\n\n  // Position at the first key in the source.  The iterator is Valid()\n  // after this call iff the source is not empty.\n  virtual void SeekToFirst() = 0;\n\n  // Position at the last key in the source.  The iterator is\n  // Valid() after this call iff the source is not empty.\n  virtual void SeekToLast() = 0;\n\n  // Position at the first key in the source that is at or past target.\n  // The iterator is Valid() after this call iff the source contains\n  // an entry that comes at or past target.\n  virtual void Seek(const Slice& target) = 0;\n\n  // Moves to the next entry in the source.  After this call, Valid() is\n  // true iff the iterator was not positioned at the last entry in the source.\n  // REQUIRES: Valid()\n  virtual void Next() = 0;\n\n  // Moves to the previous entry in the source.  After this call, Valid() is\n  // true iff the iterator was not positioned at the first entry in source.\n  // REQUIRES: Valid()\n  virtual void Prev() = 0;\n\n  // Return the key for the current entry.  The underlying storage for\n  // the returned slice is valid only until the next modification of\n  // the iterator.\n  // REQUIRES: Valid()\n  virtual Slice key() const = 0;\n\n  // Return the value for the current entry.  The underlying storage for\n  // the returned slice is valid only until the next modification of\n  // the iterator.\n  // REQUIRES: Valid()\n  virtual Slice value() const = 0;\n\n  // If an error has occurred, return it.  Else return an ok status.\n  virtual Status status() const = 0;\n\n  // Clients are allowed to register function/arg1/arg2 triples that\n  // will be invoked when this iterator is destroyed.\n  //\n  // Note that unlike all of the preceding methods, this method is\n  // not abstract and therefore clients should not override it.\n  typedef void (*CleanupFunction)(void* arg1, void* arg2);\n  void RegisterCleanup(CleanupFunction function, void* arg1, void* arg2);\n\n private:\n  struct Cleanup {\n    CleanupFunction function;\n    void* arg1;\n    void* arg2;\n    Cleanup* next;\n  };\n  Cleanup cleanup_;\n\n  // No copying allowed\n  Iterator(const Iterator&);\n  void operator=(const Iterator&);\n};\n\n// Return an empty iterator (yields nothing).\nextern Iterator* NewEmptyIterator();\n\n// Return an empty iterator with the specified status.\nextern Iterator* NewErrorIterator(const Status& status);\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_INCLUDE_ITERATOR_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/include/leveldb/iterator.h.bk",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// An iterator yields a sequence of key/value pairs from a source.\n// The following class defines the interface.  Multiple implementations\n// are provided by this library.  In particular, iterators are provided\n// to access the contents of a Table or a DB.\n//\n// Multiple threads can invoke const methods on an Iterator without\n// external synchronization, but if any of the threads may call a\n// non-const method, all threads accessing the same Iterator must use\n// external synchronization.\n\n#ifndef STORAGE_LEVELDB_INCLUDE_ITERATOR_H_\n#define STORAGE_LEVELDB_INCLUDE_ITERATOR_H_\n\n#include \"leveldb/slice.h\"\n#include \"leveldb/status.h\"\n\nnamespace leveldb {\n\nclass Iterator {\n public:\n  Iterator();\n  virtual ~Iterator();\n\n  // An iterator is either positioned at a key/value pair, or\n  // not valid.  This method returns true iff the iterator is valid.\n  virtual bool Valid() const = 0;\n\n  // Position at the first key in the source.  The iterator is Valid()\n  // after this call iff the source is not empty.\n  virtual void SeekToFirst() = 0;\n\n  // Position at the last key in the source.  The iterator is\n  // Valid() after this call iff the source is not empty.\n  virtual void SeekToLast() = 0;\n\n  // Position at the first key in the source that is at or past target.\n  // The iterator is Valid() after this call iff the source contains\n  // an entry that comes at or past target.\n  virtual void Seek(const Slice& target) = 0;\n\n  // Moves to the next entry in the source.  After this call, Valid() is\n  // true iff the iterator was not positioned at the last entry in the source.\n  // REQUIRES: Valid()\n  virtual void Next() = 0;\n\n  // Moves to the previous entry in the source.  After this call, Valid() is\n  // true iff the iterator was not positioned at the first entry in source.\n  // REQUIRES: Valid()\n  virtual void Prev() = 0;\n\n  // Return the key for the current entry.  The underlying storage for\n  // the returned slice is valid only until the next modification of\n  // the iterator.\n  // REQUIRES: Valid()\n  virtual Slice key() const = 0;\n\n  // Return the value for the current entry.  The underlying storage for\n  // the returned slice is valid only until the next modification of\n  // the iterator.\n  // REQUIRES: Valid()\n  virtual Slice value() const = 0;\n\n  // If an error has occurred, return it.  Else return an ok status.\n  virtual Status status() const = 0;\n\n  // Clients are allowed to register function/arg1/arg2 triples that\n  // will be invoked when this iterator is destroyed.\n  //\n  // Note that unlike all of the preceding methods, this method is\n  // not abstract and therefore clients should not override it.\n  typedef void (*CleanupFunction)(void* arg1, void* arg2);\n  void RegisterCleanup(CleanupFunction function, void* arg1, void* arg2);\n\n private:\n  struct Cleanup {\n    CleanupFunction function;\n    void* arg1;\n    void* arg2;\n    Cleanup* next;\n  };\n  Cleanup cleanup_;\n\n  // No copying allowed\n  Iterator(const Iterator&);\n  void operator=(const Iterator&);\n};\n\n// Return an empty iterator (yields nothing).\nextern Iterator* NewEmptyIterator();\n\n// Return an empty iterator with the specified status.\nextern Iterator* NewErrorIterator(const Status& status);\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_INCLUDE_ITERATOR_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/include/leveldb/options.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_INCLUDE_OPTIONS_H_\n#define STORAGE_LEVELDB_INCLUDE_OPTIONS_H_\n\n#include <stddef.h>\n\nnamespace leveldb {\n\nclass Cache;\nclass Comparator;\nclass Env;\nclass FilterPolicy;\nclass Logger;\nclass Snapshot;\n\n// DB contents are stored in a set of blocks, each of which holds a\n// sequence of key,value pairs.  Each block may be compressed before\n// being stored in a file.  The following enum describes which\n// compression method (if any) is used to compress a block.\nenum CompressionType {\n  // NOTE: do not change the values of existing entries, as these are\n  // part of the persistent format on disk.\n  kNoCompression     = 0x0,\n  kSnappyCompression = 0x1\n};\n\n// Options to control the behavior of a database (passed to DB::Open)\nstruct Options {\n    // It is known that during compaction, the disk IO capacity is all taken\n    // by the compaction thread, this leads to extremly BAD performance.\n    // Limit compaction IO speed to this, in MB\n    // Default: 0(not limited)\n    // Added by me@ideawu.com\n    int compaction_speed;\n\n  // -------------------\n  // Parameters that affect behavior\n\n  // Comparator used to define the order of keys in the table.\n  // Default: a comparator that uses lexicographic byte-wise ordering\n  //\n  // REQUIRES: The client must ensure that the comparator supplied\n  // here has the same name and orders keys *exactly* the same as the\n  // comparator provided to previous open calls on the same DB.\n  const Comparator* comparator;\n\n  // If true, the database will be created if it is missing.\n  // Default: false\n  bool create_if_missing;\n\n  // If true, an error is raised if the database already exists.\n  // Default: false\n  bool error_if_exists;\n\n  // If true, the implementation will do aggressive checking of the\n  // data it is processing and will stop early if it detects any\n  // errors.  This may have unforeseen ramifications: for example, a\n  // corruption of one DB entry may cause a large number of entries to\n  // become unreadable or for the entire DB to become unopenable.\n  // Default: false\n  bool paranoid_checks;\n\n  // Use the specified object to interact with the environment,\n  // e.g. to read/write files, schedule background work, etc.\n  // Default: Env::Default()\n  Env* env;\n\n  // Any internal progress/error information generated by the db will\n  // be written to info_log if it is non-NULL, or to a file stored\n  // in the same directory as the DB contents if info_log is NULL.\n  // Default: NULL\n  Logger* info_log;\n\n  // -------------------\n  // Parameters that affect performance\n\n  // Amount of data to build up in memory (backed by an unsorted log\n  // on disk) before converting to a sorted on-disk file.\n  //\n  // Larger values increase performance, especially during bulk loads.\n  // Up to two write buffers may be held in memory at the same time,\n  // so you may wish to adjust this parameter to control memory usage.\n  // Also, a larger write buffer will result in a longer recovery time\n  // the next time the database is opened.\n  //\n  // Default: 4MB\n  size_t write_buffer_size;\n\n  // Number of open files that can be used by the DB.  You may need to\n  // increase this if your database has a large working set (budget\n  // one open file per 2MB of working set).\n  //\n  // Default: 1000\n  int max_open_files;\n\n  // Control over blocks (user data is stored in a set of blocks, and\n  // a block is the unit of reading from disk).\n\n  // If non-NULL, use the specified cache for blocks.\n  // If NULL, leveldb will automatically create and use an 8MB internal cache.\n  // Default: NULL\n  Cache* block_cache;\n\n  // Approximate size of user data packed per block.  Note that the\n  // block size specified here corresponds to uncompressed data.  The\n  // actual size of the unit read from disk may be smaller if\n  // compression is enabled.  This parameter can be changed dynamically.\n  //\n  // Default: 4K\n  size_t block_size;\n\n  // Number of keys between restart points for delta encoding of keys.\n  // This parameter can be changed dynamically.  Most clients should\n  // leave this parameter alone.\n  //\n  // Default: 16\n  int block_restart_interval;\n\n  // Leveldb will write up to this amount of bytes to a file before\n  // switching to a new one.\n  // Most clients should leave this parameter alone.  However if your\n  // filesystem is more efficient with larger files, you could\n  // consider increasing the value.  The downside will be longer\n  // compactions and hence longer latency/performance hiccups.\n  // Another reason to increase this parameter might be when you are\n  // initially populating a large database.\n  //\n  // Default: 2MB\n  size_t max_file_size;\n\n  // Compress blocks using the specified compression algorithm.  This\n  // parameter can be changed dynamically.\n  //\n  // Default: kSnappyCompression, which gives lightweight but fast\n  // compression.\n  //\n  // Typical speeds of kSnappyCompression on an Intel(R) Core(TM)2 2.4GHz:\n  //    ~200-500MB/s compression\n  //    ~400-800MB/s decompression\n  // Note that these speeds are significantly faster than most\n  // persistent storage speeds, and therefore it is typically never\n  // worth switching to kNoCompression.  Even if the input data is\n  // incompressible, the kSnappyCompression implementation will\n  // efficiently detect that and will switch to uncompressed mode.\n  CompressionType compression;\n\n  // EXPERIMENTAL: If true, append to existing MANIFEST and log files\n  // when a database is opened.  This can significantly speed up open.\n  //\n  // Default: currently false, but may become true later.\n  bool reuse_logs;\n\n  // If non-NULL, use the specified filter policy to reduce disk reads.\n  // Many applications will benefit from passing the result of\n  // NewBloomFilterPolicy() here.\n  //\n  // Default: NULL\n  const FilterPolicy* filter_policy;\n\n  // Create an Options object with default values for all fields.\n  Options();\n};\n\n// Options that control read operations\nstruct ReadOptions {\n  // If true, all data read from underlying storage will be\n  // verified against corresponding checksums.\n  // Default: false\n  bool verify_checksums;\n\n  // Should the data read for this iteration be cached in memory?\n  // Callers may wish to set this field to false for bulk scans.\n  // Default: true\n  bool fill_cache;\n\n  // If \"snapshot\" is non-NULL, read as of the supplied snapshot\n  // (which must belong to the DB that is being read and which must\n  // not have been released).  If \"snapshot\" is NULL, use an implicit\n  // snapshot of the state at the beginning of this read operation.\n  // Default: NULL\n  const Snapshot* snapshot;\n\n  ReadOptions()\n      : verify_checksums(false),\n        fill_cache(true),\n        snapshot(NULL) {\n  }\n};\n\n// Options that control write operations\nstruct WriteOptions {\n  // If true, the write will be flushed from the operating system\n  // buffer cache (by calling WritableFile::Sync()) before the write\n  // is considered complete.  If this flag is true, writes will be\n  // slower.\n  //\n  // If this flag is false, and the machine crashes, some recent\n  // writes may be lost.  Note that if it is just the process that\n  // crashes (i.e., the machine does not reboot), no writes will be\n  // lost even if sync==false.\n  //\n  // In other words, a DB write with sync==false has similar\n  // crash semantics as the \"write()\" system call.  A DB write\n  // with sync==true has similar crash semantics to a \"write()\"\n  // system call followed by \"fsync()\".\n  //\n  // Default: false\n  bool sync;\n\n  WriteOptions()\n      : sync(false) {\n  }\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_INCLUDE_OPTIONS_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/include/leveldb/slice.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// Slice is a simple structure containing a pointer into some external\n// storage and a size.  The user of a Slice must ensure that the slice\n// is not used after the corresponding external storage has been\n// deallocated.\n//\n// Multiple threads can invoke const methods on a Slice without\n// external synchronization, but if any of the threads may call a\n// non-const method, all threads accessing the same Slice must use\n// external synchronization.\n\n#ifndef STORAGE_LEVELDB_INCLUDE_SLICE_H_\n#define STORAGE_LEVELDB_INCLUDE_SLICE_H_\n\n#include <assert.h>\n#include <stddef.h>\n#include <string.h>\n#include <string>\n\nnamespace leveldb {\n\nclass Slice {\n public:\n  // Create an empty slice.\n  Slice() : data_(\"\"), size_(0) { }\n\n  // Create a slice that refers to d[0,n-1].\n  Slice(const char* d, size_t n) : data_(d), size_(n) { }\n\n  // Create a slice that refers to the contents of \"s\"\n  Slice(const std::string& s) : data_(s.data()), size_(s.size()) { }\n\n  // Create a slice that refers to s[0,strlen(s)-1]\n  Slice(const char* s) : data_(s), size_(strlen(s)) { }\n\n  // Return a pointer to the beginning of the referenced data\n  const char* data() const { return data_; }\n\n  // Return the length (in bytes) of the referenced data\n  size_t size() const { return size_; }\n\n  // Return true iff the length of the referenced data is zero\n  bool empty() const { return size_ == 0; }\n\n  // Return the ith byte in the referenced data.\n  // REQUIRES: n < size()\n  char operator[](size_t n) const {\n    assert(n < size());\n    return data_[n];\n  }\n\n  // Change this slice to refer to an empty array\n  void clear() { data_ = \"\"; size_ = 0; }\n\n  // Drop the first \"n\" bytes from this slice.\n  void remove_prefix(size_t n) {\n    assert(n <= size());\n    data_ += n;\n    size_ -= n;\n  }\n\n  // Return a string that contains the copy of the referenced data.\n  std::string ToString() const { return std::string(data_, size_); }\n\n  // Three-way comparison.  Returns value:\n  //   <  0 iff \"*this\" <  \"b\",\n  //   == 0 iff \"*this\" == \"b\",\n  //   >  0 iff \"*this\" >  \"b\"\n  int compare(const Slice& b) const;\n\n  // Return true iff \"x\" is a prefix of \"*this\"\n  bool starts_with(const Slice& x) const {\n    return ((size_ >= x.size_) &&\n            (memcmp(data_, x.data_, x.size_) == 0));\n  }\n\n private:\n  const char* data_;\n  size_t size_;\n\n  // Intentionally copyable\n};\n\ninline bool operator==(const Slice& x, const Slice& y) {\n  return ((x.size() == y.size()) &&\n          (memcmp(x.data(), y.data(), x.size()) == 0));\n}\n\ninline bool operator!=(const Slice& x, const Slice& y) {\n  return !(x == y);\n}\n\ninline int Slice::compare(const Slice& b) const {\n  const size_t min_len = (size_ < b.size_) ? size_ : b.size_;\n  int r = memcmp(data_, b.data_, min_len);\n  if (r == 0) {\n    if (size_ < b.size_) r = -1;\n    else if (size_ > b.size_) r = +1;\n  }\n  return r;\n}\n\n}  // namespace leveldb\n\n\n#endif  // STORAGE_LEVELDB_INCLUDE_SLICE_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/include/leveldb/status.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// A Status encapsulates the result of an operation.  It may indicate success,\n// or it may indicate an error with an associated error message.\n//\n// Multiple threads can invoke const methods on a Status without\n// external synchronization, but if any of the threads may call a\n// non-const method, all threads accessing the same Status must use\n// external synchronization.\n\n#ifndef STORAGE_LEVELDB_INCLUDE_STATUS_H_\n#define STORAGE_LEVELDB_INCLUDE_STATUS_H_\n\n#include <string>\n#include \"leveldb/slice.h\"\n\nnamespace leveldb {\n\nclass Status {\n public:\n  // Create a success status.\n  Status() : state_(NULL) { }\n  ~Status() { delete[] state_; }\n\n  // Copy the specified status.\n  Status(const Status& s);\n  void operator=(const Status& s);\n\n  // Return a success status.\n  static Status OK() { return Status(); }\n\n  // Return error status of an appropriate type.\n  static Status NotFound(const Slice& msg, const Slice& msg2 = Slice()) {\n    return Status(kNotFound, msg, msg2);\n  }\n  static Status Corruption(const Slice& msg, const Slice& msg2 = Slice()) {\n    return Status(kCorruption, msg, msg2);\n  }\n  static Status NotSupported(const Slice& msg, const Slice& msg2 = Slice()) {\n    return Status(kNotSupported, msg, msg2);\n  }\n  static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice()) {\n    return Status(kInvalidArgument, msg, msg2);\n  }\n  static Status IOError(const Slice& msg, const Slice& msg2 = Slice()) {\n    return Status(kIOError, msg, msg2);\n  }\n\n  // Returns true iff the status indicates success.\n  bool ok() const { return (state_ == NULL); }\n\n  // Returns true iff the status indicates a NotFound error.\n  bool IsNotFound() const { return code() == kNotFound; }\n\n  // Returns true iff the status indicates a Corruption error.\n  bool IsCorruption() const { return code() == kCorruption; }\n\n  // Returns true iff the status indicates an IOError.\n  bool IsIOError() const { return code() == kIOError; }\n\n  // Returns true iff the status indicates a NotSupportedError.\n  bool IsNotSupportedError() const { return code() == kNotSupported; }\n\n  // Returns true iff the status indicates an InvalidArgument.\n  bool IsInvalidArgument() const { return code() == kInvalidArgument; }\n\n  // Return a string representation of this status suitable for printing.\n  // Returns the string \"OK\" for success.\n  std::string ToString() const;\n\n private:\n  // OK status has a NULL state_.  Otherwise, state_ is a new[] array\n  // of the following form:\n  //    state_[0..3] == length of message\n  //    state_[4]    == code\n  //    state_[5..]  == message\n  const char* state_;\n\n  enum Code {\n    kOk = 0,\n    kNotFound = 1,\n    kCorruption = 2,\n    kNotSupported = 3,\n    kInvalidArgument = 4,\n    kIOError = 5\n  };\n\n  Code code() const {\n    return (state_ == NULL) ? kOk : static_cast<Code>(state_[4]);\n  }\n\n  Status(Code code, const Slice& msg, const Slice& msg2);\n  static const char* CopyState(const char* s);\n};\n\ninline Status::Status(const Status& s) {\n  state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);\n}\ninline void Status::operator=(const Status& s) {\n  // The following condition catches both aliasing (when this == &s),\n  // and the common case where both s and *this are ok.\n  if (state_ != s.state_) {\n    delete[] state_;\n    state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);\n  }\n}\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_INCLUDE_STATUS_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/include/leveldb/table.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_INCLUDE_TABLE_H_\n#define STORAGE_LEVELDB_INCLUDE_TABLE_H_\n\n#include <stdint.h>\n#include \"leveldb/iterator.h\"\n\nnamespace leveldb {\n\nclass Block;\nclass BlockHandle;\nclass Footer;\nstruct Options;\nclass RandomAccessFile;\nstruct ReadOptions;\nclass TableCache;\n\n// A Table is a sorted map from strings to strings.  Tables are\n// immutable and persistent.  A Table may be safely accessed from\n// multiple threads without external synchronization.\nclass Table {\n public:\n  // Attempt to open the table that is stored in bytes [0..file_size)\n  // of \"file\", and read the metadata entries necessary to allow\n  // retrieving data from the table.\n  //\n  // If successful, returns ok and sets \"*table\" to the newly opened\n  // table.  The client should delete \"*table\" when no longer needed.\n  // If there was an error while initializing the table, sets \"*table\"\n  // to NULL and returns a non-ok status.  Does not take ownership of\n  // \"*source\", but the client must ensure that \"source\" remains live\n  // for the duration of the returned table's lifetime.\n  //\n  // *file must remain live while this Table is in use.\n  static Status Open(const Options& options,\n                     RandomAccessFile* file,\n                     uint64_t file_size,\n                     Table** table);\n\n  ~Table();\n\n  // Returns a new iterator over the table contents.\n  // The result of NewIterator() is initially invalid (caller must\n  // call one of the Seek methods on the iterator before using it).\n  Iterator* NewIterator(const ReadOptions&) const;\n\n  // Given a key, return an approximate byte offset in the file where\n  // the data for that key begins (or would begin if the key were\n  // present in the file).  The returned value is in terms of file\n  // bytes, and so includes effects like compression of the underlying data.\n  // E.g., the approximate offset of the last key in the table will\n  // be close to the file length.\n  uint64_t ApproximateOffsetOf(const Slice& key) const;\n\n private:\n  struct Rep;\n  Rep* rep_;\n\n  explicit Table(Rep* rep) { rep_ = rep; }\n  static Iterator* BlockReader(void*, const ReadOptions&, const Slice&);\n\n  // Calls (*handle_result)(arg, ...) with the entry found after a call\n  // to Seek(key).  May not make such a call if filter policy says\n  // that key is not present.\n  friend class TableCache;\n  Status InternalGet(\n      const ReadOptions&, const Slice& key,\n      void* arg,\n      void (*handle_result)(void* arg, const Slice& k, const Slice& v));\n\n\n  void ReadMeta(const Footer& footer);\n  void ReadFilter(const Slice& filter_handle_value);\n\n  // No copying allowed\n  Table(const Table&);\n  void operator=(const Table&);\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_INCLUDE_TABLE_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/include/leveldb/table_builder.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// TableBuilder provides the interface used to build a Table\n// (an immutable and sorted map from keys to values).\n//\n// Multiple threads can invoke const methods on a TableBuilder without\n// external synchronization, but if any of the threads may call a\n// non-const method, all threads accessing the same TableBuilder must use\n// external synchronization.\n\n#ifndef STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_\n#define STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_\n\n#include <stdint.h>\n#include \"leveldb/options.h\"\n#include \"leveldb/status.h\"\n\nnamespace leveldb {\n\nclass BlockBuilder;\nclass BlockHandle;\nclass WritableFile;\n\nclass TableBuilder {\n public:\n  // Create a builder that will store the contents of the table it is\n  // building in *file.  Does not close the file.  It is up to the\n  // caller to close the file after calling Finish().\n  TableBuilder(const Options& options, WritableFile* file);\n\n  // REQUIRES: Either Finish() or Abandon() has been called.\n  ~TableBuilder();\n\n  // Change the options used by this builder.  Note: only some of the\n  // option fields can be changed after construction.  If a field is\n  // not allowed to change dynamically and its value in the structure\n  // passed to the constructor is different from its value in the\n  // structure passed to this method, this method will return an error\n  // without changing any fields.\n  Status ChangeOptions(const Options& options);\n\n  // Add key,value to the table being constructed.\n  // REQUIRES: key is after any previously added key according to comparator.\n  // REQUIRES: Finish(), Abandon() have not been called\n  void Add(const Slice& key, const Slice& value);\n\n  // Advanced operation: flush any buffered key/value pairs to file.\n  // Can be used to ensure that two adjacent entries never live in\n  // the same data block.  Most clients should not need to use this method.\n  // REQUIRES: Finish(), Abandon() have not been called\n  void Flush();\n\n  // Return non-ok iff some error has been detected.\n  Status status() const;\n\n  // Finish building the table.  Stops using the file passed to the\n  // constructor after this function returns.\n  // REQUIRES: Finish(), Abandon() have not been called\n  Status Finish();\n\n  // Indicate that the contents of this builder should be abandoned.  Stops\n  // using the file passed to the constructor after this function returns.\n  // If the caller is not going to call Finish(), it must call Abandon()\n  // before destroying this builder.\n  // REQUIRES: Finish(), Abandon() have not been called\n  void Abandon();\n\n  // Number of calls to Add() so far.\n  uint64_t NumEntries() const;\n\n  // Size of the file generated so far.  If invoked after a successful\n  // Finish() call, returns the size of the final generated file.\n  uint64_t FileSize() const;\n\n private:\n  bool ok() const { return status().ok(); }\n  void WriteBlock(BlockBuilder* block, BlockHandle* handle);\n  void WriteRawBlock(const Slice& data, CompressionType, BlockHandle* handle);\n\n  struct Rep;\n  Rep* rep_;\n\n  // No copying allowed\n  TableBuilder(const TableBuilder&);\n  void operator=(const TableBuilder&);\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/include/leveldb/write_batch.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// WriteBatch holds a collection of updates to apply atomically to a DB.\n//\n// The updates are applied in the order in which they are added\n// to the WriteBatch.  For example, the value of \"key\" will be \"v3\"\n// after the following batch is written:\n//\n//    batch.Put(\"key\", \"v1\");\n//    batch.Delete(\"key\");\n//    batch.Put(\"key\", \"v2\");\n//    batch.Put(\"key\", \"v3\");\n//\n// Multiple threads can invoke const methods on a WriteBatch without\n// external synchronization, but if any of the threads may call a\n// non-const method, all threads accessing the same WriteBatch must use\n// external synchronization.\n\n#ifndef STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_\n#define STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_\n\n#include <string>\n#include \"leveldb/status.h\"\n\nnamespace leveldb {\n\nclass Slice;\n\nclass WriteBatch {\n public:\n  WriteBatch();\n  ~WriteBatch();\n\n  // Store the mapping \"key->value\" in the database.\n  void Put(const Slice& key, const Slice& value);\n\n  // If the database contains a mapping for \"key\", erase it.  Else do nothing.\n  void Delete(const Slice& key);\n\n  // Clear all updates buffered in this batch.\n  void Clear();\n\n  // The size of the database changes caused by this batch.\n  //\n  // This number is tied to implementation details, and may change across\n  // releases. It is intended for LevelDB usage metrics.\n  size_t ApproximateSize();\n\n  // Support for iterating over the contents of a batch.\n  class Handler {\n   public:\n    virtual ~Handler();\n    virtual void Put(const Slice& key, const Slice& value) = 0;\n    virtual void Delete(const Slice& key) = 0;\n  };\n  Status Iterate(Handler* handler) const;\n\n private:\n  friend class WriteBatchInternal;\n\n  std::string rep_;  // See comment in write_batch.cc for the format of rep_\n\n  // Intentionally copyable\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/issues/issue178_test.cc",
    "content": "// Copyright (c) 2013 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n// Test for issue 178: a manual compaction causes deleted data to reappear.\n#include <iostream>\n#include <sstream>\n#include <cstdlib>\n\n#include \"leveldb/db.h\"\n#include \"leveldb/write_batch.h\"\n#include \"util/testharness.h\"\n\nnamespace {\n\nconst int kNumKeys = 1100000;\n\nstd::string Key1(int i) {\n  char buf[100];\n  snprintf(buf, sizeof(buf), \"my_key_%d\", i);\n  return buf;\n}\n\nstd::string Key2(int i) {\n  return Key1(i) + \"_xxx\";\n}\n\nclass Issue178 { };\n\nTEST(Issue178, Test) {\n  // Get rid of any state from an old run.\n  std::string dbpath = leveldb::test::TmpDir() + \"/leveldb_cbug_test\";\n  DestroyDB(dbpath, leveldb::Options());\n\n  // Open database.  Disable compression since it affects the creation\n  // of layers and the code below is trying to test against a very\n  // specific scenario.\n  leveldb::DB* db;\n  leveldb::Options db_options;\n  db_options.create_if_missing = true;\n  db_options.compression = leveldb::kNoCompression;\n  ASSERT_OK(leveldb::DB::Open(db_options, dbpath, &db));\n\n  // create first key range\n  leveldb::WriteBatch batch;\n  for (size_t i = 0; i < kNumKeys; i++) {\n    batch.Put(Key1(i), \"value for range 1 key\");\n  }\n  ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch));\n\n  // create second key range\n  batch.Clear();\n  for (size_t i = 0; i < kNumKeys; i++) {\n    batch.Put(Key2(i), \"value for range 2 key\");\n  }\n  ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch));\n\n  // delete second key range\n  batch.Clear();\n  for (size_t i = 0; i < kNumKeys; i++) {\n    batch.Delete(Key2(i));\n  }\n  ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch));\n\n  // compact database\n  std::string start_key = Key1(0);\n  std::string end_key = Key1(kNumKeys - 1);\n  leveldb::Slice least(start_key.data(), start_key.size());\n  leveldb::Slice greatest(end_key.data(), end_key.size());\n\n  // commenting out the line below causes the example to work correctly\n  db->CompactRange(&least, &greatest);\n\n  // count the keys\n  leveldb::Iterator* iter = db->NewIterator(leveldb::ReadOptions());\n  size_t num_keys = 0;\n  for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {\n    num_keys++;\n  }\n  delete iter;\n  ASSERT_EQ(kNumKeys, num_keys) << \"Bad number of keys\";\n\n  // close database\n  delete db;\n  DestroyDB(dbpath, leveldb::Options());\n}\n\n}  // anonymous namespace\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/issues/issue200_test.cc",
    "content": "// Copyright (c) 2013 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n// Test for issue 200: when iterator switches direction from backward\n// to forward, the current key can be yielded unexpectedly if a new\n// mutation has been added just before the current key.\n\n#include \"leveldb/db.h\"\n#include \"util/testharness.h\"\n\nnamespace leveldb {\n\nclass Issue200 { };\n\nTEST(Issue200, Test) {\n  // Get rid of any state from an old run.\n  std::string dbpath = test::TmpDir() + \"/leveldb_issue200_test\";\n  DestroyDB(dbpath, Options());\n\n  DB *db;\n  Options options;\n  options.create_if_missing = true;\n  ASSERT_OK(DB::Open(options, dbpath, &db));\n\n  WriteOptions write_options;\n  ASSERT_OK(db->Put(write_options, \"1\", \"b\"));\n  ASSERT_OK(db->Put(write_options, \"2\", \"c\"));\n  ASSERT_OK(db->Put(write_options, \"3\", \"d\"));\n  ASSERT_OK(db->Put(write_options, \"4\", \"e\"));\n  ASSERT_OK(db->Put(write_options, \"5\", \"f\"));\n\n  ReadOptions read_options;\n  Iterator *iter = db->NewIterator(read_options);\n\n  // Add an element that should not be reflected in the iterator.\n  ASSERT_OK(db->Put(write_options, \"25\", \"cd\"));\n\n  iter->Seek(\"5\");\n  ASSERT_EQ(iter->key().ToString(), \"5\");\n  iter->Prev();\n  ASSERT_EQ(iter->key().ToString(), \"4\");\n  iter->Prev();\n  ASSERT_EQ(iter->key().ToString(), \"3\");\n  iter->Next();\n  ASSERT_EQ(iter->key().ToString(), \"4\");\n  iter->Next();\n  ASSERT_EQ(iter->key().ToString(), \"5\");\n\n  delete iter;\n  delete db;\n  DestroyDB(dbpath, options);\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/port/README",
    "content": "This directory contains interfaces and implementations that isolate the\nrest of the package from platform details.\n\nCode in the rest of the package includes \"port.h\" from this directory.\n\"port.h\" in turn includes a platform specific \"port_<platform>.h\" file\nthat provides the platform specific implementation.\n\nSee port_posix.h for an example of what must be provided in a platform\nspecific header file.\n\n"
  },
  {
    "path": "deps/leveldb-1.20/port/atomic_pointer.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n// AtomicPointer provides storage for a lock-free pointer.\n// Platform-dependent implementation of AtomicPointer:\n// - If the platform provides a cheap barrier, we use it with raw pointers\n// - If <atomic> is present (on newer versions of gcc, it is), we use\n//   a <atomic>-based AtomicPointer.  However we prefer the memory\n//   barrier based version, because at least on a gcc 4.4 32-bit build\n//   on linux, we have encountered a buggy <atomic> implementation.\n//   Also, some <atomic> implementations are much slower than a memory-barrier\n//   based implementation (~16ns for <atomic> based acquire-load vs. ~1ns for\n//   a barrier based acquire-load).\n// This code is based on atomicops-internals-* in Google's perftools:\n// http://code.google.com/p/google-perftools/source/browse/#svn%2Ftrunk%2Fsrc%2Fbase\n\n#ifndef PORT_ATOMIC_POINTER_H_\n#define PORT_ATOMIC_POINTER_H_\n\n#include <stdint.h>\n#ifdef LEVELDB_ATOMIC_PRESENT\n#include <atomic>\n#endif\n#ifdef OS_WIN\n#include <windows.h>\n#endif\n#ifdef __APPLE__\n#include <libkern/OSAtomic.h>\n#endif\n\n#if defined(_M_X64) || defined(__x86_64__)\n#define ARCH_CPU_X86_FAMILY 1\n#elif defined(_M_IX86) || defined(__i386__) || defined(__i386)\n#define ARCH_CPU_X86_FAMILY 1\n#elif defined(__ARMEL__)\n#define ARCH_CPU_ARM_FAMILY 1\n#elif defined(__aarch64__)\n#define ARCH_CPU_ARM64_FAMILY 1\n#elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc64__)\n#define ARCH_CPU_PPC_FAMILY 1\n#elif defined(__mips__)\n#define ARCH_CPU_MIPS_FAMILY 1\n#endif\n\nnamespace leveldb {\nnamespace port {\n\n// Define MemoryBarrier() if available\n// Windows on x86\n#if defined(OS_WIN) && defined(COMPILER_MSVC) && defined(ARCH_CPU_X86_FAMILY)\n// windows.h already provides a MemoryBarrier(void) macro\n// http://msdn.microsoft.com/en-us/library/ms684208(v=vs.85).aspx\n#define LEVELDB_HAVE_MEMORY_BARRIER\n\n// Mac OS\n#elif defined(__APPLE__)\ninline void MemoryBarrier() {\n  OSMemoryBarrier();\n}\n#define LEVELDB_HAVE_MEMORY_BARRIER\n\n// Gcc on x86\n#elif defined(ARCH_CPU_X86_FAMILY) && defined(__GNUC__)\ninline void MemoryBarrier() {\n  // See http://gcc.gnu.org/ml/gcc/2003-04/msg01180.html for a discussion on\n  // this idiom. Also see http://en.wikipedia.org/wiki/Memory_ordering.\n  __asm__ __volatile__(\"\" : : : \"memory\");\n}\n#define LEVELDB_HAVE_MEMORY_BARRIER\n\n// Sun Studio\n#elif defined(ARCH_CPU_X86_FAMILY) && defined(__SUNPRO_CC)\ninline void MemoryBarrier() {\n  // See http://gcc.gnu.org/ml/gcc/2003-04/msg01180.html for a discussion on\n  // this idiom. Also see http://en.wikipedia.org/wiki/Memory_ordering.\n  asm volatile(\"\" : : : \"memory\");\n}\n#define LEVELDB_HAVE_MEMORY_BARRIER\n\n// ARM Linux\n#elif defined(ARCH_CPU_ARM_FAMILY) && defined(__linux__)\ntypedef void (*LinuxKernelMemoryBarrierFunc)(void);\n// The Linux ARM kernel provides a highly optimized device-specific memory\n// barrier function at a fixed memory address that is mapped in every\n// user-level process.\n//\n// This beats using CPU-specific instructions which are, on single-core\n// devices, un-necessary and very costly (e.g. ARMv7-A \"dmb\" takes more\n// than 180ns on a Cortex-A8 like the one on a Nexus One). Benchmarking\n// shows that the extra function call cost is completely negligible on\n// multi-core devices.\n//\ninline void MemoryBarrier() {\n  (*(LinuxKernelMemoryBarrierFunc)0xffff0fa0)();\n}\n#define LEVELDB_HAVE_MEMORY_BARRIER\n\n// ARM64\n#elif defined(ARCH_CPU_ARM64_FAMILY)\ninline void MemoryBarrier() {\n  asm volatile(\"dmb sy\" : : : \"memory\");\n}\n#define LEVELDB_HAVE_MEMORY_BARRIER\n\n// PPC\n#elif defined(ARCH_CPU_PPC_FAMILY) && defined(__GNUC__)\ninline void MemoryBarrier() {\n  // TODO for some powerpc expert: is there a cheaper suitable variant?\n  // Perhaps by having separate barriers for acquire and release ops.\n  asm volatile(\"sync\" : : : \"memory\");\n}\n#define LEVELDB_HAVE_MEMORY_BARRIER\n\n// MIPS\n#elif defined(ARCH_CPU_MIPS_FAMILY) && defined(__GNUC__)\ninline void MemoryBarrier() {\n  __asm__ __volatile__(\"sync\" : : : \"memory\");\n}\n#define LEVELDB_HAVE_MEMORY_BARRIER\n\n#endif\n\n// AtomicPointer built using platform-specific MemoryBarrier()\n#if defined(LEVELDB_HAVE_MEMORY_BARRIER)\nclass AtomicPointer {\n private:\n  void* rep_;\n public:\n  AtomicPointer() { }\n  explicit AtomicPointer(void* p) : rep_(p) {}\n  inline void* NoBarrier_Load() const { return rep_; }\n  inline void NoBarrier_Store(void* v) { rep_ = v; }\n  inline void* Acquire_Load() const {\n    void* result = rep_;\n    MemoryBarrier();\n    return result;\n  }\n  inline void Release_Store(void* v) {\n    MemoryBarrier();\n    rep_ = v;\n  }\n};\n\n// AtomicPointer based on <cstdatomic>\n#elif defined(LEVELDB_ATOMIC_PRESENT)\nclass AtomicPointer {\n private:\n  std::atomic<void*> rep_;\n public:\n  AtomicPointer() { }\n  explicit AtomicPointer(void* v) : rep_(v) { }\n  inline void* Acquire_Load() const {\n    return rep_.load(std::memory_order_acquire);\n  }\n  inline void Release_Store(void* v) {\n    rep_.store(v, std::memory_order_release);\n  }\n  inline void* NoBarrier_Load() const {\n    return rep_.load(std::memory_order_relaxed);\n  }\n  inline void NoBarrier_Store(void* v) {\n    rep_.store(v, std::memory_order_relaxed);\n  }\n};\n\n// Atomic pointer based on sparc memory barriers\n#elif defined(__sparcv9) && defined(__GNUC__)\nclass AtomicPointer {\n private:\n  void* rep_;\n public:\n  AtomicPointer() { }\n  explicit AtomicPointer(void* v) : rep_(v) { }\n  inline void* Acquire_Load() const {\n    void* val;\n    __asm__ __volatile__ (\n        \"ldx [%[rep_]], %[val] \\n\\t\"\n         \"membar #LoadLoad|#LoadStore \\n\\t\"\n        : [val] \"=r\" (val)\n        : [rep_] \"r\" (&rep_)\n        : \"memory\");\n    return val;\n  }\n  inline void Release_Store(void* v) {\n    __asm__ __volatile__ (\n        \"membar #LoadStore|#StoreStore \\n\\t\"\n        \"stx %[v], [%[rep_]] \\n\\t\"\n        :\n        : [rep_] \"r\" (&rep_), [v] \"r\" (v)\n        : \"memory\");\n  }\n  inline void* NoBarrier_Load() const { return rep_; }\n  inline void NoBarrier_Store(void* v) { rep_ = v; }\n};\n\n// Atomic pointer based on ia64 acq/rel\n#elif defined(__ia64) && defined(__GNUC__)\nclass AtomicPointer {\n private:\n  void* rep_;\n public:\n  AtomicPointer() { }\n  explicit AtomicPointer(void* v) : rep_(v) { }\n  inline void* Acquire_Load() const {\n    void* val    ;\n    __asm__ __volatile__ (\n        \"ld8.acq %[val] = [%[rep_]] \\n\\t\"\n        : [val] \"=r\" (val)\n        : [rep_] \"r\" (&rep_)\n        : \"memory\"\n        );\n    return val;\n  }\n  inline void Release_Store(void* v) {\n    __asm__ __volatile__ (\n        \"st8.rel [%[rep_]] = %[v]  \\n\\t\"\n        :\n        : [rep_] \"r\" (&rep_), [v] \"r\" (v)\n        : \"memory\"\n        );\n  }\n  inline void* NoBarrier_Load() const { return rep_; }\n  inline void NoBarrier_Store(void* v) { rep_ = v; }\n};\n\n// We have neither MemoryBarrier(), nor <atomic>\n#else\n#error Please implement AtomicPointer for this platform.\n\n#endif\n\n#undef LEVELDB_HAVE_MEMORY_BARRIER\n#undef ARCH_CPU_X86_FAMILY\n#undef ARCH_CPU_ARM_FAMILY\n#undef ARCH_CPU_ARM64_FAMILY\n#undef ARCH_CPU_PPC_FAMILY\n\n}  // namespace port\n}  // namespace leveldb\n\n#endif  // PORT_ATOMIC_POINTER_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/port/port.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_PORT_PORT_H_\n#define STORAGE_LEVELDB_PORT_PORT_H_\n\n#include <string.h>\n\n// Include the appropriate platform specific file below.  If you are\n// porting to a new platform, see \"port_example.h\" for documentation\n// of what the new port_<platform>.h file must provide.\n#if defined(LEVELDB_PLATFORM_POSIX)\n#  include \"port/port_posix.h\"\n#elif defined(LEVELDB_PLATFORM_CHROMIUM)\n#  include \"port/port_chromium.h\"\n#endif\n\n#endif  // STORAGE_LEVELDB_PORT_PORT_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/port/port_example.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// This file contains the specification, but not the implementations,\n// of the types/operations/etc. that should be defined by a platform\n// specific port_<platform>.h file.  Use this file as a reference for\n// how to port this package to a new platform.\n\n#ifndef STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_\n#define STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_\n\nnamespace leveldb {\nnamespace port {\n\n// TODO(jorlow): Many of these belong more in the environment class rather than\n//               here. We should try moving them and see if it affects perf.\n\n// The following boolean constant must be true on a little-endian machine\n// and false otherwise.\nstatic const bool kLittleEndian = true /* or some other expression */;\n\n// ------------------ Threading -------------------\n\n// A Mutex represents an exclusive lock.\nclass Mutex {\n public:\n  Mutex();\n  ~Mutex();\n\n  // Lock the mutex.  Waits until other lockers have exited.\n  // Will deadlock if the mutex is already locked by this thread.\n  void Lock();\n\n  // Unlock the mutex.\n  // REQUIRES: This mutex was locked by this thread.\n  void Unlock();\n\n  // Optionally crash if this thread does not hold this mutex.\n  // The implementation must be fast, especially if NDEBUG is\n  // defined.  The implementation is allowed to skip all checks.\n  void AssertHeld();\n};\n\nclass CondVar {\n public:\n  explicit CondVar(Mutex* mu);\n  ~CondVar();\n\n  // Atomically release *mu and block on this condition variable until\n  // either a call to SignalAll(), or a call to Signal() that picks\n  // this thread to wakeup.\n  // REQUIRES: this thread holds *mu\n  void Wait();\n\n  // If there are some threads waiting, wake up at least one of them.\n  void Signal();\n\n  // Wake up all waiting threads.\n  void SignallAll();\n};\n\n// Thread-safe initialization.\n// Used as follows:\n//      static port::OnceType init_control = LEVELDB_ONCE_INIT;\n//      static void Initializer() { ... do something ...; }\n//      ...\n//      port::InitOnce(&init_control, &Initializer);\ntypedef intptr_t OnceType;\n#define LEVELDB_ONCE_INIT 0\nextern void InitOnce(port::OnceType*, void (*initializer)());\n\n// A type that holds a pointer that can be read or written atomically\n// (i.e., without word-tearing.)\nclass AtomicPointer {\n private:\n  intptr_t rep_;\n public:\n  // Initialize to arbitrary value\n  AtomicPointer();\n\n  // Initialize to hold v\n  explicit AtomicPointer(void* v) : rep_(v) { }\n\n  // Read and return the stored pointer with the guarantee that no\n  // later memory access (read or write) by this thread can be\n  // reordered ahead of this read.\n  void* Acquire_Load() const;\n\n  // Set v as the stored pointer with the guarantee that no earlier\n  // memory access (read or write) by this thread can be reordered\n  // after this store.\n  void Release_Store(void* v);\n\n  // Read the stored pointer with no ordering guarantees.\n  void* NoBarrier_Load() const;\n\n  // Set va as the stored pointer with no ordering guarantees.\n  void NoBarrier_Store(void* v);\n};\n\n// ------------------ Compression -------------------\n\n// Store the snappy compression of \"input[0,input_length-1]\" in *output.\n// Returns false if snappy is not supported by this port.\nextern bool Snappy_Compress(const char* input, size_t input_length,\n                            std::string* output);\n\n// If input[0,input_length-1] looks like a valid snappy compressed\n// buffer, store the size of the uncompressed data in *result and\n// return true.  Else return false.\nextern bool Snappy_GetUncompressedLength(const char* input, size_t length,\n                                         size_t* result);\n\n// Attempt to snappy uncompress input[0,input_length-1] into *output.\n// Returns true if successful, false if the input is invalid lightweight\n// compressed data.\n//\n// REQUIRES: at least the first \"n\" bytes of output[] must be writable\n// where \"n\" is the result of a successful call to\n// Snappy_GetUncompressedLength.\nextern bool Snappy_Uncompress(const char* input_data, size_t input_length,\n                              char* output);\n\n// ------------------ Miscellaneous -------------------\n\n// If heap profiling is not supported, returns false.\n// Else repeatedly calls (*func)(arg, data, n) and then returns true.\n// The concatenation of all \"data[0,n-1]\" fragments is the heap profile.\nextern bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg);\n\n// Extend the CRC to include the first n bytes of buf.\n//\n// Returns zero if the CRC cannot be extended using acceleration, else returns\n// the newly extended CRC value (which may also be zero).\nuint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size);\n\n}  // namespace port\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/port/port_posix.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"port/port_posix.h\"\n\n#include <cstdlib>\n#include <stdio.h>\n#include <string.h>\n\nnamespace leveldb {\nnamespace port {\n\nstatic void PthreadCall(const char* label, int result) {\n  if (result != 0) {\n    fprintf(stderr, \"pthread %s: %s\\n\", label, strerror(result));\n    abort();\n  }\n}\n\nMutex::Mutex() { PthreadCall(\"init mutex\", pthread_mutex_init(&mu_, NULL)); }\n\nMutex::~Mutex() { PthreadCall(\"destroy mutex\", pthread_mutex_destroy(&mu_)); }\n\nvoid Mutex::Lock() { PthreadCall(\"lock\", pthread_mutex_lock(&mu_)); }\n\nvoid Mutex::Unlock() { PthreadCall(\"unlock\", pthread_mutex_unlock(&mu_)); }\n\nCondVar::CondVar(Mutex* mu)\n    : mu_(mu) {\n    PthreadCall(\"init cv\", pthread_cond_init(&cv_, NULL));\n}\n\nCondVar::~CondVar() { PthreadCall(\"destroy cv\", pthread_cond_destroy(&cv_)); }\n\nvoid CondVar::Wait() {\n  PthreadCall(\"wait\", pthread_cond_wait(&cv_, &mu_->mu_));\n}\n\nvoid CondVar::Signal() {\n  PthreadCall(\"signal\", pthread_cond_signal(&cv_));\n}\n\nvoid CondVar::SignalAll() {\n  PthreadCall(\"broadcast\", pthread_cond_broadcast(&cv_));\n}\n\nvoid InitOnce(OnceType* once, void (*initializer)()) {\n  PthreadCall(\"once\", pthread_once(once, initializer));\n}\n\n}  // namespace port\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/port/port_posix.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// See port_example.h for documentation for the following types/functions.\n\n#ifndef STORAGE_LEVELDB_PORT_PORT_POSIX_H_\n#define STORAGE_LEVELDB_PORT_PORT_POSIX_H_\n\n#undef PLATFORM_IS_LITTLE_ENDIAN\n#if defined(__APPLE__)\n  #include <machine/endian.h>\n  #if defined(__DARWIN_LITTLE_ENDIAN) && defined(__DARWIN_BYTE_ORDER)\n    #define PLATFORM_IS_LITTLE_ENDIAN \\\n        (__DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN)\n  #endif\n#elif defined(OS_SOLARIS)\n  #include <sys/isa_defs.h>\n  #ifdef _LITTLE_ENDIAN\n    #define PLATFORM_IS_LITTLE_ENDIAN true\n  #else\n    #define PLATFORM_IS_LITTLE_ENDIAN false\n  #endif\n#elif defined(OS_FREEBSD) || defined(OS_OPENBSD) ||\\\n      defined(OS_NETBSD) || defined(OS_DRAGONFLYBSD)\n  #include <sys/types.h>\n  #include <sys/endian.h>\n  #define PLATFORM_IS_LITTLE_ENDIAN (_BYTE_ORDER == _LITTLE_ENDIAN)\n#elif defined(OS_HPUX)\n  #define PLATFORM_IS_LITTLE_ENDIAN false\n#elif defined(OS_ANDROID)\n  // Due to a bug in the NDK x86 <sys/endian.h> definition,\n  // _BYTE_ORDER must be used instead of __BYTE_ORDER on Android.\n  // See http://code.google.com/p/android/issues/detail?id=39824\n  #include <endian.h>\n  #define PLATFORM_IS_LITTLE_ENDIAN  (_BYTE_ORDER == _LITTLE_ENDIAN)\n#else\n  #include <endian.h>\n#endif\n\n#include <pthread.h>\n#ifdef SNAPPY\n#include <snappy.h>\n#endif\n#include <stdint.h>\n#include <string>\n#include \"port/atomic_pointer.h\"\n\n#ifndef PLATFORM_IS_LITTLE_ENDIAN\n#define PLATFORM_IS_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN)\n#endif\n\n#if defined(__APPLE__) || defined(OS_SOLARIS) || defined(OS_FREEBSD) ||\\\n    defined(OS_NETBSD) || defined(OS_OPENBSD) || defined(OS_DRAGONFLYBSD) ||\\\n    defined(OS_ANDROID) || defined(OS_HPUX) || defined(CYGWIN)\n// Use fread/fwrite/fflush on platforms without _unlocked variants\n#define fread_unlocked fread\n#define fwrite_unlocked fwrite\n#define fflush_unlocked fflush\n#endif\n\n#if defined(__APPLE__) || defined(OS_FREEBSD) ||\\\n    defined(OS_OPENBSD) || defined(OS_DRAGONFLYBSD)\n// Use fsync() on platforms without fdatasync()\n#define fdatasync fsync\n#endif\n\n#if defined(OS_ANDROID) && __ANDROID_API__ < 9\n// fdatasync() was only introduced in API level 9 on Android. Use fsync()\n// when targetting older platforms.\n#define fdatasync fsync\n#endif\n\nnamespace leveldb {\nnamespace port {\n\nstatic const bool kLittleEndian = PLATFORM_IS_LITTLE_ENDIAN;\n#undef PLATFORM_IS_LITTLE_ENDIAN\n\nclass CondVar;\n\nclass Mutex {\n public:\n  Mutex();\n  ~Mutex();\n\n  void Lock();\n  void Unlock();\n  void AssertHeld() { }\n\n private:\n  friend class CondVar;\n  pthread_mutex_t mu_;\n\n  // No copying\n  Mutex(const Mutex&);\n  void operator=(const Mutex&);\n};\n\nclass CondVar {\n public:\n  explicit CondVar(Mutex* mu);\n  ~CondVar();\n  void Wait();\n  void Signal();\n  void SignalAll();\n private:\n  pthread_cond_t cv_;\n  Mutex* mu_;\n};\n\ntypedef pthread_once_t OnceType;\n#define LEVELDB_ONCE_INIT PTHREAD_ONCE_INIT\nextern void InitOnce(OnceType* once, void (*initializer)());\n\ninline bool Snappy_Compress(const char* input, size_t length,\n                            ::std::string* output) {\n#ifdef SNAPPY\n  output->resize(snappy::MaxCompressedLength(length));\n  size_t outlen;\n  snappy::RawCompress(input, length, &(*output)[0], &outlen);\n  output->resize(outlen);\n  return true;\n#endif\n\n  return false;\n}\n\ninline bool Snappy_GetUncompressedLength(const char* input, size_t length,\n                                         size_t* result) {\n#ifdef SNAPPY\n  return snappy::GetUncompressedLength(input, length, result);\n#else\n  return false;\n#endif\n}\n\ninline bool Snappy_Uncompress(const char* input, size_t length,\n                              char* output) {\n#ifdef SNAPPY\n  return snappy::RawUncompress(input, length, output);\n#else\n  return false;\n#endif\n}\n\ninline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) {\n  return false;\n}\n\nuint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size);\n\n} // namespace port\n} // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_PORT_PORT_POSIX_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/port/port_posix_sse.cc",
    "content": "// Copyright 2016 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// A portable implementation of crc32c, optimized to handle\n// four bytes at a time.\n//\n// In a separate source file to allow this accelerated CRC32C function to be\n// compiled with the appropriate compiler flags to enable x86 SSE 4.2\n// instructions.\n\n#include <stdint.h>\n#include <string.h>\n#include \"port/port.h\"\n\n#if defined(LEVELDB_PLATFORM_POSIX_SSE)\n\n#if defined(_MSC_VER)\n#include <intrin.h>\n#elif defined(__GNUC__) && defined(__SSE4_2__)\n#include <nmmintrin.h>\n#include <cpuid.h>\n#endif\n\n#endif  // defined(LEVELDB_PLATFORM_POSIX_SSE)\n\nnamespace leveldb {\nnamespace port {\n\n#if defined(LEVELDB_PLATFORM_POSIX_SSE)\n\n// Used to fetch a naturally-aligned 32-bit word in little endian byte-order\nstatic inline uint32_t LE_LOAD32(const uint8_t *p) {\n  // SSE is x86 only, so ensured that |p| is always little-endian.\n  uint32_t word;\n  memcpy(&word, p, sizeof(word));\n  return word;\n}\n\n#if defined(_M_X64) || defined(__x86_64__)  // LE_LOAD64 is only used on x64.\n\n// Used to fetch a naturally-aligned 64-bit word in little endian byte-order\nstatic inline uint64_t LE_LOAD64(const uint8_t *p) {\n  uint64_t dword;\n  memcpy(&dword, p, sizeof(dword));\n  return dword;\n}\n\n#endif  // defined(_M_X64) || defined(__x86_64__)\n\nstatic inline bool HaveSSE42() {\n#if defined(_MSC_VER)\n  int cpu_info[4];\n  __cpuid(cpu_info, 1);\n  return (cpu_info[2] & (1 << 20)) != 0;\n#elif defined(__GNUC__)\n  unsigned int eax, ebx, ecx, edx;\n  __get_cpuid(1, &eax, &ebx, &ecx, &edx);\n  return (ecx & (1 << 20)) != 0;\n#else\n  return false;\n#endif\n}\n\n#endif  // defined(LEVELDB_PLATFORM_POSIX_SSE)\n\n// For further improvements see Intel publication at:\n// http://download.intel.com/design/intarch/papers/323405.pdf\nuint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size) {\n#if !defined(LEVELDB_PLATFORM_POSIX_SSE)\n  return 0;\n#else\n  static bool have = HaveSSE42();\n  if (!have) {\n    return 0;\n  }\n\n  const uint8_t *p = reinterpret_cast<const uint8_t *>(buf);\n  const uint8_t *e = p + size;\n  uint32_t l = crc ^ 0xffffffffu;\n\n#define STEP1 do {                              \\\n    l = _mm_crc32_u8(l, *p++);                  \\\n} while (0)\n#define STEP4 do {                              \\\n    l = _mm_crc32_u32(l, LE_LOAD32(p));         \\\n    p += 4;                                     \\\n} while (0)\n#define STEP8 do {                              \\\n    l = _mm_crc32_u64(l, LE_LOAD64(p));         \\\n    p += 8;                                     \\\n} while (0)\n\n  if (size > 16) {\n    // Point x at first 8-byte aligned byte in string. This must be inside the\n    // string, due to the size check above.\n    const uintptr_t pval = reinterpret_cast<uintptr_t>(p);\n    const uint8_t* x = reinterpret_cast<const uint8_t*>(((pval + 7) >> 3) << 3);\n    // Process bytes until p is 8-byte aligned.\n    while (p != x) {\n      STEP1;\n    }\n\n    // _mm_crc32_u64 is only available on x64.\n#if defined(_M_X64) || defined(__x86_64__)\n    // Process 8 bytes at a time\n    while ((e-p) >= 8) {\n      STEP8;\n    }\n    // Process 4 bytes at a time\n    if ((e-p) >= 4) {\n      STEP4;\n    }\n#else  // !(defined(_M_X64) || defined(__x86_64__))\n    // Process 4 bytes at a time\n    while ((e-p) >= 4) {\n      STEP4;\n    }\n#endif  // defined(_M_X64) || defined(__x86_64__)\n  }\n  // Process the last few bytes\n  while (p != e) {\n    STEP1;\n  }\n#undef STEP8\n#undef STEP4\n#undef STEP1\n  return l ^ 0xffffffffu;\n#endif  // defined(LEVELDB_PLATFORM_POSIX_SSE)\n}\n\n}  // namespace port\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/port/thread_annotations.h",
    "content": "// Copyright (c) 2012 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_\n#define STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_\n\n// Some environments provide custom macros to aid in static thread-safety\n// analysis.  Provide empty definitions of such macros unless they are already\n// defined.\n\n#ifndef EXCLUSIVE_LOCKS_REQUIRED\n#define EXCLUSIVE_LOCKS_REQUIRED(...)\n#endif\n\n#ifndef SHARED_LOCKS_REQUIRED\n#define SHARED_LOCKS_REQUIRED(...)\n#endif\n\n#ifndef LOCKS_EXCLUDED\n#define LOCKS_EXCLUDED(...)\n#endif\n\n#ifndef LOCK_RETURNED\n#define LOCK_RETURNED(x)\n#endif\n\n#ifndef LOCKABLE\n#define LOCKABLE\n#endif\n\n#ifndef SCOPED_LOCKABLE\n#define SCOPED_LOCKABLE\n#endif\n\n#ifndef EXCLUSIVE_LOCK_FUNCTION\n#define EXCLUSIVE_LOCK_FUNCTION(...)\n#endif\n\n#ifndef SHARED_LOCK_FUNCTION\n#define SHARED_LOCK_FUNCTION(...)\n#endif\n\n#ifndef EXCLUSIVE_TRYLOCK_FUNCTION\n#define EXCLUSIVE_TRYLOCK_FUNCTION(...)\n#endif\n\n#ifndef SHARED_TRYLOCK_FUNCTION\n#define SHARED_TRYLOCK_FUNCTION(...)\n#endif\n\n#ifndef UNLOCK_FUNCTION\n#define UNLOCK_FUNCTION(...)\n#endif\n\n#ifndef NO_THREAD_SAFETY_ANALYSIS\n#define NO_THREAD_SAFETY_ANALYSIS\n#endif\n\n#endif  // STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/port/win/stdint.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n// MSVC didn't ship with this file until the 2010 version.\n\n#ifndef STORAGE_LEVELDB_PORT_WIN_STDINT_H_\n#define STORAGE_LEVELDB_PORT_WIN_STDINT_H_\n\n#if !defined(_MSC_VER)\n#error This file should only be included when compiling with MSVC.\n#endif\n\n// Define C99 equivalent types.\ntypedef signed char           int8_t;\ntypedef signed short          int16_t;\ntypedef signed int            int32_t;\ntypedef signed long long      int64_t;\ntypedef unsigned char         uint8_t;\ntypedef unsigned short        uint16_t;\ntypedef unsigned int          uint32_t;\ntypedef unsigned long long    uint64_t;\n\n#endif  // STORAGE_LEVELDB_PORT_WIN_STDINT_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/table/block.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// Decodes the blocks generated by block_builder.cc.\n\n#include \"table/block.h\"\n\n#include <vector>\n#include <algorithm>\n#include \"leveldb/comparator.h\"\n#include \"table/format.h\"\n#include \"util/coding.h\"\n#include \"util/logging.h\"\n\nnamespace leveldb {\n\ninline uint32_t Block::NumRestarts() const {\n  assert(size_ >= sizeof(uint32_t));\n  return DecodeFixed32(data_ + size_ - sizeof(uint32_t));\n}\n\nBlock::Block(const BlockContents& contents)\n    : data_(contents.data.data()),\n      size_(contents.data.size()),\n      owned_(contents.heap_allocated) {\n  if (size_ < sizeof(uint32_t)) {\n    size_ = 0;  // Error marker\n  } else {\n    size_t max_restarts_allowed = (size_-sizeof(uint32_t)) / sizeof(uint32_t);\n    if (NumRestarts() > max_restarts_allowed) {\n      // The size is too small for NumRestarts()\n      size_ = 0;\n    } else {\n      restart_offset_ = size_ - (1 + NumRestarts()) * sizeof(uint32_t);\n    }\n  }\n}\n\nBlock::~Block() {\n  if (owned_) {\n    delete[] data_;\n  }\n}\n\n// Helper routine: decode the next block entry starting at \"p\",\n// storing the number of shared key bytes, non_shared key bytes,\n// and the length of the value in \"*shared\", \"*non_shared\", and\n// \"*value_length\", respectively.  Will not dereference past \"limit\".\n//\n// If any errors are detected, returns NULL.  Otherwise, returns a\n// pointer to the key delta (just past the three decoded values).\nstatic inline const char* DecodeEntry(const char* p, const char* limit,\n                                      uint32_t* shared,\n                                      uint32_t* non_shared,\n                                      uint32_t* value_length) {\n  if (limit - p < 3) return NULL;\n  *shared = reinterpret_cast<const unsigned char*>(p)[0];\n  *non_shared = reinterpret_cast<const unsigned char*>(p)[1];\n  *value_length = reinterpret_cast<const unsigned char*>(p)[2];\n  if ((*shared | *non_shared | *value_length) < 128) {\n    // Fast path: all three values are encoded in one byte each\n    p += 3;\n  } else {\n    if ((p = GetVarint32Ptr(p, limit, shared)) == NULL) return NULL;\n    if ((p = GetVarint32Ptr(p, limit, non_shared)) == NULL) return NULL;\n    if ((p = GetVarint32Ptr(p, limit, value_length)) == NULL) return NULL;\n  }\n\n  if (static_cast<uint32_t>(limit - p) < (*non_shared + *value_length)) {\n    return NULL;\n  }\n  return p;\n}\n\nclass Block::Iter : public Iterator {\n private:\n  const Comparator* const comparator_;\n  const char* const data_;      // underlying block contents\n  uint32_t const restarts_;     // Offset of restart array (list of fixed32)\n  uint32_t const num_restarts_; // Number of uint32_t entries in restart array\n\n  // current_ is offset in data_ of current entry.  >= restarts_ if !Valid\n  uint32_t current_;\n  uint32_t restart_index_;  // Index of restart block in which current_ falls\n  std::string key_;\n  Slice value_;\n  Status status_;\n\n  inline int Compare(const Slice& a, const Slice& b) const {\n    return comparator_->Compare(a, b);\n  }\n\n  // Return the offset in data_ just past the end of the current entry.\n  inline uint32_t NextEntryOffset() const {\n    return (value_.data() + value_.size()) - data_;\n  }\n\n  uint32_t GetRestartPoint(uint32_t index) {\n    assert(index < num_restarts_);\n    return DecodeFixed32(data_ + restarts_ + index * sizeof(uint32_t));\n  }\n\n  void SeekToRestartPoint(uint32_t index) {\n    key_.clear();\n    restart_index_ = index;\n    // current_ will be fixed by ParseNextKey();\n\n    // ParseNextKey() starts at the end of value_, so set value_ accordingly\n    uint32_t offset = GetRestartPoint(index);\n    value_ = Slice(data_ + offset, 0);\n  }\n\n public:\n  Iter(const Comparator* comparator,\n       const char* data,\n       uint32_t restarts,\n       uint32_t num_restarts)\n      : comparator_(comparator),\n        data_(data),\n        restarts_(restarts),\n        num_restarts_(num_restarts),\n        current_(restarts_),\n        restart_index_(num_restarts_) {\n    assert(num_restarts_ > 0);\n  }\n\n  virtual bool Valid() const { return current_ < restarts_; }\n  virtual Status status() const { return status_; }\n  virtual Slice key() const {\n    assert(Valid());\n    return key_;\n  }\n  virtual Slice value() const {\n    assert(Valid());\n    return value_;\n  }\n\n  virtual void Next() {\n    assert(Valid());\n    ParseNextKey();\n  }\n\n  virtual void Prev() {\n    assert(Valid());\n\n    // Scan backwards to a restart point before current_\n    const uint32_t original = current_;\n    while (GetRestartPoint(restart_index_) >= original) {\n      if (restart_index_ == 0) {\n        // No more entries\n        current_ = restarts_;\n        restart_index_ = num_restarts_;\n        return;\n      }\n      restart_index_--;\n    }\n\n    SeekToRestartPoint(restart_index_);\n    do {\n      // Loop until end of current entry hits the start of original entry\n    } while (ParseNextKey() && NextEntryOffset() < original);\n  }\n\n  virtual void Seek(const Slice& target) {\n    // Binary search in restart array to find the last restart point\n    // with a key < target\n    uint32_t left = 0;\n    uint32_t right = num_restarts_ - 1;\n    while (left < right) {\n      uint32_t mid = (left + right + 1) / 2;\n      uint32_t region_offset = GetRestartPoint(mid);\n      uint32_t shared, non_shared, value_length;\n      const char* key_ptr = DecodeEntry(data_ + region_offset,\n                                        data_ + restarts_,\n                                        &shared, &non_shared, &value_length);\n      if (key_ptr == NULL || (shared != 0)) {\n        CorruptionError();\n        return;\n      }\n      Slice mid_key(key_ptr, non_shared);\n      if (Compare(mid_key, target) < 0) {\n        // Key at \"mid\" is smaller than \"target\".  Therefore all\n        // blocks before \"mid\" are uninteresting.\n        left = mid;\n      } else {\n        // Key at \"mid\" is >= \"target\".  Therefore all blocks at or\n        // after \"mid\" are uninteresting.\n        right = mid - 1;\n      }\n    }\n\n    // Linear search (within restart block) for first key >= target\n    SeekToRestartPoint(left);\n    while (true) {\n      if (!ParseNextKey()) {\n        return;\n      }\n      if (Compare(key_, target) >= 0) {\n        return;\n      }\n    }\n  }\n\n  virtual void SeekToFirst() {\n    SeekToRestartPoint(0);\n    ParseNextKey();\n  }\n\n  virtual void SeekToLast() {\n    SeekToRestartPoint(num_restarts_ - 1);\n    while (ParseNextKey() && NextEntryOffset() < restarts_) {\n      // Keep skipping\n    }\n  }\n\n private:\n  void CorruptionError() {\n    current_ = restarts_;\n    restart_index_ = num_restarts_;\n    status_ = Status::Corruption(\"bad entry in block\");\n    key_.clear();\n    value_.clear();\n  }\n\n  bool ParseNextKey() {\n    current_ = NextEntryOffset();\n    const char* p = data_ + current_;\n    const char* limit = data_ + restarts_;  // Restarts come right after data\n    if (p >= limit) {\n      // No more entries to return.  Mark as invalid.\n      current_ = restarts_;\n      restart_index_ = num_restarts_;\n      return false;\n    }\n\n    // Decode next entry\n    uint32_t shared, non_shared, value_length;\n    p = DecodeEntry(p, limit, &shared, &non_shared, &value_length);\n    if (p == NULL || key_.size() < shared) {\n      CorruptionError();\n      return false;\n    } else {\n      key_.resize(shared);\n      key_.append(p, non_shared);\n      value_ = Slice(p + non_shared, value_length);\n      while (restart_index_ + 1 < num_restarts_ &&\n             GetRestartPoint(restart_index_ + 1) < current_) {\n        ++restart_index_;\n      }\n      return true;\n    }\n  }\n};\n\nIterator* Block::NewIterator(const Comparator* cmp) {\n  if (size_ < sizeof(uint32_t)) {\n    return NewErrorIterator(Status::Corruption(\"bad block contents\"));\n  }\n  const uint32_t num_restarts = NumRestarts();\n  if (num_restarts == 0) {\n    return NewEmptyIterator();\n  } else {\n    return new Iter(cmp, data_, restart_offset_, num_restarts);\n  }\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/table/block.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_TABLE_BLOCK_H_\n#define STORAGE_LEVELDB_TABLE_BLOCK_H_\n\n#include <stddef.h>\n#include <stdint.h>\n#include \"leveldb/iterator.h\"\n\nnamespace leveldb {\n\nstruct BlockContents;\nclass Comparator;\n\nclass Block {\n public:\n  // Initialize the block with the specified contents.\n  explicit Block(const BlockContents& contents);\n\n  ~Block();\n\n  size_t size() const { return size_; }\n  Iterator* NewIterator(const Comparator* comparator);\n\n private:\n  uint32_t NumRestarts() const;\n\n  const char* data_;\n  size_t size_;\n  uint32_t restart_offset_;     // Offset in data_ of restart array\n  bool owned_;                  // Block owns data_[]\n\n  // No copying allowed\n  Block(const Block&);\n  void operator=(const Block&);\n\n  class Iter;\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_TABLE_BLOCK_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/table/block_builder.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// BlockBuilder generates blocks where keys are prefix-compressed:\n//\n// When we store a key, we drop the prefix shared with the previous\n// string.  This helps reduce the space requirement significantly.\n// Furthermore, once every K keys, we do not apply the prefix\n// compression and store the entire key.  We call this a \"restart\n// point\".  The tail end of the block stores the offsets of all of the\n// restart points, and can be used to do a binary search when looking\n// for a particular key.  Values are stored as-is (without compression)\n// immediately following the corresponding key.\n//\n// An entry for a particular key-value pair has the form:\n//     shared_bytes: varint32\n//     unshared_bytes: varint32\n//     value_length: varint32\n//     key_delta: char[unshared_bytes]\n//     value: char[value_length]\n// shared_bytes == 0 for restart points.\n//\n// The trailer of the block has the form:\n//     restarts: uint32[num_restarts]\n//     num_restarts: uint32\n// restarts[i] contains the offset within the block of the ith restart point.\n\n#include \"table/block_builder.h\"\n\n#include <algorithm>\n#include <assert.h>\n#include \"leveldb/comparator.h\"\n#include \"leveldb/table_builder.h\"\n#include \"util/coding.h\"\n\nnamespace leveldb {\n\nBlockBuilder::BlockBuilder(const Options* options)\n    : options_(options),\n      restarts_(),\n      counter_(0),\n      finished_(false) {\n  assert(options->block_restart_interval >= 1);\n  restarts_.push_back(0);       // First restart point is at offset 0\n}\n\nvoid BlockBuilder::Reset() {\n  buffer_.clear();\n  restarts_.clear();\n  restarts_.push_back(0);       // First restart point is at offset 0\n  counter_ = 0;\n  finished_ = false;\n  last_key_.clear();\n}\n\nsize_t BlockBuilder::CurrentSizeEstimate() const {\n  return (buffer_.size() +                        // Raw data buffer\n          restarts_.size() * sizeof(uint32_t) +   // Restart array\n          sizeof(uint32_t));                      // Restart array length\n}\n\nSlice BlockBuilder::Finish() {\n  // Append restart array\n  for (size_t i = 0; i < restarts_.size(); i++) {\n    PutFixed32(&buffer_, restarts_[i]);\n  }\n  PutFixed32(&buffer_, restarts_.size());\n  finished_ = true;\n  return Slice(buffer_);\n}\n\nvoid BlockBuilder::Add(const Slice& key, const Slice& value) {\n  Slice last_key_piece(last_key_);\n  assert(!finished_);\n  assert(counter_ <= options_->block_restart_interval);\n  assert(buffer_.empty() // No values yet?\n         || options_->comparator->Compare(key, last_key_piece) > 0);\n  size_t shared = 0;\n  if (counter_ < options_->block_restart_interval) {\n    // See how much sharing to do with previous string\n    const size_t min_length = std::min(last_key_piece.size(), key.size());\n    while ((shared < min_length) && (last_key_piece[shared] == key[shared])) {\n      shared++;\n    }\n  } else {\n    // Restart compression\n    restarts_.push_back(buffer_.size());\n    counter_ = 0;\n  }\n  const size_t non_shared = key.size() - shared;\n\n  // Add \"<shared><non_shared><value_size>\" to buffer_\n  PutVarint32(&buffer_, shared);\n  PutVarint32(&buffer_, non_shared);\n  PutVarint32(&buffer_, value.size());\n\n  // Add string delta to buffer_ followed by value\n  buffer_.append(key.data() + shared, non_shared);\n  buffer_.append(value.data(), value.size());\n\n  // Update state\n  last_key_.resize(shared);\n  last_key_.append(key.data() + shared, non_shared);\n  assert(Slice(last_key_) == key);\n  counter_++;\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/table/block_builder.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_\n#define STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_\n\n#include <vector>\n\n#include <stdint.h>\n#include \"leveldb/slice.h\"\n\nnamespace leveldb {\n\nstruct Options;\n\nclass BlockBuilder {\n public:\n  explicit BlockBuilder(const Options* options);\n\n  // Reset the contents as if the BlockBuilder was just constructed.\n  void Reset();\n\n  // REQUIRES: Finish() has not been called since the last call to Reset().\n  // REQUIRES: key is larger than any previously added key\n  void Add(const Slice& key, const Slice& value);\n\n  // Finish building the block and return a slice that refers to the\n  // block contents.  The returned slice will remain valid for the\n  // lifetime of this builder or until Reset() is called.\n  Slice Finish();\n\n  // Returns an estimate of the current (uncompressed) size of the block\n  // we are building.\n  size_t CurrentSizeEstimate() const;\n\n  // Return true iff no entries have been added since the last Reset()\n  bool empty() const {\n    return buffer_.empty();\n  }\n\n private:\n  const Options*        options_;\n  std::string           buffer_;      // Destination buffer\n  std::vector<uint32_t> restarts_;    // Restart points\n  int                   counter_;     // Number of entries emitted since restart\n  bool                  finished_;    // Has Finish() been called?\n  std::string           last_key_;\n\n  // No copying allowed\n  BlockBuilder(const BlockBuilder&);\n  void operator=(const BlockBuilder&);\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/table/filter_block.cc",
    "content": "// Copyright (c) 2012 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"table/filter_block.h\"\n\n#include \"leveldb/filter_policy.h\"\n#include \"util/coding.h\"\n\nnamespace leveldb {\n\n// See doc/table_format.md for an explanation of the filter block format.\n\n// Generate new filter every 2KB of data\nstatic const size_t kFilterBaseLg = 11;\nstatic const size_t kFilterBase = 1 << kFilterBaseLg;\n\nFilterBlockBuilder::FilterBlockBuilder(const FilterPolicy* policy)\n    : policy_(policy) {\n}\n\nvoid FilterBlockBuilder::StartBlock(uint64_t block_offset) {\n  uint64_t filter_index = (block_offset / kFilterBase);\n  assert(filter_index >= filter_offsets_.size());\n  while (filter_index > filter_offsets_.size()) {\n    GenerateFilter();\n  }\n}\n\nvoid FilterBlockBuilder::AddKey(const Slice& key) {\n  Slice k = key;\n  start_.push_back(keys_.size());\n  keys_.append(k.data(), k.size());\n}\n\nSlice FilterBlockBuilder::Finish() {\n  if (!start_.empty()) {\n    GenerateFilter();\n  }\n\n  // Append array of per-filter offsets\n  const uint32_t array_offset = result_.size();\n  for (size_t i = 0; i < filter_offsets_.size(); i++) {\n    PutFixed32(&result_, filter_offsets_[i]);\n  }\n\n  PutFixed32(&result_, array_offset);\n  result_.push_back(kFilterBaseLg);  // Save encoding parameter in result\n  return Slice(result_);\n}\n\nvoid FilterBlockBuilder::GenerateFilter() {\n  const size_t num_keys = start_.size();\n  if (num_keys == 0) {\n    // Fast path if there are no keys for this filter\n    filter_offsets_.push_back(result_.size());\n    return;\n  }\n\n  // Make list of keys from flattened key structure\n  start_.push_back(keys_.size());  // Simplify length computation\n  tmp_keys_.resize(num_keys);\n  for (size_t i = 0; i < num_keys; i++) {\n    const char* base = keys_.data() + start_[i];\n    size_t length = start_[i+1] - start_[i];\n    tmp_keys_[i] = Slice(base, length);\n  }\n\n  // Generate filter for current set of keys and append to result_.\n  filter_offsets_.push_back(result_.size());\n  policy_->CreateFilter(&tmp_keys_[0], static_cast<int>(num_keys), &result_);\n\n  tmp_keys_.clear();\n  keys_.clear();\n  start_.clear();\n}\n\nFilterBlockReader::FilterBlockReader(const FilterPolicy* policy,\n                                     const Slice& contents)\n    : policy_(policy),\n      data_(NULL),\n      offset_(NULL),\n      num_(0),\n      base_lg_(0) {\n  size_t n = contents.size();\n  if (n < 5) return;  // 1 byte for base_lg_ and 4 for start of offset array\n  base_lg_ = contents[n-1];\n  uint32_t last_word = DecodeFixed32(contents.data() + n - 5);\n  if (last_word > n - 5) return;\n  data_ = contents.data();\n  offset_ = data_ + last_word;\n  num_ = (n - 5 - last_word) / 4;\n}\n\nbool FilterBlockReader::KeyMayMatch(uint64_t block_offset, const Slice& key) {\n  uint64_t index = block_offset >> base_lg_;\n  if (index < num_) {\n    uint32_t start = DecodeFixed32(offset_ + index*4);\n    uint32_t limit = DecodeFixed32(offset_ + index*4 + 4);\n    if (start <= limit && limit <= static_cast<size_t>(offset_ - data_)) {\n      Slice filter = Slice(data_ + start, limit - start);\n      return policy_->KeyMayMatch(key, filter);\n    } else if (start == limit) {\n      // Empty filters do not match any keys\n      return false;\n    }\n  }\n  return true;  // Errors are treated as potential matches\n}\n\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/table/filter_block.h",
    "content": "// Copyright (c) 2012 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// A filter block is stored near the end of a Table file.  It contains\n// filters (e.g., bloom filters) for all data blocks in the table combined\n// into a single filter block.\n\n#ifndef STORAGE_LEVELDB_TABLE_FILTER_BLOCK_H_\n#define STORAGE_LEVELDB_TABLE_FILTER_BLOCK_H_\n\n#include <stddef.h>\n#include <stdint.h>\n#include <string>\n#include <vector>\n#include \"leveldb/slice.h\"\n#include \"util/hash.h\"\n\nnamespace leveldb {\n\nclass FilterPolicy;\n\n// A FilterBlockBuilder is used to construct all of the filters for a\n// particular Table.  It generates a single string which is stored as\n// a special block in the Table.\n//\n// The sequence of calls to FilterBlockBuilder must match the regexp:\n//      (StartBlock AddKey*)* Finish\nclass FilterBlockBuilder {\n public:\n  explicit FilterBlockBuilder(const FilterPolicy*);\n\n  void StartBlock(uint64_t block_offset);\n  void AddKey(const Slice& key);\n  Slice Finish();\n\n private:\n  void GenerateFilter();\n\n  const FilterPolicy* policy_;\n  std::string keys_;              // Flattened key contents\n  std::vector<size_t> start_;     // Starting index in keys_ of each key\n  std::string result_;            // Filter data computed so far\n  std::vector<Slice> tmp_keys_;   // policy_->CreateFilter() argument\n  std::vector<uint32_t> filter_offsets_;\n\n  // No copying allowed\n  FilterBlockBuilder(const FilterBlockBuilder&);\n  void operator=(const FilterBlockBuilder&);\n};\n\nclass FilterBlockReader {\n public:\n // REQUIRES: \"contents\" and *policy must stay live while *this is live.\n  FilterBlockReader(const FilterPolicy* policy, const Slice& contents);\n  bool KeyMayMatch(uint64_t block_offset, const Slice& key);\n\n private:\n  const FilterPolicy* policy_;\n  const char* data_;    // Pointer to filter data (at block-start)\n  const char* offset_;  // Pointer to beginning of offset array (at block-end)\n  size_t num_;          // Number of entries in offset array\n  size_t base_lg_;      // Encoding parameter (see kFilterBaseLg in .cc file)\n};\n\n}\n\n#endif  // STORAGE_LEVELDB_TABLE_FILTER_BLOCK_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/table/filter_block_test.cc",
    "content": "// Copyright (c) 2012 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"table/filter_block.h\"\n\n#include \"leveldb/filter_policy.h\"\n#include \"util/coding.h\"\n#include \"util/hash.h\"\n#include \"util/logging.h\"\n#include \"util/testharness.h\"\n#include \"util/testutil.h\"\n\nnamespace leveldb {\n\n// For testing: emit an array with one hash value per key\nclass TestHashFilter : public FilterPolicy {\n public:\n  virtual const char* Name() const {\n    return \"TestHashFilter\";\n  }\n\n  virtual void CreateFilter(const Slice* keys, int n, std::string* dst) const {\n    for (int i = 0; i < n; i++) {\n      uint32_t h = Hash(keys[i].data(), keys[i].size(), 1);\n      PutFixed32(dst, h);\n    }\n  }\n\n  virtual bool KeyMayMatch(const Slice& key, const Slice& filter) const {\n    uint32_t h = Hash(key.data(), key.size(), 1);\n    for (size_t i = 0; i + 4 <= filter.size(); i += 4) {\n      if (h == DecodeFixed32(filter.data() + i)) {\n        return true;\n      }\n    }\n    return false;\n  }\n};\n\nclass FilterBlockTest {\n public:\n  TestHashFilter policy_;\n};\n\nTEST(FilterBlockTest, EmptyBuilder) {\n  FilterBlockBuilder builder(&policy_);\n  Slice block = builder.Finish();\n  ASSERT_EQ(\"\\\\x00\\\\x00\\\\x00\\\\x00\\\\x0b\", EscapeString(block));\n  FilterBlockReader reader(&policy_, block);\n  ASSERT_TRUE(reader.KeyMayMatch(0, \"foo\"));\n  ASSERT_TRUE(reader.KeyMayMatch(100000, \"foo\"));\n}\n\nTEST(FilterBlockTest, SingleChunk) {\n  FilterBlockBuilder builder(&policy_);\n  builder.StartBlock(100);\n  builder.AddKey(\"foo\");\n  builder.AddKey(\"bar\");\n  builder.AddKey(\"box\");\n  builder.StartBlock(200);\n  builder.AddKey(\"box\");\n  builder.StartBlock(300);\n  builder.AddKey(\"hello\");\n  Slice block = builder.Finish();\n  FilterBlockReader reader(&policy_, block);\n  ASSERT_TRUE(reader.KeyMayMatch(100, \"foo\"));\n  ASSERT_TRUE(reader.KeyMayMatch(100, \"bar\"));\n  ASSERT_TRUE(reader.KeyMayMatch(100, \"box\"));\n  ASSERT_TRUE(reader.KeyMayMatch(100, \"hello\"));\n  ASSERT_TRUE(reader.KeyMayMatch(100, \"foo\"));\n  ASSERT_TRUE(! reader.KeyMayMatch(100, \"missing\"));\n  ASSERT_TRUE(! reader.KeyMayMatch(100, \"other\"));\n}\n\nTEST(FilterBlockTest, MultiChunk) {\n  FilterBlockBuilder builder(&policy_);\n\n  // First filter\n  builder.StartBlock(0);\n  builder.AddKey(\"foo\");\n  builder.StartBlock(2000);\n  builder.AddKey(\"bar\");\n\n  // Second filter\n  builder.StartBlock(3100);\n  builder.AddKey(\"box\");\n\n  // Third filter is empty\n\n  // Last filter\n  builder.StartBlock(9000);\n  builder.AddKey(\"box\");\n  builder.AddKey(\"hello\");\n\n  Slice block = builder.Finish();\n  FilterBlockReader reader(&policy_, block);\n\n  // Check first filter\n  ASSERT_TRUE(reader.KeyMayMatch(0, \"foo\"));\n  ASSERT_TRUE(reader.KeyMayMatch(2000, \"bar\"));\n  ASSERT_TRUE(! reader.KeyMayMatch(0, \"box\"));\n  ASSERT_TRUE(! reader.KeyMayMatch(0, \"hello\"));\n\n  // Check second filter\n  ASSERT_TRUE(reader.KeyMayMatch(3100, \"box\"));\n  ASSERT_TRUE(! reader.KeyMayMatch(3100, \"foo\"));\n  ASSERT_TRUE(! reader.KeyMayMatch(3100, \"bar\"));\n  ASSERT_TRUE(! reader.KeyMayMatch(3100, \"hello\"));\n\n  // Check third filter (empty)\n  ASSERT_TRUE(! reader.KeyMayMatch(4100, \"foo\"));\n  ASSERT_TRUE(! reader.KeyMayMatch(4100, \"bar\"));\n  ASSERT_TRUE(! reader.KeyMayMatch(4100, \"box\"));\n  ASSERT_TRUE(! reader.KeyMayMatch(4100, \"hello\"));\n\n  // Check last filter\n  ASSERT_TRUE(reader.KeyMayMatch(9000, \"box\"));\n  ASSERT_TRUE(reader.KeyMayMatch(9000, \"hello\"));\n  ASSERT_TRUE(! reader.KeyMayMatch(9000, \"foo\"));\n  ASSERT_TRUE(! reader.KeyMayMatch(9000, \"bar\"));\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/table/format.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"table/format.h\"\n\n#include \"leveldb/env.h\"\n#include \"port/port.h\"\n#include \"table/block.h\"\n#include \"util/coding.h\"\n#include \"util/crc32c.h\"\n\nnamespace leveldb {\n\nvoid BlockHandle::EncodeTo(std::string* dst) const {\n  // Sanity check that all fields have been set\n  assert(offset_ != ~static_cast<uint64_t>(0));\n  assert(size_ != ~static_cast<uint64_t>(0));\n  PutVarint64(dst, offset_);\n  PutVarint64(dst, size_);\n}\n\nStatus BlockHandle::DecodeFrom(Slice* input) {\n  if (GetVarint64(input, &offset_) &&\n      GetVarint64(input, &size_)) {\n    return Status::OK();\n  } else {\n    return Status::Corruption(\"bad block handle\");\n  }\n}\n\nvoid Footer::EncodeTo(std::string* dst) const {\n  const size_t original_size = dst->size();\n  metaindex_handle_.EncodeTo(dst);\n  index_handle_.EncodeTo(dst);\n  dst->resize(2 * BlockHandle::kMaxEncodedLength);  // Padding\n  PutFixed32(dst, static_cast<uint32_t>(kTableMagicNumber & 0xffffffffu));\n  PutFixed32(dst, static_cast<uint32_t>(kTableMagicNumber >> 32));\n  assert(dst->size() == original_size + kEncodedLength);\n  (void)original_size;  // Disable unused variable warning.\n}\n\nStatus Footer::DecodeFrom(Slice* input) {\n  const char* magic_ptr = input->data() + kEncodedLength - 8;\n  const uint32_t magic_lo = DecodeFixed32(magic_ptr);\n  const uint32_t magic_hi = DecodeFixed32(magic_ptr + 4);\n  const uint64_t magic = ((static_cast<uint64_t>(magic_hi) << 32) |\n                          (static_cast<uint64_t>(magic_lo)));\n  if (magic != kTableMagicNumber) {\n    return Status::Corruption(\"not an sstable (bad magic number)\");\n  }\n\n  Status result = metaindex_handle_.DecodeFrom(input);\n  if (result.ok()) {\n    result = index_handle_.DecodeFrom(input);\n  }\n  if (result.ok()) {\n    // We skip over any leftover data (just padding for now) in \"input\"\n    const char* end = magic_ptr + 8;\n    *input = Slice(end, input->data() + input->size() - end);\n  }\n  return result;\n}\n\nStatus ReadBlock(RandomAccessFile* file,\n                 const ReadOptions& options,\n                 const BlockHandle& handle,\n                 BlockContents* result) {\n  result->data = Slice();\n  result->cachable = false;\n  result->heap_allocated = false;\n\n  // Read the block contents as well as the type/crc footer.\n  // See table_builder.cc for the code that built this structure.\n  size_t n = static_cast<size_t>(handle.size());\n  char* buf = new char[n + kBlockTrailerSize];\n  Slice contents;\n  Status s = file->Read(handle.offset(), n + kBlockTrailerSize, &contents, buf);\n  if (!s.ok()) {\n    delete[] buf;\n    return s;\n  }\n  if (contents.size() != n + kBlockTrailerSize) {\n    delete[] buf;\n    return Status::Corruption(\"truncated block read\");\n  }\n\n  // Check the crc of the type and the block contents\n  const char* data = contents.data();    // Pointer to where Read put the data\n  if (options.verify_checksums) {\n    const uint32_t crc = crc32c::Unmask(DecodeFixed32(data + n + 1));\n    const uint32_t actual = crc32c::Value(data, n + 1);\n    if (actual != crc) {\n      delete[] buf;\n      s = Status::Corruption(\"block checksum mismatch\");\n      return s;\n    }\n  }\n\n  switch (data[n]) {\n    case kNoCompression:\n      if (data != buf) {\n        // File implementation gave us pointer to some other data.\n        // Use it directly under the assumption that it will be live\n        // while the file is open.\n        delete[] buf;\n        result->data = Slice(data, n);\n        result->heap_allocated = false;\n        result->cachable = false;  // Do not double-cache\n      } else {\n        result->data = Slice(buf, n);\n        result->heap_allocated = true;\n        result->cachable = true;\n      }\n\n      // Ok\n      break;\n    case kSnappyCompression: {\n      size_t ulength = 0;\n      if (!port::Snappy_GetUncompressedLength(data, n, &ulength)) {\n        delete[] buf;\n        return Status::Corruption(\"corrupted compressed block contents\");\n      }\n      char* ubuf = new char[ulength];\n      if (!port::Snappy_Uncompress(data, n, ubuf)) {\n        delete[] buf;\n        delete[] ubuf;\n        return Status::Corruption(\"corrupted compressed block contents\");\n      }\n      delete[] buf;\n      result->data = Slice(ubuf, ulength);\n      result->heap_allocated = true;\n      result->cachable = true;\n      break;\n    }\n    default:\n      delete[] buf;\n      return Status::Corruption(\"bad block type\");\n  }\n\n  return Status::OK();\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/table/format.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_TABLE_FORMAT_H_\n#define STORAGE_LEVELDB_TABLE_FORMAT_H_\n\n#include <string>\n#include <stdint.h>\n#include \"leveldb/slice.h\"\n#include \"leveldb/status.h\"\n#include \"leveldb/table_builder.h\"\n\nnamespace leveldb {\n\nclass Block;\nclass RandomAccessFile;\nstruct ReadOptions;\n\n// BlockHandle is a pointer to the extent of a file that stores a data\n// block or a meta block.\nclass BlockHandle {\n public:\n  BlockHandle();\n\n  // The offset of the block in the file.\n  uint64_t offset() const { return offset_; }\n  void set_offset(uint64_t offset) { offset_ = offset; }\n\n  // The size of the stored block\n  uint64_t size() const { return size_; }\n  void set_size(uint64_t size) { size_ = size; }\n\n  void EncodeTo(std::string* dst) const;\n  Status DecodeFrom(Slice* input);\n\n  // Maximum encoding length of a BlockHandle\n  enum { kMaxEncodedLength = 10 + 10 };\n\n private:\n  uint64_t offset_;\n  uint64_t size_;\n};\n\n// Footer encapsulates the fixed information stored at the tail\n// end of every table file.\nclass Footer {\n public:\n  Footer() { }\n\n  // The block handle for the metaindex block of the table\n  const BlockHandle& metaindex_handle() const { return metaindex_handle_; }\n  void set_metaindex_handle(const BlockHandle& h) { metaindex_handle_ = h; }\n\n  // The block handle for the index block of the table\n  const BlockHandle& index_handle() const {\n    return index_handle_;\n  }\n  void set_index_handle(const BlockHandle& h) {\n    index_handle_ = h;\n  }\n\n  void EncodeTo(std::string* dst) const;\n  Status DecodeFrom(Slice* input);\n\n  // Encoded length of a Footer.  Note that the serialization of a\n  // Footer will always occupy exactly this many bytes.  It consists\n  // of two block handles and a magic number.\n  enum {\n    kEncodedLength = 2*BlockHandle::kMaxEncodedLength + 8\n  };\n\n private:\n  BlockHandle metaindex_handle_;\n  BlockHandle index_handle_;\n};\n\n// kTableMagicNumber was picked by running\n//    echo http://code.google.com/p/leveldb/ | sha1sum\n// and taking the leading 64 bits.\nstatic const uint64_t kTableMagicNumber = 0xdb4775248b80fb57ull;\n\n// 1-byte type + 32-bit crc\nstatic const size_t kBlockTrailerSize = 5;\n\nstruct BlockContents {\n  Slice data;           // Actual contents of data\n  bool cachable;        // True iff data can be cached\n  bool heap_allocated;  // True iff caller should delete[] data.data()\n};\n\n// Read the block identified by \"handle\" from \"file\".  On failure\n// return non-OK.  On success fill *result and return OK.\nextern Status ReadBlock(RandomAccessFile* file,\n                        const ReadOptions& options,\n                        const BlockHandle& handle,\n                        BlockContents* result);\n\n// Implementation details follow.  Clients should ignore,\n\ninline BlockHandle::BlockHandle()\n    : offset_(~static_cast<uint64_t>(0)),\n      size_(~static_cast<uint64_t>(0)) {\n}\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_TABLE_FORMAT_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/table/iterator.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/iterator.h\"\n\nnamespace leveldb {\n\nIterator::Iterator() {\n  cleanup_.function = NULL;\n  cleanup_.next = NULL;\n}\n\nIterator::~Iterator() {\n  if (cleanup_.function != NULL) {\n    (*cleanup_.function)(cleanup_.arg1, cleanup_.arg2);\n    for (Cleanup* c = cleanup_.next; c != NULL; ) {\n      (*c->function)(c->arg1, c->arg2);\n      Cleanup* next = c->next;\n      delete c;\n      c = next;\n    }\n  }\n}\n\nvoid Iterator::RegisterCleanup(CleanupFunction func, void* arg1, void* arg2) {\n  assert(func != NULL);\n  Cleanup* c;\n  if (cleanup_.function == NULL) {\n    c = &cleanup_;\n  } else {\n    c = new Cleanup;\n    c->next = cleanup_.next;\n    cleanup_.next = c;\n  }\n  c->function = func;\n  c->arg1 = arg1;\n  c->arg2 = arg2;\n}\n\nnamespace {\nclass EmptyIterator : public Iterator {\n public:\n  EmptyIterator(const Status& s) : status_(s) { }\n  virtual bool Valid() const { return false; }\n  virtual void Seek(const Slice& target) { }\n  virtual void SeekToFirst() { }\n  virtual void SeekToLast() { }\n  virtual void Next() { assert(false); }\n  virtual void Prev() { assert(false); }\n  Slice key() const { assert(false); return Slice(); }\n  Slice value() const { assert(false); return Slice(); }\n  virtual Status status() const { return status_; }\n private:\n  Status status_;\n};\n}  // namespace\n\nIterator* NewEmptyIterator() {\n  return new EmptyIterator(Status::OK());\n}\n\nIterator* NewErrorIterator(const Status& status) {\n  return new EmptyIterator(status);\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/table/iterator_wrapper.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_TABLE_ITERATOR_WRAPPER_H_\n#define STORAGE_LEVELDB_TABLE_ITERATOR_WRAPPER_H_\n\n#include \"leveldb/iterator.h\"\n#include \"leveldb/slice.h\"\n\nnamespace leveldb {\n\n// A internal wrapper class with an interface similar to Iterator that\n// caches the valid() and key() results for an underlying iterator.\n// This can help avoid virtual function calls and also gives better\n// cache locality.\nclass IteratorWrapper {\n public:\n  IteratorWrapper(): iter_(NULL), valid_(false) { }\n  explicit IteratorWrapper(Iterator* iter): iter_(NULL) {\n    Set(iter);\n  }\n  ~IteratorWrapper() { delete iter_; }\n  Iterator* iter() const { return iter_; }\n\n  // Takes ownership of \"iter\" and will delete it when destroyed, or\n  // when Set() is invoked again.\n  void Set(Iterator* iter) {\n    delete iter_;\n    iter_ = iter;\n    if (iter_ == NULL) {\n      valid_ = false;\n    } else {\n      Update();\n    }\n  }\n\n\n  // Iterator interface methods\n  bool Valid() const        { return valid_; }\n  Slice key() const         { assert(Valid()); return key_; }\n  Slice value() const       { assert(Valid()); return iter_->value(); }\n  // Methods below require iter() != NULL\n  Status status() const     { assert(iter_); return iter_->status(); }\n  void Next()               { assert(iter_); iter_->Next();        Update(); }\n  void Prev()               { assert(iter_); iter_->Prev();        Update(); }\n  void Seek(const Slice& k) { assert(iter_); iter_->Seek(k);       Update(); }\n  void SeekToFirst()        { assert(iter_); iter_->SeekToFirst(); Update(); }\n  void SeekToLast()         { assert(iter_); iter_->SeekToLast();  Update(); }\n\n private:\n  void Update() {\n    valid_ = iter_->Valid();\n    if (valid_) {\n      key_ = iter_->key();\n    }\n  }\n\n  Iterator* iter_;\n  bool valid_;\n  Slice key_;\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_TABLE_ITERATOR_WRAPPER_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/table/merger.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"table/merger.h\"\n\n#include \"leveldb/comparator.h\"\n#include \"leveldb/iterator.h\"\n#include \"table/iterator_wrapper.h\"\n\nnamespace leveldb {\n\nnamespace {\nclass MergingIterator : public Iterator {\n public:\n  MergingIterator(const Comparator* comparator, Iterator** children, int n)\n      : comparator_(comparator),\n        children_(new IteratorWrapper[n]),\n        n_(n),\n        current_(NULL),\n        direction_(kForward) {\n    for (int i = 0; i < n; i++) {\n      children_[i].Set(children[i]);\n    }\n  }\n\n  virtual ~MergingIterator() {\n    delete[] children_;\n  }\n\n  virtual bool Valid() const {\n    return (current_ != NULL);\n  }\n\n  virtual void SeekToFirst() {\n    for (int i = 0; i < n_; i++) {\n      children_[i].SeekToFirst();\n    }\n    FindSmallest();\n    direction_ = kForward;\n  }\n\n  virtual void SeekToLast() {\n    for (int i = 0; i < n_; i++) {\n      children_[i].SeekToLast();\n    }\n    FindLargest();\n    direction_ = kReverse;\n  }\n\n  virtual void Seek(const Slice& target) {\n    for (int i = 0; i < n_; i++) {\n      children_[i].Seek(target);\n    }\n    FindSmallest();\n    direction_ = kForward;\n  }\n\n  virtual void Next() {\n    assert(Valid());\n\n    // Ensure that all children are positioned after key().\n    // If we are moving in the forward direction, it is already\n    // true for all of the non-current_ children since current_ is\n    // the smallest child and key() == current_->key().  Otherwise,\n    // we explicitly position the non-current_ children.\n    if (direction_ != kForward) {\n      for (int i = 0; i < n_; i++) {\n        IteratorWrapper* child = &children_[i];\n        if (child != current_) {\n          child->Seek(key());\n          if (child->Valid() &&\n              comparator_->Compare(key(), child->key()) == 0) {\n            child->Next();\n          }\n        }\n      }\n      direction_ = kForward;\n    }\n\n    current_->Next();\n    FindSmallest();\n  }\n\n  virtual void Prev() {\n    assert(Valid());\n\n    // Ensure that all children are positioned before key().\n    // If we are moving in the reverse direction, it is already\n    // true for all of the non-current_ children since current_ is\n    // the largest child and key() == current_->key().  Otherwise,\n    // we explicitly position the non-current_ children.\n    if (direction_ != kReverse) {\n      for (int i = 0; i < n_; i++) {\n        IteratorWrapper* child = &children_[i];\n        if (child != current_) {\n          child->Seek(key());\n          if (child->Valid()) {\n            // Child is at first entry >= key().  Step back one to be < key()\n            child->Prev();\n          } else {\n            // Child has no entries >= key().  Position at last entry.\n            child->SeekToLast();\n          }\n        }\n      }\n      direction_ = kReverse;\n    }\n\n    current_->Prev();\n    FindLargest();\n  }\n\n  virtual Slice key() const {\n    assert(Valid());\n    return current_->key();\n  }\n\n  virtual Slice value() const {\n    assert(Valid());\n    return current_->value();\n  }\n\n  virtual Status status() const {\n    Status status;\n    for (int i = 0; i < n_; i++) {\n      status = children_[i].status();\n      if (!status.ok()) {\n        break;\n      }\n    }\n    return status;\n  }\n\n private:\n  void FindSmallest();\n  void FindLargest();\n\n  // We might want to use a heap in case there are lots of children.\n  // For now we use a simple array since we expect a very small number\n  // of children in leveldb.\n  const Comparator* comparator_;\n  IteratorWrapper* children_;\n  int n_;\n  IteratorWrapper* current_;\n\n  // Which direction is the iterator moving?\n  enum Direction {\n    kForward,\n    kReverse\n  };\n  Direction direction_;\n};\n\nvoid MergingIterator::FindSmallest() {\n  IteratorWrapper* smallest = NULL;\n  for (int i = 0; i < n_; i++) {\n    IteratorWrapper* child = &children_[i];\n    if (child->Valid()) {\n      if (smallest == NULL) {\n        smallest = child;\n      } else if (comparator_->Compare(child->key(), smallest->key()) < 0) {\n        smallest = child;\n      }\n    }\n  }\n  current_ = smallest;\n}\n\nvoid MergingIterator::FindLargest() {\n  IteratorWrapper* largest = NULL;\n  for (int i = n_-1; i >= 0; i--) {\n    IteratorWrapper* child = &children_[i];\n    if (child->Valid()) {\n      if (largest == NULL) {\n        largest = child;\n      } else if (comparator_->Compare(child->key(), largest->key()) > 0) {\n        largest = child;\n      }\n    }\n  }\n  current_ = largest;\n}\n}  // namespace\n\nIterator* NewMergingIterator(const Comparator* cmp, Iterator** list, int n) {\n  assert(n >= 0);\n  if (n == 0) {\n    return NewEmptyIterator();\n  } else if (n == 1) {\n    return list[0];\n  } else {\n    return new MergingIterator(cmp, list, n);\n  }\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/table/merger.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_TABLE_MERGER_H_\n#define STORAGE_LEVELDB_TABLE_MERGER_H_\n\nnamespace leveldb {\n\nclass Comparator;\nclass Iterator;\n\n// Return an iterator that provided the union of the data in\n// children[0,n-1].  Takes ownership of the child iterators and\n// will delete them when the result iterator is deleted.\n//\n// The result does no duplicate suppression.  I.e., if a particular\n// key is present in K child iterators, it will be yielded K times.\n//\n// REQUIRES: n >= 0\nextern Iterator* NewMergingIterator(\n    const Comparator* comparator, Iterator** children, int n);\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_TABLE_MERGER_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/table/table.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/table.h\"\n\n#include \"leveldb/cache.h\"\n#include \"leveldb/comparator.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/filter_policy.h\"\n#include \"leveldb/options.h\"\n#include \"table/block.h\"\n#include \"table/filter_block.h\"\n#include \"table/format.h\"\n#include \"table/two_level_iterator.h\"\n#include \"util/coding.h\"\n\nnamespace leveldb {\n\nstruct Table::Rep {\n  ~Rep() {\n    delete filter;\n    delete [] filter_data;\n    delete index_block;\n  }\n\n  Options options;\n  Status status;\n  RandomAccessFile* file;\n  uint64_t cache_id;\n  FilterBlockReader* filter;\n  const char* filter_data;\n\n  BlockHandle metaindex_handle;  // Handle to metaindex_block: saved from footer\n  Block* index_block;\n};\n\nStatus Table::Open(const Options& options,\n                   RandomAccessFile* file,\n                   uint64_t size,\n                   Table** table) {\n  *table = NULL;\n  if (size < Footer::kEncodedLength) {\n    return Status::Corruption(\"file is too short to be an sstable\");\n  }\n\n  char footer_space[Footer::kEncodedLength];\n  Slice footer_input;\n  Status s = file->Read(size - Footer::kEncodedLength, Footer::kEncodedLength,\n                        &footer_input, footer_space);\n  if (!s.ok()) return s;\n\n  Footer footer;\n  s = footer.DecodeFrom(&footer_input);\n  if (!s.ok()) return s;\n\n  // Read the index block\n  BlockContents index_block_contents;\n  if (s.ok()) {\n    ReadOptions opt;\n    if (options.paranoid_checks) {\n      opt.verify_checksums = true;\n    }\n    s = ReadBlock(file, opt, footer.index_handle(), &index_block_contents);\n  }\n\n  if (s.ok()) {\n    // We've successfully read the footer and the index block: we're\n    // ready to serve requests.\n    Block* index_block = new Block(index_block_contents);\n    Rep* rep = new Table::Rep;\n    rep->options = options;\n    rep->file = file;\n    rep->metaindex_handle = footer.metaindex_handle();\n    rep->index_block = index_block;\n    rep->cache_id = (options.block_cache ? options.block_cache->NewId() : 0);\n    rep->filter_data = NULL;\n    rep->filter = NULL;\n    *table = new Table(rep);\n    (*table)->ReadMeta(footer);\n  }\n\n  return s;\n}\n\nvoid Table::ReadMeta(const Footer& footer) {\n  if (rep_->options.filter_policy == NULL) {\n    return;  // Do not need any metadata\n  }\n\n  // TODO(sanjay): Skip this if footer.metaindex_handle() size indicates\n  // it is an empty block.\n  ReadOptions opt;\n  if (rep_->options.paranoid_checks) {\n    opt.verify_checksums = true;\n  }\n  BlockContents contents;\n  if (!ReadBlock(rep_->file, opt, footer.metaindex_handle(), &contents).ok()) {\n    // Do not propagate errors since meta info is not needed for operation\n    return;\n  }\n  Block* meta = new Block(contents);\n\n  Iterator* iter = meta->NewIterator(BytewiseComparator());\n  std::string key = \"filter.\";\n  key.append(rep_->options.filter_policy->Name());\n  iter->Seek(key);\n  if (iter->Valid() && iter->key() == Slice(key)) {\n    ReadFilter(iter->value());\n  }\n  delete iter;\n  delete meta;\n}\n\nvoid Table::ReadFilter(const Slice& filter_handle_value) {\n  Slice v = filter_handle_value;\n  BlockHandle filter_handle;\n  if (!filter_handle.DecodeFrom(&v).ok()) {\n    return;\n  }\n\n  // We might want to unify with ReadBlock() if we start\n  // requiring checksum verification in Table::Open.\n  ReadOptions opt;\n  if (rep_->options.paranoid_checks) {\n    opt.verify_checksums = true;\n  }\n  BlockContents block;\n  if (!ReadBlock(rep_->file, opt, filter_handle, &block).ok()) {\n    return;\n  }\n  if (block.heap_allocated) {\n    rep_->filter_data = block.data.data();     // Will need to delete later\n  }\n  rep_->filter = new FilterBlockReader(rep_->options.filter_policy, block.data);\n}\n\nTable::~Table() {\n  delete rep_;\n}\n\nstatic void DeleteBlock(void* arg, void* ignored) {\n  delete reinterpret_cast<Block*>(arg);\n}\n\nstatic void DeleteCachedBlock(const Slice& key, void* value) {\n  Block* block = reinterpret_cast<Block*>(value);\n  delete block;\n}\n\nstatic void ReleaseBlock(void* arg, void* h) {\n  Cache* cache = reinterpret_cast<Cache*>(arg);\n  Cache::Handle* handle = reinterpret_cast<Cache::Handle*>(h);\n  cache->Release(handle);\n}\n\n// Convert an index iterator value (i.e., an encoded BlockHandle)\n// into an iterator over the contents of the corresponding block.\nIterator* Table::BlockReader(void* arg,\n                             const ReadOptions& options,\n                             const Slice& index_value) {\n  Table* table = reinterpret_cast<Table*>(arg);\n  Cache* block_cache = table->rep_->options.block_cache;\n  Block* block = NULL;\n  Cache::Handle* cache_handle = NULL;\n\n  BlockHandle handle;\n  Slice input = index_value;\n  Status s = handle.DecodeFrom(&input);\n  // We intentionally allow extra stuff in index_value so that we\n  // can add more features in the future.\n\n  if (s.ok()) {\n    BlockContents contents;\n    if (block_cache != NULL) {\n      char cache_key_buffer[16];\n      EncodeFixed64(cache_key_buffer, table->rep_->cache_id);\n      EncodeFixed64(cache_key_buffer+8, handle.offset());\n      Slice key(cache_key_buffer, sizeof(cache_key_buffer));\n      cache_handle = block_cache->Lookup(key);\n      if (cache_handle != NULL) {\n        block = reinterpret_cast<Block*>(block_cache->Value(cache_handle));\n      } else {\n        s = ReadBlock(table->rep_->file, options, handle, &contents);\n        if (s.ok()) {\n          block = new Block(contents);\n          if (contents.cachable && options.fill_cache) {\n            cache_handle = block_cache->Insert(\n                key, block, block->size(), &DeleteCachedBlock);\n          }\n        }\n      }\n    } else {\n      s = ReadBlock(table->rep_->file, options, handle, &contents);\n      if (s.ok()) {\n        block = new Block(contents);\n      }\n    }\n  }\n\n  Iterator* iter;\n  if (block != NULL) {\n    iter = block->NewIterator(table->rep_->options.comparator);\n    if (cache_handle == NULL) {\n      iter->RegisterCleanup(&DeleteBlock, block, NULL);\n    } else {\n      iter->RegisterCleanup(&ReleaseBlock, block_cache, cache_handle);\n    }\n  } else {\n    iter = NewErrorIterator(s);\n  }\n  return iter;\n}\n\nIterator* Table::NewIterator(const ReadOptions& options) const {\n  return NewTwoLevelIterator(\n      rep_->index_block->NewIterator(rep_->options.comparator),\n      &Table::BlockReader, const_cast<Table*>(this), options);\n}\n\nStatus Table::InternalGet(const ReadOptions& options, const Slice& k,\n                          void* arg,\n                          void (*saver)(void*, const Slice&, const Slice&)) {\n  Status s;\n  Iterator* iiter = rep_->index_block->NewIterator(rep_->options.comparator);\n  iiter->Seek(k);\n  if (iiter->Valid()) {\n    Slice handle_value = iiter->value();\n    FilterBlockReader* filter = rep_->filter;\n    BlockHandle handle;\n    if (filter != NULL &&\n        handle.DecodeFrom(&handle_value).ok() &&\n        !filter->KeyMayMatch(handle.offset(), k)) {\n      // Not found\n    } else {\n      Iterator* block_iter = BlockReader(this, options, iiter->value());\n      block_iter->Seek(k);\n      if (block_iter->Valid()) {\n        (*saver)(arg, block_iter->key(), block_iter->value());\n      }\n      s = block_iter->status();\n      delete block_iter;\n    }\n  }\n  if (s.ok()) {\n    s = iiter->status();\n  }\n  delete iiter;\n  return s;\n}\n\n\nuint64_t Table::ApproximateOffsetOf(const Slice& key) const {\n  Iterator* index_iter =\n      rep_->index_block->NewIterator(rep_->options.comparator);\n  index_iter->Seek(key);\n  uint64_t result;\n  if (index_iter->Valid()) {\n    BlockHandle handle;\n    Slice input = index_iter->value();\n    Status s = handle.DecodeFrom(&input);\n    if (s.ok()) {\n      result = handle.offset();\n    } else {\n      // Strange: we can't decode the block handle in the index block.\n      // We'll just return the offset of the metaindex block, which is\n      // close to the whole file size for this case.\n      result = rep_->metaindex_handle.offset();\n    }\n  } else {\n    // key is past the last key in the file.  Approximate the offset\n    // by returning the offset of the metaindex block (which is\n    // right near the end of the file).\n    result = rep_->metaindex_handle.offset();\n  }\n  delete index_iter;\n  return result;\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/table/table_builder.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/table_builder.h\"\n\n#include <assert.h>\n#include \"leveldb/comparator.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/filter_policy.h\"\n#include \"leveldb/options.h\"\n#include \"table/block_builder.h\"\n#include \"table/filter_block.h\"\n#include \"table/format.h\"\n#include \"util/coding.h\"\n#include \"util/crc32c.h\"\n\nnamespace leveldb {\n\nstruct TableBuilder::Rep {\n  Options options;\n  Options index_block_options;\n  WritableFile* file;\n  uint64_t offset;\n  Status status;\n  BlockBuilder data_block;\n  BlockBuilder index_block;\n  std::string last_key;\n  int64_t num_entries;\n  bool closed;          // Either Finish() or Abandon() has been called.\n  FilterBlockBuilder* filter_block;\n\n  // We do not emit the index entry for a block until we have seen the\n  // first key for the next data block.  This allows us to use shorter\n  // keys in the index block.  For example, consider a block boundary\n  // between the keys \"the quick brown fox\" and \"the who\".  We can use\n  // \"the r\" as the key for the index block entry since it is >= all\n  // entries in the first block and < all entries in subsequent\n  // blocks.\n  //\n  // Invariant: r->pending_index_entry is true only if data_block is empty.\n  bool pending_index_entry;\n  BlockHandle pending_handle;  // Handle to add to index block\n\n  std::string compressed_output;\n\n  Rep(const Options& opt, WritableFile* f)\n      : options(opt),\n        index_block_options(opt),\n        file(f),\n        offset(0),\n        data_block(&options),\n        index_block(&index_block_options),\n        num_entries(0),\n        closed(false),\n        filter_block(opt.filter_policy == NULL ? NULL\n                     : new FilterBlockBuilder(opt.filter_policy)),\n        pending_index_entry(false) {\n    index_block_options.block_restart_interval = 1;\n  }\n};\n\nTableBuilder::TableBuilder(const Options& options, WritableFile* file)\n    : rep_(new Rep(options, file)) {\n  if (rep_->filter_block != NULL) {\n    rep_->filter_block->StartBlock(0);\n  }\n}\n\nTableBuilder::~TableBuilder() {\n  assert(rep_->closed);  // Catch errors where caller forgot to call Finish()\n  delete rep_->filter_block;\n  delete rep_;\n}\n\nStatus TableBuilder::ChangeOptions(const Options& options) {\n  // Note: if more fields are added to Options, update\n  // this function to catch changes that should not be allowed to\n  // change in the middle of building a Table.\n  if (options.comparator != rep_->options.comparator) {\n    return Status::InvalidArgument(\"changing comparator while building table\");\n  }\n\n  // Note that any live BlockBuilders point to rep_->options and therefore\n  // will automatically pick up the updated options.\n  rep_->options = options;\n  rep_->index_block_options = options;\n  rep_->index_block_options.block_restart_interval = 1;\n  return Status::OK();\n}\n\nvoid TableBuilder::Add(const Slice& key, const Slice& value) {\n  Rep* r = rep_;\n  assert(!r->closed);\n  if (!ok()) return;\n  if (r->num_entries > 0) {\n    assert(r->options.comparator->Compare(key, Slice(r->last_key)) > 0);\n  }\n\n  if (r->pending_index_entry) {\n    assert(r->data_block.empty());\n    r->options.comparator->FindShortestSeparator(&r->last_key, key);\n    std::string handle_encoding;\n    r->pending_handle.EncodeTo(&handle_encoding);\n    r->index_block.Add(r->last_key, Slice(handle_encoding));\n    r->pending_index_entry = false;\n  }\n\n  if (r->filter_block != NULL) {\n    r->filter_block->AddKey(key);\n  }\n\n  r->last_key.assign(key.data(), key.size());\n  r->num_entries++;\n  r->data_block.Add(key, value);\n\n  const size_t estimated_block_size = r->data_block.CurrentSizeEstimate();\n  if (estimated_block_size >= r->options.block_size) {\n    Flush();\n  }\n}\n\nvoid TableBuilder::Flush() {\n  Rep* r = rep_;\n  assert(!r->closed);\n  if (!ok()) return;\n  if (r->data_block.empty()) return;\n  assert(!r->pending_index_entry);\n  WriteBlock(&r->data_block, &r->pending_handle);\n  if (ok()) {\n    r->pending_index_entry = true;\n    r->status = r->file->Flush();\n  }\n  if (r->filter_block != NULL) {\n    r->filter_block->StartBlock(r->offset);\n  }\n}\n\nvoid TableBuilder::WriteBlock(BlockBuilder* block, BlockHandle* handle) {\n  // File format contains a sequence of blocks where each block has:\n  //    block_data: uint8[n]\n  //    type: uint8\n  //    crc: uint32\n  assert(ok());\n  Rep* r = rep_;\n  Slice raw = block->Finish();\n\n  Slice block_contents;\n  CompressionType type = r->options.compression;\n  // TODO(postrelease): Support more compression options: zlib?\n  switch (type) {\n    case kNoCompression:\n      block_contents = raw;\n      break;\n\n    case kSnappyCompression: {\n      std::string* compressed = &r->compressed_output;\n      if (port::Snappy_Compress(raw.data(), raw.size(), compressed) &&\n          compressed->size() < raw.size() - (raw.size() / 8u)) {\n        block_contents = *compressed;\n      } else {\n        // Snappy not supported, or compressed less than 12.5%, so just\n        // store uncompressed form\n        block_contents = raw;\n        type = kNoCompression;\n      }\n      break;\n    }\n  }\n  WriteRawBlock(block_contents, type, handle);\n  r->compressed_output.clear();\n  block->Reset();\n}\n\nvoid TableBuilder::WriteRawBlock(const Slice& block_contents,\n                                 CompressionType type,\n                                 BlockHandle* handle) {\n  Rep* r = rep_;\n  handle->set_offset(r->offset);\n  handle->set_size(block_contents.size());\n  r->status = r->file->Append(block_contents);\n  if (r->status.ok()) {\n    char trailer[kBlockTrailerSize];\n    trailer[0] = type;\n    uint32_t crc = crc32c::Value(block_contents.data(), block_contents.size());\n    crc = crc32c::Extend(crc, trailer, 1);  // Extend crc to cover block type\n    EncodeFixed32(trailer+1, crc32c::Mask(crc));\n    r->status = r->file->Append(Slice(trailer, kBlockTrailerSize));\n    if (r->status.ok()) {\n      r->offset += block_contents.size() + kBlockTrailerSize;\n    }\n  }\n}\n\nStatus TableBuilder::status() const {\n  return rep_->status;\n}\n\nStatus TableBuilder::Finish() {\n  Rep* r = rep_;\n  Flush();\n  assert(!r->closed);\n  r->closed = true;\n\n  BlockHandle filter_block_handle, metaindex_block_handle, index_block_handle;\n\n  // Write filter block\n  if (ok() && r->filter_block != NULL) {\n    WriteRawBlock(r->filter_block->Finish(), kNoCompression,\n                  &filter_block_handle);\n  }\n\n  // Write metaindex block\n  if (ok()) {\n    BlockBuilder meta_index_block(&r->options);\n    if (r->filter_block != NULL) {\n      // Add mapping from \"filter.Name\" to location of filter data\n      std::string key = \"filter.\";\n      key.append(r->options.filter_policy->Name());\n      std::string handle_encoding;\n      filter_block_handle.EncodeTo(&handle_encoding);\n      meta_index_block.Add(key, handle_encoding);\n    }\n\n    // TODO(postrelease): Add stats and other meta blocks\n    WriteBlock(&meta_index_block, &metaindex_block_handle);\n  }\n\n  // Write index block\n  if (ok()) {\n    if (r->pending_index_entry) {\n      r->options.comparator->FindShortSuccessor(&r->last_key);\n      std::string handle_encoding;\n      r->pending_handle.EncodeTo(&handle_encoding);\n      r->index_block.Add(r->last_key, Slice(handle_encoding));\n      r->pending_index_entry = false;\n    }\n    WriteBlock(&r->index_block, &index_block_handle);\n  }\n\n  // Write footer\n  if (ok()) {\n    Footer footer;\n    footer.set_metaindex_handle(metaindex_block_handle);\n    footer.set_index_handle(index_block_handle);\n    std::string footer_encoding;\n    footer.EncodeTo(&footer_encoding);\n    r->status = r->file->Append(footer_encoding);\n    if (r->status.ok()) {\n      r->offset += footer_encoding.size();\n    }\n  }\n  return r->status;\n}\n\nvoid TableBuilder::Abandon() {\n  Rep* r = rep_;\n  assert(!r->closed);\n  r->closed = true;\n}\n\nuint64_t TableBuilder::NumEntries() const {\n  return rep_->num_entries;\n}\n\nuint64_t TableBuilder::FileSize() const {\n  return rep_->offset;\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/table/table_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/table.h\"\n\n#include <map>\n#include <string>\n#include \"db/dbformat.h\"\n#include \"db/memtable.h\"\n#include \"db/write_batch_internal.h\"\n#include \"leveldb/db.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/iterator.h\"\n#include \"leveldb/table_builder.h\"\n#include \"table/block.h\"\n#include \"table/block_builder.h\"\n#include \"table/format.h\"\n#include \"util/random.h\"\n#include \"util/testharness.h\"\n#include \"util/testutil.h\"\n\nnamespace leveldb {\n\n// Return reverse of \"key\".\n// Used to test non-lexicographic comparators.\nstatic std::string Reverse(const Slice& key) {\n  std::string str(key.ToString());\n  std::string rev(\"\");\n  for (std::string::reverse_iterator rit = str.rbegin();\n       rit != str.rend(); ++rit) {\n    rev.push_back(*rit);\n  }\n  return rev;\n}\n\nnamespace {\nclass ReverseKeyComparator : public Comparator {\n public:\n  virtual const char* Name() const {\n    return \"leveldb.ReverseBytewiseComparator\";\n  }\n\n  virtual int Compare(const Slice& a, const Slice& b) const {\n    return BytewiseComparator()->Compare(Reverse(a), Reverse(b));\n  }\n\n  virtual void FindShortestSeparator(\n      std::string* start,\n      const Slice& limit) const {\n    std::string s = Reverse(*start);\n    std::string l = Reverse(limit);\n    BytewiseComparator()->FindShortestSeparator(&s, l);\n    *start = Reverse(s);\n  }\n\n  virtual void FindShortSuccessor(std::string* key) const {\n    std::string s = Reverse(*key);\n    BytewiseComparator()->FindShortSuccessor(&s);\n    *key = Reverse(s);\n  }\n};\n}  // namespace\nstatic ReverseKeyComparator reverse_key_comparator;\n\nstatic void Increment(const Comparator* cmp, std::string* key) {\n  if (cmp == BytewiseComparator()) {\n    key->push_back('\\0');\n  } else {\n    assert(cmp == &reverse_key_comparator);\n    std::string rev = Reverse(*key);\n    rev.push_back('\\0');\n    *key = Reverse(rev);\n  }\n}\n\n// An STL comparator that uses a Comparator\nnamespace {\nstruct STLLessThan {\n  const Comparator* cmp;\n\n  STLLessThan() : cmp(BytewiseComparator()) { }\n  STLLessThan(const Comparator* c) : cmp(c) { }\n  bool operator()(const std::string& a, const std::string& b) const {\n    return cmp->Compare(Slice(a), Slice(b)) < 0;\n  }\n};\n}  // namespace\n\nclass StringSink: public WritableFile {\n public:\n  ~StringSink() { }\n\n  const std::string& contents() const { return contents_; }\n\n  virtual Status Close() { return Status::OK(); }\n  virtual Status Flush() { return Status::OK(); }\n  virtual Status Sync() { return Status::OK(); }\n\n  virtual Status Append(const Slice& data) {\n    contents_.append(data.data(), data.size());\n    return Status::OK();\n  }\n\n private:\n  std::string contents_;\n};\n\n\nclass StringSource: public RandomAccessFile {\n public:\n  StringSource(const Slice& contents)\n      : contents_(contents.data(), contents.size()) {\n  }\n\n  virtual ~StringSource() { }\n\n  uint64_t Size() const { return contents_.size(); }\n\n  virtual Status Read(uint64_t offset, size_t n, Slice* result,\n                       char* scratch) const {\n    if (offset > contents_.size()) {\n      return Status::InvalidArgument(\"invalid Read offset\");\n    }\n    if (offset + n > contents_.size()) {\n      n = contents_.size() - offset;\n    }\n    memcpy(scratch, &contents_[offset], n);\n    *result = Slice(scratch, n);\n    return Status::OK();\n  }\n\n private:\n  std::string contents_;\n};\n\ntypedef std::map<std::string, std::string, STLLessThan> KVMap;\n\n// Helper class for tests to unify the interface between\n// BlockBuilder/TableBuilder and Block/Table.\nclass Constructor {\n public:\n  explicit Constructor(const Comparator* cmp) : data_(STLLessThan(cmp)) { }\n  virtual ~Constructor() { }\n\n  void Add(const std::string& key, const Slice& value) {\n    data_[key] = value.ToString();\n  }\n\n  // Finish constructing the data structure with all the keys that have\n  // been added so far.  Returns the keys in sorted order in \"*keys\"\n  // and stores the key/value pairs in \"*kvmap\"\n  void Finish(const Options& options,\n              std::vector<std::string>* keys,\n              KVMap* kvmap) {\n    *kvmap = data_;\n    keys->clear();\n    for (KVMap::const_iterator it = data_.begin();\n         it != data_.end();\n         ++it) {\n      keys->push_back(it->first);\n    }\n    data_.clear();\n    Status s = FinishImpl(options, *kvmap);\n    ASSERT_TRUE(s.ok()) << s.ToString();\n  }\n\n  // Construct the data structure from the data in \"data\"\n  virtual Status FinishImpl(const Options& options, const KVMap& data) = 0;\n\n  virtual Iterator* NewIterator() const = 0;\n\n  virtual const KVMap& data() { return data_; }\n\n  virtual DB* db() const { return NULL; }  // Overridden in DBConstructor\n\n private:\n  KVMap data_;\n};\n\nclass BlockConstructor: public Constructor {\n public:\n  explicit BlockConstructor(const Comparator* cmp)\n      : Constructor(cmp),\n        comparator_(cmp),\n        block_(NULL) { }\n  ~BlockConstructor() {\n    delete block_;\n  }\n  virtual Status FinishImpl(const Options& options, const KVMap& data) {\n    delete block_;\n    block_ = NULL;\n    BlockBuilder builder(&options);\n\n    for (KVMap::const_iterator it = data.begin();\n         it != data.end();\n         ++it) {\n      builder.Add(it->first, it->second);\n    }\n    // Open the block\n    data_ = builder.Finish().ToString();\n    BlockContents contents;\n    contents.data = data_;\n    contents.cachable = false;\n    contents.heap_allocated = false;\n    block_ = new Block(contents);\n    return Status::OK();\n  }\n  virtual Iterator* NewIterator() const {\n    return block_->NewIterator(comparator_);\n  }\n\n private:\n  const Comparator* comparator_;\n  std::string data_;\n  Block* block_;\n\n  BlockConstructor();\n};\n\nclass TableConstructor: public Constructor {\n public:\n  TableConstructor(const Comparator* cmp)\n      : Constructor(cmp),\n        source_(NULL), table_(NULL) {\n  }\n  ~TableConstructor() {\n    Reset();\n  }\n  virtual Status FinishImpl(const Options& options, const KVMap& data) {\n    Reset();\n    StringSink sink;\n    TableBuilder builder(options, &sink);\n\n    for (KVMap::const_iterator it = data.begin();\n         it != data.end();\n         ++it) {\n      builder.Add(it->first, it->second);\n      ASSERT_TRUE(builder.status().ok());\n    }\n    Status s = builder.Finish();\n    ASSERT_TRUE(s.ok()) << s.ToString();\n\n    ASSERT_EQ(sink.contents().size(), builder.FileSize());\n\n    // Open the table\n    source_ = new StringSource(sink.contents());\n    Options table_options;\n    table_options.comparator = options.comparator;\n    return Table::Open(table_options, source_, sink.contents().size(), &table_);\n  }\n\n  virtual Iterator* NewIterator() const {\n    return table_->NewIterator(ReadOptions());\n  }\n\n  uint64_t ApproximateOffsetOf(const Slice& key) const {\n    return table_->ApproximateOffsetOf(key);\n  }\n\n private:\n  void Reset() {\n    delete table_;\n    delete source_;\n    table_ = NULL;\n    source_ = NULL;\n  }\n\n  StringSource* source_;\n  Table* table_;\n\n  TableConstructor();\n};\n\n// A helper class that converts internal format keys into user keys\nclass KeyConvertingIterator: public Iterator {\n public:\n  explicit KeyConvertingIterator(Iterator* iter) : iter_(iter) { }\n  virtual ~KeyConvertingIterator() { delete iter_; }\n  virtual bool Valid() const { return iter_->Valid(); }\n  virtual void Seek(const Slice& target) {\n    ParsedInternalKey ikey(target, kMaxSequenceNumber, kTypeValue);\n    std::string encoded;\n    AppendInternalKey(&encoded, ikey);\n    iter_->Seek(encoded);\n  }\n  virtual void SeekToFirst() { iter_->SeekToFirst(); }\n  virtual void SeekToLast() { iter_->SeekToLast(); }\n  virtual void Next() { iter_->Next(); }\n  virtual void Prev() { iter_->Prev(); }\n\n  virtual Slice key() const {\n    assert(Valid());\n    ParsedInternalKey key;\n    if (!ParseInternalKey(iter_->key(), &key)) {\n      status_ = Status::Corruption(\"malformed internal key\");\n      return Slice(\"corrupted key\");\n    }\n    return key.user_key;\n  }\n\n  virtual Slice value() const { return iter_->value(); }\n  virtual Status status() const {\n    return status_.ok() ? iter_->status() : status_;\n  }\n\n private:\n  mutable Status status_;\n  Iterator* iter_;\n\n  // No copying allowed\n  KeyConvertingIterator(const KeyConvertingIterator&);\n  void operator=(const KeyConvertingIterator&);\n};\n\nclass MemTableConstructor: public Constructor {\n public:\n  explicit MemTableConstructor(const Comparator* cmp)\n      : Constructor(cmp),\n        internal_comparator_(cmp) {\n    memtable_ = new MemTable(internal_comparator_);\n    memtable_->Ref();\n  }\n  ~MemTableConstructor() {\n    memtable_->Unref();\n  }\n  virtual Status FinishImpl(const Options& options, const KVMap& data) {\n    memtable_->Unref();\n    memtable_ = new MemTable(internal_comparator_);\n    memtable_->Ref();\n    int seq = 1;\n    for (KVMap::const_iterator it = data.begin();\n         it != data.end();\n         ++it) {\n      memtable_->Add(seq, kTypeValue, it->first, it->second);\n      seq++;\n    }\n    return Status::OK();\n  }\n  virtual Iterator* NewIterator() const {\n    return new KeyConvertingIterator(memtable_->NewIterator());\n  }\n\n private:\n  InternalKeyComparator internal_comparator_;\n  MemTable* memtable_;\n};\n\nclass DBConstructor: public Constructor {\n public:\n  explicit DBConstructor(const Comparator* cmp)\n      : Constructor(cmp),\n        comparator_(cmp) {\n    db_ = NULL;\n    NewDB();\n  }\n  ~DBConstructor() {\n    delete db_;\n  }\n  virtual Status FinishImpl(const Options& options, const KVMap& data) {\n    delete db_;\n    db_ = NULL;\n    NewDB();\n    for (KVMap::const_iterator it = data.begin();\n         it != data.end();\n         ++it) {\n      WriteBatch batch;\n      batch.Put(it->first, it->second);\n      ASSERT_TRUE(db_->Write(WriteOptions(), &batch).ok());\n    }\n    return Status::OK();\n  }\n  virtual Iterator* NewIterator() const {\n    return db_->NewIterator(ReadOptions());\n  }\n\n  virtual DB* db() const { return db_; }\n\n private:\n  void NewDB() {\n    std::string name = test::TmpDir() + \"/table_testdb\";\n\n    Options options;\n    options.comparator = comparator_;\n    Status status = DestroyDB(name, options);\n    ASSERT_TRUE(status.ok()) << status.ToString();\n\n    options.create_if_missing = true;\n    options.error_if_exists = true;\n    options.write_buffer_size = 10000;  // Something small to force merging\n    status = DB::Open(options, name, &db_);\n    ASSERT_TRUE(status.ok()) << status.ToString();\n  }\n\n  const Comparator* comparator_;\n  DB* db_;\n};\n\nenum TestType {\n  TABLE_TEST,\n  BLOCK_TEST,\n  MEMTABLE_TEST,\n  DB_TEST\n};\n\nstruct TestArgs {\n  TestType type;\n  bool reverse_compare;\n  int restart_interval;\n};\n\nstatic const TestArgs kTestArgList[] = {\n  { TABLE_TEST, false, 16 },\n  { TABLE_TEST, false, 1 },\n  { TABLE_TEST, false, 1024 },\n  { TABLE_TEST, true, 16 },\n  { TABLE_TEST, true, 1 },\n  { TABLE_TEST, true, 1024 },\n\n  { BLOCK_TEST, false, 16 },\n  { BLOCK_TEST, false, 1 },\n  { BLOCK_TEST, false, 1024 },\n  { BLOCK_TEST, true, 16 },\n  { BLOCK_TEST, true, 1 },\n  { BLOCK_TEST, true, 1024 },\n\n  // Restart interval does not matter for memtables\n  { MEMTABLE_TEST, false, 16 },\n  { MEMTABLE_TEST, true, 16 },\n\n  // Do not bother with restart interval variations for DB\n  { DB_TEST, false, 16 },\n  { DB_TEST, true, 16 },\n};\nstatic const int kNumTestArgs = sizeof(kTestArgList) / sizeof(kTestArgList[0]);\n\nclass Harness {\n public:\n  Harness() : constructor_(NULL) { }\n\n  void Init(const TestArgs& args) {\n    delete constructor_;\n    constructor_ = NULL;\n    options_ = Options();\n\n    options_.block_restart_interval = args.restart_interval;\n    // Use shorter block size for tests to exercise block boundary\n    // conditions more.\n    options_.block_size = 256;\n    if (args.reverse_compare) {\n      options_.comparator = &reverse_key_comparator;\n    }\n    switch (args.type) {\n      case TABLE_TEST:\n        constructor_ = new TableConstructor(options_.comparator);\n        break;\n      case BLOCK_TEST:\n        constructor_ = new BlockConstructor(options_.comparator);\n        break;\n      case MEMTABLE_TEST:\n        constructor_ = new MemTableConstructor(options_.comparator);\n        break;\n      case DB_TEST:\n        constructor_ = new DBConstructor(options_.comparator);\n        break;\n    }\n  }\n\n  ~Harness() {\n    delete constructor_;\n  }\n\n  void Add(const std::string& key, const std::string& value) {\n    constructor_->Add(key, value);\n  }\n\n  void Test(Random* rnd) {\n    std::vector<std::string> keys;\n    KVMap data;\n    constructor_->Finish(options_, &keys, &data);\n\n    TestForwardScan(keys, data);\n    TestBackwardScan(keys, data);\n    TestRandomAccess(rnd, keys, data);\n  }\n\n  void TestForwardScan(const std::vector<std::string>& keys,\n                       const KVMap& data) {\n    Iterator* iter = constructor_->NewIterator();\n    ASSERT_TRUE(!iter->Valid());\n    iter->SeekToFirst();\n    for (KVMap::const_iterator model_iter = data.begin();\n         model_iter != data.end();\n         ++model_iter) {\n      ASSERT_EQ(ToString(data, model_iter), ToString(iter));\n      iter->Next();\n    }\n    ASSERT_TRUE(!iter->Valid());\n    delete iter;\n  }\n\n  void TestBackwardScan(const std::vector<std::string>& keys,\n                        const KVMap& data) {\n    Iterator* iter = constructor_->NewIterator();\n    ASSERT_TRUE(!iter->Valid());\n    iter->SeekToLast();\n    for (KVMap::const_reverse_iterator model_iter = data.rbegin();\n         model_iter != data.rend();\n         ++model_iter) {\n      ASSERT_EQ(ToString(data, model_iter), ToString(iter));\n      iter->Prev();\n    }\n    ASSERT_TRUE(!iter->Valid());\n    delete iter;\n  }\n\n  void TestRandomAccess(Random* rnd,\n                        const std::vector<std::string>& keys,\n                        const KVMap& data) {\n    static const bool kVerbose = false;\n    Iterator* iter = constructor_->NewIterator();\n    ASSERT_TRUE(!iter->Valid());\n    KVMap::const_iterator model_iter = data.begin();\n    if (kVerbose) fprintf(stderr, \"---\\n\");\n    for (int i = 0; i < 200; i++) {\n      const int toss = rnd->Uniform(5);\n      switch (toss) {\n        case 0: {\n          if (iter->Valid()) {\n            if (kVerbose) fprintf(stderr, \"Next\\n\");\n            iter->Next();\n            ++model_iter;\n            ASSERT_EQ(ToString(data, model_iter), ToString(iter));\n          }\n          break;\n        }\n\n        case 1: {\n          if (kVerbose) fprintf(stderr, \"SeekToFirst\\n\");\n          iter->SeekToFirst();\n          model_iter = data.begin();\n          ASSERT_EQ(ToString(data, model_iter), ToString(iter));\n          break;\n        }\n\n        case 2: {\n          std::string key = PickRandomKey(rnd, keys);\n          model_iter = data.lower_bound(key);\n          if (kVerbose) fprintf(stderr, \"Seek '%s'\\n\",\n                                EscapeString(key).c_str());\n          iter->Seek(Slice(key));\n          ASSERT_EQ(ToString(data, model_iter), ToString(iter));\n          break;\n        }\n\n        case 3: {\n          if (iter->Valid()) {\n            if (kVerbose) fprintf(stderr, \"Prev\\n\");\n            iter->Prev();\n            if (model_iter == data.begin()) {\n              model_iter = data.end();   // Wrap around to invalid value\n            } else {\n              --model_iter;\n            }\n            ASSERT_EQ(ToString(data, model_iter), ToString(iter));\n          }\n          break;\n        }\n\n        case 4: {\n          if (kVerbose) fprintf(stderr, \"SeekToLast\\n\");\n          iter->SeekToLast();\n          if (keys.empty()) {\n            model_iter = data.end();\n          } else {\n            std::string last = data.rbegin()->first;\n            model_iter = data.lower_bound(last);\n          }\n          ASSERT_EQ(ToString(data, model_iter), ToString(iter));\n          break;\n        }\n      }\n    }\n    delete iter;\n  }\n\n  std::string ToString(const KVMap& data, const KVMap::const_iterator& it) {\n    if (it == data.end()) {\n      return \"END\";\n    } else {\n      return \"'\" + it->first + \"->\" + it->second + \"'\";\n    }\n  }\n\n  std::string ToString(const KVMap& data,\n                       const KVMap::const_reverse_iterator& it) {\n    if (it == data.rend()) {\n      return \"END\";\n    } else {\n      return \"'\" + it->first + \"->\" + it->second + \"'\";\n    }\n  }\n\n  std::string ToString(const Iterator* it) {\n    if (!it->Valid()) {\n      return \"END\";\n    } else {\n      return \"'\" + it->key().ToString() + \"->\" + it->value().ToString() + \"'\";\n    }\n  }\n\n  std::string PickRandomKey(Random* rnd, const std::vector<std::string>& keys) {\n    if (keys.empty()) {\n      return \"foo\";\n    } else {\n      const int index = rnd->Uniform(keys.size());\n      std::string result = keys[index];\n      switch (rnd->Uniform(3)) {\n        case 0:\n          // Return an existing key\n          break;\n        case 1: {\n          // Attempt to return something smaller than an existing key\n          if (result.size() > 0 && result[result.size()-1] > '\\0') {\n            result[result.size()-1]--;\n          }\n          break;\n        }\n        case 2: {\n          // Return something larger than an existing key\n          Increment(options_.comparator, &result);\n          break;\n        }\n      }\n      return result;\n    }\n  }\n\n  // Returns NULL if not running against a DB\n  DB* db() const { return constructor_->db(); }\n\n private:\n  Options options_;\n  Constructor* constructor_;\n};\n\n// Test empty table/block.\nTEST(Harness, Empty) {\n  for (int i = 0; i < kNumTestArgs; i++) {\n    Init(kTestArgList[i]);\n    Random rnd(test::RandomSeed() + 1);\n    Test(&rnd);\n  }\n}\n\n// Special test for a block with no restart entries.  The C++ leveldb\n// code never generates such blocks, but the Java version of leveldb\n// seems to.\nTEST(Harness, ZeroRestartPointsInBlock) {\n  char data[sizeof(uint32_t)];\n  memset(data, 0, sizeof(data));\n  BlockContents contents;\n  contents.data = Slice(data, sizeof(data));\n  contents.cachable = false;\n  contents.heap_allocated = false;\n  Block block(contents);\n  Iterator* iter = block.NewIterator(BytewiseComparator());\n  iter->SeekToFirst();\n  ASSERT_TRUE(!iter->Valid());\n  iter->SeekToLast();\n  ASSERT_TRUE(!iter->Valid());\n  iter->Seek(\"foo\");\n  ASSERT_TRUE(!iter->Valid());\n  delete iter;\n}\n\n// Test the empty key\nTEST(Harness, SimpleEmptyKey) {\n  for (int i = 0; i < kNumTestArgs; i++) {\n    Init(kTestArgList[i]);\n    Random rnd(test::RandomSeed() + 1);\n    Add(\"\", \"v\");\n    Test(&rnd);\n  }\n}\n\nTEST(Harness, SimpleSingle) {\n  for (int i = 0; i < kNumTestArgs; i++) {\n    Init(kTestArgList[i]);\n    Random rnd(test::RandomSeed() + 2);\n    Add(\"abc\", \"v\");\n    Test(&rnd);\n  }\n}\n\nTEST(Harness, SimpleMulti) {\n  for (int i = 0; i < kNumTestArgs; i++) {\n    Init(kTestArgList[i]);\n    Random rnd(test::RandomSeed() + 3);\n    Add(\"abc\", \"v\");\n    Add(\"abcd\", \"v\");\n    Add(\"ac\", \"v2\");\n    Test(&rnd);\n  }\n}\n\nTEST(Harness, SimpleSpecialKey) {\n  for (int i = 0; i < kNumTestArgs; i++) {\n    Init(kTestArgList[i]);\n    Random rnd(test::RandomSeed() + 4);\n    Add(\"\\xff\\xff\", \"v3\");\n    Test(&rnd);\n  }\n}\n\nTEST(Harness, Randomized) {\n  for (int i = 0; i < kNumTestArgs; i++) {\n    Init(kTestArgList[i]);\n    Random rnd(test::RandomSeed() + 5);\n    for (int num_entries = 0; num_entries < 2000;\n         num_entries += (num_entries < 50 ? 1 : 200)) {\n      if ((num_entries % 10) == 0) {\n        fprintf(stderr, \"case %d of %d: num_entries = %d\\n\",\n                (i + 1), int(kNumTestArgs), num_entries);\n      }\n      for (int e = 0; e < num_entries; e++) {\n        std::string v;\n        Add(test::RandomKey(&rnd, rnd.Skewed(4)),\n            test::RandomString(&rnd, rnd.Skewed(5), &v).ToString());\n      }\n      Test(&rnd);\n    }\n  }\n}\n\nTEST(Harness, RandomizedLongDB) {\n  Random rnd(test::RandomSeed());\n  TestArgs args = { DB_TEST, false, 16 };\n  Init(args);\n  int num_entries = 100000;\n  for (int e = 0; e < num_entries; e++) {\n    std::string v;\n    Add(test::RandomKey(&rnd, rnd.Skewed(4)),\n        test::RandomString(&rnd, rnd.Skewed(5), &v).ToString());\n  }\n  Test(&rnd);\n\n  // We must have created enough data to force merging\n  int files = 0;\n  for (int level = 0; level < config::kNumLevels; level++) {\n    std::string value;\n    char name[100];\n    snprintf(name, sizeof(name), \"leveldb.num-files-at-level%d\", level);\n    ASSERT_TRUE(db()->GetProperty(name, &value));\n    files += atoi(value.c_str());\n  }\n  ASSERT_GT(files, 0);\n}\n\nclass MemTableTest { };\n\nTEST(MemTableTest, Simple) {\n  InternalKeyComparator cmp(BytewiseComparator());\n  MemTable* memtable = new MemTable(cmp);\n  memtable->Ref();\n  WriteBatch batch;\n  WriteBatchInternal::SetSequence(&batch, 100);\n  batch.Put(std::string(\"k1\"), std::string(\"v1\"));\n  batch.Put(std::string(\"k2\"), std::string(\"v2\"));\n  batch.Put(std::string(\"k3\"), std::string(\"v3\"));\n  batch.Put(std::string(\"largekey\"), std::string(\"vlarge\"));\n  ASSERT_TRUE(WriteBatchInternal::InsertInto(&batch, memtable).ok());\n\n  Iterator* iter = memtable->NewIterator();\n  iter->SeekToFirst();\n  while (iter->Valid()) {\n    fprintf(stderr, \"key: '%s' -> '%s'\\n\",\n            iter->key().ToString().c_str(),\n            iter->value().ToString().c_str());\n    iter->Next();\n  }\n\n  delete iter;\n  memtable->Unref();\n}\n\nstatic bool Between(uint64_t val, uint64_t low, uint64_t high) {\n  bool result = (val >= low) && (val <= high);\n  if (!result) {\n    fprintf(stderr, \"Value %llu is not in range [%llu, %llu]\\n\",\n            (unsigned long long)(val),\n            (unsigned long long)(low),\n            (unsigned long long)(high));\n  }\n  return result;\n}\n\nclass TableTest { };\n\nTEST(TableTest, ApproximateOffsetOfPlain) {\n  TableConstructor c(BytewiseComparator());\n  c.Add(\"k01\", \"hello\");\n  c.Add(\"k02\", \"hello2\");\n  c.Add(\"k03\", std::string(10000, 'x'));\n  c.Add(\"k04\", std::string(200000, 'x'));\n  c.Add(\"k05\", std::string(300000, 'x'));\n  c.Add(\"k06\", \"hello3\");\n  c.Add(\"k07\", std::string(100000, 'x'));\n  std::vector<std::string> keys;\n  KVMap kvmap;\n  Options options;\n  options.block_size = 1024;\n  options.compression = kNoCompression;\n  c.Finish(options, &keys, &kvmap);\n\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"abc\"),       0,      0));\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"k01\"),       0,      0));\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"k01a\"),      0,      0));\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"k02\"),       0,      0));\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"k03\"),       0,      0));\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"k04\"),   10000,  11000));\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"k04a\"), 210000, 211000));\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"k05\"),  210000, 211000));\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"k06\"),  510000, 511000));\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"k07\"),  510000, 511000));\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"xyz\"),  610000, 612000));\n\n}\n\nstatic bool SnappyCompressionSupported() {\n  std::string out;\n  Slice in = \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\";\n  return port::Snappy_Compress(in.data(), in.size(), &out);\n}\n\nTEST(TableTest, ApproximateOffsetOfCompressed) {\n  if (!SnappyCompressionSupported()) {\n    fprintf(stderr, \"skipping compression tests\\n\");\n    return;\n  }\n\n  Random rnd(301);\n  TableConstructor c(BytewiseComparator());\n  std::string tmp;\n  c.Add(\"k01\", \"hello\");\n  c.Add(\"k02\", test::CompressibleString(&rnd, 0.25, 10000, &tmp));\n  c.Add(\"k03\", \"hello3\");\n  c.Add(\"k04\", test::CompressibleString(&rnd, 0.25, 10000, &tmp));\n  std::vector<std::string> keys;\n  KVMap kvmap;\n  Options options;\n  options.block_size = 1024;\n  options.compression = kSnappyCompression;\n  c.Finish(options, &keys, &kvmap);\n\n  // Expected upper and lower bounds of space used by compressible strings.\n  static const int kSlop = 1000;  // Compressor effectiveness varies.\n  const int expected = 2500;  // 10000 * compression ratio (0.25)\n  const int min_z = expected - kSlop;\n  const int max_z = expected + kSlop;\n\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"abc\"), 0, kSlop));\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"k01\"), 0, kSlop));\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"k02\"), 0, kSlop));\n  // Have now emitted a large compressible string, so adjust expected offset.\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"k03\"), min_z, max_z));\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"k04\"), min_z, max_z));\n  // Have now emitted two large compressible strings, so adjust expected offset.\n  ASSERT_TRUE(Between(c.ApproximateOffsetOf(\"xyz\"), 2 * min_z, 2 * max_z));\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/table/two_level_iterator.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"table/two_level_iterator.h\"\n\n#include \"leveldb/table.h\"\n#include \"table/block.h\"\n#include \"table/format.h\"\n#include \"table/iterator_wrapper.h\"\n\nnamespace leveldb {\n\nnamespace {\n\ntypedef Iterator* (*BlockFunction)(void*, const ReadOptions&, const Slice&);\n\nclass TwoLevelIterator: public Iterator {\n public:\n  TwoLevelIterator(\n    Iterator* index_iter,\n    BlockFunction block_function,\n    void* arg,\n    const ReadOptions& options);\n\n  virtual ~TwoLevelIterator();\n\n  virtual void Seek(const Slice& target);\n  virtual void SeekToFirst();\n  virtual void SeekToLast();\n  virtual void Next();\n  virtual void Prev();\n\n  virtual bool Valid() const {\n    return data_iter_.Valid();\n  }\n  virtual Slice key() const {\n    assert(Valid());\n    return data_iter_.key();\n  }\n  virtual Slice value() const {\n    assert(Valid());\n    return data_iter_.value();\n  }\n  virtual Status status() const {\n    // It'd be nice if status() returned a const Status& instead of a Status\n    if (!index_iter_.status().ok()) {\n      return index_iter_.status();\n    } else if (data_iter_.iter() != NULL && !data_iter_.status().ok()) {\n      return data_iter_.status();\n    } else {\n      return status_;\n    }\n  }\n\n private:\n  void SaveError(const Status& s) {\n    if (status_.ok() && !s.ok()) status_ = s;\n  }\n  void SkipEmptyDataBlocksForward();\n  void SkipEmptyDataBlocksBackward();\n  void SetDataIterator(Iterator* data_iter);\n  void InitDataBlock();\n\n  BlockFunction block_function_;\n  void* arg_;\n  const ReadOptions options_;\n  Status status_;\n  IteratorWrapper index_iter_;\n  IteratorWrapper data_iter_; // May be NULL\n  // If data_iter_ is non-NULL, then \"data_block_handle_\" holds the\n  // \"index_value\" passed to block_function_ to create the data_iter_.\n  std::string data_block_handle_;\n};\n\nTwoLevelIterator::TwoLevelIterator(\n    Iterator* index_iter,\n    BlockFunction block_function,\n    void* arg,\n    const ReadOptions& options)\n    : block_function_(block_function),\n      arg_(arg),\n      options_(options),\n      index_iter_(index_iter),\n      data_iter_(NULL) {\n}\n\nTwoLevelIterator::~TwoLevelIterator() {\n}\n\nvoid TwoLevelIterator::Seek(const Slice& target) {\n  index_iter_.Seek(target);\n  InitDataBlock();\n  if (data_iter_.iter() != NULL) data_iter_.Seek(target);\n  SkipEmptyDataBlocksForward();\n}\n\nvoid TwoLevelIterator::SeekToFirst() {\n  index_iter_.SeekToFirst();\n  InitDataBlock();\n  if (data_iter_.iter() != NULL) data_iter_.SeekToFirst();\n  SkipEmptyDataBlocksForward();\n}\n\nvoid TwoLevelIterator::SeekToLast() {\n  index_iter_.SeekToLast();\n  InitDataBlock();\n  if (data_iter_.iter() != NULL) data_iter_.SeekToLast();\n  SkipEmptyDataBlocksBackward();\n}\n\nvoid TwoLevelIterator::Next() {\n  assert(Valid());\n  data_iter_.Next();\n  SkipEmptyDataBlocksForward();\n}\n\nvoid TwoLevelIterator::Prev() {\n  assert(Valid());\n  data_iter_.Prev();\n  SkipEmptyDataBlocksBackward();\n}\n\n\nvoid TwoLevelIterator::SkipEmptyDataBlocksForward() {\n  while (data_iter_.iter() == NULL || !data_iter_.Valid()) {\n    // Move to next block\n    if (!index_iter_.Valid()) {\n      SetDataIterator(NULL);\n      return;\n    }\n    index_iter_.Next();\n    InitDataBlock();\n    if (data_iter_.iter() != NULL) data_iter_.SeekToFirst();\n  }\n}\n\nvoid TwoLevelIterator::SkipEmptyDataBlocksBackward() {\n  while (data_iter_.iter() == NULL || !data_iter_.Valid()) {\n    // Move to next block\n    if (!index_iter_.Valid()) {\n      SetDataIterator(NULL);\n      return;\n    }\n    index_iter_.Prev();\n    InitDataBlock();\n    if (data_iter_.iter() != NULL) data_iter_.SeekToLast();\n  }\n}\n\nvoid TwoLevelIterator::SetDataIterator(Iterator* data_iter) {\n  if (data_iter_.iter() != NULL) SaveError(data_iter_.status());\n  data_iter_.Set(data_iter);\n}\n\nvoid TwoLevelIterator::InitDataBlock() {\n  if (!index_iter_.Valid()) {\n    SetDataIterator(NULL);\n  } else {\n    Slice handle = index_iter_.value();\n    if (data_iter_.iter() != NULL && handle.compare(data_block_handle_) == 0) {\n      // data_iter_ is already constructed with this iterator, so\n      // no need to change anything\n    } else {\n      Iterator* iter = (*block_function_)(arg_, options_, handle);\n      data_block_handle_.assign(handle.data(), handle.size());\n      SetDataIterator(iter);\n    }\n  }\n}\n\n}  // namespace\n\nIterator* NewTwoLevelIterator(\n    Iterator* index_iter,\n    BlockFunction block_function,\n    void* arg,\n    const ReadOptions& options) {\n  return new TwoLevelIterator(index_iter, block_function, arg, options);\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/table/two_level_iterator.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_TABLE_TWO_LEVEL_ITERATOR_H_\n#define STORAGE_LEVELDB_TABLE_TWO_LEVEL_ITERATOR_H_\n\n#include \"leveldb/iterator.h\"\n\nnamespace leveldb {\n\nstruct ReadOptions;\n\n// Return a new two level iterator.  A two-level iterator contains an\n// index iterator whose values point to a sequence of blocks where\n// each block is itself a sequence of key,value pairs.  The returned\n// two-level iterator yields the concatenation of all key/value pairs\n// in the sequence of blocks.  Takes ownership of \"index_iter\" and\n// will delete it when no longer needed.\n//\n// Uses a supplied function to convert an index_iter value into\n// an iterator over the contents of the corresponding block.\nextern Iterator* NewTwoLevelIterator(\n    Iterator* index_iter,\n    Iterator* (*block_function)(\n        void* arg,\n        const ReadOptions& options,\n        const Slice& index_value),\n    void* arg,\n    const ReadOptions& options);\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_TABLE_TWO_LEVEL_ITERATOR_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/util/arena.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"util/arena.h\"\n#include <assert.h>\n\nnamespace leveldb {\n\nstatic const int kBlockSize = 4096;\n\nArena::Arena() : memory_usage_(0) {\n  alloc_ptr_ = NULL;  // First allocation will allocate a block\n  alloc_bytes_remaining_ = 0;\n}\n\nArena::~Arena() {\n  for (size_t i = 0; i < blocks_.size(); i++) {\n    delete[] blocks_[i];\n  }\n}\n\nchar* Arena::AllocateFallback(size_t bytes) {\n  if (bytes > kBlockSize / 4) {\n    // Object is more than a quarter of our block size.  Allocate it separately\n    // to avoid wasting too much space in leftover bytes.\n    char* result = AllocateNewBlock(bytes);\n    return result;\n  }\n\n  // We waste the remaining space in the current block.\n  alloc_ptr_ = AllocateNewBlock(kBlockSize);\n  alloc_bytes_remaining_ = kBlockSize;\n\n  char* result = alloc_ptr_;\n  alloc_ptr_ += bytes;\n  alloc_bytes_remaining_ -= bytes;\n  return result;\n}\n\nchar* Arena::AllocateAligned(size_t bytes) {\n  const int align = (sizeof(void*) > 8) ? sizeof(void*) : 8;\n  assert((align & (align-1)) == 0);   // Pointer size should be a power of 2\n  size_t current_mod = reinterpret_cast<uintptr_t>(alloc_ptr_) & (align-1);\n  size_t slop = (current_mod == 0 ? 0 : align - current_mod);\n  size_t needed = bytes + slop;\n  char* result;\n  if (needed <= alloc_bytes_remaining_) {\n    result = alloc_ptr_ + slop;\n    alloc_ptr_ += needed;\n    alloc_bytes_remaining_ -= needed;\n  } else {\n    // AllocateFallback always returned aligned memory\n    result = AllocateFallback(bytes);\n  }\n  assert((reinterpret_cast<uintptr_t>(result) & (align-1)) == 0);\n  return result;\n}\n\nchar* Arena::AllocateNewBlock(size_t block_bytes) {\n  char* result = new char[block_bytes];\n  blocks_.push_back(result);\n  memory_usage_.NoBarrier_Store(\n      reinterpret_cast<void*>(MemoryUsage() + block_bytes + sizeof(char*)));\n  return result;\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/util/arena.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_UTIL_ARENA_H_\n#define STORAGE_LEVELDB_UTIL_ARENA_H_\n\n#include <vector>\n#include <assert.h>\n#include <stddef.h>\n#include <stdint.h>\n#include \"port/port.h\"\n\nnamespace leveldb {\n\nclass Arena {\n public:\n  Arena();\n  ~Arena();\n\n  // Return a pointer to a newly allocated memory block of \"bytes\" bytes.\n  char* Allocate(size_t bytes);\n\n  // Allocate memory with the normal alignment guarantees provided by malloc\n  char* AllocateAligned(size_t bytes);\n\n  // Returns an estimate of the total memory usage of data allocated\n  // by the arena.\n  size_t MemoryUsage() const {\n    return reinterpret_cast<uintptr_t>(memory_usage_.NoBarrier_Load());\n  }\n\n private:\n  char* AllocateFallback(size_t bytes);\n  char* AllocateNewBlock(size_t block_bytes);\n\n  // Allocation state\n  char* alloc_ptr_;\n  size_t alloc_bytes_remaining_;\n\n  // Array of new[] allocated memory blocks\n  std::vector<char*> blocks_;\n\n  // Total memory usage of the arena.\n  port::AtomicPointer memory_usage_;\n\n  // No copying allowed\n  Arena(const Arena&);\n  void operator=(const Arena&);\n};\n\ninline char* Arena::Allocate(size_t bytes) {\n  // The semantics of what to return are a bit messy if we allow\n  // 0-byte allocations, so we disallow them here (we don't need\n  // them for our internal use).\n  assert(bytes > 0);\n  if (bytes <= alloc_bytes_remaining_) {\n    char* result = alloc_ptr_;\n    alloc_ptr_ += bytes;\n    alloc_bytes_remaining_ -= bytes;\n    return result;\n  }\n  return AllocateFallback(bytes);\n}\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_UTIL_ARENA_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/util/arena_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"util/arena.h\"\n\n#include \"util/random.h\"\n#include \"util/testharness.h\"\n\nnamespace leveldb {\n\nclass ArenaTest { };\n\nTEST(ArenaTest, Empty) {\n  Arena arena;\n}\n\nTEST(ArenaTest, Simple) {\n  std::vector<std::pair<size_t, char*> > allocated;\n  Arena arena;\n  const int N = 100000;\n  size_t bytes = 0;\n  Random rnd(301);\n  for (int i = 0; i < N; i++) {\n    size_t s;\n    if (i % (N / 10) == 0) {\n      s = i;\n    } else {\n      s = rnd.OneIn(4000) ? rnd.Uniform(6000) :\n          (rnd.OneIn(10) ? rnd.Uniform(100) : rnd.Uniform(20));\n    }\n    if (s == 0) {\n      // Our arena disallows size 0 allocations.\n      s = 1;\n    }\n    char* r;\n    if (rnd.OneIn(10)) {\n      r = arena.AllocateAligned(s);\n    } else {\n      r = arena.Allocate(s);\n    }\n\n    for (size_t b = 0; b < s; b++) {\n      // Fill the \"i\"th allocation with a known bit pattern\n      r[b] = i % 256;\n    }\n    bytes += s;\n    allocated.push_back(std::make_pair(s, r));\n    ASSERT_GE(arena.MemoryUsage(), bytes);\n    if (i > N/10) {\n      ASSERT_LE(arena.MemoryUsage(), bytes * 1.10);\n    }\n  }\n  for (size_t i = 0; i < allocated.size(); i++) {\n    size_t num_bytes = allocated[i].first;\n    const char* p = allocated[i].second;\n    for (size_t b = 0; b < num_bytes; b++) {\n      // Check the \"i\"th allocation for the known bit pattern\n      ASSERT_EQ(int(p[b]) & 0xff, i % 256);\n    }\n  }\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/util/bloom.cc",
    "content": "// Copyright (c) 2012 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/filter_policy.h\"\n\n#include \"leveldb/slice.h\"\n#include \"util/hash.h\"\n\nnamespace leveldb {\n\nnamespace {\nstatic uint32_t BloomHash(const Slice& key) {\n  return Hash(key.data(), key.size(), 0xbc9f1d34);\n}\n\nclass BloomFilterPolicy : public FilterPolicy {\n private:\n  size_t bits_per_key_;\n  size_t k_;\n\n public:\n  explicit BloomFilterPolicy(int bits_per_key)\n      : bits_per_key_(bits_per_key) {\n    // We intentionally round down to reduce probing cost a little bit\n    k_ = static_cast<size_t>(bits_per_key * 0.69);  // 0.69 =~ ln(2)\n    if (k_ < 1) k_ = 1;\n    if (k_ > 30) k_ = 30;\n  }\n\n  virtual const char* Name() const {\n    return \"leveldb.BuiltinBloomFilter2\";\n  }\n\n  virtual void CreateFilter(const Slice* keys, int n, std::string* dst) const {\n    // Compute bloom filter size (in both bits and bytes)\n    size_t bits = n * bits_per_key_;\n\n    // For small n, we can see a very high false positive rate.  Fix it\n    // by enforcing a minimum bloom filter length.\n    if (bits < 64) bits = 64;\n\n    size_t bytes = (bits + 7) / 8;\n    bits = bytes * 8;\n\n    const size_t init_size = dst->size();\n    dst->resize(init_size + bytes, 0);\n    dst->push_back(static_cast<char>(k_));  // Remember # of probes in filter\n    char* array = &(*dst)[init_size];\n    for (int i = 0; i < n; i++) {\n      // Use double-hashing to generate a sequence of hash values.\n      // See analysis in [Kirsch,Mitzenmacher 2006].\n      uint32_t h = BloomHash(keys[i]);\n      const uint32_t delta = (h >> 17) | (h << 15);  // Rotate right 17 bits\n      for (size_t j = 0; j < k_; j++) {\n        const uint32_t bitpos = h % bits;\n        array[bitpos/8] |= (1 << (bitpos % 8));\n        h += delta;\n      }\n    }\n  }\n\n  virtual bool KeyMayMatch(const Slice& key, const Slice& bloom_filter) const {\n    const size_t len = bloom_filter.size();\n    if (len < 2) return false;\n\n    const char* array = bloom_filter.data();\n    const size_t bits = (len - 1) * 8;\n\n    // Use the encoded k so that we can read filters generated by\n    // bloom filters created using different parameters.\n    const size_t k = array[len-1];\n    if (k > 30) {\n      // Reserved for potentially new encodings for short bloom filters.\n      // Consider it a match.\n      return true;\n    }\n\n    uint32_t h = BloomHash(key);\n    const uint32_t delta = (h >> 17) | (h << 15);  // Rotate right 17 bits\n    for (size_t j = 0; j < k; j++) {\n      const uint32_t bitpos = h % bits;\n      if ((array[bitpos/8] & (1 << (bitpos % 8))) == 0) return false;\n      h += delta;\n    }\n    return true;\n  }\n};\n}\n\nconst FilterPolicy* NewBloomFilterPolicy(int bits_per_key) {\n  return new BloomFilterPolicy(bits_per_key);\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/util/bloom_test.cc",
    "content": "// Copyright (c) 2012 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/filter_policy.h\"\n\n#include \"util/coding.h\"\n#include \"util/logging.h\"\n#include \"util/testharness.h\"\n#include \"util/testutil.h\"\n\nnamespace leveldb {\n\nstatic const int kVerbose = 1;\n\nstatic Slice Key(int i, char* buffer) {\n  EncodeFixed32(buffer, i);\n  return Slice(buffer, sizeof(uint32_t));\n}\n\nclass BloomTest {\n private:\n  const FilterPolicy* policy_;\n  std::string filter_;\n  std::vector<std::string> keys_;\n\n public:\n  BloomTest() : policy_(NewBloomFilterPolicy(10)) { }\n\n  ~BloomTest() {\n    delete policy_;\n  }\n\n  void Reset() {\n    keys_.clear();\n    filter_.clear();\n  }\n\n  void Add(const Slice& s) {\n    keys_.push_back(s.ToString());\n  }\n\n  void Build() {\n    std::vector<Slice> key_slices;\n    for (size_t i = 0; i < keys_.size(); i++) {\n      key_slices.push_back(Slice(keys_[i]));\n    }\n    filter_.clear();\n    policy_->CreateFilter(&key_slices[0], static_cast<int>(key_slices.size()),\n                          &filter_);\n    keys_.clear();\n    if (kVerbose >= 2) DumpFilter();\n  }\n\n  size_t FilterSize() const {\n    return filter_.size();\n  }\n\n  void DumpFilter() {\n    fprintf(stderr, \"F(\");\n    for (size_t i = 0; i+1 < filter_.size(); i++) {\n      const unsigned int c = static_cast<unsigned int>(filter_[i]);\n      for (int j = 0; j < 8; j++) {\n        fprintf(stderr, \"%c\", (c & (1 <<j)) ? '1' : '.');\n      }\n    }\n    fprintf(stderr, \")\\n\");\n  }\n\n  bool Matches(const Slice& s) {\n    if (!keys_.empty()) {\n      Build();\n    }\n    return policy_->KeyMayMatch(s, filter_);\n  }\n\n  double FalsePositiveRate() {\n    char buffer[sizeof(int)];\n    int result = 0;\n    for (int i = 0; i < 10000; i++) {\n      if (Matches(Key(i + 1000000000, buffer))) {\n        result++;\n      }\n    }\n    return result / 10000.0;\n  }\n};\n\nTEST(BloomTest, EmptyFilter) {\n  ASSERT_TRUE(! Matches(\"hello\"));\n  ASSERT_TRUE(! Matches(\"world\"));\n}\n\nTEST(BloomTest, Small) {\n  Add(\"hello\");\n  Add(\"world\");\n  ASSERT_TRUE(Matches(\"hello\"));\n  ASSERT_TRUE(Matches(\"world\"));\n  ASSERT_TRUE(! Matches(\"x\"));\n  ASSERT_TRUE(! Matches(\"foo\"));\n}\n\nstatic int NextLength(int length) {\n  if (length < 10) {\n    length += 1;\n  } else if (length < 100) {\n    length += 10;\n  } else if (length < 1000) {\n    length += 100;\n  } else {\n    length += 1000;\n  }\n  return length;\n}\n\nTEST(BloomTest, VaryingLengths) {\n  char buffer[sizeof(int)];\n\n  // Count number of filters that significantly exceed the false positive rate\n  int mediocre_filters = 0;\n  int good_filters = 0;\n\n  for (int length = 1; length <= 10000; length = NextLength(length)) {\n    Reset();\n    for (int i = 0; i < length; i++) {\n      Add(Key(i, buffer));\n    }\n    Build();\n\n    ASSERT_LE(FilterSize(), static_cast<size_t>((length * 10 / 8) + 40))\n        << length;\n\n    // All added keys must match\n    for (int i = 0; i < length; i++) {\n      ASSERT_TRUE(Matches(Key(i, buffer)))\n          << \"Length \" << length << \"; key \" << i;\n    }\n\n    // Check false positive rate\n    double rate = FalsePositiveRate();\n    if (kVerbose >= 1) {\n      fprintf(stderr, \"False positives: %5.2f%% @ length = %6d ; bytes = %6d\\n\",\n              rate*100.0, length, static_cast<int>(FilterSize()));\n    }\n    ASSERT_LE(rate, 0.02);   // Must not be over 2%\n    if (rate > 0.0125) mediocre_filters++;  // Allowed, but not too often\n    else good_filters++;\n  }\n  if (kVerbose >= 1) {\n    fprintf(stderr, \"Filters: %d good, %d mediocre\\n\",\n            good_filters, mediocre_filters);\n  }\n  ASSERT_LE(mediocre_filters, good_filters/5);\n}\n\n// Different bits-per-byte\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/util/cache.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include <assert.h>\n#include <stdio.h>\n#include <stdlib.h>\n\n#include \"leveldb/cache.h\"\n#include \"port/port.h\"\n#include \"util/hash.h\"\n#include \"util/mutexlock.h\"\n\nnamespace leveldb {\n\nCache::~Cache() {\n}\n\nnamespace {\n\n// LRU cache implementation\n//\n// Cache entries have an \"in_cache\" boolean indicating whether the cache has a\n// reference on the entry.  The only ways that this can become false without the\n// entry being passed to its \"deleter\" are via Erase(), via Insert() when\n// an element with a duplicate key is inserted, or on destruction of the cache.\n//\n// The cache keeps two linked lists of items in the cache.  All items in the\n// cache are in one list or the other, and never both.  Items still referenced\n// by clients but erased from the cache are in neither list.  The lists are:\n// - in-use:  contains the items currently referenced by clients, in no\n//   particular order.  (This list is used for invariant checking.  If we\n//   removed the check, elements that would otherwise be on this list could be\n//   left as disconnected singleton lists.)\n// - LRU:  contains the items not currently referenced by clients, in LRU order\n// Elements are moved between these lists by the Ref() and Unref() methods,\n// when they detect an element in the cache acquiring or losing its only\n// external reference.\n\n// An entry is a variable length heap-allocated structure.  Entries\n// are kept in a circular doubly linked list ordered by access time.\nstruct LRUHandle {\n  void* value;\n  void (*deleter)(const Slice&, void* value);\n  LRUHandle* next_hash;\n  LRUHandle* next;\n  LRUHandle* prev;\n  size_t charge;      // TODO(opt): Only allow uint32_t?\n  size_t key_length;\n  bool in_cache;      // Whether entry is in the cache.\n  uint32_t refs;      // References, including cache reference, if present.\n  uint32_t hash;      // Hash of key(); used for fast sharding and comparisons\n  char key_data[1];   // Beginning of key\n\n  Slice key() const {\n    // For cheaper lookups, we allow a temporary Handle object\n    // to store a pointer to a key in \"value\".\n    if (next == this) {\n      return *(reinterpret_cast<Slice*>(value));\n    } else {\n      return Slice(key_data, key_length);\n    }\n  }\n};\n\n// We provide our own simple hash table since it removes a whole bunch\n// of porting hacks and is also faster than some of the built-in hash\n// table implementations in some of the compiler/runtime combinations\n// we have tested.  E.g., readrandom speeds up by ~5% over the g++\n// 4.4.3's builtin hashtable.\nclass HandleTable {\n public:\n  HandleTable() : length_(0), elems_(0), list_(NULL) { Resize(); }\n  ~HandleTable() { delete[] list_; }\n\n  LRUHandle* Lookup(const Slice& key, uint32_t hash) {\n    return *FindPointer(key, hash);\n  }\n\n  LRUHandle* Insert(LRUHandle* h) {\n    LRUHandle** ptr = FindPointer(h->key(), h->hash);\n    LRUHandle* old = *ptr;\n    h->next_hash = (old == NULL ? NULL : old->next_hash);\n    *ptr = h;\n    if (old == NULL) {\n      ++elems_;\n      if (elems_ > length_) {\n        // Since each cache entry is fairly large, we aim for a small\n        // average linked list length (<= 1).\n        Resize();\n      }\n    }\n    return old;\n  }\n\n  LRUHandle* Remove(const Slice& key, uint32_t hash) {\n    LRUHandle** ptr = FindPointer(key, hash);\n    LRUHandle* result = *ptr;\n    if (result != NULL) {\n      *ptr = result->next_hash;\n      --elems_;\n    }\n    return result;\n  }\n\n private:\n  // The table consists of an array of buckets where each bucket is\n  // a linked list of cache entries that hash into the bucket.\n  uint32_t length_;\n  uint32_t elems_;\n  LRUHandle** list_;\n\n  // Return a pointer to slot that points to a cache entry that\n  // matches key/hash.  If there is no such cache entry, return a\n  // pointer to the trailing slot in the corresponding linked list.\n  LRUHandle** FindPointer(const Slice& key, uint32_t hash) {\n    LRUHandle** ptr = &list_[hash & (length_ - 1)];\n    while (*ptr != NULL &&\n           ((*ptr)->hash != hash || key != (*ptr)->key())) {\n      ptr = &(*ptr)->next_hash;\n    }\n    return ptr;\n  }\n\n  void Resize() {\n    uint32_t new_length = 4;\n    while (new_length < elems_) {\n      new_length *= 2;\n    }\n    LRUHandle** new_list = new LRUHandle*[new_length];\n    memset(new_list, 0, sizeof(new_list[0]) * new_length);\n    uint32_t count = 0;\n    for (uint32_t i = 0; i < length_; i++) {\n      LRUHandle* h = list_[i];\n      while (h != NULL) {\n        LRUHandle* next = h->next_hash;\n        uint32_t hash = h->hash;\n        LRUHandle** ptr = &new_list[hash & (new_length - 1)];\n        h->next_hash = *ptr;\n        *ptr = h;\n        h = next;\n        count++;\n      }\n    }\n    assert(elems_ == count);\n    delete[] list_;\n    list_ = new_list;\n    length_ = new_length;\n  }\n};\n\n// A single shard of sharded cache.\nclass LRUCache {\n public:\n  LRUCache();\n  ~LRUCache();\n\n  // Separate from constructor so caller can easily make an array of LRUCache\n  void SetCapacity(size_t capacity) { capacity_ = capacity; }\n\n  // Like Cache methods, but with an extra \"hash\" parameter.\n  Cache::Handle* Insert(const Slice& key, uint32_t hash,\n                        void* value, size_t charge,\n                        void (*deleter)(const Slice& key, void* value));\n  Cache::Handle* Lookup(const Slice& key, uint32_t hash);\n  void Release(Cache::Handle* handle);\n  void Erase(const Slice& key, uint32_t hash);\n  void Prune();\n  size_t TotalCharge() const {\n    MutexLock l(&mutex_);\n    return usage_;\n  }\n\n private:\n  void LRU_Remove(LRUHandle* e);\n  void LRU_Append(LRUHandle*list, LRUHandle* e);\n  void Ref(LRUHandle* e);\n  void Unref(LRUHandle* e);\n  bool FinishErase(LRUHandle* e);\n\n  // Initialized before use.\n  size_t capacity_;\n\n  // mutex_ protects the following state.\n  mutable port::Mutex mutex_;\n  size_t usage_;\n\n  // Dummy head of LRU list.\n  // lru.prev is newest entry, lru.next is oldest entry.\n  // Entries have refs==1 and in_cache==true.\n  LRUHandle lru_;\n\n  // Dummy head of in-use list.\n  // Entries are in use by clients, and have refs >= 2 and in_cache==true.\n  LRUHandle in_use_;\n\n  HandleTable table_;\n};\n\nLRUCache::LRUCache()\n    : usage_(0) {\n  // Make empty circular linked lists.\n  lru_.next = &lru_;\n  lru_.prev = &lru_;\n  in_use_.next = &in_use_;\n  in_use_.prev = &in_use_;\n}\n\nLRUCache::~LRUCache() {\n  assert(in_use_.next == &in_use_);  // Error if caller has an unreleased handle\n  for (LRUHandle* e = lru_.next; e != &lru_; ) {\n    LRUHandle* next = e->next;\n    assert(e->in_cache);\n    e->in_cache = false;\n    assert(e->refs == 1);  // Invariant of lru_ list.\n    Unref(e);\n    e = next;\n  }\n}\n\nvoid LRUCache::Ref(LRUHandle* e) {\n  if (e->refs == 1 && e->in_cache) {  // If on lru_ list, move to in_use_ list.\n    LRU_Remove(e);\n    LRU_Append(&in_use_, e);\n  }\n  e->refs++;\n}\n\nvoid LRUCache::Unref(LRUHandle* e) {\n  assert(e->refs > 0);\n  e->refs--;\n  if (e->refs == 0) { // Deallocate.\n    assert(!e->in_cache);\n    (*e->deleter)(e->key(), e->value);\n    free(e);\n  } else if (e->in_cache && e->refs == 1) {  // No longer in use; move to lru_ list.\n    LRU_Remove(e);\n    LRU_Append(&lru_, e);\n  }\n}\n\nvoid LRUCache::LRU_Remove(LRUHandle* e) {\n  e->next->prev = e->prev;\n  e->prev->next = e->next;\n}\n\nvoid LRUCache::LRU_Append(LRUHandle* list, LRUHandle* e) {\n  // Make \"e\" newest entry by inserting just before *list\n  e->next = list;\n  e->prev = list->prev;\n  e->prev->next = e;\n  e->next->prev = e;\n}\n\nCache::Handle* LRUCache::Lookup(const Slice& key, uint32_t hash) {\n  MutexLock l(&mutex_);\n  LRUHandle* e = table_.Lookup(key, hash);\n  if (e != NULL) {\n    Ref(e);\n  }\n  return reinterpret_cast<Cache::Handle*>(e);\n}\n\nvoid LRUCache::Release(Cache::Handle* handle) {\n  MutexLock l(&mutex_);\n  Unref(reinterpret_cast<LRUHandle*>(handle));\n}\n\nCache::Handle* LRUCache::Insert(\n    const Slice& key, uint32_t hash, void* value, size_t charge,\n    void (*deleter)(const Slice& key, void* value)) {\n  MutexLock l(&mutex_);\n\n  LRUHandle* e = reinterpret_cast<LRUHandle*>(\n      malloc(sizeof(LRUHandle)-1 + key.size()));\n  e->value = value;\n  e->deleter = deleter;\n  e->charge = charge;\n  e->key_length = key.size();\n  e->hash = hash;\n  e->in_cache = false;\n  e->refs = 1;  // for the returned handle.\n  memcpy(e->key_data, key.data(), key.size());\n\n  if (capacity_ > 0) {\n    e->refs++;  // for the cache's reference.\n    e->in_cache = true;\n    LRU_Append(&in_use_, e);\n    usage_ += charge;\n    FinishErase(table_.Insert(e));\n  } // else don't cache.  (Tests use capacity_==0 to turn off caching.)\n\n  while (usage_ > capacity_ && lru_.next != &lru_) {\n    LRUHandle* old = lru_.next;\n    assert(old->refs == 1);\n    bool erased = FinishErase(table_.Remove(old->key(), old->hash));\n    if (!erased) {  // to avoid unused variable when compiled NDEBUG\n      assert(erased);\n    }\n  }\n\n  return reinterpret_cast<Cache::Handle*>(e);\n}\n\n// If e != NULL, finish removing *e from the cache; it has already been removed\n// from the hash table.  Return whether e != NULL.  Requires mutex_ held.\nbool LRUCache::FinishErase(LRUHandle* e) {\n  if (e != NULL) {\n    assert(e->in_cache);\n    LRU_Remove(e);\n    e->in_cache = false;\n    usage_ -= e->charge;\n    Unref(e);\n  }\n  return e != NULL;\n}\n\nvoid LRUCache::Erase(const Slice& key, uint32_t hash) {\n  MutexLock l(&mutex_);\n  FinishErase(table_.Remove(key, hash));\n}\n\nvoid LRUCache::Prune() {\n  MutexLock l(&mutex_);\n  while (lru_.next != &lru_) {\n    LRUHandle* e = lru_.next;\n    assert(e->refs == 1);\n    bool erased = FinishErase(table_.Remove(e->key(), e->hash));\n    if (!erased) {  // to avoid unused variable when compiled NDEBUG\n      assert(erased);\n    }\n  }\n}\n\nstatic const int kNumShardBits = 4;\nstatic const int kNumShards = 1 << kNumShardBits;\n\nclass ShardedLRUCache : public Cache {\n private:\n  LRUCache shard_[kNumShards];\n  port::Mutex id_mutex_;\n  uint64_t last_id_;\n\n  static inline uint32_t HashSlice(const Slice& s) {\n    return Hash(s.data(), s.size(), 0);\n  }\n\n  static uint32_t Shard(uint32_t hash) {\n    return hash >> (32 - kNumShardBits);\n  }\n\n public:\n  explicit ShardedLRUCache(size_t capacity)\n      : last_id_(0) {\n    const size_t per_shard = (capacity + (kNumShards - 1)) / kNumShards;\n    for (int s = 0; s < kNumShards; s++) {\n      shard_[s].SetCapacity(per_shard);\n    }\n  }\n  virtual ~ShardedLRUCache() { }\n  virtual Handle* Insert(const Slice& key, void* value, size_t charge,\n                         void (*deleter)(const Slice& key, void* value)) {\n    const uint32_t hash = HashSlice(key);\n    return shard_[Shard(hash)].Insert(key, hash, value, charge, deleter);\n  }\n  virtual Handle* Lookup(const Slice& key) {\n    const uint32_t hash = HashSlice(key);\n    return shard_[Shard(hash)].Lookup(key, hash);\n  }\n  virtual void Release(Handle* handle) {\n    LRUHandle* h = reinterpret_cast<LRUHandle*>(handle);\n    shard_[Shard(h->hash)].Release(handle);\n  }\n  virtual void Erase(const Slice& key) {\n    const uint32_t hash = HashSlice(key);\n    shard_[Shard(hash)].Erase(key, hash);\n  }\n  virtual void* Value(Handle* handle) {\n    return reinterpret_cast<LRUHandle*>(handle)->value;\n  }\n  virtual uint64_t NewId() {\n    MutexLock l(&id_mutex_);\n    return ++(last_id_);\n  }\n  virtual void Prune() {\n    for (int s = 0; s < kNumShards; s++) {\n      shard_[s].Prune();\n    }\n  }\n  virtual size_t TotalCharge() const {\n    size_t total = 0;\n    for (int s = 0; s < kNumShards; s++) {\n      total += shard_[s].TotalCharge();\n    }\n    return total;\n  }\n};\n\n}  // end anonymous namespace\n\nCache* NewLRUCache(size_t capacity) {\n  return new ShardedLRUCache(capacity);\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/util/cache_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/cache.h\"\n\n#include <vector>\n#include \"util/coding.h\"\n#include \"util/testharness.h\"\n\nnamespace leveldb {\n\n// Conversions between numeric keys/values and the types expected by Cache.\nstatic std::string EncodeKey(int k) {\n  std::string result;\n  PutFixed32(&result, k);\n  return result;\n}\nstatic int DecodeKey(const Slice& k) {\n  assert(k.size() == 4);\n  return DecodeFixed32(k.data());\n}\nstatic void* EncodeValue(uintptr_t v) { return reinterpret_cast<void*>(v); }\nstatic int DecodeValue(void* v) { return reinterpret_cast<uintptr_t>(v); }\n\nclass CacheTest {\n public:\n  static CacheTest* current_;\n\n  static void Deleter(const Slice& key, void* v) {\n    current_->deleted_keys_.push_back(DecodeKey(key));\n    current_->deleted_values_.push_back(DecodeValue(v));\n  }\n\n  static const int kCacheSize = 1000;\n  std::vector<int> deleted_keys_;\n  std::vector<int> deleted_values_;\n  Cache* cache_;\n\n  CacheTest() : cache_(NewLRUCache(kCacheSize)) {\n    current_ = this;\n  }\n\n  ~CacheTest() {\n    delete cache_;\n  }\n\n  int Lookup(int key) {\n    Cache::Handle* handle = cache_->Lookup(EncodeKey(key));\n    const int r = (handle == NULL) ? -1 : DecodeValue(cache_->Value(handle));\n    if (handle != NULL) {\n      cache_->Release(handle);\n    }\n    return r;\n  }\n\n  void Insert(int key, int value, int charge = 1) {\n    cache_->Release(cache_->Insert(EncodeKey(key), EncodeValue(value), charge,\n                                   &CacheTest::Deleter));\n  }\n\n  Cache::Handle* InsertAndReturnHandle(int key, int value, int charge = 1) {\n    return cache_->Insert(EncodeKey(key), EncodeValue(value), charge,\n                          &CacheTest::Deleter);\n  }\n\n  void Erase(int key) {\n    cache_->Erase(EncodeKey(key));\n  }\n};\nCacheTest* CacheTest::current_;\n\nTEST(CacheTest, HitAndMiss) {\n  ASSERT_EQ(-1, Lookup(100));\n\n  Insert(100, 101);\n  ASSERT_EQ(101, Lookup(100));\n  ASSERT_EQ(-1,  Lookup(200));\n  ASSERT_EQ(-1,  Lookup(300));\n\n  Insert(200, 201);\n  ASSERT_EQ(101, Lookup(100));\n  ASSERT_EQ(201, Lookup(200));\n  ASSERT_EQ(-1,  Lookup(300));\n\n  Insert(100, 102);\n  ASSERT_EQ(102, Lookup(100));\n  ASSERT_EQ(201, Lookup(200));\n  ASSERT_EQ(-1,  Lookup(300));\n\n  ASSERT_EQ(1, deleted_keys_.size());\n  ASSERT_EQ(100, deleted_keys_[0]);\n  ASSERT_EQ(101, deleted_values_[0]);\n}\n\nTEST(CacheTest, Erase) {\n  Erase(200);\n  ASSERT_EQ(0, deleted_keys_.size());\n\n  Insert(100, 101);\n  Insert(200, 201);\n  Erase(100);\n  ASSERT_EQ(-1,  Lookup(100));\n  ASSERT_EQ(201, Lookup(200));\n  ASSERT_EQ(1, deleted_keys_.size());\n  ASSERT_EQ(100, deleted_keys_[0]);\n  ASSERT_EQ(101, deleted_values_[0]);\n\n  Erase(100);\n  ASSERT_EQ(-1,  Lookup(100));\n  ASSERT_EQ(201, Lookup(200));\n  ASSERT_EQ(1, deleted_keys_.size());\n}\n\nTEST(CacheTest, EntriesArePinned) {\n  Insert(100, 101);\n  Cache::Handle* h1 = cache_->Lookup(EncodeKey(100));\n  ASSERT_EQ(101, DecodeValue(cache_->Value(h1)));\n\n  Insert(100, 102);\n  Cache::Handle* h2 = cache_->Lookup(EncodeKey(100));\n  ASSERT_EQ(102, DecodeValue(cache_->Value(h2)));\n  ASSERT_EQ(0, deleted_keys_.size());\n\n  cache_->Release(h1);\n  ASSERT_EQ(1, deleted_keys_.size());\n  ASSERT_EQ(100, deleted_keys_[0]);\n  ASSERT_EQ(101, deleted_values_[0]);\n\n  Erase(100);\n  ASSERT_EQ(-1, Lookup(100));\n  ASSERT_EQ(1, deleted_keys_.size());\n\n  cache_->Release(h2);\n  ASSERT_EQ(2, deleted_keys_.size());\n  ASSERT_EQ(100, deleted_keys_[1]);\n  ASSERT_EQ(102, deleted_values_[1]);\n}\n\nTEST(CacheTest, EvictionPolicy) {\n  Insert(100, 101);\n  Insert(200, 201);\n  Insert(300, 301);\n  Cache::Handle* h = cache_->Lookup(EncodeKey(300));\n\n  // Frequently used entry must be kept around,\n  // as must things that are still in use.\n  for (int i = 0; i < kCacheSize + 100; i++) {\n    Insert(1000+i, 2000+i);\n    ASSERT_EQ(2000+i, Lookup(1000+i));\n    ASSERT_EQ(101, Lookup(100));\n  }\n  ASSERT_EQ(101, Lookup(100));\n  ASSERT_EQ(-1, Lookup(200));\n  ASSERT_EQ(301, Lookup(300));\n  cache_->Release(h);\n}\n\nTEST(CacheTest, UseExceedsCacheSize) {\n  // Overfill the cache, keeping handles on all inserted entries.\n  std::vector<Cache::Handle*> h;\n  for (int i = 0; i < kCacheSize + 100; i++) {\n    h.push_back(InsertAndReturnHandle(1000+i, 2000+i));\n  }\n\n  // Check that all the entries can be found in the cache.\n  for (int i = 0; i < h.size(); i++) {\n    ASSERT_EQ(2000+i, Lookup(1000+i));\n  }\n\n  for (int i = 0; i < h.size(); i++) {\n    cache_->Release(h[i]);\n  }\n}\n\nTEST(CacheTest, HeavyEntries) {\n  // Add a bunch of light and heavy entries and then count the combined\n  // size of items still in the cache, which must be approximately the\n  // same as the total capacity.\n  const int kLight = 1;\n  const int kHeavy = 10;\n  int added = 0;\n  int index = 0;\n  while (added < 2*kCacheSize) {\n    const int weight = (index & 1) ? kLight : kHeavy;\n    Insert(index, 1000+index, weight);\n    added += weight;\n    index++;\n  }\n\n  int cached_weight = 0;\n  for (int i = 0; i < index; i++) {\n    const int weight = (i & 1 ? kLight : kHeavy);\n    int r = Lookup(i);\n    if (r >= 0) {\n      cached_weight += weight;\n      ASSERT_EQ(1000+i, r);\n    }\n  }\n  ASSERT_LE(cached_weight, kCacheSize + kCacheSize/10);\n}\n\nTEST(CacheTest, NewId) {\n  uint64_t a = cache_->NewId();\n  uint64_t b = cache_->NewId();\n  ASSERT_NE(a, b);\n}\n\nTEST(CacheTest, Prune) {\n  Insert(1, 100);\n  Insert(2, 200);\n\n  Cache::Handle* handle = cache_->Lookup(EncodeKey(1));\n  ASSERT_TRUE(handle);\n  cache_->Prune();\n  cache_->Release(handle);\n\n  ASSERT_EQ(100, Lookup(1));\n  ASSERT_EQ(-1, Lookup(2));\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/util/coding.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"util/coding.h\"\n\nnamespace leveldb {\n\nvoid EncodeFixed32(char* buf, uint32_t value) {\n  if (port::kLittleEndian) {\n    memcpy(buf, &value, sizeof(value));\n  } else {\n    buf[0] = value & 0xff;\n    buf[1] = (value >> 8) & 0xff;\n    buf[2] = (value >> 16) & 0xff;\n    buf[3] = (value >> 24) & 0xff;\n  }\n}\n\nvoid EncodeFixed64(char* buf, uint64_t value) {\n  if (port::kLittleEndian) {\n    memcpy(buf, &value, sizeof(value));\n  } else {\n    buf[0] = value & 0xff;\n    buf[1] = (value >> 8) & 0xff;\n    buf[2] = (value >> 16) & 0xff;\n    buf[3] = (value >> 24) & 0xff;\n    buf[4] = (value >> 32) & 0xff;\n    buf[5] = (value >> 40) & 0xff;\n    buf[6] = (value >> 48) & 0xff;\n    buf[7] = (value >> 56) & 0xff;\n  }\n}\n\nvoid PutFixed32(std::string* dst, uint32_t value) {\n  char buf[sizeof(value)];\n  EncodeFixed32(buf, value);\n  dst->append(buf, sizeof(buf));\n}\n\nvoid PutFixed64(std::string* dst, uint64_t value) {\n  char buf[sizeof(value)];\n  EncodeFixed64(buf, value);\n  dst->append(buf, sizeof(buf));\n}\n\nchar* EncodeVarint32(char* dst, uint32_t v) {\n  // Operate on characters as unsigneds\n  unsigned char* ptr = reinterpret_cast<unsigned char*>(dst);\n  static const int B = 128;\n  if (v < (1<<7)) {\n    *(ptr++) = v;\n  } else if (v < (1<<14)) {\n    *(ptr++) = v | B;\n    *(ptr++) = v>>7;\n  } else if (v < (1<<21)) {\n    *(ptr++) = v | B;\n    *(ptr++) = (v>>7) | B;\n    *(ptr++) = v>>14;\n  } else if (v < (1<<28)) {\n    *(ptr++) = v | B;\n    *(ptr++) = (v>>7) | B;\n    *(ptr++) = (v>>14) | B;\n    *(ptr++) = v>>21;\n  } else {\n    *(ptr++) = v | B;\n    *(ptr++) = (v>>7) | B;\n    *(ptr++) = (v>>14) | B;\n    *(ptr++) = (v>>21) | B;\n    *(ptr++) = v>>28;\n  }\n  return reinterpret_cast<char*>(ptr);\n}\n\nvoid PutVarint32(std::string* dst, uint32_t v) {\n  char buf[5];\n  char* ptr = EncodeVarint32(buf, v);\n  dst->append(buf, ptr - buf);\n}\n\nchar* EncodeVarint64(char* dst, uint64_t v) {\n  static const int B = 128;\n  unsigned char* ptr = reinterpret_cast<unsigned char*>(dst);\n  while (v >= B) {\n    *(ptr++) = (v & (B-1)) | B;\n    v >>= 7;\n  }\n  *(ptr++) = static_cast<unsigned char>(v);\n  return reinterpret_cast<char*>(ptr);\n}\n\nvoid PutVarint64(std::string* dst, uint64_t v) {\n  char buf[10];\n  char* ptr = EncodeVarint64(buf, v);\n  dst->append(buf, ptr - buf);\n}\n\nvoid PutLengthPrefixedSlice(std::string* dst, const Slice& value) {\n  PutVarint32(dst, value.size());\n  dst->append(value.data(), value.size());\n}\n\nint VarintLength(uint64_t v) {\n  int len = 1;\n  while (v >= 128) {\n    v >>= 7;\n    len++;\n  }\n  return len;\n}\n\nconst char* GetVarint32PtrFallback(const char* p,\n                                   const char* limit,\n                                   uint32_t* value) {\n  uint32_t result = 0;\n  for (uint32_t shift = 0; shift <= 28 && p < limit; shift += 7) {\n    uint32_t byte = *(reinterpret_cast<const unsigned char*>(p));\n    p++;\n    if (byte & 128) {\n      // More bytes are present\n      result |= ((byte & 127) << shift);\n    } else {\n      result |= (byte << shift);\n      *value = result;\n      return reinterpret_cast<const char*>(p);\n    }\n  }\n  return NULL;\n}\n\nbool GetVarint32(Slice* input, uint32_t* value) {\n  const char* p = input->data();\n  const char* limit = p + input->size();\n  const char* q = GetVarint32Ptr(p, limit, value);\n  if (q == NULL) {\n    return false;\n  } else {\n    *input = Slice(q, limit - q);\n    return true;\n  }\n}\n\nconst char* GetVarint64Ptr(const char* p, const char* limit, uint64_t* value) {\n  uint64_t result = 0;\n  for (uint32_t shift = 0; shift <= 63 && p < limit; shift += 7) {\n    uint64_t byte = *(reinterpret_cast<const unsigned char*>(p));\n    p++;\n    if (byte & 128) {\n      // More bytes are present\n      result |= ((byte & 127) << shift);\n    } else {\n      result |= (byte << shift);\n      *value = result;\n      return reinterpret_cast<const char*>(p);\n    }\n  }\n  return NULL;\n}\n\nbool GetVarint64(Slice* input, uint64_t* value) {\n  const char* p = input->data();\n  const char* limit = p + input->size();\n  const char* q = GetVarint64Ptr(p, limit, value);\n  if (q == NULL) {\n    return false;\n  } else {\n    *input = Slice(q, limit - q);\n    return true;\n  }\n}\n\nconst char* GetLengthPrefixedSlice(const char* p, const char* limit,\n                                   Slice* result) {\n  uint32_t len;\n  p = GetVarint32Ptr(p, limit, &len);\n  if (p == NULL) return NULL;\n  if (p + len > limit) return NULL;\n  *result = Slice(p, len);\n  return p + len;\n}\n\nbool GetLengthPrefixedSlice(Slice* input, Slice* result) {\n  uint32_t len;\n  if (GetVarint32(input, &len) &&\n      input->size() >= len) {\n    *result = Slice(input->data(), len);\n    input->remove_prefix(len);\n    return true;\n  } else {\n    return false;\n  }\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/util/coding.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// Endian-neutral encoding:\n// * Fixed-length numbers are encoded with least-significant byte first\n// * In addition we support variable length \"varint\" encoding\n// * Strings are encoded prefixed by their length in varint format\n\n#ifndef STORAGE_LEVELDB_UTIL_CODING_H_\n#define STORAGE_LEVELDB_UTIL_CODING_H_\n\n#include <stdint.h>\n#include <string.h>\n#include <string>\n#include \"leveldb/slice.h\"\n#include \"port/port.h\"\n\nnamespace leveldb {\n\n// Standard Put... routines append to a string\nextern void PutFixed32(std::string* dst, uint32_t value);\nextern void PutFixed64(std::string* dst, uint64_t value);\nextern void PutVarint32(std::string* dst, uint32_t value);\nextern void PutVarint64(std::string* dst, uint64_t value);\nextern void PutLengthPrefixedSlice(std::string* dst, const Slice& value);\n\n// Standard Get... routines parse a value from the beginning of a Slice\n// and advance the slice past the parsed value.\nextern bool GetVarint32(Slice* input, uint32_t* value);\nextern bool GetVarint64(Slice* input, uint64_t* value);\nextern bool GetLengthPrefixedSlice(Slice* input, Slice* result);\n\n// Pointer-based variants of GetVarint...  These either store a value\n// in *v and return a pointer just past the parsed value, or return\n// NULL on error.  These routines only look at bytes in the range\n// [p..limit-1]\nextern const char* GetVarint32Ptr(const char* p,const char* limit, uint32_t* v);\nextern const char* GetVarint64Ptr(const char* p,const char* limit, uint64_t* v);\n\n// Returns the length of the varint32 or varint64 encoding of \"v\"\nextern int VarintLength(uint64_t v);\n\n// Lower-level versions of Put... that write directly into a character buffer\n// REQUIRES: dst has enough space for the value being written\nextern void EncodeFixed32(char* dst, uint32_t value);\nextern void EncodeFixed64(char* dst, uint64_t value);\n\n// Lower-level versions of Put... that write directly into a character buffer\n// and return a pointer just past the last byte written.\n// REQUIRES: dst has enough space for the value being written\nextern char* EncodeVarint32(char* dst, uint32_t value);\nextern char* EncodeVarint64(char* dst, uint64_t value);\n\n// Lower-level versions of Get... that read directly from a character buffer\n// without any bounds checking.\n\ninline uint32_t DecodeFixed32(const char* ptr) {\n  if (port::kLittleEndian) {\n    // Load the raw bytes\n    uint32_t result;\n    memcpy(&result, ptr, sizeof(result));  // gcc optimizes this to a plain load\n    return result;\n  } else {\n    return ((static_cast<uint32_t>(static_cast<unsigned char>(ptr[0])))\n        | (static_cast<uint32_t>(static_cast<unsigned char>(ptr[1])) << 8)\n        | (static_cast<uint32_t>(static_cast<unsigned char>(ptr[2])) << 16)\n        | (static_cast<uint32_t>(static_cast<unsigned char>(ptr[3])) << 24));\n  }\n}\n\ninline uint64_t DecodeFixed64(const char* ptr) {\n  if (port::kLittleEndian) {\n    // Load the raw bytes\n    uint64_t result;\n    memcpy(&result, ptr, sizeof(result));  // gcc optimizes this to a plain load\n    return result;\n  } else {\n    uint64_t lo = DecodeFixed32(ptr);\n    uint64_t hi = DecodeFixed32(ptr + 4);\n    return (hi << 32) | lo;\n  }\n}\n\n// Internal routine for use by fallback path of GetVarint32Ptr\nextern const char* GetVarint32PtrFallback(const char* p,\n                                          const char* limit,\n                                          uint32_t* value);\ninline const char* GetVarint32Ptr(const char* p,\n                                  const char* limit,\n                                  uint32_t* value) {\n  if (p < limit) {\n    uint32_t result = *(reinterpret_cast<const unsigned char*>(p));\n    if ((result & 128) == 0) {\n      *value = result;\n      return p + 1;\n    }\n  }\n  return GetVarint32PtrFallback(p, limit, value);\n}\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_UTIL_CODING_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/util/coding_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"util/coding.h\"\n\n#include \"util/testharness.h\"\n\nnamespace leveldb {\n\nclass Coding { };\n\nTEST(Coding, Fixed32) {\n  std::string s;\n  for (uint32_t v = 0; v < 100000; v++) {\n    PutFixed32(&s, v);\n  }\n\n  const char* p = s.data();\n  for (uint32_t v = 0; v < 100000; v++) {\n    uint32_t actual = DecodeFixed32(p);\n    ASSERT_EQ(v, actual);\n    p += sizeof(uint32_t);\n  }\n}\n\nTEST(Coding, Fixed64) {\n  std::string s;\n  for (int power = 0; power <= 63; power++) {\n    uint64_t v = static_cast<uint64_t>(1) << power;\n    PutFixed64(&s, v - 1);\n    PutFixed64(&s, v + 0);\n    PutFixed64(&s, v + 1);\n  }\n\n  const char* p = s.data();\n  for (int power = 0; power <= 63; power++) {\n    uint64_t v = static_cast<uint64_t>(1) << power;\n    uint64_t actual;\n    actual = DecodeFixed64(p);\n    ASSERT_EQ(v-1, actual);\n    p += sizeof(uint64_t);\n\n    actual = DecodeFixed64(p);\n    ASSERT_EQ(v+0, actual);\n    p += sizeof(uint64_t);\n\n    actual = DecodeFixed64(p);\n    ASSERT_EQ(v+1, actual);\n    p += sizeof(uint64_t);\n  }\n}\n\n// Test that encoding routines generate little-endian encodings\nTEST(Coding, EncodingOutput) {\n  std::string dst;\n  PutFixed32(&dst, 0x04030201);\n  ASSERT_EQ(4, dst.size());\n  ASSERT_EQ(0x01, static_cast<int>(dst[0]));\n  ASSERT_EQ(0x02, static_cast<int>(dst[1]));\n  ASSERT_EQ(0x03, static_cast<int>(dst[2]));\n  ASSERT_EQ(0x04, static_cast<int>(dst[3]));\n\n  dst.clear();\n  PutFixed64(&dst, 0x0807060504030201ull);\n  ASSERT_EQ(8, dst.size());\n  ASSERT_EQ(0x01, static_cast<int>(dst[0]));\n  ASSERT_EQ(0x02, static_cast<int>(dst[1]));\n  ASSERT_EQ(0x03, static_cast<int>(dst[2]));\n  ASSERT_EQ(0x04, static_cast<int>(dst[3]));\n  ASSERT_EQ(0x05, static_cast<int>(dst[4]));\n  ASSERT_EQ(0x06, static_cast<int>(dst[5]));\n  ASSERT_EQ(0x07, static_cast<int>(dst[6]));\n  ASSERT_EQ(0x08, static_cast<int>(dst[7]));\n}\n\nTEST(Coding, Varint32) {\n  std::string s;\n  for (uint32_t i = 0; i < (32 * 32); i++) {\n    uint32_t v = (i / 32) << (i % 32);\n    PutVarint32(&s, v);\n  }\n\n  const char* p = s.data();\n  const char* limit = p + s.size();\n  for (uint32_t i = 0; i < (32 * 32); i++) {\n    uint32_t expected = (i / 32) << (i % 32);\n    uint32_t actual;\n    const char* start = p;\n    p = GetVarint32Ptr(p, limit, &actual);\n    ASSERT_TRUE(p != NULL);\n    ASSERT_EQ(expected, actual);\n    ASSERT_EQ(VarintLength(actual), p - start);\n  }\n  ASSERT_EQ(p, s.data() + s.size());\n}\n\nTEST(Coding, Varint64) {\n  // Construct the list of values to check\n  std::vector<uint64_t> values;\n  // Some special values\n  values.push_back(0);\n  values.push_back(100);\n  values.push_back(~static_cast<uint64_t>(0));\n  values.push_back(~static_cast<uint64_t>(0) - 1);\n  for (uint32_t k = 0; k < 64; k++) {\n    // Test values near powers of two\n    const uint64_t power = 1ull << k;\n    values.push_back(power);\n    values.push_back(power-1);\n    values.push_back(power+1);\n  }\n\n  std::string s;\n  for (size_t i = 0; i < values.size(); i++) {\n    PutVarint64(&s, values[i]);\n  }\n\n  const char* p = s.data();\n  const char* limit = p + s.size();\n  for (size_t i = 0; i < values.size(); i++) {\n    ASSERT_TRUE(p < limit);\n    uint64_t actual;\n    const char* start = p;\n    p = GetVarint64Ptr(p, limit, &actual);\n    ASSERT_TRUE(p != NULL);\n    ASSERT_EQ(values[i], actual);\n    ASSERT_EQ(VarintLength(actual), p - start);\n  }\n  ASSERT_EQ(p, limit);\n\n}\n\nTEST(Coding, Varint32Overflow) {\n  uint32_t result;\n  std::string input(\"\\x81\\x82\\x83\\x84\\x85\\x11\");\n  ASSERT_TRUE(GetVarint32Ptr(input.data(), input.data() + input.size(), &result)\n              == NULL);\n}\n\nTEST(Coding, Varint32Truncation) {\n  uint32_t large_value = (1u << 31) + 100;\n  std::string s;\n  PutVarint32(&s, large_value);\n  uint32_t result;\n  for (size_t len = 0; len < s.size() - 1; len++) {\n    ASSERT_TRUE(GetVarint32Ptr(s.data(), s.data() + len, &result) == NULL);\n  }\n  ASSERT_TRUE(GetVarint32Ptr(s.data(), s.data() + s.size(), &result) != NULL);\n  ASSERT_EQ(large_value, result);\n}\n\nTEST(Coding, Varint64Overflow) {\n  uint64_t result;\n  std::string input(\"\\x81\\x82\\x83\\x84\\x85\\x81\\x82\\x83\\x84\\x85\\x11\");\n  ASSERT_TRUE(GetVarint64Ptr(input.data(), input.data() + input.size(), &result)\n              == NULL);\n}\n\nTEST(Coding, Varint64Truncation) {\n  uint64_t large_value = (1ull << 63) + 100ull;\n  std::string s;\n  PutVarint64(&s, large_value);\n  uint64_t result;\n  for (size_t len = 0; len < s.size() - 1; len++) {\n    ASSERT_TRUE(GetVarint64Ptr(s.data(), s.data() + len, &result) == NULL);\n  }\n  ASSERT_TRUE(GetVarint64Ptr(s.data(), s.data() + s.size(), &result) != NULL);\n  ASSERT_EQ(large_value, result);\n}\n\nTEST(Coding, Strings) {\n  std::string s;\n  PutLengthPrefixedSlice(&s, Slice(\"\"));\n  PutLengthPrefixedSlice(&s, Slice(\"foo\"));\n  PutLengthPrefixedSlice(&s, Slice(\"bar\"));\n  PutLengthPrefixedSlice(&s, Slice(std::string(200, 'x')));\n\n  Slice input(s);\n  Slice v;\n  ASSERT_TRUE(GetLengthPrefixedSlice(&input, &v));\n  ASSERT_EQ(\"\", v.ToString());\n  ASSERT_TRUE(GetLengthPrefixedSlice(&input, &v));\n  ASSERT_EQ(\"foo\", v.ToString());\n  ASSERT_TRUE(GetLengthPrefixedSlice(&input, &v));\n  ASSERT_EQ(\"bar\", v.ToString());\n  ASSERT_TRUE(GetLengthPrefixedSlice(&input, &v));\n  ASSERT_EQ(std::string(200, 'x'), v.ToString());\n  ASSERT_EQ(\"\", input.ToString());\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/util/comparator.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include <algorithm>\n#include <stdint.h>\n#include \"leveldb/comparator.h\"\n#include \"leveldb/slice.h\"\n#include \"port/port.h\"\n#include \"util/logging.h\"\n\nnamespace leveldb {\n\nComparator::~Comparator() { }\n\nnamespace {\nclass BytewiseComparatorImpl : public Comparator {\n public:\n  BytewiseComparatorImpl() { }\n\n  virtual const char* Name() const {\n    return \"leveldb.BytewiseComparator\";\n  }\n\n  virtual int Compare(const Slice& a, const Slice& b) const {\n    return a.compare(b);\n  }\n\n  virtual void FindShortestSeparator(\n      std::string* start,\n      const Slice& limit) const {\n    // Find length of common prefix\n    size_t min_length = std::min(start->size(), limit.size());\n    size_t diff_index = 0;\n    while ((diff_index < min_length) &&\n           ((*start)[diff_index] == limit[diff_index])) {\n      diff_index++;\n    }\n\n    if (diff_index >= min_length) {\n      // Do not shorten if one string is a prefix of the other\n    } else {\n      uint8_t diff_byte = static_cast<uint8_t>((*start)[diff_index]);\n      if (diff_byte < static_cast<uint8_t>(0xff) &&\n          diff_byte + 1 < static_cast<uint8_t>(limit[diff_index])) {\n        (*start)[diff_index]++;\n        start->resize(diff_index + 1);\n        assert(Compare(*start, limit) < 0);\n      }\n    }\n  }\n\n  virtual void FindShortSuccessor(std::string* key) const {\n    // Find first character that can be incremented\n    size_t n = key->size();\n    for (size_t i = 0; i < n; i++) {\n      const uint8_t byte = (*key)[i];\n      if (byte != static_cast<uint8_t>(0xff)) {\n        (*key)[i] = byte + 1;\n        key->resize(i+1);\n        return;\n      }\n    }\n    // *key is a run of 0xffs.  Leave it alone.\n  }\n};\n}  // namespace\n\nstatic port::OnceType once = LEVELDB_ONCE_INIT;\nstatic const Comparator* bytewise;\n\nstatic void InitModule() {\n  bytewise = new BytewiseComparatorImpl;\n}\n\nconst Comparator* BytewiseComparator() {\n  port::InitOnce(&once, InitModule);\n  return bytewise;\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/util/crc32c.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// A portable implementation of crc32c, optimized to handle\n// four bytes at a time.\n\n#include \"util/crc32c.h\"\n\n#include <stdint.h>\n\n#include \"port/port.h\"\n#include \"util/coding.h\"\n\nnamespace leveldb {\nnamespace crc32c {\n\nstatic const uint32_t table0_[256] = {\n  0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4,\n  0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb,\n  0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b,\n  0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24,\n  0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b,\n  0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384,\n  0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54,\n  0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b,\n  0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a,\n  0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35,\n  0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5,\n  0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa,\n  0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45,\n  0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a,\n  0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a,\n  0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595,\n  0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48,\n  0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957,\n  0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687,\n  0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198,\n  0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927,\n  0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38,\n  0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8,\n  0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7,\n  0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096,\n  0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789,\n  0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859,\n  0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46,\n  0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9,\n  0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6,\n  0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36,\n  0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829,\n  0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c,\n  0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93,\n  0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043,\n  0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c,\n  0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3,\n  0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc,\n  0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c,\n  0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033,\n  0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652,\n  0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d,\n  0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d,\n  0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982,\n  0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d,\n  0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622,\n  0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2,\n  0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed,\n  0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530,\n  0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f,\n  0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff,\n  0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0,\n  0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f,\n  0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540,\n  0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90,\n  0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f,\n  0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee,\n  0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1,\n  0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321,\n  0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e,\n  0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81,\n  0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e,\n  0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e,\n  0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351\n};\nstatic const uint32_t table1_[256] = {\n  0x00000000, 0x13a29877, 0x274530ee, 0x34e7a899,\n  0x4e8a61dc, 0x5d28f9ab, 0x69cf5132, 0x7a6dc945,\n  0x9d14c3b8, 0x8eb65bcf, 0xba51f356, 0xa9f36b21,\n  0xd39ea264, 0xc03c3a13, 0xf4db928a, 0xe7790afd,\n  0x3fc5f181, 0x2c6769f6, 0x1880c16f, 0x0b225918,\n  0x714f905d, 0x62ed082a, 0x560aa0b3, 0x45a838c4,\n  0xa2d13239, 0xb173aa4e, 0x859402d7, 0x96369aa0,\n  0xec5b53e5, 0xfff9cb92, 0xcb1e630b, 0xd8bcfb7c,\n  0x7f8be302, 0x6c297b75, 0x58ced3ec, 0x4b6c4b9b,\n  0x310182de, 0x22a31aa9, 0x1644b230, 0x05e62a47,\n  0xe29f20ba, 0xf13db8cd, 0xc5da1054, 0xd6788823,\n  0xac154166, 0xbfb7d911, 0x8b507188, 0x98f2e9ff,\n  0x404e1283, 0x53ec8af4, 0x670b226d, 0x74a9ba1a,\n  0x0ec4735f, 0x1d66eb28, 0x298143b1, 0x3a23dbc6,\n  0xdd5ad13b, 0xcef8494c, 0xfa1fe1d5, 0xe9bd79a2,\n  0x93d0b0e7, 0x80722890, 0xb4958009, 0xa737187e,\n  0xff17c604, 0xecb55e73, 0xd852f6ea, 0xcbf06e9d,\n  0xb19da7d8, 0xa23f3faf, 0x96d89736, 0x857a0f41,\n  0x620305bc, 0x71a19dcb, 0x45463552, 0x56e4ad25,\n  0x2c896460, 0x3f2bfc17, 0x0bcc548e, 0x186eccf9,\n  0xc0d23785, 0xd370aff2, 0xe797076b, 0xf4359f1c,\n  0x8e585659, 0x9dface2e, 0xa91d66b7, 0xbabffec0,\n  0x5dc6f43d, 0x4e646c4a, 0x7a83c4d3, 0x69215ca4,\n  0x134c95e1, 0x00ee0d96, 0x3409a50f, 0x27ab3d78,\n  0x809c2506, 0x933ebd71, 0xa7d915e8, 0xb47b8d9f,\n  0xce1644da, 0xddb4dcad, 0xe9537434, 0xfaf1ec43,\n  0x1d88e6be, 0x0e2a7ec9, 0x3acdd650, 0x296f4e27,\n  0x53028762, 0x40a01f15, 0x7447b78c, 0x67e52ffb,\n  0xbf59d487, 0xacfb4cf0, 0x981ce469, 0x8bbe7c1e,\n  0xf1d3b55b, 0xe2712d2c, 0xd69685b5, 0xc5341dc2,\n  0x224d173f, 0x31ef8f48, 0x050827d1, 0x16aabfa6,\n  0x6cc776e3, 0x7f65ee94, 0x4b82460d, 0x5820de7a,\n  0xfbc3faf9, 0xe861628e, 0xdc86ca17, 0xcf245260,\n  0xb5499b25, 0xa6eb0352, 0x920cabcb, 0x81ae33bc,\n  0x66d73941, 0x7575a136, 0x419209af, 0x523091d8,\n  0x285d589d, 0x3bffc0ea, 0x0f186873, 0x1cbaf004,\n  0xc4060b78, 0xd7a4930f, 0xe3433b96, 0xf0e1a3e1,\n  0x8a8c6aa4, 0x992ef2d3, 0xadc95a4a, 0xbe6bc23d,\n  0x5912c8c0, 0x4ab050b7, 0x7e57f82e, 0x6df56059,\n  0x1798a91c, 0x043a316b, 0x30dd99f2, 0x237f0185,\n  0x844819fb, 0x97ea818c, 0xa30d2915, 0xb0afb162,\n  0xcac27827, 0xd960e050, 0xed8748c9, 0xfe25d0be,\n  0x195cda43, 0x0afe4234, 0x3e19eaad, 0x2dbb72da,\n  0x57d6bb9f, 0x447423e8, 0x70938b71, 0x63311306,\n  0xbb8de87a, 0xa82f700d, 0x9cc8d894, 0x8f6a40e3,\n  0xf50789a6, 0xe6a511d1, 0xd242b948, 0xc1e0213f,\n  0x26992bc2, 0x353bb3b5, 0x01dc1b2c, 0x127e835b,\n  0x68134a1e, 0x7bb1d269, 0x4f567af0, 0x5cf4e287,\n  0x04d43cfd, 0x1776a48a, 0x23910c13, 0x30339464,\n  0x4a5e5d21, 0x59fcc556, 0x6d1b6dcf, 0x7eb9f5b8,\n  0x99c0ff45, 0x8a626732, 0xbe85cfab, 0xad2757dc,\n  0xd74a9e99, 0xc4e806ee, 0xf00fae77, 0xe3ad3600,\n  0x3b11cd7c, 0x28b3550b, 0x1c54fd92, 0x0ff665e5,\n  0x759baca0, 0x663934d7, 0x52de9c4e, 0x417c0439,\n  0xa6050ec4, 0xb5a796b3, 0x81403e2a, 0x92e2a65d,\n  0xe88f6f18, 0xfb2df76f, 0xcfca5ff6, 0xdc68c781,\n  0x7b5fdfff, 0x68fd4788, 0x5c1aef11, 0x4fb87766,\n  0x35d5be23, 0x26772654, 0x12908ecd, 0x013216ba,\n  0xe64b1c47, 0xf5e98430, 0xc10e2ca9, 0xd2acb4de,\n  0xa8c17d9b, 0xbb63e5ec, 0x8f844d75, 0x9c26d502,\n  0x449a2e7e, 0x5738b609, 0x63df1e90, 0x707d86e7,\n  0x0a104fa2, 0x19b2d7d5, 0x2d557f4c, 0x3ef7e73b,\n  0xd98eedc6, 0xca2c75b1, 0xfecbdd28, 0xed69455f,\n  0x97048c1a, 0x84a6146d, 0xb041bcf4, 0xa3e32483\n};\nstatic const uint32_t table2_[256] = {\n  0x00000000, 0xa541927e, 0x4f6f520d, 0xea2ec073,\n  0x9edea41a, 0x3b9f3664, 0xd1b1f617, 0x74f06469,\n  0x38513ec5, 0x9d10acbb, 0x773e6cc8, 0xd27ffeb6,\n  0xa68f9adf, 0x03ce08a1, 0xe9e0c8d2, 0x4ca15aac,\n  0x70a27d8a, 0xd5e3eff4, 0x3fcd2f87, 0x9a8cbdf9,\n  0xee7cd990, 0x4b3d4bee, 0xa1138b9d, 0x045219e3,\n  0x48f3434f, 0xedb2d131, 0x079c1142, 0xa2dd833c,\n  0xd62de755, 0x736c752b, 0x9942b558, 0x3c032726,\n  0xe144fb14, 0x4405696a, 0xae2ba919, 0x0b6a3b67,\n  0x7f9a5f0e, 0xdadbcd70, 0x30f50d03, 0x95b49f7d,\n  0xd915c5d1, 0x7c5457af, 0x967a97dc, 0x333b05a2,\n  0x47cb61cb, 0xe28af3b5, 0x08a433c6, 0xade5a1b8,\n  0x91e6869e, 0x34a714e0, 0xde89d493, 0x7bc846ed,\n  0x0f382284, 0xaa79b0fa, 0x40577089, 0xe516e2f7,\n  0xa9b7b85b, 0x0cf62a25, 0xe6d8ea56, 0x43997828,\n  0x37691c41, 0x92288e3f, 0x78064e4c, 0xdd47dc32,\n  0xc76580d9, 0x622412a7, 0x880ad2d4, 0x2d4b40aa,\n  0x59bb24c3, 0xfcfab6bd, 0x16d476ce, 0xb395e4b0,\n  0xff34be1c, 0x5a752c62, 0xb05bec11, 0x151a7e6f,\n  0x61ea1a06, 0xc4ab8878, 0x2e85480b, 0x8bc4da75,\n  0xb7c7fd53, 0x12866f2d, 0xf8a8af5e, 0x5de93d20,\n  0x29195949, 0x8c58cb37, 0x66760b44, 0xc337993a,\n  0x8f96c396, 0x2ad751e8, 0xc0f9919b, 0x65b803e5,\n  0x1148678c, 0xb409f5f2, 0x5e273581, 0xfb66a7ff,\n  0x26217bcd, 0x8360e9b3, 0x694e29c0, 0xcc0fbbbe,\n  0xb8ffdfd7, 0x1dbe4da9, 0xf7908dda, 0x52d11fa4,\n  0x1e704508, 0xbb31d776, 0x511f1705, 0xf45e857b,\n  0x80aee112, 0x25ef736c, 0xcfc1b31f, 0x6a802161,\n  0x56830647, 0xf3c29439, 0x19ec544a, 0xbcadc634,\n  0xc85da25d, 0x6d1c3023, 0x8732f050, 0x2273622e,\n  0x6ed23882, 0xcb93aafc, 0x21bd6a8f, 0x84fcf8f1,\n  0xf00c9c98, 0x554d0ee6, 0xbf63ce95, 0x1a225ceb,\n  0x8b277743, 0x2e66e53d, 0xc448254e, 0x6109b730,\n  0x15f9d359, 0xb0b84127, 0x5a968154, 0xffd7132a,\n  0xb3764986, 0x1637dbf8, 0xfc191b8b, 0x595889f5,\n  0x2da8ed9c, 0x88e97fe2, 0x62c7bf91, 0xc7862def,\n  0xfb850ac9, 0x5ec498b7, 0xb4ea58c4, 0x11abcaba,\n  0x655baed3, 0xc01a3cad, 0x2a34fcde, 0x8f756ea0,\n  0xc3d4340c, 0x6695a672, 0x8cbb6601, 0x29faf47f,\n  0x5d0a9016, 0xf84b0268, 0x1265c21b, 0xb7245065,\n  0x6a638c57, 0xcf221e29, 0x250cde5a, 0x804d4c24,\n  0xf4bd284d, 0x51fcba33, 0xbbd27a40, 0x1e93e83e,\n  0x5232b292, 0xf77320ec, 0x1d5de09f, 0xb81c72e1,\n  0xccec1688, 0x69ad84f6, 0x83834485, 0x26c2d6fb,\n  0x1ac1f1dd, 0xbf8063a3, 0x55aea3d0, 0xf0ef31ae,\n  0x841f55c7, 0x215ec7b9, 0xcb7007ca, 0x6e3195b4,\n  0x2290cf18, 0x87d15d66, 0x6dff9d15, 0xc8be0f6b,\n  0xbc4e6b02, 0x190ff97c, 0xf321390f, 0x5660ab71,\n  0x4c42f79a, 0xe90365e4, 0x032da597, 0xa66c37e9,\n  0xd29c5380, 0x77ddc1fe, 0x9df3018d, 0x38b293f3,\n  0x7413c95f, 0xd1525b21, 0x3b7c9b52, 0x9e3d092c,\n  0xeacd6d45, 0x4f8cff3b, 0xa5a23f48, 0x00e3ad36,\n  0x3ce08a10, 0x99a1186e, 0x738fd81d, 0xd6ce4a63,\n  0xa23e2e0a, 0x077fbc74, 0xed517c07, 0x4810ee79,\n  0x04b1b4d5, 0xa1f026ab, 0x4bdee6d8, 0xee9f74a6,\n  0x9a6f10cf, 0x3f2e82b1, 0xd50042c2, 0x7041d0bc,\n  0xad060c8e, 0x08479ef0, 0xe2695e83, 0x4728ccfd,\n  0x33d8a894, 0x96993aea, 0x7cb7fa99, 0xd9f668e7,\n  0x9557324b, 0x3016a035, 0xda386046, 0x7f79f238,\n  0x0b899651, 0xaec8042f, 0x44e6c45c, 0xe1a75622,\n  0xdda47104, 0x78e5e37a, 0x92cb2309, 0x378ab177,\n  0x437ad51e, 0xe63b4760, 0x0c158713, 0xa954156d,\n  0xe5f54fc1, 0x40b4ddbf, 0xaa9a1dcc, 0x0fdb8fb2,\n  0x7b2bebdb, 0xde6a79a5, 0x3444b9d6, 0x91052ba8\n};\nstatic const uint32_t table3_[256] = {\n  0x00000000, 0xdd45aab8, 0xbf672381, 0x62228939,\n  0x7b2231f3, 0xa6679b4b, 0xc4451272, 0x1900b8ca,\n  0xf64463e6, 0x2b01c95e, 0x49234067, 0x9466eadf,\n  0x8d665215, 0x5023f8ad, 0x32017194, 0xef44db2c,\n  0xe964b13d, 0x34211b85, 0x560392bc, 0x8b463804,\n  0x924680ce, 0x4f032a76, 0x2d21a34f, 0xf06409f7,\n  0x1f20d2db, 0xc2657863, 0xa047f15a, 0x7d025be2,\n  0x6402e328, 0xb9474990, 0xdb65c0a9, 0x06206a11,\n  0xd725148b, 0x0a60be33, 0x6842370a, 0xb5079db2,\n  0xac072578, 0x71428fc0, 0x136006f9, 0xce25ac41,\n  0x2161776d, 0xfc24ddd5, 0x9e0654ec, 0x4343fe54,\n  0x5a43469e, 0x8706ec26, 0xe524651f, 0x3861cfa7,\n  0x3e41a5b6, 0xe3040f0e, 0x81268637, 0x5c632c8f,\n  0x45639445, 0x98263efd, 0xfa04b7c4, 0x27411d7c,\n  0xc805c650, 0x15406ce8, 0x7762e5d1, 0xaa274f69,\n  0xb327f7a3, 0x6e625d1b, 0x0c40d422, 0xd1057e9a,\n  0xaba65fe7, 0x76e3f55f, 0x14c17c66, 0xc984d6de,\n  0xd0846e14, 0x0dc1c4ac, 0x6fe34d95, 0xb2a6e72d,\n  0x5de23c01, 0x80a796b9, 0xe2851f80, 0x3fc0b538,\n  0x26c00df2, 0xfb85a74a, 0x99a72e73, 0x44e284cb,\n  0x42c2eeda, 0x9f874462, 0xfda5cd5b, 0x20e067e3,\n  0x39e0df29, 0xe4a57591, 0x8687fca8, 0x5bc25610,\n  0xb4868d3c, 0x69c32784, 0x0be1aebd, 0xd6a40405,\n  0xcfa4bccf, 0x12e11677, 0x70c39f4e, 0xad8635f6,\n  0x7c834b6c, 0xa1c6e1d4, 0xc3e468ed, 0x1ea1c255,\n  0x07a17a9f, 0xdae4d027, 0xb8c6591e, 0x6583f3a6,\n  0x8ac7288a, 0x57828232, 0x35a00b0b, 0xe8e5a1b3,\n  0xf1e51979, 0x2ca0b3c1, 0x4e823af8, 0x93c79040,\n  0x95e7fa51, 0x48a250e9, 0x2a80d9d0, 0xf7c57368,\n  0xeec5cba2, 0x3380611a, 0x51a2e823, 0x8ce7429b,\n  0x63a399b7, 0xbee6330f, 0xdcc4ba36, 0x0181108e,\n  0x1881a844, 0xc5c402fc, 0xa7e68bc5, 0x7aa3217d,\n  0x52a0c93f, 0x8fe56387, 0xedc7eabe, 0x30824006,\n  0x2982f8cc, 0xf4c75274, 0x96e5db4d, 0x4ba071f5,\n  0xa4e4aad9, 0x79a10061, 0x1b838958, 0xc6c623e0,\n  0xdfc69b2a, 0x02833192, 0x60a1b8ab, 0xbde41213,\n  0xbbc47802, 0x6681d2ba, 0x04a35b83, 0xd9e6f13b,\n  0xc0e649f1, 0x1da3e349, 0x7f816a70, 0xa2c4c0c8,\n  0x4d801be4, 0x90c5b15c, 0xf2e73865, 0x2fa292dd,\n  0x36a22a17, 0xebe780af, 0x89c50996, 0x5480a32e,\n  0x8585ddb4, 0x58c0770c, 0x3ae2fe35, 0xe7a7548d,\n  0xfea7ec47, 0x23e246ff, 0x41c0cfc6, 0x9c85657e,\n  0x73c1be52, 0xae8414ea, 0xcca69dd3, 0x11e3376b,\n  0x08e38fa1, 0xd5a62519, 0xb784ac20, 0x6ac10698,\n  0x6ce16c89, 0xb1a4c631, 0xd3864f08, 0x0ec3e5b0,\n  0x17c35d7a, 0xca86f7c2, 0xa8a47efb, 0x75e1d443,\n  0x9aa50f6f, 0x47e0a5d7, 0x25c22cee, 0xf8878656,\n  0xe1873e9c, 0x3cc29424, 0x5ee01d1d, 0x83a5b7a5,\n  0xf90696d8, 0x24433c60, 0x4661b559, 0x9b241fe1,\n  0x8224a72b, 0x5f610d93, 0x3d4384aa, 0xe0062e12,\n  0x0f42f53e, 0xd2075f86, 0xb025d6bf, 0x6d607c07,\n  0x7460c4cd, 0xa9256e75, 0xcb07e74c, 0x16424df4,\n  0x106227e5, 0xcd278d5d, 0xaf050464, 0x7240aedc,\n  0x6b401616, 0xb605bcae, 0xd4273597, 0x09629f2f,\n  0xe6264403, 0x3b63eebb, 0x59416782, 0x8404cd3a,\n  0x9d0475f0, 0x4041df48, 0x22635671, 0xff26fcc9,\n  0x2e238253, 0xf36628eb, 0x9144a1d2, 0x4c010b6a,\n  0x5501b3a0, 0x88441918, 0xea669021, 0x37233a99,\n  0xd867e1b5, 0x05224b0d, 0x6700c234, 0xba45688c,\n  0xa345d046, 0x7e007afe, 0x1c22f3c7, 0xc167597f,\n  0xc747336e, 0x1a0299d6, 0x782010ef, 0xa565ba57,\n  0xbc65029d, 0x6120a825, 0x0302211c, 0xde478ba4,\n  0x31035088, 0xec46fa30, 0x8e647309, 0x5321d9b1,\n  0x4a21617b, 0x9764cbc3, 0xf54642fa, 0x2803e842\n};\n\n// Used to fetch a naturally-aligned 32-bit word in little endian byte-order\nstatic inline uint32_t LE_LOAD32(const uint8_t *p) {\n  return DecodeFixed32(reinterpret_cast<const char*>(p));\n}\n\n// Determine if the CPU running this program can accelerate the CRC32C\n// calculation.\nstatic bool CanAccelerateCRC32C() {\n  // port::AcceleretedCRC32C returns zero when unable to accelerate.\n  static const char kTestCRCBuffer[] = \"TestCRCBuffer\";\n  static const char kBufSize = sizeof(kTestCRCBuffer) - 1;\n  static const uint32_t kTestCRCValue = 0xdcbc59fa;\n\n  return port::AcceleratedCRC32C(0, kTestCRCBuffer, kBufSize) == kTestCRCValue;\n}\n\nuint32_t Extend(uint32_t crc, const char* buf, size_t size) {\n  static bool accelerate = CanAccelerateCRC32C();\n  if (accelerate) {\n    return port::AcceleratedCRC32C(crc, buf, size);\n  }\n\n  const uint8_t *p = reinterpret_cast<const uint8_t *>(buf);\n  const uint8_t *e = p + size;\n  uint32_t l = crc ^ 0xffffffffu;\n\n#define STEP1 do {                              \\\n    int c = (l & 0xff) ^ *p++;                  \\\n    l = table0_[c] ^ (l >> 8);                  \\\n} while (0)\n#define STEP4 do {                              \\\n    uint32_t c = l ^ LE_LOAD32(p);              \\\n    p += 4;                                     \\\n    l = table3_[c & 0xff] ^                     \\\n        table2_[(c >> 8) & 0xff] ^              \\\n        table1_[(c >> 16) & 0xff] ^             \\\n        table0_[c >> 24];                       \\\n} while (0)\n\n  // Point x at first 4-byte aligned byte in string.  This might be\n  // just past the end of the string.\n  const uintptr_t pval = reinterpret_cast<uintptr_t>(p);\n  const uint8_t* x = reinterpret_cast<const uint8_t*>(((pval + 3) >> 2) << 2);\n  if (x <= e) {\n    // Process bytes until finished or p is 4-byte aligned\n    while (p != x) {\n      STEP1;\n    }\n  }\n  // Process bytes 16 at a time\n  while ((e-p) >= 16) {\n    STEP4; STEP4; STEP4; STEP4;\n  }\n  // Process bytes 4 at a time\n  while ((e-p) >= 4) {\n    STEP4;\n  }\n  // Process the last few bytes\n  while (p != e) {\n    STEP1;\n  }\n#undef STEP4\n#undef STEP1\n  return l ^ 0xffffffffu;\n}\n\n}  // namespace crc32c\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/util/crc32c.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_UTIL_CRC32C_H_\n#define STORAGE_LEVELDB_UTIL_CRC32C_H_\n\n#include <stddef.h>\n#include <stdint.h>\n\nnamespace leveldb {\nnamespace crc32c {\n\n// Return the crc32c of concat(A, data[0,n-1]) where init_crc is the\n// crc32c of some string A.  Extend() is often used to maintain the\n// crc32c of a stream of data.\nextern uint32_t Extend(uint32_t init_crc, const char* data, size_t n);\n\n// Return the crc32c of data[0,n-1]\ninline uint32_t Value(const char* data, size_t n) {\n  return Extend(0, data, n);\n}\n\nstatic const uint32_t kMaskDelta = 0xa282ead8ul;\n\n// Return a masked representation of crc.\n//\n// Motivation: it is problematic to compute the CRC of a string that\n// contains embedded CRCs.  Therefore we recommend that CRCs stored\n// somewhere (e.g., in files) should be masked before being stored.\ninline uint32_t Mask(uint32_t crc) {\n  // Rotate right by 15 bits and add a constant.\n  return ((crc >> 15) | (crc << 17)) + kMaskDelta;\n}\n\n// Return the crc whose masked representation is masked_crc.\ninline uint32_t Unmask(uint32_t masked_crc) {\n  uint32_t rot = masked_crc - kMaskDelta;\n  return ((rot >> 17) | (rot << 15));\n}\n\n}  // namespace crc32c\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_UTIL_CRC32C_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/util/crc32c_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"util/crc32c.h\"\n#include \"util/testharness.h\"\n\nnamespace leveldb {\nnamespace crc32c {\n\nclass CRC { };\n\nTEST(CRC, StandardResults) {\n  // From rfc3720 section B.4.\n  char buf[32];\n\n  memset(buf, 0, sizeof(buf));\n  ASSERT_EQ(0x8a9136aa, Value(buf, sizeof(buf)));\n\n  memset(buf, 0xff, sizeof(buf));\n  ASSERT_EQ(0x62a8ab43, Value(buf, sizeof(buf)));\n\n  for (int i = 0; i < 32; i++) {\n    buf[i] = i;\n  }\n  ASSERT_EQ(0x46dd794e, Value(buf, sizeof(buf)));\n\n  for (int i = 0; i < 32; i++) {\n    buf[i] = 31 - i;\n  }\n  ASSERT_EQ(0x113fdb5c, Value(buf, sizeof(buf)));\n\n  unsigned char data[48] = {\n    0x01, 0xc0, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00,\n    0x14, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x04, 0x00,\n    0x00, 0x00, 0x00, 0x14,\n    0x00, 0x00, 0x00, 0x18,\n    0x28, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00,\n    0x02, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00,\n  };\n  ASSERT_EQ(0xd9963a56, Value(reinterpret_cast<char*>(data), sizeof(data)));\n}\n\nTEST(CRC, Values) {\n  ASSERT_NE(Value(\"a\", 1), Value(\"foo\", 3));\n}\n\nTEST(CRC, Extend) {\n  ASSERT_EQ(Value(\"hello world\", 11),\n            Extend(Value(\"hello \", 6), \"world\", 5));\n}\n\nTEST(CRC, Mask) {\n  uint32_t crc = Value(\"foo\", 3);\n  ASSERT_NE(crc, Mask(crc));\n  ASSERT_NE(crc, Mask(Mask(crc)));\n  ASSERT_EQ(crc, Unmask(Mask(crc)));\n  ASSERT_EQ(crc, Unmask(Unmask(Mask(Mask(crc)))));\n}\n\n}  // namespace crc32c\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/util/env.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/env.h\"\n\nnamespace leveldb {\n\nEnv::~Env() {\n}\n\nStatus Env::NewAppendableFile(const std::string& fname, WritableFile** result) {\n  return Status::NotSupported(\"NewAppendableFile\", fname);\n}\n\nSequentialFile::~SequentialFile() {\n}\n\nRandomAccessFile::~RandomAccessFile() {\n}\n\nWritableFile::~WritableFile() {\n}\n\nLogger::~Logger() {\n}\n\nFileLock::~FileLock() {\n}\n\nvoid Log(Logger* info_log, const char* format, ...) {\n  if (info_log != NULL) {\n    va_list ap;\n    va_start(ap, format);\n    info_log->Logv(format, ap);\n    va_end(ap);\n  }\n}\n\nstatic Status DoWriteStringToFile(Env* env, const Slice& data,\n                                  const std::string& fname,\n                                  bool should_sync) {\n  WritableFile* file;\n  Status s = env->NewWritableFile(fname, &file);\n  if (!s.ok()) {\n    return s;\n  }\n  s = file->Append(data);\n  if (s.ok() && should_sync) {\n    s = file->Sync();\n  }\n  if (s.ok()) {\n    s = file->Close();\n  }\n  delete file;  // Will auto-close if we did not close above\n  if (!s.ok()) {\n    env->DeleteFile(fname);\n  }\n  return s;\n}\n\nStatus WriteStringToFile(Env* env, const Slice& data,\n                         const std::string& fname) {\n  return DoWriteStringToFile(env, data, fname, false);\n}\n\nStatus WriteStringToFileSync(Env* env, const Slice& data,\n                             const std::string& fname) {\n  return DoWriteStringToFile(env, data, fname, true);\n}\n\nStatus ReadFileToString(Env* env, const std::string& fname, std::string* data) {\n  data->clear();\n  SequentialFile* file;\n  Status s = env->NewSequentialFile(fname, &file);\n  if (!s.ok()) {\n    return s;\n  }\n  static const int kBufferSize = 8192;\n  char* space = new char[kBufferSize];\n  while (true) {\n    Slice fragment;\n    s = file->Read(kBufferSize, &fragment, space);\n    if (!s.ok()) {\n      break;\n    }\n    data->append(fragment.data(), fragment.size());\n    if (fragment.empty()) {\n      break;\n    }\n  }\n  delete[] space;\n  delete file;\n  return s;\n}\n\nEnvWrapper::~EnvWrapper() {\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/util/env_posix.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include <dirent.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/mman.h>\n#include <sys/resource.h>\n#include <sys/stat.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <time.h>\n#include <unistd.h>\n#include <deque>\n#include <limits>\n#include <set>\n#include \"leveldb/env.h\"\n#include \"leveldb/slice.h\"\n#include \"port/port.h\"\n#include \"util/logging.h\"\n#include \"util/mutexlock.h\"\n#include \"util/posix_logger.h\"\n#include \"util/env_posix_test_helper.h\"\n\nnamespace leveldb {\n\nnamespace {\n\nstatic int open_read_only_file_limit = -1;\nstatic int mmap_limit = -1;\n\nstatic Status PosixError(const std::string& context, int err_number) {\n  if (err_number == ENOENT) {\n    return Status::NotFound(context, strerror(err_number));\n  } else {\n    return Status::IOError(context, strerror(err_number));\n  }\n}\n\n// Helper class to limit resource usage to avoid exhaustion.\n// Currently used to limit read-only file descriptors and mmap file usage\n// so that we do not end up running out of file descriptors, virtual memory,\n// or running into kernel performance problems for very large databases.\nclass Limiter {\n public:\n  // Limit maximum number of resources to |n|.\n  Limiter(intptr_t n) {\n    SetAllowed(n);\n  }\n\n  // If another resource is available, acquire it and return true.\n  // Else return false.\n  bool Acquire() {\n    if (GetAllowed() <= 0) {\n      return false;\n    }\n    MutexLock l(&mu_);\n    intptr_t x = GetAllowed();\n    if (x <= 0) {\n      return false;\n    } else {\n      SetAllowed(x - 1);\n      return true;\n    }\n  }\n\n  // Release a resource acquired by a previous call to Acquire() that returned\n  // true.\n  void Release() {\n    MutexLock l(&mu_);\n    SetAllowed(GetAllowed() + 1);\n  }\n\n private:\n  port::Mutex mu_;\n  port::AtomicPointer allowed_;\n\n  intptr_t GetAllowed() const {\n    return reinterpret_cast<intptr_t>(allowed_.Acquire_Load());\n  }\n\n  // REQUIRES: mu_ must be held\n  void SetAllowed(intptr_t v) {\n    allowed_.Release_Store(reinterpret_cast<void*>(v));\n  }\n\n  Limiter(const Limiter&);\n  void operator=(const Limiter&);\n};\n\nclass PosixSequentialFile: public SequentialFile {\n private:\n  std::string filename_;\n  FILE* file_;\n\n public:\n  PosixSequentialFile(const std::string& fname, FILE* f)\n      : filename_(fname), file_(f) { }\n  virtual ~PosixSequentialFile() { fclose(file_); }\n\n  virtual Status Read(size_t n, Slice* result, char* scratch) {\n    Status s;\n    size_t r = fread_unlocked(scratch, 1, n, file_);\n    *result = Slice(scratch, r);\n    if (r < n) {\n      if (feof(file_)) {\n        // We leave status as ok if we hit the end of the file\n      } else {\n        // A partial read with an error: return a non-ok status\n        s = PosixError(filename_, errno);\n      }\n    }\n    return s;\n  }\n\n  virtual Status Skip(uint64_t n) {\n    if (fseek(file_, n, SEEK_CUR)) {\n      return PosixError(filename_, errno);\n    }\n    return Status::OK();\n  }\n};\n\n// pread() based random-access\nclass PosixRandomAccessFile: public RandomAccessFile {\n private:\n  std::string filename_;\n  bool temporary_fd_;  // If true, fd_ is -1 and we open on every read.\n  int fd_;\n  Limiter* limiter_;\n\n public:\n  PosixRandomAccessFile(const std::string& fname, int fd, Limiter* limiter)\n      : filename_(fname), fd_(fd), limiter_(limiter) {\n    temporary_fd_ = !limiter->Acquire();\n    if (temporary_fd_) {\n      // Open file on every access.\n      close(fd_);\n      fd_ = -1;\n    }\n  }\n\n  virtual ~PosixRandomAccessFile() {\n    if (!temporary_fd_) {\n      close(fd_);\n      limiter_->Release();\n    }\n  }\n\n  virtual Status Read(uint64_t offset, size_t n, Slice* result,\n                      char* scratch) const {\n    int fd = fd_;\n    if (temporary_fd_) {\n      fd = open(filename_.c_str(), O_RDONLY);\n      if (fd < 0) {\n        return PosixError(filename_, errno);\n      }\n    }\n\n    Status s;\n    ssize_t r = pread(fd, scratch, n, static_cast<off_t>(offset));\n    *result = Slice(scratch, (r < 0) ? 0 : r);\n    if (r < 0) {\n      // An error: return a non-ok status\n      s = PosixError(filename_, errno);\n    }\n    if (temporary_fd_) {\n      // Close the temporary file descriptor opened earlier.\n      close(fd);\n    }\n    return s;\n  }\n};\n\n// mmap() based random-access\nclass PosixMmapReadableFile: public RandomAccessFile {\n private:\n  std::string filename_;\n  void* mmapped_region_;\n  size_t length_;\n  Limiter* limiter_;\n\n public:\n  // base[0,length-1] contains the mmapped contents of the file.\n  PosixMmapReadableFile(const std::string& fname, void* base, size_t length,\n                        Limiter* limiter)\n      : filename_(fname), mmapped_region_(base), length_(length),\n        limiter_(limiter) {\n  }\n\n  virtual ~PosixMmapReadableFile() {\n    munmap(mmapped_region_, length_);\n    limiter_->Release();\n  }\n\n  virtual Status Read(uint64_t offset, size_t n, Slice* result,\n                      char* scratch) const {\n    Status s;\n    if (offset + n > length_) {\n      *result = Slice();\n      s = PosixError(filename_, EINVAL);\n    } else {\n      *result = Slice(reinterpret_cast<char*>(mmapped_region_) + offset, n);\n    }\n    return s;\n  }\n};\n\nclass PosixWritableFile : public WritableFile {\n private:\n  std::string filename_;\n  FILE* file_;\n\n public:\n  PosixWritableFile(const std::string& fname, FILE* f)\n      : filename_(fname), file_(f) { }\n\n  ~PosixWritableFile() {\n    if (file_ != NULL) {\n      // Ignoring any potential errors\n      fclose(file_);\n    }\n  }\n\n  virtual Status Append(const Slice& data) {\n    size_t r = fwrite_unlocked(data.data(), 1, data.size(), file_);\n    if (r != data.size()) {\n      return PosixError(filename_, errno);\n    }\n    return Status::OK();\n  }\n\n  virtual Status Close() {\n    Status result;\n    if (fclose(file_) != 0) {\n      result = PosixError(filename_, errno);\n    }\n    file_ = NULL;\n    return result;\n  }\n\n  virtual Status Flush() {\n    if (fflush_unlocked(file_) != 0) {\n      return PosixError(filename_, errno);\n    }\n    return Status::OK();\n  }\n\n  Status SyncDirIfManifest() {\n    const char* f = filename_.c_str();\n    const char* sep = strrchr(f, '/');\n    Slice basename;\n    std::string dir;\n    if (sep == NULL) {\n      dir = \".\";\n      basename = f;\n    } else {\n      dir = std::string(f, sep - f);\n      basename = sep + 1;\n    }\n    Status s;\n    if (basename.starts_with(\"MANIFEST\")) {\n      int fd = open(dir.c_str(), O_RDONLY);\n      if (fd < 0) {\n        s = PosixError(dir, errno);\n      } else {\n        if (fsync(fd) < 0) {\n          s = PosixError(dir, errno);\n        }\n        close(fd);\n      }\n    }\n    return s;\n  }\n\n  virtual Status Sync() {\n    // Ensure new files referred to by the manifest are in the filesystem.\n    Status s = SyncDirIfManifest();\n    if (!s.ok()) {\n      return s;\n    }\n    if (fflush_unlocked(file_) != 0 ||\n        fdatasync(fileno(file_)) != 0) {\n      s = Status::IOError(filename_, strerror(errno));\n    }\n    return s;\n  }\n};\n\nstatic int LockOrUnlock(int fd, bool lock) {\n  errno = 0;\n  struct flock f;\n  memset(&f, 0, sizeof(f));\n  f.l_type = (lock ? F_WRLCK : F_UNLCK);\n  f.l_whence = SEEK_SET;\n  f.l_start = 0;\n  f.l_len = 0;        // Lock/unlock entire file\n  return fcntl(fd, F_SETLK, &f);\n}\n\nclass PosixFileLock : public FileLock {\n public:\n  int fd_;\n  std::string name_;\n};\n\n// Set of locked files.  We keep a separate set instead of just\n// relying on fcntrl(F_SETLK) since fcntl(F_SETLK) does not provide\n// any protection against multiple uses from the same process.\nclass PosixLockTable {\n private:\n  port::Mutex mu_;\n  std::set<std::string> locked_files_;\n public:\n  bool Insert(const std::string& fname) {\n    MutexLock l(&mu_);\n    return locked_files_.insert(fname).second;\n  }\n  void Remove(const std::string& fname) {\n    MutexLock l(&mu_);\n    locked_files_.erase(fname);\n  }\n};\n\nclass PosixEnv : public Env {\n public:\n  PosixEnv();\n  virtual ~PosixEnv() {\n    char msg[] = \"Destroying Env::Default()\\n\";\n    fwrite(msg, 1, sizeof(msg), stderr);\n    abort();\n  }\n\n  virtual Status NewSequentialFile(const std::string& fname,\n                                   SequentialFile** result) {\n    FILE* f = fopen(fname.c_str(), \"r\");\n    if (f == NULL) {\n      *result = NULL;\n      return PosixError(fname, errno);\n    } else {\n      *result = new PosixSequentialFile(fname, f);\n      return Status::OK();\n    }\n  }\n\n  virtual Status NewRandomAccessFile(const std::string& fname,\n                                     RandomAccessFile** result) {\n    *result = NULL;\n    Status s;\n    int fd = open(fname.c_str(), O_RDONLY);\n    if (fd < 0) {\n      s = PosixError(fname, errno);\n    } else if (mmap_limit_.Acquire()) {\n      uint64_t size;\n      s = GetFileSize(fname, &size);\n      if (s.ok()) {\n        void* base = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);\n        if (base != MAP_FAILED) {\n          *result = new PosixMmapReadableFile(fname, base, size, &mmap_limit_);\n        } else {\n          s = PosixError(fname, errno);\n        }\n      }\n      close(fd);\n      if (!s.ok()) {\n        mmap_limit_.Release();\n      }\n    } else {\n      *result = new PosixRandomAccessFile(fname, fd, &fd_limit_);\n    }\n    return s;\n  }\n\n  virtual Status NewWritableFile(const std::string& fname,\n                                 WritableFile** result) {\n    Status s;\n    FILE* f = fopen(fname.c_str(), \"w\");\n    if (f == NULL) {\n      *result = NULL;\n      s = PosixError(fname, errno);\n    } else {\n      *result = new PosixWritableFile(fname, f);\n    }\n    return s;\n  }\n\n  virtual Status NewAppendableFile(const std::string& fname,\n                                   WritableFile** result) {\n    Status s;\n    FILE* f = fopen(fname.c_str(), \"a\");\n    if (f == NULL) {\n      *result = NULL;\n      s = PosixError(fname, errno);\n    } else {\n      *result = new PosixWritableFile(fname, f);\n    }\n    return s;\n  }\n\n  virtual bool FileExists(const std::string& fname) {\n    return access(fname.c_str(), F_OK) == 0;\n  }\n\n  virtual Status GetChildren(const std::string& dir,\n                             std::vector<std::string>* result) {\n    result->clear();\n    DIR* d = opendir(dir.c_str());\n    if (d == NULL) {\n      return PosixError(dir, errno);\n    }\n    struct dirent* entry;\n    while ((entry = readdir(d)) != NULL) {\n      result->push_back(entry->d_name);\n    }\n    closedir(d);\n    return Status::OK();\n  }\n\n  virtual Status DeleteFile(const std::string& fname) {\n    Status result;\n    if (unlink(fname.c_str()) != 0) {\n      result = PosixError(fname, errno);\n    }\n    return result;\n  }\n\n  virtual Status CreateDir(const std::string& name) {\n    Status result;\n    if (mkdir(name.c_str(), 0755) != 0) {\n      result = PosixError(name, errno);\n    }\n    return result;\n  }\n\n  virtual Status DeleteDir(const std::string& name) {\n    Status result;\n    if (rmdir(name.c_str()) != 0) {\n      result = PosixError(name, errno);\n    }\n    return result;\n  }\n\n  virtual Status GetFileSize(const std::string& fname, uint64_t* size) {\n    Status s;\n    struct stat sbuf;\n    if (stat(fname.c_str(), &sbuf) != 0) {\n      *size = 0;\n      s = PosixError(fname, errno);\n    } else {\n      *size = sbuf.st_size;\n    }\n    return s;\n  }\n\n  virtual Status RenameFile(const std::string& src, const std::string& target) {\n    Status result;\n    if (rename(src.c_str(), target.c_str()) != 0) {\n      result = PosixError(src, errno);\n    }\n    return result;\n  }\n\n  virtual Status LockFile(const std::string& fname, FileLock** lock) {\n    *lock = NULL;\n    Status result;\n    int fd = open(fname.c_str(), O_RDWR | O_CREAT, 0644);\n    if (fd < 0) {\n      result = PosixError(fname, errno);\n    } else if (!locks_.Insert(fname)) {\n      close(fd);\n      result = Status::IOError(\"lock \" + fname, \"already held by process\");\n    } else if (LockOrUnlock(fd, true) == -1) {\n      result = PosixError(\"lock \" + fname, errno);\n      close(fd);\n      locks_.Remove(fname);\n    } else {\n      PosixFileLock* my_lock = new PosixFileLock;\n      my_lock->fd_ = fd;\n      my_lock->name_ = fname;\n      *lock = my_lock;\n    }\n    return result;\n  }\n\n  virtual Status UnlockFile(FileLock* lock) {\n    PosixFileLock* my_lock = reinterpret_cast<PosixFileLock*>(lock);\n    Status result;\n    if (LockOrUnlock(my_lock->fd_, false) == -1) {\n      result = PosixError(\"unlock\", errno);\n    }\n    locks_.Remove(my_lock->name_);\n    close(my_lock->fd_);\n    delete my_lock;\n    return result;\n  }\n\n  virtual void Schedule(void (*function)(void*), void* arg);\n\n  virtual void StartThread(void (*function)(void* arg), void* arg);\n\n  virtual Status GetTestDirectory(std::string* result) {\n    const char* env = getenv(\"TEST_TMPDIR\");\n    if (env && env[0] != '\\0') {\n      *result = env;\n    } else {\n      char buf[100];\n      snprintf(buf, sizeof(buf), \"/tmp/leveldbtest-%d\", int(geteuid()));\n      *result = buf;\n    }\n    // Directory may already exist\n    CreateDir(*result);\n    return Status::OK();\n  }\n\n  static uint64_t gettid() {\n    pthread_t tid = pthread_self();\n    uint64_t thread_id = 0;\n    memcpy(&thread_id, &tid, std::min(sizeof(thread_id), sizeof(tid)));\n    return thread_id;\n  }\n\n  virtual Status NewLogger(const std::string& fname, Logger** result) {\n    FILE* f = fopen(fname.c_str(), \"w\");\n    if (f == NULL) {\n      *result = NULL;\n      return PosixError(fname, errno);\n    } else {\n      *result = new PosixLogger(f, &PosixEnv::gettid);\n      return Status::OK();\n    }\n  }\n\n  virtual uint64_t NowMicros() {\n    struct timeval tv;\n    gettimeofday(&tv, NULL);\n    return static_cast<uint64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;\n  }\n\n  virtual void SleepForMicroseconds(int micros) {\n    usleep(micros);\n  }\n\n private:\n  void PthreadCall(const char* label, int result) {\n    if (result != 0) {\n      fprintf(stderr, \"pthread %s: %s\\n\", label, strerror(result));\n      abort();\n    }\n  }\n\n  // BGThread() is the body of the background thread\n  void BGThread();\n  static void* BGThreadWrapper(void* arg) {\n    reinterpret_cast<PosixEnv*>(arg)->BGThread();\n    return NULL;\n  }\n\n  pthread_mutex_t mu_;\n  pthread_cond_t bgsignal_;\n  pthread_t bgthread_;\n  bool started_bgthread_;\n\n  // Entry per Schedule() call\n  struct BGItem { void* arg; void (*function)(void*); };\n  typedef std::deque<BGItem> BGQueue;\n  BGQueue queue_;\n\n  PosixLockTable locks_;\n  Limiter mmap_limit_;\n  Limiter fd_limit_;\n};\n\n// Return the maximum number of concurrent mmaps.\nstatic int MaxMmaps() {\n  if (mmap_limit >= 0) {\n    return mmap_limit;\n  }\n  // Up to 1000 mmaps for 64-bit binaries; none for smaller pointer sizes.\n  mmap_limit = sizeof(void*) >= 8 ? 1000 : 0;\n  return mmap_limit;\n}\n\n// Return the maximum number of read-only files to keep open.\nstatic intptr_t MaxOpenFiles() {\n  if (open_read_only_file_limit >= 0) {\n    return open_read_only_file_limit;\n  }\n  struct rlimit rlim;\n  if (getrlimit(RLIMIT_NOFILE, &rlim)) {\n    // getrlimit failed, fallback to hard-coded default.\n    open_read_only_file_limit = 50;\n  } else if (rlim.rlim_cur == RLIM_INFINITY) {\n    open_read_only_file_limit = std::numeric_limits<int>::max();\n  } else {\n    // Allow use of 20% of available file descriptors for read-only files.\n    open_read_only_file_limit = rlim.rlim_cur / 5;\n  }\n  return open_read_only_file_limit;\n}\n\nPosixEnv::PosixEnv()\n    : started_bgthread_(false),\n      mmap_limit_(MaxMmaps()),\n      fd_limit_(MaxOpenFiles()) {\n  PthreadCall(\"mutex_init\", pthread_mutex_init(&mu_, NULL));\n  PthreadCall(\"cvar_init\", pthread_cond_init(&bgsignal_, NULL));\n}\n\nvoid PosixEnv::Schedule(void (*function)(void*), void* arg) {\n  PthreadCall(\"lock\", pthread_mutex_lock(&mu_));\n\n  // Start background thread if necessary\n  if (!started_bgthread_) {\n    started_bgthread_ = true;\n    PthreadCall(\n        \"create thread\",\n        pthread_create(&bgthread_, NULL,  &PosixEnv::BGThreadWrapper, this));\n  }\n\n  // If the queue is currently empty, the background thread may currently be\n  // waiting.\n  if (queue_.empty()) {\n    PthreadCall(\"signal\", pthread_cond_signal(&bgsignal_));\n  }\n\n  // Add to priority queue\n  queue_.push_back(BGItem());\n  queue_.back().function = function;\n  queue_.back().arg = arg;\n\n  PthreadCall(\"unlock\", pthread_mutex_unlock(&mu_));\n}\n\nvoid PosixEnv::BGThread() {\n  while (true) {\n    // Wait until there is an item that is ready to run\n    PthreadCall(\"lock\", pthread_mutex_lock(&mu_));\n    while (queue_.empty()) {\n      PthreadCall(\"wait\", pthread_cond_wait(&bgsignal_, &mu_));\n    }\n\n    void (*function)(void*) = queue_.front().function;\n    void* arg = queue_.front().arg;\n    queue_.pop_front();\n\n    PthreadCall(\"unlock\", pthread_mutex_unlock(&mu_));\n    (*function)(arg);\n  }\n}\n\nnamespace {\nstruct StartThreadState {\n  void (*user_function)(void*);\n  void* arg;\n};\n}\nstatic void* StartThreadWrapper(void* arg) {\n  StartThreadState* state = reinterpret_cast<StartThreadState*>(arg);\n  state->user_function(state->arg);\n  delete state;\n  return NULL;\n}\n\nvoid PosixEnv::StartThread(void (*function)(void* arg), void* arg) {\n  pthread_t t;\n  StartThreadState* state = new StartThreadState;\n  state->user_function = function;\n  state->arg = arg;\n  PthreadCall(\"start thread\",\n              pthread_create(&t, NULL,  &StartThreadWrapper, state));\n}\n\n}  // namespace\n\nstatic pthread_once_t once = PTHREAD_ONCE_INIT;\nstatic Env* default_env;\nstatic void InitDefaultEnv() { default_env = new PosixEnv; }\n\nvoid EnvPosixTestHelper::SetReadOnlyFDLimit(int limit) {\n  assert(default_env == NULL);\n  open_read_only_file_limit = limit;\n}\n\nvoid EnvPosixTestHelper::SetReadOnlyMMapLimit(int limit) {\n  assert(default_env == NULL);\n  mmap_limit = limit;\n}\n\nEnv* Env::Default() {\n  pthread_once(&once, InitDefaultEnv);\n  return default_env;\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/util/env_posix_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/env.h\"\n\n#include \"port/port.h\"\n#include \"util/testharness.h\"\n#include \"util/env_posix_test_helper.h\"\n\nnamespace leveldb {\n\nstatic const int kDelayMicros = 100000;\nstatic const int kReadOnlyFileLimit = 4;\nstatic const int kMMapLimit = 4;\n\nclass EnvPosixTest {\n public:\n  Env* env_;\n  EnvPosixTest() : env_(Env::Default()) { }\n\n  static void SetFileLimits(int read_only_file_limit, int mmap_limit) {\n    EnvPosixTestHelper::SetReadOnlyFDLimit(read_only_file_limit);\n    EnvPosixTestHelper::SetReadOnlyMMapLimit(mmap_limit);\n  }\n};\n\nTEST(EnvPosixTest, TestOpenOnRead) {\n  // Write some test data to a single file that will be opened |n| times.\n  std::string test_dir;\n  ASSERT_OK(env_->GetTestDirectory(&test_dir));\n  std::string test_file = test_dir + \"/open_on_read.txt\";\n\n  FILE* f = fopen(test_file.c_str(), \"w\");\n  ASSERT_TRUE(f != NULL);\n  const char kFileData[] = \"abcdefghijklmnopqrstuvwxyz\";\n  fputs(kFileData, f);\n  fclose(f);\n\n  // Open test file some number above the sum of the two limits to force\n  // open-on-read behavior of POSIX Env leveldb::RandomAccessFile.\n  const int kNumFiles = kReadOnlyFileLimit + kMMapLimit + 5;\n  leveldb::RandomAccessFile* files[kNumFiles] = {0};\n  for (int i = 0; i < kNumFiles; i++) {\n    ASSERT_OK(env_->NewRandomAccessFile(test_file, &files[i]));\n  }\n  char scratch;\n  Slice read_result;\n  for (int i = 0; i < kNumFiles; i++) {\n    ASSERT_OK(files[i]->Read(i, 1, &read_result, &scratch));\n    ASSERT_EQ(kFileData[i], read_result[0]);\n  }\n  for (int i = 0; i < kNumFiles; i++) {\n    delete files[i];\n  }\n  ASSERT_OK(env_->DeleteFile(test_file));\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  // All tests currently run with the same read-only file limits.\n  leveldb::EnvPosixTest::SetFileLimits(leveldb::kReadOnlyFileLimit,\n                                       leveldb::kMMapLimit);\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/util/env_posix_test_helper.h",
    "content": "// Copyright 2017 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_UTIL_ENV_POSIX_TEST_HELPER_H_\n#define STORAGE_LEVELDB_UTIL_ENV_POSIX_TEST_HELPER_H_\n\nnamespace leveldb {\n\nclass EnvPosixTest;\n\n// A helper for the POSIX Env to facilitate testing.\nclass EnvPosixTestHelper {\n private:\n  friend class EnvPosixTest;\n\n  // Set the maximum number of read-only files that will be opened.\n  // Must be called before creating an Env.\n  static void SetReadOnlyFDLimit(int limit);\n\n  // Set the maximum number of read-only files that will be mapped via mmap.\n  // Must be called before creating an Env.\n  static void SetReadOnlyMMapLimit(int limit);\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_UTIL_ENV_POSIX_TEST_HELPER_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/util/env_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/env.h\"\n\n#include \"port/port.h\"\n#include \"util/testharness.h\"\n\nnamespace leveldb {\n\nstatic const int kDelayMicros = 100000;\nstatic const int kReadOnlyFileLimit = 4;\nstatic const int kMMapLimit = 4;\n\nclass EnvTest {\n private:\n  port::Mutex mu_;\n  std::string events_;\n\n public:\n  Env* env_;\n  EnvTest() : env_(Env::Default()) { }\n};\n\nstatic void SetBool(void* ptr) {\n  reinterpret_cast<port::AtomicPointer*>(ptr)->NoBarrier_Store(ptr);\n}\n\nTEST(EnvTest, RunImmediately) {\n  port::AtomicPointer called (NULL);\n  env_->Schedule(&SetBool, &called);\n  env_->SleepForMicroseconds(kDelayMicros);\n  ASSERT_TRUE(called.NoBarrier_Load() != NULL);\n}\n\nTEST(EnvTest, RunMany) {\n  port::AtomicPointer last_id (NULL);\n\n  struct CB {\n    port::AtomicPointer* last_id_ptr;   // Pointer to shared slot\n    uintptr_t id;             // Order# for the execution of this callback\n\n    CB(port::AtomicPointer* p, int i) : last_id_ptr(p), id(i) { }\n\n    static void Run(void* v) {\n      CB* cb = reinterpret_cast<CB*>(v);\n      void* cur = cb->last_id_ptr->NoBarrier_Load();\n      ASSERT_EQ(cb->id-1, reinterpret_cast<uintptr_t>(cur));\n      cb->last_id_ptr->Release_Store(reinterpret_cast<void*>(cb->id));\n    }\n  };\n\n  // Schedule in different order than start time\n  CB cb1(&last_id, 1);\n  CB cb2(&last_id, 2);\n  CB cb3(&last_id, 3);\n  CB cb4(&last_id, 4);\n  env_->Schedule(&CB::Run, &cb1);\n  env_->Schedule(&CB::Run, &cb2);\n  env_->Schedule(&CB::Run, &cb3);\n  env_->Schedule(&CB::Run, &cb4);\n\n  env_->SleepForMicroseconds(kDelayMicros);\n  void* cur = last_id.Acquire_Load();\n  ASSERT_EQ(4, reinterpret_cast<uintptr_t>(cur));\n}\n\nstruct State {\n  port::Mutex mu;\n  int val;\n  int num_running;\n};\n\nstatic void ThreadBody(void* arg) {\n  State* s = reinterpret_cast<State*>(arg);\n  s->mu.Lock();\n  s->val += 1;\n  s->num_running -= 1;\n  s->mu.Unlock();\n}\n\nTEST(EnvTest, StartThread) {\n  State state;\n  state.val = 0;\n  state.num_running = 3;\n  for (int i = 0; i < 3; i++) {\n    env_->StartThread(&ThreadBody, &state);\n  }\n  while (true) {\n    state.mu.Lock();\n    int num = state.num_running;\n    state.mu.Unlock();\n    if (num == 0) {\n      break;\n    }\n    env_->SleepForMicroseconds(kDelayMicros);\n  }\n  ASSERT_EQ(state.val, 3);\n}\n\nTEST(EnvTest, TestOpenNonExistentFile) {\n  // Write some test data to a single file that will be opened |n| times.\n  std::string test_dir;\n  ASSERT_OK(env_->GetTestDirectory(&test_dir));\n\n  std::string non_existent_file = test_dir + \"/non_existent_file\";\n  ASSERT_TRUE(!env_->FileExists(non_existent_file));\n\n  RandomAccessFile* random_access_file;\n  Status status = env_->NewRandomAccessFile(\n      non_existent_file, &random_access_file);\n  ASSERT_TRUE(status.IsNotFound());\n\n  SequentialFile* sequential_file;\n  status = env_->NewSequentialFile(non_existent_file, &sequential_file);\n  ASSERT_TRUE(status.IsNotFound());\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/util/filter_policy.cc",
    "content": "// Copyright (c) 2012 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/filter_policy.h\"\n\nnamespace leveldb {\n\nFilterPolicy::~FilterPolicy() { }\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/util/hash.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include <string.h>\n#include \"util/coding.h\"\n#include \"util/hash.h\"\n\n// The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through\n// between switch labels. The real definition should be provided externally.\n// This one is a fallback version for unsupported compilers.\n#ifndef FALLTHROUGH_INTENDED\n#define FALLTHROUGH_INTENDED do { } while (0)\n#endif\n\nnamespace leveldb {\n\nuint32_t Hash(const char* data, size_t n, uint32_t seed) {\n  // Similar to murmur hash\n  const uint32_t m = 0xc6a4a793;\n  const uint32_t r = 24;\n  const char* limit = data + n;\n  uint32_t h = seed ^ (n * m);\n\n  // Pick up four bytes at a time\n  while (data + 4 <= limit) {\n    uint32_t w = DecodeFixed32(data);\n    data += 4;\n    h += w;\n    h *= m;\n    h ^= (h >> 16);\n  }\n\n  // Pick up remaining bytes\n  switch (limit - data) {\n    case 3:\n      h += static_cast<unsigned char>(data[2]) << 16;\n      FALLTHROUGH_INTENDED;\n    case 2:\n      h += static_cast<unsigned char>(data[1]) << 8;\n      FALLTHROUGH_INTENDED;\n    case 1:\n      h += static_cast<unsigned char>(data[0]);\n      h *= m;\n      h ^= (h >> r);\n      break;\n  }\n  return h;\n}\n\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/util/hash.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// Simple hash function used for internal data structures\n\n#ifndef STORAGE_LEVELDB_UTIL_HASH_H_\n#define STORAGE_LEVELDB_UTIL_HASH_H_\n\n#include <stddef.h>\n#include <stdint.h>\n\nnamespace leveldb {\n\nextern uint32_t Hash(const char* data, size_t n, uint32_t seed);\n\n}\n\n#endif  // STORAGE_LEVELDB_UTIL_HASH_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/util/hash_test.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"util/hash.h\"\n#include \"util/testharness.h\"\n\nnamespace leveldb {\n\nclass HASH { };\n\nTEST(HASH, SignedUnsignedIssue) {\n  const unsigned char data1[1] = {0x62};\n  const unsigned char data2[2] = {0xc3, 0x97};\n  const unsigned char data3[3] = {0xe2, 0x99, 0xa5};\n  const unsigned char data4[4] = {0xe1, 0x80, 0xb9, 0x32};\n  const unsigned char data5[48] = {\n    0x01, 0xc0, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00,\n    0x14, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x04, 0x00,\n    0x00, 0x00, 0x00, 0x14,\n    0x00, 0x00, 0x00, 0x18,\n    0x28, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00,\n    0x02, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00,\n  };\n\n  ASSERT_EQ(Hash(0, 0, 0xbc9f1d34), 0xbc9f1d34);\n  ASSERT_EQ(\n      Hash(reinterpret_cast<const char*>(data1), sizeof(data1), 0xbc9f1d34),\n      0xef1345c4);\n  ASSERT_EQ(\n      Hash(reinterpret_cast<const char*>(data2), sizeof(data2), 0xbc9f1d34),\n      0x5b663814);\n  ASSERT_EQ(\n      Hash(reinterpret_cast<const char*>(data3), sizeof(data3), 0xbc9f1d34),\n      0x323c078f);\n  ASSERT_EQ(\n      Hash(reinterpret_cast<const char*>(data4), sizeof(data4), 0xbc9f1d34),\n      0xed21633a);\n  ASSERT_EQ(\n      Hash(reinterpret_cast<const char*>(data5), sizeof(data5), 0x12345678),\n      0xf333dabb);\n}\n\n}  // namespace leveldb\n\nint main(int argc, char** argv) {\n  return leveldb::test::RunAllTests();\n}\n"
  },
  {
    "path": "deps/leveldb-1.20/util/histogram.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include <math.h>\n#include <stdio.h>\n#include \"port/port.h\"\n#include \"util/histogram.h\"\n\nnamespace leveldb {\n\nconst double Histogram::kBucketLimit[kNumBuckets] = {\n  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 25, 30, 35, 40, 45,\n  50, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200, 250, 300, 350, 400, 450,\n  500, 600, 700, 800, 900, 1000, 1200, 1400, 1600, 1800, 2000, 2500, 3000,\n  3500, 4000, 4500, 5000, 6000, 7000, 8000, 9000, 10000, 12000, 14000,\n  16000, 18000, 20000, 25000, 30000, 35000, 40000, 45000, 50000, 60000,\n  70000, 80000, 90000, 100000, 120000, 140000, 160000, 180000, 200000,\n  250000, 300000, 350000, 400000, 450000, 500000, 600000, 700000, 800000,\n  900000, 1000000, 1200000, 1400000, 1600000, 1800000, 2000000, 2500000,\n  3000000, 3500000, 4000000, 4500000, 5000000, 6000000, 7000000, 8000000,\n  9000000, 10000000, 12000000, 14000000, 16000000, 18000000, 20000000,\n  25000000, 30000000, 35000000, 40000000, 45000000, 50000000, 60000000,\n  70000000, 80000000, 90000000, 100000000, 120000000, 140000000, 160000000,\n  180000000, 200000000, 250000000, 300000000, 350000000, 400000000,\n  450000000, 500000000, 600000000, 700000000, 800000000, 900000000,\n  1000000000, 1200000000, 1400000000, 1600000000, 1800000000, 2000000000,\n  2500000000.0, 3000000000.0, 3500000000.0, 4000000000.0, 4500000000.0,\n  5000000000.0, 6000000000.0, 7000000000.0, 8000000000.0, 9000000000.0,\n  1e200,\n};\n\nvoid Histogram::Clear() {\n  min_ = kBucketLimit[kNumBuckets-1];\n  max_ = 0;\n  num_ = 0;\n  sum_ = 0;\n  sum_squares_ = 0;\n  for (int i = 0; i < kNumBuckets; i++) {\n    buckets_[i] = 0;\n  }\n}\n\nvoid Histogram::Add(double value) {\n  // Linear search is fast enough for our usage in db_bench\n  int b = 0;\n  while (b < kNumBuckets - 1 && kBucketLimit[b] <= value) {\n    b++;\n  }\n  buckets_[b] += 1.0;\n  if (min_ > value) min_ = value;\n  if (max_ < value) max_ = value;\n  num_++;\n  sum_ += value;\n  sum_squares_ += (value * value);\n}\n\nvoid Histogram::Merge(const Histogram& other) {\n  if (other.min_ < min_) min_ = other.min_;\n  if (other.max_ > max_) max_ = other.max_;\n  num_ += other.num_;\n  sum_ += other.sum_;\n  sum_squares_ += other.sum_squares_;\n  for (int b = 0; b < kNumBuckets; b++) {\n    buckets_[b] += other.buckets_[b];\n  }\n}\n\ndouble Histogram::Median() const {\n  return Percentile(50.0);\n}\n\ndouble Histogram::Percentile(double p) const {\n  double threshold = num_ * (p / 100.0);\n  double sum = 0;\n  for (int b = 0; b < kNumBuckets; b++) {\n    sum += buckets_[b];\n    if (sum >= threshold) {\n      // Scale linearly within this bucket\n      double left_point = (b == 0) ? 0 : kBucketLimit[b-1];\n      double right_point = kBucketLimit[b];\n      double left_sum = sum - buckets_[b];\n      double right_sum = sum;\n      double pos = (threshold - left_sum) / (right_sum - left_sum);\n      double r = left_point + (right_point - left_point) * pos;\n      if (r < min_) r = min_;\n      if (r > max_) r = max_;\n      return r;\n    }\n  }\n  return max_;\n}\n\ndouble Histogram::Average() const {\n  if (num_ == 0.0) return 0;\n  return sum_ / num_;\n}\n\ndouble Histogram::StandardDeviation() const {\n  if (num_ == 0.0) return 0;\n  double variance = (sum_squares_ * num_ - sum_ * sum_) / (num_ * num_);\n  return sqrt(variance);\n}\n\nstd::string Histogram::ToString() const {\n  std::string r;\n  char buf[200];\n  snprintf(buf, sizeof(buf),\n           \"Count: %.0f  Average: %.4f  StdDev: %.2f\\n\",\n           num_, Average(), StandardDeviation());\n  r.append(buf);\n  snprintf(buf, sizeof(buf),\n           \"Min: %.4f  Median: %.4f  Max: %.4f\\n\",\n           (num_ == 0.0 ? 0.0 : min_), Median(), max_);\n  r.append(buf);\n  r.append(\"------------------------------------------------------\\n\");\n  const double mult = 100.0 / num_;\n  double sum = 0;\n  for (int b = 0; b < kNumBuckets; b++) {\n    if (buckets_[b] <= 0.0) continue;\n    sum += buckets_[b];\n    snprintf(buf, sizeof(buf),\n             \"[ %7.0f, %7.0f ) %7.0f %7.3f%% %7.3f%% \",\n             ((b == 0) ? 0.0 : kBucketLimit[b-1]),      // left\n             kBucketLimit[b],                           // right\n             buckets_[b],                               // count\n             mult * buckets_[b],                        // percentage\n             mult * sum);                               // cumulative percentage\n    r.append(buf);\n\n    // Add hash marks based on percentage; 20 marks for 100%.\n    int marks = static_cast<int>(20*(buckets_[b] / num_) + 0.5);\n    r.append(marks, '#');\n    r.push_back('\\n');\n  }\n  return r;\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/util/histogram.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_UTIL_HISTOGRAM_H_\n#define STORAGE_LEVELDB_UTIL_HISTOGRAM_H_\n\n#include <string>\n\nnamespace leveldb {\n\nclass Histogram {\n public:\n  Histogram() { }\n  ~Histogram() { }\n\n  void Clear();\n  void Add(double value);\n  void Merge(const Histogram& other);\n\n  std::string ToString() const;\n\n private:\n  double min_;\n  double max_;\n  double num_;\n  double sum_;\n  double sum_squares_;\n\n  enum { kNumBuckets = 154 };\n  static const double kBucketLimit[kNumBuckets];\n  double buckets_[kNumBuckets];\n\n  double Median() const;\n  double Percentile(double p) const;\n  double Average() const;\n  double StandardDeviation() const;\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_UTIL_HISTOGRAM_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/util/logging.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"util/logging.h\"\n\n#include <errno.h>\n#include <stdarg.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include \"leveldb/env.h\"\n#include \"leveldb/slice.h\"\n\nnamespace leveldb {\n\nvoid AppendNumberTo(std::string* str, uint64_t num) {\n  char buf[30];\n  snprintf(buf, sizeof(buf), \"%llu\", (unsigned long long) num);\n  str->append(buf);\n}\n\nvoid AppendEscapedStringTo(std::string* str, const Slice& value) {\n  for (size_t i = 0; i < value.size(); i++) {\n    char c = value[i];\n    if (c >= ' ' && c <= '~') {\n      str->push_back(c);\n    } else {\n      char buf[10];\n      snprintf(buf, sizeof(buf), \"\\\\x%02x\",\n               static_cast<unsigned int>(c) & 0xff);\n      str->append(buf);\n    }\n  }\n}\n\nstd::string NumberToString(uint64_t num) {\n  std::string r;\n  AppendNumberTo(&r, num);\n  return r;\n}\n\nstd::string EscapeString(const Slice& value) {\n  std::string r;\n  AppendEscapedStringTo(&r, value);\n  return r;\n}\n\nbool ConsumeDecimalNumber(Slice* in, uint64_t* val) {\n  uint64_t v = 0;\n  int digits = 0;\n  while (!in->empty()) {\n    char c = (*in)[0];\n    if (c >= '0' && c <= '9') {\n      ++digits;\n      // |delta| intentionally unit64_t to avoid Android crash (see log).\n      const uint64_t delta = (c - '0');\n      static const uint64_t kMaxUint64 = ~static_cast<uint64_t>(0);\n      if (v > kMaxUint64/10 ||\n          (v == kMaxUint64/10 && delta > kMaxUint64%10)) {\n        // Overflow\n        return false;\n      }\n      v = (v * 10) + delta;\n      in->remove_prefix(1);\n    } else {\n      break;\n    }\n  }\n  *val = v;\n  return (digits > 0);\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/util/logging.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// Must not be included from any .h files to avoid polluting the namespace\n// with macros.\n\n#ifndef STORAGE_LEVELDB_UTIL_LOGGING_H_\n#define STORAGE_LEVELDB_UTIL_LOGGING_H_\n\n#include <stdio.h>\n#include <stdint.h>\n#include <string>\n#include \"port/port.h\"\n\nnamespace leveldb {\n\nclass Slice;\nclass WritableFile;\n\n// Append a human-readable printout of \"num\" to *str\nextern void AppendNumberTo(std::string* str, uint64_t num);\n\n// Append a human-readable printout of \"value\" to *str.\n// Escapes any non-printable characters found in \"value\".\nextern void AppendEscapedStringTo(std::string* str, const Slice& value);\n\n// Return a human-readable printout of \"num\"\nextern std::string NumberToString(uint64_t num);\n\n// Return a human-readable version of \"value\".\n// Escapes any non-printable characters found in \"value\".\nextern std::string EscapeString(const Slice& value);\n\n// Parse a human-readable number from \"*in\" into *value.  On success,\n// advances \"*in\" past the consumed number and sets \"*val\" to the\n// numeric value.  Otherwise, returns false and leaves *in in an\n// unspecified state.\nextern bool ConsumeDecimalNumber(Slice* in, uint64_t* val);\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_UTIL_LOGGING_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/util/mutexlock.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_\n#define STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_\n\n#include \"port/port.h\"\n#include \"port/thread_annotations.h\"\n\nnamespace leveldb {\n\n// Helper class that locks a mutex on construction and unlocks the mutex when\n// the destructor of the MutexLock object is invoked.\n//\n// Typical usage:\n//\n//   void MyClass::MyMethod() {\n//     MutexLock l(&mu_);       // mu_ is an instance variable\n//     ... some complex code, possibly with multiple return paths ...\n//   }\n\nclass SCOPED_LOCKABLE MutexLock {\n public:\n  explicit MutexLock(port::Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu)\n      : mu_(mu)  {\n    this->mu_->Lock();\n  }\n  ~MutexLock() UNLOCK_FUNCTION() { this->mu_->Unlock(); }\n\n private:\n  port::Mutex *const mu_;\n  // No copying allowed\n  MutexLock(const MutexLock&);\n  void operator=(const MutexLock&);\n};\n\n}  // namespace leveldb\n\n\n#endif  // STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/util/options.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"leveldb/options.h\"\n\n#include \"leveldb/comparator.h\"\n#include \"leveldb/env.h\"\n\nnamespace leveldb {\n\nOptions::Options()\n    : comparator(BytewiseComparator()),\n      compaction_speed(4096),\n      create_if_missing(false),\n      error_if_exists(false),\n      paranoid_checks(false),\n      env(Env::Default()),\n      info_log(NULL),\n      write_buffer_size(4<<20),\n      max_open_files(1000),\n      block_cache(NULL),\n      block_size(4096),\n      block_restart_interval(16),\n      max_file_size(2<<20),\n      compression(kSnappyCompression),\n      reuse_logs(false),\n      filter_policy(NULL) {\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/util/posix_logger.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n//\n// Logger implementation that can be shared by all environments\n// where enough posix functionality is available.\n\n#ifndef STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_\n#define STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_\n\n#include <algorithm>\n#include <stdio.h>\n#include <sys/time.h>\n#include <time.h>\n#include \"leveldb/env.h\"\n\nnamespace leveldb {\n\nclass PosixLogger : public Logger {\n private:\n  FILE* file_;\n  uint64_t (*gettid_)();  // Return the thread id for the current thread\n public:\n  PosixLogger(FILE* f, uint64_t (*gettid)()) : file_(f), gettid_(gettid) { }\n  virtual ~PosixLogger() {\n    fclose(file_);\n  }\n  virtual void Logv(const char* format, va_list ap) {\n    const uint64_t thread_id = (*gettid_)();\n\n    // We try twice: the first time with a fixed-size stack allocated buffer,\n    // and the second time with a much larger dynamically allocated buffer.\n    char buffer[500];\n    for (int iter = 0; iter < 2; iter++) {\n      char* base;\n      int bufsize;\n      if (iter == 0) {\n        bufsize = sizeof(buffer);\n        base = buffer;\n      } else {\n        bufsize = 30000;\n        base = new char[bufsize];\n      }\n      char* p = base;\n      char* limit = base + bufsize;\n\n      struct timeval now_tv;\n      gettimeofday(&now_tv, NULL);\n      const time_t seconds = now_tv.tv_sec;\n      struct tm t;\n      localtime_r(&seconds, &t);\n      p += snprintf(p, limit - p,\n                    \"%04d/%02d/%02d-%02d:%02d:%02d.%06d %llx \",\n                    t.tm_year + 1900,\n                    t.tm_mon + 1,\n                    t.tm_mday,\n                    t.tm_hour,\n                    t.tm_min,\n                    t.tm_sec,\n                    static_cast<int>(now_tv.tv_usec),\n                    static_cast<long long unsigned int>(thread_id));\n\n      // Print the message\n      if (p < limit) {\n        va_list backup_ap;\n        va_copy(backup_ap, ap);\n        p += vsnprintf(p, limit - p, format, backup_ap);\n        va_end(backup_ap);\n      }\n\n      // Truncate to available space if necessary\n      if (p >= limit) {\n        if (iter == 0) {\n          continue;       // Try again with larger buffer\n        } else {\n          p = limit - 1;\n        }\n      }\n\n      // Add newline if necessary\n      if (p == base || p[-1] != '\\n') {\n        *p++ = '\\n';\n      }\n\n      assert(p <= limit);\n      fwrite(base, 1, p - base, file_);\n      fflush(file_);\n      if (base != buffer) {\n        delete[] base;\n      }\n      break;\n    }\n  }\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/util/random.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_UTIL_RANDOM_H_\n#define STORAGE_LEVELDB_UTIL_RANDOM_H_\n\n#include <stdint.h>\n\nnamespace leveldb {\n\n// A very simple random number generator.  Not especially good at\n// generating truly random bits, but good enough for our needs in this\n// package.\nclass Random {\n private:\n  uint32_t seed_;\n public:\n  explicit Random(uint32_t s) : seed_(s & 0x7fffffffu) {\n    // Avoid bad seeds.\n    if (seed_ == 0 || seed_ == 2147483647L) {\n      seed_ = 1;\n    }\n  }\n  uint32_t Next() {\n    static const uint32_t M = 2147483647L;   // 2^31-1\n    static const uint64_t A = 16807;  // bits 14, 8, 7, 5, 2, 1, 0\n    // We are computing\n    //       seed_ = (seed_ * A) % M,    where M = 2^31-1\n    //\n    // seed_ must not be zero or M, or else all subsequent computed values\n    // will be zero or M respectively.  For all other values, seed_ will end\n    // up cycling through every number in [1,M-1]\n    uint64_t product = seed_ * A;\n\n    // Compute (product % M) using the fact that ((x << 31) % M) == x.\n    seed_ = static_cast<uint32_t>((product >> 31) + (product & M));\n    // The first reduction may overflow by 1 bit, so we may need to\n    // repeat.  mod == M is not possible; using > allows the faster\n    // sign-bit-based test.\n    if (seed_ > M) {\n      seed_ -= M;\n    }\n    return seed_;\n  }\n  // Returns a uniformly distributed value in the range [0..n-1]\n  // REQUIRES: n > 0\n  uint32_t Uniform(int n) { return Next() % n; }\n\n  // Randomly returns true ~\"1/n\" of the time, and false otherwise.\n  // REQUIRES: n > 0\n  bool OneIn(int n) { return (Next() % n) == 0; }\n\n  // Skewed: pick \"base\" uniformly from range [0,max_log] and then\n  // return \"base\" random bits.  The effect is to pick a number in the\n  // range [0,2^max_log-1] with exponential bias towards smaller numbers.\n  uint32_t Skewed(int max_log) {\n    return Uniform(1 << Uniform(max_log + 1));\n  }\n};\n\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_UTIL_RANDOM_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/util/status.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include <stdio.h>\n#include \"port/port.h\"\n#include \"leveldb/status.h\"\n\nnamespace leveldb {\n\nconst char* Status::CopyState(const char* state) {\n  uint32_t size;\n  memcpy(&size, state, sizeof(size));\n  char* result = new char[size + 5];\n  memcpy(result, state, size + 5);\n  return result;\n}\n\nStatus::Status(Code code, const Slice& msg, const Slice& msg2) {\n  assert(code != kOk);\n  const uint32_t len1 = msg.size();\n  const uint32_t len2 = msg2.size();\n  const uint32_t size = len1 + (len2 ? (2 + len2) : 0);\n  char* result = new char[size + 5];\n  memcpy(result, &size, sizeof(size));\n  result[4] = static_cast<char>(code);\n  memcpy(result + 5, msg.data(), len1);\n  if (len2) {\n    result[5 + len1] = ':';\n    result[6 + len1] = ' ';\n    memcpy(result + 7 + len1, msg2.data(), len2);\n  }\n  state_ = result;\n}\n\nstd::string Status::ToString() const {\n  if (state_ == NULL) {\n    return \"OK\";\n  } else {\n    char tmp[30];\n    const char* type;\n    switch (code()) {\n      case kOk:\n        type = \"OK\";\n        break;\n      case kNotFound:\n        type = \"NotFound: \";\n        break;\n      case kCorruption:\n        type = \"Corruption: \";\n        break;\n      case kNotSupported:\n        type = \"Not implemented: \";\n        break;\n      case kInvalidArgument:\n        type = \"Invalid argument: \";\n        break;\n      case kIOError:\n        type = \"IO error: \";\n        break;\n      default:\n        snprintf(tmp, sizeof(tmp), \"Unknown code(%d): \",\n                 static_cast<int>(code()));\n        type = tmp;\n        break;\n    }\n    std::string result(type);\n    uint32_t length;\n    memcpy(&length, state_, sizeof(length));\n    result.append(state_ + 5, length);\n    return result;\n  }\n}\n\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/util/testharness.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"util/testharness.h\"\n\n#include <string>\n#include <stdlib.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n\nnamespace leveldb {\nnamespace test {\n\nnamespace {\nstruct Test {\n  const char* base;\n  const char* name;\n  void (*func)();\n};\nstd::vector<Test>* tests;\n}\n\nbool RegisterTest(const char* base, const char* name, void (*func)()) {\n  if (tests == NULL) {\n    tests = new std::vector<Test>;\n  }\n  Test t;\n  t.base = base;\n  t.name = name;\n  t.func = func;\n  tests->push_back(t);\n  return true;\n}\n\nint RunAllTests() {\n  const char* matcher = getenv(\"LEVELDB_TESTS\");\n\n  int num = 0;\n  if (tests != NULL) {\n    for (size_t i = 0; i < tests->size(); i++) {\n      const Test& t = (*tests)[i];\n      if (matcher != NULL) {\n        std::string name = t.base;\n        name.push_back('.');\n        name.append(t.name);\n        if (strstr(name.c_str(), matcher) == NULL) {\n          continue;\n        }\n      }\n      fprintf(stderr, \"==== Test %s.%s\\n\", t.base, t.name);\n      (*t.func)();\n      ++num;\n    }\n  }\n  fprintf(stderr, \"==== PASSED %d tests\\n\", num);\n  return 0;\n}\n\nstd::string TmpDir() {\n  std::string dir;\n  Status s = Env::Default()->GetTestDirectory(&dir);\n  ASSERT_TRUE(s.ok()) << s.ToString();\n  return dir;\n}\n\nint RandomSeed() {\n  const char* env = getenv(\"TEST_RANDOM_SEED\");\n  int result = (env != NULL ? atoi(env) : 301);\n  if (result <= 0) {\n    result = 301;\n  }\n  return result;\n}\n\n}  // namespace test\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/util/testharness.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_UTIL_TESTHARNESS_H_\n#define STORAGE_LEVELDB_UTIL_TESTHARNESS_H_\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <sstream>\n#include \"leveldb/env.h\"\n#include \"leveldb/slice.h\"\n#include \"util/random.h\"\n\nnamespace leveldb {\nnamespace test {\n\n// Run some of the tests registered by the TEST() macro.  If the\n// environment variable \"LEVELDB_TESTS\" is not set, runs all tests.\n// Otherwise, runs only the tests whose name contains the value of\n// \"LEVELDB_TESTS\" as a substring.  E.g., suppose the tests are:\n//    TEST(Foo, Hello) { ... }\n//    TEST(Foo, World) { ... }\n// LEVELDB_TESTS=Hello will run the first test\n// LEVELDB_TESTS=o     will run both tests\n// LEVELDB_TESTS=Junk  will run no tests\n//\n// Returns 0 if all tests pass.\n// Dies or returns a non-zero value if some test fails.\nextern int RunAllTests();\n\n// Return the directory to use for temporary storage.\nextern std::string TmpDir();\n\n// Return a randomization seed for this run.  Typically returns the\n// same number on repeated invocations of this binary, but automated\n// runs may be able to vary the seed.\nextern int RandomSeed();\n\n// An instance of Tester is allocated to hold temporary state during\n// the execution of an assertion.\nclass Tester {\n private:\n  bool ok_;\n  const char* fname_;\n  int line_;\n  std::stringstream ss_;\n\n public:\n  Tester(const char* f, int l)\n      : ok_(true), fname_(f), line_(l) {\n  }\n\n  ~Tester() {\n    if (!ok_) {\n      fprintf(stderr, \"%s:%d:%s\\n\", fname_, line_, ss_.str().c_str());\n      exit(1);\n    }\n  }\n\n  Tester& Is(bool b, const char* msg) {\n    if (!b) {\n      ss_ << \" Assertion failure \" << msg;\n      ok_ = false;\n    }\n    return *this;\n  }\n\n  Tester& IsOk(const Status& s) {\n    if (!s.ok()) {\n      ss_ << \" \" << s.ToString();\n      ok_ = false;\n    }\n    return *this;\n  }\n\n#define BINARY_OP(name,op)                              \\\n  template <class X, class Y>                           \\\n  Tester& name(const X& x, const Y& y) {                \\\n    if (! (x op y)) {                                   \\\n      ss_ << \" failed: \" << x << (\" \" #op \" \") << y;    \\\n      ok_ = false;                                      \\\n    }                                                   \\\n    return *this;                                       \\\n  }\n\n  BINARY_OP(IsEq, ==)\n  BINARY_OP(IsNe, !=)\n  BINARY_OP(IsGe, >=)\n  BINARY_OP(IsGt, >)\n  BINARY_OP(IsLe, <=)\n  BINARY_OP(IsLt, <)\n#undef BINARY_OP\n\n  // Attach the specified value to the error message if an error has occurred\n  template <class V>\n  Tester& operator<<(const V& value) {\n    if (!ok_) {\n      ss_ << \" \" << value;\n    }\n    return *this;\n  }\n};\n\n#define ASSERT_TRUE(c) ::leveldb::test::Tester(__FILE__, __LINE__).Is((c), #c)\n#define ASSERT_OK(s) ::leveldb::test::Tester(__FILE__, __LINE__).IsOk((s))\n#define ASSERT_EQ(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsEq((a),(b))\n#define ASSERT_NE(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsNe((a),(b))\n#define ASSERT_GE(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsGe((a),(b))\n#define ASSERT_GT(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsGt((a),(b))\n#define ASSERT_LE(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsLe((a),(b))\n#define ASSERT_LT(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsLt((a),(b))\n\n#define TCONCAT(a,b) TCONCAT1(a,b)\n#define TCONCAT1(a,b) a##b\n\n#define TEST(base,name)                                                 \\\nclass TCONCAT(_Test_,name) : public base {                              \\\n public:                                                                \\\n  void _Run();                                                          \\\n  static void _RunIt() {                                                \\\n    TCONCAT(_Test_,name) t;                                             \\\n    t._Run();                                                           \\\n  }                                                                     \\\n};                                                                      \\\nbool TCONCAT(_Test_ignored_,name) =                                     \\\n  ::leveldb::test::RegisterTest(#base, #name, &TCONCAT(_Test_,name)::_RunIt); \\\nvoid TCONCAT(_Test_,name)::_Run()\n\n// Register the specified test.  Typically not used directly, but\n// invoked via the macro expansion of TEST.\nextern bool RegisterTest(const char* base, const char* name, void (*func)());\n\n\n}  // namespace test\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_UTIL_TESTHARNESS_H_\n"
  },
  {
    "path": "deps/leveldb-1.20/util/testutil.cc",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#include \"util/testutil.h\"\n\n#include \"util/random.h\"\n\nnamespace leveldb {\nnamespace test {\n\nSlice RandomString(Random* rnd, int len, std::string* dst) {\n  dst->resize(len);\n  for (int i = 0; i < len; i++) {\n    (*dst)[i] = static_cast<char>(' ' + rnd->Uniform(95));   // ' ' .. '~'\n  }\n  return Slice(*dst);\n}\n\nstd::string RandomKey(Random* rnd, int len) {\n  // Make sure to generate a wide variety of characters so we\n  // test the boundary conditions for short-key optimizations.\n  static const char kTestChars[] = {\n    '\\0', '\\1', 'a', 'b', 'c', 'd', 'e', '\\xfd', '\\xfe', '\\xff'\n  };\n  std::string result;\n  for (int i = 0; i < len; i++) {\n    result += kTestChars[rnd->Uniform(sizeof(kTestChars))];\n  }\n  return result;\n}\n\n\nextern Slice CompressibleString(Random* rnd, double compressed_fraction,\n                                size_t len, std::string* dst) {\n  int raw = static_cast<int>(len * compressed_fraction);\n  if (raw < 1) raw = 1;\n  std::string raw_data;\n  RandomString(rnd, raw, &raw_data);\n\n  // Duplicate the random data until we have filled \"len\" bytes\n  dst->clear();\n  while (dst->size() < len) {\n    dst->append(raw_data);\n  }\n  dst->resize(len);\n  return Slice(*dst);\n}\n\n}  // namespace test\n}  // namespace leveldb\n"
  },
  {
    "path": "deps/leveldb-1.20/util/testutil.h",
    "content": "// Copyright (c) 2011 The LevelDB Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file. See the AUTHORS file for names of contributors.\n\n#ifndef STORAGE_LEVELDB_UTIL_TESTUTIL_H_\n#define STORAGE_LEVELDB_UTIL_TESTUTIL_H_\n\n#include \"leveldb/env.h\"\n#include \"leveldb/slice.h\"\n#include \"util/random.h\"\n\nnamespace leveldb {\nnamespace test {\n\n// Store in *dst a random string of length \"len\" and return a Slice that\n// references the generated data.\nextern Slice RandomString(Random* rnd, int len, std::string* dst);\n\n// Return a random key with the specified length that may contain interesting\n// characters (e.g. \\x00, \\xff, etc.).\nextern std::string RandomKey(Random* rnd, int len);\n\n// Store in *dst a string of length \"len\" that will compress to\n// \"N*compressed_fraction\" bytes and return a Slice that references\n// the generated data.\nextern Slice CompressibleString(Random* rnd, double compressed_fraction,\n                                size_t len, std::string* dst);\n\n// A wrapper that allows injection of errors.\nclass ErrorEnv : public EnvWrapper {\n public:\n  bool writable_file_error_;\n  int num_writable_file_errors_;\n\n  ErrorEnv() : EnvWrapper(Env::Default()),\n               writable_file_error_(false),\n               num_writable_file_errors_(0) { }\n\n  virtual Status NewWritableFile(const std::string& fname,\n                                 WritableFile** result) {\n    if (writable_file_error_) {\n      ++num_writable_file_errors_;\n      *result = NULL;\n      return Status::IOError(fname, \"fake error\");\n    }\n    return target()->NewWritableFile(fname, result);\n  }\n\n  virtual Status NewAppendableFile(const std::string& fname,\n                                   WritableFile** result) {\n    if (writable_file_error_) {\n      ++num_writable_file_errors_;\n      *result = NULL;\n      return Status::IOError(fname, \"fake error\");\n    }\n    return target()->NewAppendableFile(fname, result);\n  }\n};\n\n}  // namespace test\n}  // namespace leveldb\n\n#endif  // STORAGE_LEVELDB_UTIL_TESTUTIL_H_\n"
  },
  {
    "path": "deps/snappy-1.1.0/.gitignore",
    "content": "*.lo\n*.libs\n*.deps\n*.la\n*.o\nMakefile\nconfig.h\nconfig.log\nconfig.status\nlibtool\nsnappy_unittest\nstamp-h1\ntestdata\n\n\n"
  },
  {
    "path": "deps/snappy-1.1.0/AUTHORS",
    "content": "opensource@google.com\n"
  },
  {
    "path": "deps/snappy-1.1.0/COPYING",
    "content": "Copyright 2011, 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": "deps/snappy-1.1.0/ChangeLog",
    "content": "------------------------------------------------------------------------\nr72 | snappy.mirrorbot@gmail.com | 2013-02-05 15:30:05 +0100 (Tue, 05 Feb 2013) | 9 lines\n\nMake ./snappy_unittest pass without \"srcdir\" being defined.\n\nPreviously, snappy_unittests would read from an absolute path /testdata/..;\nconvert it to use a relative path instead.\n\nPatch from Marc-Antonie Ruel.\n\nR=maruel\n\n------------------------------------------------------------------------\nr71 | snappy.mirrorbot@gmail.com | 2013-01-18 13:16:36 +0100 (Fri, 18 Jan 2013) | 287 lines\n\nIncrease the Zippy block size from 32 kB to 64 kB, winning ~3% density\nwhile being effectively performance neutral.\n\nThe longer story about density is that we win 3-6% density on the benchmarks \nwhere this has any effect at all; many of the benchmarks (cp, c, lsp, man)\nare smaller than 32 kB and thus will have no effect. Binary data also seems\nto win little or nothing; of course, the already-compressed data wins nothing.\nThe protobuf benchmark wins as much as ~18% depending on architecture,\nbut I wouldn't be too sure that this is representative of protobuf data in\ngeneral.\n\nAs of performance, we lose a tiny amount since we get more tags (e.g., a long\nliteral might be broken up into literal-copy-literal), but we win it back with\nless clearing of the hash table, and more opportunities to skip incompressible\ndata (e.g. in the jpg benchmark). Decompression seems to get ever so slightly\nslower, again due to more tags. The total net change is about as close to zero\nas we can get, so the end effect seems to be simply more density and no\nreal performance change.\n\nThe comment about not changing kBlockSize, scary as it is, is not really\nrelevant, since we're never going to have a block-level decompressor without\nexplicitly marked blocks. Replace it with something more appropriate.\n\nThis affects the framing format, but it's okay to change it since it basically\nhas no users yet.\n\n\nDensity (note that cp, c, lsp and man are all smaller than 32 kB):\n\n   Benchmark         Description   Base (%)  New (%)  Improvement\n   --------------------------------------------------------------\n   ZFlat/0           html            22.57    22.31     +5.6%\n   ZFlat/1           urls            50.89    47.77     +6.5%\n   ZFlat/2           jpg             99.88    99.87     +0.0%\n   ZFlat/3           pdf             82.13    82.07     +0.1%\n   ZFlat/4           html4           23.55    22.51     +4.6%\n   ZFlat/5           cp              48.12    48.12     +0.0%\n   ZFlat/6           c               42.40    42.40     +0.0%\n   ZFlat/7           lsp             48.37    48.37     +0.0%\n   ZFlat/8           xls             41.34    41.23     +0.3%\n   ZFlat/9           txt1            59.81    57.87     +3.4%\n   ZFlat/10          txt2            64.07    61.93     +3.5%\n   ZFlat/11          txt3            57.11    54.92     +4.0%\n   ZFlat/12          txt4            68.35    66.22     +3.2%\n   ZFlat/13          bin             18.21    18.11     +0.6%\n   ZFlat/14          sum             51.88    48.96     +6.0%\n   ZFlat/15          man             59.36    59.36     +0.0%\n   ZFlat/16          pb              23.15    19.64    +17.9%\n   ZFlat/17          gaviota         38.27    37.72     +1.5%\n   Geometric mean                    45.51    44.15     +3.1%\n\n\nMicrobenchmarks (64-bit, opt):\n\nWestmere 2.8 GHz:\n\n   Benchmark                          Base (ns)  New (ns)                                Improvement\n   -------------------------------------------------------------------------------------------------\n   BM_UFlat/0                             75342     75027  1.3GB/s  html                    +0.4%\n   BM_UFlat/1                            723767    744269  899.6MB/s  urls                  -2.8%\n   BM_UFlat/2                             10072     10072  11.7GB/s  jpg                    +0.0%\n   BM_UFlat/3                             30747     30388  2.9GB/s  pdf                     +1.2%\n   BM_UFlat/4                            307353    306063  1.2GB/s  html4                   +0.4%\n   BM_UFlat/5                             28593     28743  816.3MB/s  cp                    -0.5%\n   BM_UFlat/6                             12958     12998  818.1MB/s  c                     -0.3%\n   BM_UFlat/7                              3700      3792  935.8MB/s  lsp                   -2.4%\n   BM_UFlat/8                            999685    999905  982.1MB/s  xls                   -0.0%\n   BM_UFlat/9                            232954    230079  630.4MB/s  txt1                  +1.2%\n   BM_UFlat/10                           200785    201468  592.6MB/s  txt2                  -0.3%\n   BM_UFlat/11                           617267    610968  666.1MB/s  txt3                  +1.0%\n   BM_UFlat/12                           821595    822475  558.7MB/s  txt4                  -0.1%\n   BM_UFlat/13                           377097    377632  1.3GB/s  bin                     -0.1%\n   BM_UFlat/14                            45476     45260  805.8MB/s  sum                   +0.5%\n   BM_UFlat/15                             4985      5003  805.7MB/s  man                   -0.4%\n   BM_UFlat/16                            80813     77494  1.4GB/s  pb                      +4.3%\n   BM_UFlat/17                           251792    241553  727.7MB/s  gaviota               +4.2%\n   BM_UValidate/0                         40343     40354  2.4GB/s  html                    -0.0%\n   BM_UValidate/1                        426890    451574  1.4GB/s  urls                    -5.5%\n   BM_UValidate/2                           187       179  661.9GB/s  jpg                   +4.5%\n   BM_UValidate/3                         13783     13827  6.4GB/s  pdf                     -0.3%\n   BM_UValidate/4                        162393    163335  2.3GB/s  html4                   -0.6%\n   BM_UDataBuffer/0                       93756     93302  1046.7MB/s  html                 +0.5%\n   BM_UDataBuffer/1                      886714    916292  730.7MB/s  urls                  -3.2%\n   BM_UDataBuffer/2                       15861     16401  7.2GB/s  jpg                     -3.3%\n   BM_UDataBuffer/3                       38934     39224  2.2GB/s  pdf                     -0.7%\n   BM_UDataBuffer/4                      381008    379428  1029.5MB/s  html4                +0.4%\n   BM_UCord/0                             92528     91098  1072.0MB/s  html                 +1.6%\n   BM_UCord/1                            858421    885287  756.3MB/s  urls                  -3.0%\n   BM_UCord/2                             13140     13464  8.8GB/s  jpg                     -2.4%\n   BM_UCord/3                             39012     37773  2.3GB/s  pdf                     +3.3%\n   BM_UCord/4                            376869    371267  1052.1MB/s  html4                +1.5%\n   BM_UCordString/0                       75810     75303  1.3GB/s  html                    +0.7%\n   BM_UCordString/1                      735290    753841  888.2MB/s  urls                  -2.5%\n   BM_UCordString/2                       11945     13113  9.0GB/s  jpg                     -8.9%\n   BM_UCordString/3                       33901     32562  2.7GB/s  pdf                     +4.1%\n   BM_UCordString/4                      310985    309390  1.2GB/s  html4                   +0.5%\n   BM_UCordValidate/0                     40952     40450  2.4GB/s  html                    +1.2%\n   BM_UCordValidate/1                    433842    456531  1.4GB/s  urls                    -5.0%\n   BM_UCordValidate/2                      1179      1173  100.8GB/s  jpg                   +0.5%\n   BM_UCordValidate/3                     14481     14392  6.1GB/s  pdf                     +0.6%\n   BM_UCordValidate/4                    164364    164151  2.3GB/s  html4                   +0.1%\n   BM_ZFlat/0                            160610    156601  623.6MB/s  html (22.31 %)        +2.6%\n   BM_ZFlat/1                           1995238   1993582  335.9MB/s  urls (47.77 %)        +0.1%\n   BM_ZFlat/2                             30133     24983  4.7GB/s  jpg (99.87 %)          +20.6%\n   BM_ZFlat/3                             74453     73128  1.2GB/s  pdf (82.07 %)           +1.8%\n   BM_ZFlat/4                            647674    633729  616.4MB/s  html4 (22.51 %)       +2.2%\n   BM_ZFlat/5                             76259     76090  308.4MB/s  cp (48.12 %)          +0.2%\n   BM_ZFlat/6                             31106     31084  342.1MB/s  c (42.40 %)           +0.1%\n   BM_ZFlat/7                             10507     10443  339.8MB/s  lsp (48.37 %)         +0.6%\n   BM_ZFlat/8                           1811047   1793325  547.6MB/s  xls (41.23 %)         +1.0%\n   BM_ZFlat/9                            597903    581793  249.3MB/s  txt1 (57.87 %)        +2.8%\n   BM_ZFlat/10                           525320    514522  232.0MB/s  txt2 (61.93 %)        +2.1%\n   BM_ZFlat/11                          1596591   1551636  262.3MB/s  txt3 (54.92 %)        +2.9%\n   BM_ZFlat/12                          2134523   2094033  219.5MB/s  txt4 (66.22 %)        +1.9%\n   BM_ZFlat/13                           593024    587869  832.6MB/s  bin (18.11 %)         +0.9%\n   BM_ZFlat/14                           114746    110666  329.5MB/s  sum (48.96 %)         +3.7%\n   BM_ZFlat/15                            14376     14485  278.3MB/s  man (59.36 %)         -0.8%\n   BM_ZFlat/16                           167908    150070  753.6MB/s  pb (19.64 %)         +11.9%\n   BM_ZFlat/17                           460228    442253  397.5MB/s  gaviota (37.72 %)     +4.1%\n   BM_ZCord/0                            164896    160241  609.4MB/s  html                  +2.9%\n   BM_ZCord/1                           2070239   2043492  327.7MB/s  urls                  +1.3%\n   BM_ZCord/2                             54402     47002  2.5GB/s  jpg                    +15.7%\n   BM_ZCord/3                             85871     83832  1073.1MB/s  pdf                  +2.4%\n   BM_ZCord/4                            664078    648825  602.0MB/s  html4                 +2.4%\n   BM_ZDataBuffer/0                      174874    172549  566.0MB/s  html                  +1.3%\n   BM_ZDataBuffer/1                     2134410   2139173  313.0MB/s  urls                  -0.2%\n   BM_ZDataBuffer/2                       71911     69551  1.7GB/s  jpg                     +3.4%\n   BM_ZDataBuffer/3                       98236     99727  902.1MB/s  pdf                   -1.5%\n   BM_ZDataBuffer/4                      710776    699104  558.8MB/s  html4                 +1.7%\n   Sum of all benchmarks               27358908  27200688                                   +0.6%\n\n\nSandy Bridge 2.6 GHz:\n\n   Benchmark                          Base (ns)  New (ns)                                Improvement\n   -------------------------------------------------------------------------------------------------\n   BM_UFlat/0                             49356     49018  1.9GB/s  html                    +0.7%\n   BM_UFlat/1                            516764    531955  1.2GB/s  urls                    -2.9%\n   BM_UFlat/2                              6982      7304  16.2GB/s  jpg                    -4.4%\n   BM_UFlat/3                             15285     15598  5.6GB/s  pdf                     -2.0%\n   BM_UFlat/4                            206557    206669  1.8GB/s  html4                   -0.1%\n   BM_UFlat/5                             13681     13567  1.7GB/s  cp                      +0.8%\n   BM_UFlat/6                              6571      6592  1.6GB/s  c                       -0.3%\n   BM_UFlat/7                              2008      1994  1.7GB/s  lsp                     +0.7%\n   BM_UFlat/8                            775700    773286  1.2GB/s  xls                     +0.3%\n   BM_UFlat/9                            165578    164480  881.8MB/s  txt1                  +0.7%\n   BM_UFlat/10                           143707    144139  828.2MB/s  txt2                  -0.3%\n   BM_UFlat/11                           443026    436281  932.8MB/s  txt3                  +1.5%\n   BM_UFlat/12                           603129    595856  771.2MB/s  txt4                  +1.2%\n   BM_UFlat/13                           271682    270450  1.8GB/s  bin                     +0.5%\n   BM_UFlat/14                            26200     25666  1.4GB/s  sum                     +2.1%\n   BM_UFlat/15                             2620      2608  1.5GB/s  man                     +0.5%\n   BM_UFlat/16                            48908     47756  2.3GB/s  pb                      +2.4%\n   BM_UFlat/17                           174638    170346  1031.9MB/s  gaviota              +2.5%\n   BM_UValidate/0                         31922     31898  3.0GB/s  html                    +0.1%\n   BM_UValidate/1                        341265    363554  1.8GB/s  urls                    -6.1%\n   BM_UValidate/2                           160       151  782.8GB/s  jpg                   +6.0%\n   BM_UValidate/3                         10402     10380  8.5GB/s  pdf                     +0.2%\n   BM_UValidate/4                        129490    130587  2.9GB/s  html4                   -0.8%\n   BM_UDataBuffer/0                       59383     58736  1.6GB/s  html                    +1.1%\n   BM_UDataBuffer/1                      619222    637786  1049.8MB/s  urls                 -2.9%\n   BM_UDataBuffer/2                       10775     11941  9.9GB/s  jpg                     -9.8%\n   BM_UDataBuffer/3                       18002     17930  4.9GB/s  pdf                     +0.4%\n   BM_UDataBuffer/4                      259182    259306  1.5GB/s  html4                   -0.0%\n   BM_UCord/0                             59379     57814  1.6GB/s  html                    +2.7%\n   BM_UCord/1                            598456    615162  1088.4MB/s  urls                 -2.7%\n   BM_UCord/2                              8519      8628  13.7GB/s  jpg                    -1.3%\n   BM_UCord/3                             18123     17537  5.0GB/s  pdf                     +3.3%\n   BM_UCord/4                            252375    252331  1.5GB/s  html4                   +0.0%\n   BM_UCordString/0                       49494     49790  1.9GB/s  html                    -0.6%\n   BM_UCordString/1                      524659    541803  1.2GB/s  urls                    -3.2%\n   BM_UCordString/2                        8206      8354  14.2GB/s  jpg                    -1.8%\n   BM_UCordString/3                       17235     16537  5.3GB/s  pdf                     +4.2%\n   BM_UCordString/4                      210188    211072  1.8GB/s  html4                   -0.4%\n   BM_UCordValidate/0                     31956     31587  3.0GB/s  html                    +1.2%\n   BM_UCordValidate/1                    340828    362141  1.8GB/s  urls                    -5.9%\n   BM_UCordValidate/2                       783       744  158.9GB/s  jpg                   +5.2%\n   BM_UCordValidate/3                     10543     10462  8.4GB/s  pdf                     +0.8%\n   BM_UCordValidate/4                    130150    129789  2.9GB/s  html4                   +0.3%\n   BM_ZFlat/0                            113873    111200  878.2MB/s  html (22.31 %)        +2.4%\n   BM_ZFlat/1                           1473023   1489858  449.4MB/s  urls (47.77 %)        -1.1%\n   BM_ZFlat/2                             23569     19486  6.1GB/s  jpg (99.87 %)          +21.0%\n   BM_ZFlat/3                             49178     48046  1.8GB/s  pdf (82.07 %)           +2.4%\n   BM_ZFlat/4                            475063    469394  832.2MB/s  html4 (22.51 %)       +1.2%\n   BM_ZFlat/5                             46910     46816  501.2MB/s  cp (48.12 %)          +0.2%\n   BM_ZFlat/6                             16883     16916  628.6MB/s  c (42.40 %)           -0.2%\n   BM_ZFlat/7                              5381      5447  651.5MB/s  lsp (48.37 %)         -1.2%\n   BM_ZFlat/8                           1466870   1473861  666.3MB/s  xls (41.23 %)         -0.5%\n   BM_ZFlat/9                            468006    464101  312.5MB/s  txt1 (57.87 %)        +0.8%\n   BM_ZFlat/10                           408157    408957  291.9MB/s  txt2 (61.93 %)        -0.2%\n   BM_ZFlat/11                          1253348   1232910  330.1MB/s  txt3 (54.92 %)        +1.7%\n   BM_ZFlat/12                          1702373   1702977  269.8MB/s  txt4 (66.22 %)        -0.0%\n   BM_ZFlat/13                           439792    438557  1116.0MB/s  bin (18.11 %)        +0.3%\n   BM_ZFlat/14                            80766     78851  462.5MB/s  sum (48.96 %)         +2.4%\n   BM_ZFlat/15                             7420      7542  534.5MB/s  man (59.36 %)         -1.6%\n   BM_ZFlat/16                           112043    100126  1.1GB/s  pb (19.64 %)           +11.9%\n   BM_ZFlat/17                           368877    357703  491.4MB/s  gaviota (37.72 %)     +3.1%\n   BM_ZCord/0                            116402    113564  859.9MB/s  html                  +2.5%\n   BM_ZCord/1                           1507156   1519911  440.5MB/s  urls                  -0.8%\n   BM_ZCord/2                             39860     33686  3.5GB/s  jpg                    +18.3%\n   BM_ZCord/3                             56211     54694  1.6GB/s  pdf                     +2.8%\n   BM_ZCord/4                            485594    479212  815.1MB/s  html4                 +1.3%\n   BM_ZDataBuffer/0                      123185    121572  803.3MB/s  html                  +1.3%\n   BM_ZDataBuffer/1                     1569111   1589380  421.3MB/s  urls                  -1.3%\n   BM_ZDataBuffer/2                       53143     49556  2.4GB/s  jpg                     +7.2%\n   BM_ZDataBuffer/3                       65725     66826  1.3GB/s  pdf                     -1.6%\n   BM_ZDataBuffer/4                      517871    514750  758.9MB/s  html4                 +0.6%\n   Sum of all benchmarks               20258879  20315484                                   -0.3%\n\n\nAMD Instanbul 2.4 GHz:\n\n   Benchmark                          Base (ns)  New (ns)                                Improvement\n   -------------------------------------------------------------------------------------------------\n   BM_UFlat/0                             97120     96585  1011.1MB/s  html                 +0.6%\n   BM_UFlat/1                            917473    948016  706.3MB/s  urls                  -3.2%\n   BM_UFlat/2                             21496     23938  4.9GB/s  jpg                    -10.2%\n   BM_UFlat/3                             44751     45639  1.9GB/s  pdf                     -1.9%\n   BM_UFlat/4                            391950    391413  998.0MB/s  html4                 +0.1%\n   BM_UFlat/5                             37366     37201  630.7MB/s  cp                    +0.4%\n   BM_UFlat/6                             18350     18318  580.5MB/s  c                     +0.2%\n   BM_UFlat/7                              5672      5661  626.9MB/s  lsp                   +0.2%\n   BM_UFlat/8                           1533390   1529441  642.1MB/s  xls                   +0.3%\n   BM_UFlat/9                            335477    336553  431.0MB/s  txt1                  -0.3%\n   BM_UFlat/10                           285140    292080  408.7MB/s  txt2                  -2.4%\n   BM_UFlat/11                           888507    894758  454.9MB/s  txt3                  -0.7%\n   BM_UFlat/12                          1187643   1210928  379.5MB/s  txt4                  -1.9%\n   BM_UFlat/13                           493717    507447  964.5MB/s  bin                   -2.7%\n   BM_UFlat/14                            61740     60870  599.1MB/s  sum                   +1.4%\n   BM_UFlat/15                             7211      7187  560.9MB/s  man                   +0.3%\n   BM_UFlat/16                            97435     93100  1.2GB/s  pb                      +4.7%\n   BM_UFlat/17                           362662    356395  493.2MB/s  gaviota               +1.8%\n   BM_UValidate/0                         47475     47118  2.0GB/s  html                    +0.8%\n   BM_UValidate/1                        501304    529741  1.2GB/s  urls                    -5.4%\n   BM_UValidate/2                           276       243  486.2GB/s  jpg                  +13.6%\n   BM_UValidate/3                         16361     16261  5.4GB/s  pdf                     +0.6%\n   BM_UValidate/4                        190741    190353  2.0GB/s  html4                   +0.2%\n   BM_UDataBuffer/0                      111080    109771  889.6MB/s  html                  +1.2%\n   BM_UDataBuffer/1                     1051035   1085999  616.5MB/s  urls                  -3.2%\n   BM_UDataBuffer/2                       25801     25463  4.6GB/s  jpg                     +1.3%\n   BM_UDataBuffer/3                       50493     49946  1.8GB/s  pdf                     +1.1%\n   BM_UDataBuffer/4                      447258    444138  879.5MB/s  html4                 +0.7%\n   BM_UCord/0                            109350    107909  905.0MB/s  html                  +1.3%\n   BM_UCord/1                           1023396   1054964  634.7MB/s  urls                  -3.0%\n   BM_UCord/2                             25292     24371  4.9GB/s  jpg                     +3.8%\n   BM_UCord/3                             48955     49736  1.8GB/s  pdf                     -1.6%\n   BM_UCord/4                            440452    437331  893.2MB/s  html4                 +0.7%\n   BM_UCordString/0                       98511     98031  996.2MB/s  html                  +0.5%\n   BM_UCordString/1                      933230    963495  694.9MB/s  urls                  -3.1%\n   BM_UCordString/2                       23311     24076  4.9GB/s  jpg                     -3.2%\n   BM_UCordString/3                       45568     46196  1.9GB/s  pdf                     -1.4%\n   BM_UCordString/4                      397791    396934  984.1MB/s  html4                 +0.2%\n   BM_UCordValidate/0                     47537     46921  2.0GB/s  html                    +1.3%\n   BM_UCordValidate/1                    505071    532716  1.2GB/s  urls                    -5.2%\n   BM_UCordValidate/2                      1663      1621  72.9GB/s  jpg                    +2.6%\n   BM_UCordValidate/3                     16890     16926  5.2GB/s  pdf                     -0.2%\n   BM_UCordValidate/4                    192365    191984  2.0GB/s  html4                   +0.2%\n   BM_ZFlat/0                            184708    179103  545.3MB/s  html (22.31 %)        +3.1%\n   BM_ZFlat/1                           2293864   2302950  290.7MB/s  urls (47.77 %)        -0.4%\n   BM_ZFlat/2                             52852     47618  2.5GB/s  jpg (99.87 %)          +11.0%\n   BM_ZFlat/3                            100766     96179  935.3MB/s  pdf (82.07 %)         +4.8%\n   BM_ZFlat/4                            741220    727977  536.6MB/s  html4 (22.51 %)       +1.8%\n   BM_ZFlat/5                             85402     85418  274.7MB/s  cp (48.12 %)          -0.0%\n   BM_ZFlat/6                             36558     36494  291.4MB/s  c (42.40 %)           +0.2%\n   BM_ZFlat/7                             12706     12507  283.7MB/s  lsp (48.37 %)         +1.6%\n   BM_ZFlat/8                           2336823   2335688  420.5MB/s  xls (41.23 %)         +0.0%\n   BM_ZFlat/9                            701804    681153  212.9MB/s  txt1 (57.87 %)        +3.0%\n   BM_ZFlat/10                           606700    597194  199.9MB/s  txt2 (61.93 %)        +1.6%\n   BM_ZFlat/11                          1852283   1803238  225.7MB/s  txt3 (54.92 %)        +2.7%\n   BM_ZFlat/12                          2475527   2443354  188.1MB/s  txt4 (66.22 %)        +1.3%\n   BM_ZFlat/13                           694497    696654  702.6MB/s  bin (18.11 %)         -0.3%\n   BM_ZFlat/14                           136929    129855  280.8MB/s  sum (48.96 %)         +5.4%\n   BM_ZFlat/15                            17172     17124  235.4MB/s  man (59.36 %)         +0.3%\n   BM_ZFlat/16                           190364    171763  658.4MB/s  pb (19.64 %)         +10.8%\n   BM_ZFlat/17                           567285    555190  316.6MB/s  gaviota (37.72 %)     +2.2%\n   BM_ZCord/0                            193490    187031  522.1MB/s  html                  +3.5%\n   BM_ZCord/1                           2427537   2415315  277.2MB/s  urls                  +0.5%\n   BM_ZCord/2                             85378     81412  1.5GB/s  jpg                     +4.9%\n   BM_ZCord/3                            121898    119419  753.3MB/s  pdf                   +2.1%\n   BM_ZCord/4                            779564    762961  512.0MB/s  html4                 +2.2%\n   BM_ZDataBuffer/0                      213820    207272  471.1MB/s  html                  +3.2%\n   BM_ZDataBuffer/1                     2589010   2586495  258.9MB/s  urls                  +0.1%\n   BM_ZDataBuffer/2                      121871    118885  1018.4MB/s  jpg                  +2.5%\n   BM_ZDataBuffer/3                      145382    145986  616.2MB/s  pdf                   -0.4%\n   BM_ZDataBuffer/4                      868117    852754  458.1MB/s  html4                 +1.8%\n   Sum of all benchmarks               33771833  33744763                                   +0.1%\n\n------------------------------------------------------------------------\nr70 | snappy.mirrorbot@gmail.com | 2013-01-06 20:21:26 +0100 (Sun, 06 Jan 2013) | 6 lines\n\nAdjust the Snappy open-source distribution for the changes in Google's\ninternal file API.\n\nR=sanjay\n\n\n------------------------------------------------------------------------\nr69 | snappy.mirrorbot@gmail.com | 2013-01-04 12:54:20 +0100 (Fri, 04 Jan 2013) | 15 lines\n\nChange a few ORs to additions where they don't matter. This helps the compiler\nuse the LEA instruction more efficiently, since e.g. a + (b << 2) can be encoded\nas one instruction. Even more importantly, it can constant-fold the\nCOPY_* enums together with the shifted negative constants, which also saves\nsome instructions. (We don't need it for LITERAL, since it happens to be 0.)\n\nI am unsure why the compiler couldn't do this itself, but the theory is that\nit cannot prove that len-1 and len-4 cannot underflow/wrap, and thus can't\ndo the optimization safely.\n\nThe gains are small but measurable; 0.5-1.0% over the BM_Z* benchmarks\n(measured on Westmere, Sandy Bridge and Istanbul).\n\nR=sanjay\n\n------------------------------------------------------------------------\nr68 | snappy.mirrorbot@gmail.com | 2012-10-08 13:37:16 +0200 (Mon, 08 Oct 2012) | 5 lines\n\nStop giving -Werror to automake, due to an incompatibility between current\nversions of libtool and automake on non-GNU platforms (e.g. Mac OS X).\n\nR=sanjay\n\n------------------------------------------------------------------------\nr67 | snappy.mirrorbot@gmail.com | 2012-08-17 15:54:47 +0200 (Fri, 17 Aug 2012) | 5 lines\n\nFix public issue 66: Document GetUncompressedLength better, in particular that\nit leaves the source in a state that's not appropriate for RawUncompress.\n\nR=sanjay\n\n------------------------------------------------------------------------\nr66 | snappy.mirrorbot@gmail.com | 2012-07-31 13:44:44 +0200 (Tue, 31 Jul 2012) | 5 lines\n\nFix public issue 64: Check for <sys/time.h> at configure time,\nsince MSVC seemingly does not have it.\n\nR=sanjay\n\n------------------------------------------------------------------------\nr65 | snappy.mirrorbot@gmail.com | 2012-07-04 11:34:48 +0200 (Wed, 04 Jul 2012) | 10 lines\n\nHandle the case where gettimeofday() goes backwards or returns the same value\ntwice; it could cause division by zero in the unit test framework.\n(We already had one fix for this in place, but it was incomplete.)\n\nThis could in theory happen on any system, since there are few guarantees\nabout gettimeofday(), but seems to only happen in practice on GNU/Hurd, where\ngettimeofday() is cached and only updated ever so often.\n\nR=sanjay\n\n------------------------------------------------------------------------\nr64 | snappy.mirrorbot@gmail.com | 2012-07-04 11:28:33 +0200 (Wed, 04 Jul 2012) | 6 lines\n\nMark ARMv4 as not supporting unaligned accesses (not just ARMv5 and ARMv6);\napparently Debian still targets these by default, giving us segfaults on\narmel.\n\nR=sanjay\n\n------------------------------------------------------------------------\nr63 | snappy.mirrorbot@gmail.com | 2012-05-22 11:46:05 +0200 (Tue, 22 May 2012) | 5 lines\n\nFix public bug #62: Remove an extraneous comma at the end of an enum list,\ncausing compile errors when embedded in Mozilla on OpenBSD.\n\nR=sanjay\n\n------------------------------------------------------------------------\nr62 | snappy.mirrorbot@gmail.com | 2012-05-22 11:32:50 +0200 (Tue, 22 May 2012) | 8 lines\n\nSnappy library no longer depends on iostream.\n\nAchieved by moving logging macro definitions to a test-only\nheader file, and by changing non-test code to use assert,\nfprintf, and abort instead of LOG/CHECK macros.\n\nR=sesse\n\n------------------------------------------------------------------------\nr61 | snappy.mirrorbot@gmail.com | 2012-02-24 16:46:37 +0100 (Fri, 24 Feb 2012) | 4 lines\n\nRelease Snappy 1.0.5.\n\nR=sanjay\n\n------------------------------------------------------------------------\nr60 | snappy.mirrorbot@gmail.com | 2012-02-23 18:00:36 +0100 (Thu, 23 Feb 2012) | 57 lines\n\nFor 32-bit platforms, do not try to accelerate multiple neighboring\n32-bit loads with a 64-bit load during compression (it's not a win).\n\nThe main target for this optimization is ARM, but 32-bit x86 gets\na small gain, too, although there is noise in the microbenchmarks.\nIt's a no-op for 64-bit x86. It does not affect decompression.\n\nMicrobenchmark results on a Cortex-A9 1GHz, using g++ 4.6.2 (from\nUbuntu/Linaro), -O2 -DNDEBUG -Wa,-march=armv7a -mtune=cortex-a9\n-mthumb-interwork, minimum 1000 iterations:\n\n  Benchmark            Time(ns)    CPU(ns) Iterations\n  ---------------------------------------------------\n  BM_ZFlat/0            1158277    1160000       1000 84.2MB/s  html (23.57 %)    [ +4.3%]\n  BM_ZFlat/1           14861782   14860000       1000 45.1MB/s  urls (50.89 %)    [ +1.1%]\n  BM_ZFlat/2             393595     390000       1000 310.5MB/s  jpg (99.88 %)    [ +0.0%]\n  BM_ZFlat/3             650583     650000       1000 138.4MB/s  pdf (82.13 %)    [ +3.1%]\n  BM_ZFlat/4            4661480    4660000       1000 83.8MB/s  html4 (23.55 %)   [ +4.3%]\n  BM_ZFlat/5             491973     490000       1000 47.9MB/s  cp (48.12 %)      [ +2.0%]\n  BM_ZFlat/6             193575     192678       1038 55.2MB/s  c (42.40 %)       [ +9.0%]\n  BM_ZFlat/7              62343      62754       3187 56.5MB/s  lsp (48.37 %)     [ +2.6%]\n  BM_ZFlat/8           17708468   17710000       1000 55.5MB/s  xls (41.34 %)     [ -0.3%]\n  BM_ZFlat/9            3755345    3760000       1000 38.6MB/s  txt1 (59.81 %)    [ +8.2%]\n  BM_ZFlat/10           3324217    3320000       1000 36.0MB/s  txt2 (64.07 %)    [ +4.2%]\n  BM_ZFlat/11          10139932   10140000       1000 40.1MB/s  txt3 (57.11 %)    [ +6.4%]\n  BM_ZFlat/12          13532109   13530000       1000 34.0MB/s  txt4 (68.35 %)    [ +5.0%]\n  BM_ZFlat/13           4690847    4690000       1000 104.4MB/s  bin (18.21 %)    [ +4.1%]\n  BM_ZFlat/14            830682     830000       1000 43.9MB/s  sum (51.88 %)     [ +1.2%]\n  BM_ZFlat/15             84784      85011       2235 47.4MB/s  man (59.36 %)     [ +1.1%]\n  BM_ZFlat/16           1293254    1290000       1000 87.7MB/s  pb (23.15 %)      [ +2.3%]\n  BM_ZFlat/17           2775155    2780000       1000 63.2MB/s  gaviota (38.27 %) [+12.2%]\n\nCore i7 in 32-bit mode (only one run and 100 iterations, though, so noisy):\n\n  Benchmark            Time(ns)    CPU(ns) Iterations\n  ---------------------------------------------------\n  BM_ZFlat/0             227582     223464       3043 437.0MB/s  html (23.57 %)    [ +7.4%]\n  BM_ZFlat/1            2982430    2918455        233 229.4MB/s  urls (50.89 %)    [ +2.9%]\n  BM_ZFlat/2              46967      46658      15217 2.5GB/s  jpg (99.88 %)       [ +0.0%]\n  BM_ZFlat/3             115298     114864       5833 783.2MB/s  pdf (82.13 %)     [ +1.5%]\n  BM_ZFlat/4             913440     899743        778 434.2MB/s  html4 (23.55 %)   [ +0.3%]\n  BM_ZFlat/5             110302     108571       7000 216.1MB/s  cp (48.12 %)      [ +0.0%]\n  BM_ZFlat/6              44409      43372      15909 245.2MB/s  c (42.40 %)       [ +0.8%]\n  BM_ZFlat/7              15713      15643      46667 226.9MB/s  lsp (48.37 %)     [ +2.7%]\n  BM_ZFlat/8            2625539    2602230        269 377.4MB/s  xls (41.34 %)     [ +1.4%]\n  BM_ZFlat/9             808884     811429        875 178.8MB/s  txt1 (59.81 %)    [ -3.9%]\n  BM_ZFlat/10            709532     700000       1000 170.5MB/s  txt2 (64.07 %)    [ +0.0%]\n  BM_ZFlat/11           2177682    2162162        333 188.2MB/s  txt3 (57.11 %)    [ -1.4%]\n  BM_ZFlat/12           2849640    2840000        250 161.8MB/s  txt4 (68.35 %)    [ -1.4%]\n  BM_ZFlat/13            849760     835476        778 585.8MB/s  bin (18.21 %)     [ +1.2%]\n  BM_ZFlat/14            165940     164571       4375 221.6MB/s  sum (51.88 %)     [ +1.4%]\n  BM_ZFlat/15             20939      20571      35000 196.0MB/s  man (59.36 %)     [ +2.1%]\n  BM_ZFlat/16            239209     236544       2917 478.1MB/s  pb (23.15 %)      [ +4.2%]\n  BM_ZFlat/17            616206     610000       1000 288.2MB/s  gaviota (38.27 %) [ -1.6%]\n\nR=sanjay\n\n------------------------------------------------------------------------\nr59 | snappy.mirrorbot@gmail.com | 2012-02-21 18:02:17 +0100 (Tue, 21 Feb 2012) | 107 lines\n\nEnable the use of unaligned loads and stores for ARM-based architectures \nwhere they are available (ARMv7 and higher). This gives a significant \nspeed boost on ARM, both for compression and decompression. \nIt should not affect x86 at all. \n \nThere are more changes possible to speed up ARM, but it might not be \nthat easy to do without hurting x86 or making the code uglier. \nAlso, we de not try to use NEON yet. \n \nMicrobenchmark results on a Cortex-A9 1GHz, using g++ 4.6.2 (from Ubuntu/Linaro), \n-O2 -DNDEBUG -Wa,-march=armv7a -mtune=cortex-a9 -mthumb-interwork: \n \nBenchmark            Time(ns)    CPU(ns) Iterations\n---------------------------------------------------\nBM_UFlat/0             524806     529100        378 184.6MB/s  html            [+33.6%]\nBM_UFlat/1            5139790    5200000        100 128.8MB/s  urls            [+28.8%]\nBM_UFlat/2              86540      84166       1901 1.4GB/s  jpg               [ +0.6%]\nBM_UFlat/3             215351     210176        904 428.0MB/s  pdf             [+29.8%]\nBM_UFlat/4            2144490    2100000        100 186.0MB/s  html4           [+33.3%]\nBM_UFlat/5             194482     190000       1000 123.5MB/s  cp              [+36.2%]\nBM_UFlat/6              91843      90175       2107 117.9MB/s  c               [+38.6%]\nBM_UFlat/7              28535      28426       6684 124.8MB/s  lsp             [+34.7%]\nBM_UFlat/8            9206600    9200000        100 106.7MB/s  xls             [+42.4%]\nBM_UFlat/9            1865273    1886792        106 76.9MB/s  txt1             [+32.5%]\nBM_UFlat/10           1576809    1587301        126 75.2MB/s  txt2             [+32.3%]\nBM_UFlat/11           4968450    4900000        100 83.1MB/s  txt3             [+32.7%]\nBM_UFlat/12           6673970    6700000        100 68.6MB/s  txt4             [+32.8%]\nBM_UFlat/13           2391470    2400000        100 203.9MB/s  bin             [+29.2%]\nBM_UFlat/14            334601     344827        522 105.8MB/s  sum             [+30.6%]\nBM_UFlat/15             37404      38080       5252 105.9MB/s  man             [+33.8%]\nBM_UFlat/16            535470     540540        370 209.2MB/s  pb              [+31.2%]\nBM_UFlat/17           1875245    1886792        106 93.2MB/s  gaviota          [+37.8%]\nBM_UValidate/0         178425     179533       1114 543.9MB/s  html            [ +2.7%]\nBM_UValidate/1        2100450    2000000        100 334.8MB/s  urls            [ +5.0%]\nBM_UValidate/2           1039       1044     172413 113.3GB/s  jpg             [ +3.4%]\nBM_UValidate/3          59423      59470       3363 1.5GB/s  pdf               [ +7.8%]\nBM_UValidate/4         760716     766283        261 509.8MB/s  html4           [ +6.5%]\nBM_ZFlat/0            1204632    1204819        166 81.1MB/s  html (23.57 %)   [+32.8%]\nBM_ZFlat/1           15656190   15600000        100 42.9MB/s  urls (50.89 %)   [+27.6%]\nBM_ZFlat/2             403336     410677        487 294.8MB/s  jpg (99.88 %)   [+16.5%]\nBM_ZFlat/3             664073     671140        298 134.0MB/s  pdf (82.13 %)   [+28.4%]\nBM_ZFlat/4            4961940    4900000        100 79.7MB/s  html4 (23.55 %)  [+30.6%]\nBM_ZFlat/5             500664     501253        399 46.8MB/s  cp (48.12 %)     [+33.4%]\nBM_ZFlat/6             217276     215982        926 49.2MB/s  c (42.40 %)      [+25.0%]\nBM_ZFlat/7              64122      65487       3054 54.2MB/s  lsp (48.37 %)    [+36.1%]\nBM_ZFlat/8           18045730   18000000        100 54.6MB/s  xls (41.34 %)    [+34.4%]\nBM_ZFlat/9            4051530    4000000        100 36.3MB/s  txt1 (59.81 %)   [+25.0%]\nBM_ZFlat/10           3451800    3500000        100 34.1MB/s  txt2 (64.07 %)   [+25.7%]\nBM_ZFlat/11          11052340   11100000        100 36.7MB/s  txt3 (57.11 %)   [+24.3%]\nBM_ZFlat/12          14538690   14600000        100 31.5MB/s  txt4 (68.35 %)   [+24.7%]\nBM_ZFlat/13           5041850    5000000        100 97.9MB/s  bin (18.21 %)    [+32.0%]\nBM_ZFlat/14            908840     909090        220 40.1MB/s  sum (51.88 %)    [+22.2%]\nBM_ZFlat/15             86921      86206       1972 46.8MB/s  man (59.36 %)    [+42.2%]\nBM_ZFlat/16           1312315    1315789        152 86.0MB/s  pb (23.15 %)     [+34.5%]\nBM_ZFlat/17           3173120    3200000        100 54.9MB/s  gaviota (38.27%) [+28.1%]\n\n\nThe move from 64-bit to 32-bit operations for the copies also affected 32-bit x86;\npositive on the decompression side, and slightly negative on the compression side\n(unless that is noise; I only ran once):\n\nBenchmark              Time(ns)    CPU(ns) Iterations\n-----------------------------------------------------\nBM_UFlat/0                86279      86140       7778 1.1GB/s  html             [ +7.5%]\nBM_UFlat/1               839265     822622        778 813.9MB/s  urls           [ +9.4%]\nBM_UFlat/2                 9180       9143      87500 12.9GB/s  jpg             [ +1.2%]\nBM_UFlat/3                35080      35000      20000 2.5GB/s  pdf              [+10.1%]\nBM_UFlat/4               350318     345000       2000 1.1GB/s  html4            [ +7.0%]\nBM_UFlat/5                33808      33472      21212 701.0MB/s  cp             [ +9.0%]\nBM_UFlat/6                15201      15214      46667 698.9MB/s  c              [+14.9%]\nBM_UFlat/7                 4652       4651     159091 762.9MB/s  lsp            [ +7.5%]\nBM_UFlat/8              1285551    1282528        538 765.7MB/s  xls            [+10.7%]\nBM_UFlat/9               282510     281690       2414 514.9MB/s  txt1           [+13.6%]\nBM_UFlat/10              243494     239286       2800 498.9MB/s  txt2           [+14.4%]\nBM_UFlat/11              743625     740000       1000 550.0MB/s  txt3           [+14.3%]\nBM_UFlat/12              999441     989717        778 464.3MB/s  txt4           [+16.1%]\nBM_UFlat/13              412402     410076       1707 1.2GB/s  bin              [ +7.3%]\nBM_UFlat/14               54876      54000      10000 675.3MB/s  sum            [+13.0%]\nBM_UFlat/15                6146       6100     100000 660.8MB/s  man            [+14.8%]\nBM_UFlat/16               90496      90286       8750 1.2GB/s  pb               [ +4.0%]\nBM_UFlat/17              292650     292000       2500 602.0MB/s  gaviota        [+18.1%]\nBM_UValidate/0            49620      49699      14286 1.9GB/s  html             [ +0.0%]\nBM_UValidate/1           501371     500000       1000 1.3GB/s  urls             [ +0.0%]\nBM_UValidate/2              232        227    3043478 521.5GB/s  jpg            [ +1.3%]\nBM_UValidate/3            17250      17143      43750 5.1GB/s  pdf              [ -1.3%]\nBM_UValidate/4           198643     200000       3500 1.9GB/s  html4            [ -0.9%]\nBM_ZFlat/0               227128     229415       3182 425.7MB/s  html (23.57 %) [ -1.4%]\nBM_ZFlat/1              2970089    2960000        250 226.2MB/s  urls (50.89 %) [ -1.9%]\nBM_ZFlat/2                45683      44999      15556 2.6GB/s  jpg (99.88 %)    [ +2.2%]\nBM_ZFlat/3               114661     113136       6364 795.1MB/s  pdf (82.13 %)  [ -1.5%]\nBM_ZFlat/4               919702     914286        875 427.2MB/s  html4 (23.55%) [ -1.3%]\nBM_ZFlat/5               108189     108422       6364 216.4MB/s  cp (48.12 %)   [ -1.2%]\nBM_ZFlat/6                44525      44000      15909 241.7MB/s  c (42.40 %)    [ -2.9%]\nBM_ZFlat/7                15973      15857      46667 223.8MB/s  lsp (48.37 %)  [ +0.0%]\nBM_ZFlat/8              2677888    2639405        269 372.1MB/s  xls (41.34 %)  [ -1.4%]\nBM_ZFlat/9               800715     780000       1000 186.0MB/s  txt1 (59.81 %) [ -0.4%]\nBM_ZFlat/10              700089     700000       1000 170.5MB/s  txt2 (64.07 %) [ -2.9%]\nBM_ZFlat/11             2159356    2138365        318 190.3MB/s  txt3 (57.11 %) [ -0.3%]\nBM_ZFlat/12             2796143    2779923        259 165.3MB/s  txt4 (68.35 %) [ -1.4%]\nBM_ZFlat/13              856458     835476        778 585.8MB/s  bin (18.21 %)  [ -0.1%]\nBM_ZFlat/14              166908     166857       4375 218.6MB/s  sum (51.88 %)  [ -1.4%]\nBM_ZFlat/15               21181      20857      35000 193.3MB/s  man (59.36 %)  [ -0.8%]\nBM_ZFlat/16              244009     239973       2917 471.3MB/s  pb (23.15 %)   [ -1.4%]\nBM_ZFlat/17              596362     590000       1000 297.9MB/s  gaviota (38.27%) [ +0.0%]\n\nR=sanjay\n\n------------------------------------------------------------------------\nr58 | snappy.mirrorbot@gmail.com | 2012-02-11 23:11:22 +0100 (Sat, 11 Feb 2012) | 9 lines\n\nLower the size allocated in the \"corrupted input\" unit test from 256 MB\nto 2 MB. This fixes issues with running the unit test on platforms with\nlittle RAM (e.g. some ARM boards).\n\nAlso, reactivate the 2 MB test for 64-bit platforms; there's no good\nreason why it shouldn't be.\n\nR=sanjay\n\n------------------------------------------------------------------------\nr57 | snappy.mirrorbot@gmail.com | 2012-01-08 18:55:48 +0100 (Sun, 08 Jan 2012) | 2 lines\n\nMinor refactoring to accomodate changes in Google's internal code tree.\n\n------------------------------------------------------------------------\nr56 | snappy.mirrorbot@gmail.com | 2012-01-04 14:10:46 +0100 (Wed, 04 Jan 2012) | 19 lines\n\nFix public issue r57: Fix most warnings with -Wall, mostly signed/unsigned\nwarnings. There are still some in the unit test, but the main .cc file should\nbe clean. We haven't enabled -Wall for the default build, since the unit test\nis still not clean.\n\nThis also fixes a real bug in the open-source implementation of\nReadFileToStringOrDie(); it would not detect errors correctly.\n\nI had to go through some pains to avoid performance loss as the types\nwere changed; I think there might still be some with 32-bit if and only if LFS\nis enabled (ie., size_t is 64-bit), but for regular 32-bit and 64-bit I can't\nsee any losses, and I've diffed the generated GCC assembler between the old and\nnew code without seeing any significant choices. If anything, it's ever so\nslightly faster.\n\nThis may or may not enable compression of very large blocks (>2^32 bytes)\nwhen size_t is 64-bit, but I haven't checked, and it is still not a supported\ncase.\n\n------------------------------------------------------------------------\nr55 | snappy.mirrorbot@gmail.com | 2012-01-04 11:46:39 +0100 (Wed, 04 Jan 2012) | 6 lines\n\nAdd a framing format description. We do not have any implementation of this at\nthe current point, but there seems to be enough of a general interest in the\ntopic (cf. public bug #34).\n\nR=csilvers,sanjay\n\n------------------------------------------------------------------------\nr54 | snappy.mirrorbot@gmail.com | 2011-12-05 22:27:26 +0100 (Mon, 05 Dec 2011) | 81 lines\n\nSpeed up decompression by moving the refill check to the end of the loop.\n\nThis seems to work because in most of the branches, the compiler can evaluate\n“ip_limit_ - ip” in a more efficient way than reloading ip_limit_ from memory\n(either by already having the entire expression in a register, or reconstructing\nit from “avail”, or something else). Memory loads, even from L1, are seemingly\ncostly in the big picture at the current decompression speeds.\n\nMicrobenchmarks (64-bit, opt mode):\n\nWestmere (Intel Core i7):\n\n  Benchmark     Time(ns)    CPU(ns) Iterations\n  --------------------------------------------\n  BM_UFlat/0       74492      74491     187894 1.3GB/s  html      [ +5.9%]\n  BM_UFlat/1      712268     712263      19644 940.0MB/s  urls    [ +3.8%]\n  BM_UFlat/2       10591      10590    1000000 11.2GB/s  jpg      [ -6.8%]\n  BM_UFlat/3       29643      29643     469915 3.0GB/s  pdf       [ +7.9%]\n  BM_UFlat/4      304669     304667      45930 1.3GB/s  html4     [ +4.8%]\n  BM_UFlat/5       28508      28507     490077 823.1MB/s  cp      [ +4.0%]\n  BM_UFlat/6       12415      12415    1000000 856.5MB/s  c       [ +8.6%]\n  BM_UFlat/7        3415       3415    4084723 1039.0MB/s  lsp    [+18.0%]\n  BM_UFlat/8      979569     979563      14261 1002.5MB/s  xls    [ +5.8%]\n  BM_UFlat/9      230150     230148      60934 630.2MB/s  txt1    [ +5.2%]\n  BM_UFlat/10     197167     197166      71135 605.5MB/s  txt2    [ +4.7%]\n  BM_UFlat/11     607394     607390      23041 670.1MB/s  txt3    [ +5.6%]\n  BM_UFlat/12     808502     808496      17316 568.4MB/s  txt4    [ +5.0%]\n  BM_UFlat/13     372791     372788      37564 1.3GB/s  bin       [ +3.3%]\n  BM_UFlat/14      44541      44541     313969 818.8MB/s  sum     [ +5.7%]\n  BM_UFlat/15       4833       4833    2898697 834.1MB/s  man     [ +4.8%]\n  BM_UFlat/16      79855      79855     175356 1.4GB/s  pb        [ +4.8%]\n  BM_UFlat/17     245845     245843      56838 715.0MB/s  gaviota [ +5.8%]\n\nClovertown (Intel Core 2):\n\n  Benchmark     Time(ns)    CPU(ns) Iterations\n  --------------------------------------------\n  BM_UFlat/0      107911     107890     100000 905.1MB/s  html    [ +2.2%]\n  BM_UFlat/1     1011237    1011041      10000 662.3MB/s  urls    [ +2.5%]\n  BM_UFlat/2       26775      26770     523089 4.4GB/s  jpg       [ +0.0%]\n  BM_UFlat/3       48103      48095     290618 1.8GB/s  pdf       [ +3.4%]\n  BM_UFlat/4      437724     437644      31937 892.6MB/s  html4   [ +2.1%]\n  BM_UFlat/5       39607      39600     358284 592.5MB/s  cp      [ +2.4%]\n  BM_UFlat/6       18227      18224     768191 583.5MB/s  c       [ +2.7%]\n  BM_UFlat/7        5171       5170    2709437 686.4MB/s  lsp     [ +3.9%]\n  BM_UFlat/8     1560291    1559989       8970 629.5MB/s  xls     [ +3.6%]\n  BM_UFlat/9      335401     335343      41731 432.5MB/s  txt1    [ +3.0%]\n  BM_UFlat/10     287014     286963      48758 416.0MB/s  txt2    [ +2.8%]\n  BM_UFlat/11     888522     888356      15752 458.1MB/s  txt3    [ +2.9%]\n  BM_UFlat/12    1186600    1186378      10000 387.3MB/s  txt4    [ +3.1%]\n  BM_UFlat/13     572295     572188      24468 855.4MB/s  bin     [ +2.1%]\n  BM_UFlat/14      64060      64049     218401 569.4MB/s  sum     [ +4.1%]\n  BM_UFlat/15       7264       7263    1916168 555.0MB/s  man     [ +1.4%]\n  BM_UFlat/16     108853     108836     100000 1039.1MB/s  pb     [ +1.7%]\n  BM_UFlat/17     364289     364223      38419 482.6MB/s  gaviota [ +4.9%]\n\nBarcelona (AMD Opteron):\n\n  Benchmark     Time(ns)    CPU(ns) Iterations\n  --------------------------------------------\n  BM_UFlat/0      103900     103871     100000 940.2MB/s  html    [ +8.3%]\n  BM_UFlat/1     1000435    1000107      10000 669.5MB/s  urls    [ +6.6%]\n  BM_UFlat/2       24659      24652     567362 4.8GB/s  jpg       [ +0.1%]\n  BM_UFlat/3       48206      48193     291121 1.8GB/s  pdf       [ +5.0%]\n  BM_UFlat/4      421980     421850      33174 926.0MB/s  html4   [ +7.3%]\n  BM_UFlat/5       40368      40357     346994 581.4MB/s  cp      [ +8.7%]\n  BM_UFlat/6       19836      19830     708695 536.2MB/s  c       [ +8.0%]\n  BM_UFlat/7        6100       6098    2292774 581.9MB/s  lsp     [ +9.0%]\n  BM_UFlat/8     1693093    1692514       8261 580.2MB/s  xls     [ +8.0%]\n  BM_UFlat/9      365991     365886      38225 396.4MB/s  txt1    [ +7.1%]\n  BM_UFlat/10     311330     311238      44950 383.6MB/s  txt2    [ +7.6%]\n  BM_UFlat/11     975037     974737      14376 417.5MB/s  txt3    [ +6.9%]\n  BM_UFlat/12    1303558    1303175      10000 352.6MB/s  txt4    [ +7.3%]\n  BM_UFlat/13     517448     517290      27144 946.2MB/s  bin     [ +5.5%]\n  BM_UFlat/14      66537      66518     210352 548.3MB/s  sum     [ +7.5%]\n  BM_UFlat/15       7976       7974    1760383 505.6MB/s  man     [ +5.6%]\n  BM_UFlat/16     103121     103092     100000 1097.0MB/s  pb     [ +8.7%]\n  BM_UFlat/17     391431     391314      35733 449.2MB/s  gaviota [ +6.5%]\n\nR=sanjay\n\n------------------------------------------------------------------------\nr53 | snappy.mirrorbot@gmail.com | 2011-11-23 12:14:17 +0100 (Wed, 23 Nov 2011) | 88 lines\n\nSpeed up decompression by making the fast path for literals faster.\n\nWe do the fast-path step as soon as possible; in fact, as soon as we know the\nliteral length. Since we usually hit the fast path, we can then skip the checks\nfor long literals and available input space (beyond what the fast path check\nalready does).\n\nNote that this changes the decompression Writer API; however, it does not\nchange the ABI, since writers are always templatized and as such never\ncross compilation units. The new API is slightly more general, in that it\ndoesn't hard-code the value 16. Note that we also take care to check\nfor len <= 16 first, since the other two checks almost always succeed\n(so we don't want to waste time checking for them until we have to).\n\nThe improvements are most marked on Nehalem, but are generally positive\non other platforms as well. All microbenchmarks are 64-bit, opt.\n\nClovertown (Core 2):\n\n  Benchmark     Time(ns)    CPU(ns) Iterations\n  --------------------------------------------\n  BM_UFlat/0      110226     110224     100000 886.0MB/s  html    [ +1.5%]\n  BM_UFlat/1     1036523    1036508      10000 646.0MB/s  urls    [ -0.8%]\n  BM_UFlat/2       26775      26775     522570 4.4GB/s  jpg       [ +0.0%]\n  BM_UFlat/3       49738      49737     280974 1.8GB/s  pdf       [ +0.3%]\n  BM_UFlat/4      446790     446792      31334 874.3MB/s  html4   [ +0.8%]\n  BM_UFlat/5       40561      40562     350424 578.5MB/s  cp      [ +1.3%]\n  BM_UFlat/6       18722      18722     746903 568.0MB/s  c       [ +1.4%]\n  BM_UFlat/7        5373       5373    2608632 660.5MB/s  lsp     [ +8.3%]\n  BM_UFlat/8     1615716    1615718       8670 607.8MB/s  xls     [ +2.0%]\n  BM_UFlat/9      345278     345281      40481 420.1MB/s  txt1    [ +1.4%]\n  BM_UFlat/10     294855     294855      47452 404.9MB/s  txt2    [ +1.6%]\n  BM_UFlat/11     914263     914263      15316 445.2MB/s  txt3    [ +1.1%]\n  BM_UFlat/12    1222694    1222691      10000 375.8MB/s  txt4    [ +1.4%]\n  BM_UFlat/13     584495     584489      23954 837.4MB/s  bin     [ -0.6%]\n  BM_UFlat/14      66662      66662     210123 547.1MB/s  sum     [ +1.2%]\n  BM_UFlat/15       7368       7368    1881856 547.1MB/s  man     [ +4.0%]\n  BM_UFlat/16     110727     110726     100000 1021.4MB/s  pb     [ +2.3%]\n  BM_UFlat/17     382138     382141      36616 460.0MB/s  gaviota [ -0.7%]\n\nWestmere (Core i7):\n\n  Benchmark     Time(ns)    CPU(ns) Iterations\n  --------------------------------------------\n  BM_UFlat/0       78861      78853     177703 1.2GB/s  html      [ +2.1%]\n  BM_UFlat/1      739560     739491      18912 905.4MB/s  urls    [ +3.4%]\n  BM_UFlat/2        9867       9866    1419014 12.0GB/s  jpg      [ +3.4%]\n  BM_UFlat/3       31989      31986     438385 2.7GB/s  pdf       [ +0.2%]\n  BM_UFlat/4      319406     319380      43771 1.2GB/s  html4     [ +1.9%]\n  BM_UFlat/5       29639      29636     472862 791.7MB/s  cp      [ +5.2%]\n  BM_UFlat/6       13478      13477    1000000 789.0MB/s  c       [ +2.3%]\n  BM_UFlat/7        4030       4029    3475364 880.7MB/s  lsp     [ +8.7%]\n  BM_UFlat/8     1036585    1036492      10000 947.5MB/s  xls     [ +6.9%]\n  BM_UFlat/9      242127     242105      57838 599.1MB/s  txt1    [ +3.0%]\n  BM_UFlat/10     206499     206480      67595 578.2MB/s  txt2    [ +3.4%]\n  BM_UFlat/11     641635     641570      21811 634.4MB/s  txt3    [ +2.4%]\n  BM_UFlat/12     848847     848769      16443 541.4MB/s  txt4    [ +3.1%]\n  BM_UFlat/13     384968     384938      36366 1.2GB/s  bin       [ +0.3%]\n  BM_UFlat/14      47106      47101     297770 774.3MB/s  sum     [ +4.4%]\n  BM_UFlat/15       5063       5063    2772202 796.2MB/s  man     [ +7.7%]\n  BM_UFlat/16      83663      83656     167697 1.3GB/s  pb        [ +1.8%]\n  BM_UFlat/17     260224     260198      53823 675.6MB/s  gaviota [ -0.5%]\n\nBarcelona (Opteron):\n\n  Benchmark     Time(ns)    CPU(ns) Iterations\n  --------------------------------------------\n  BM_UFlat/0      112490     112457     100000 868.4MB/s  html    [ -0.4%]\n  BM_UFlat/1     1066719    1066339      10000 627.9MB/s  urls    [ +1.0%]\n  BM_UFlat/2       24679      24672     563802 4.8GB/s  jpg       [ +0.7%]\n  BM_UFlat/3       50603      50589     277285 1.7GB/s  pdf       [ +2.6%]\n  BM_UFlat/4      452982     452849      30900 862.6MB/s  html4   [ -0.2%]\n  BM_UFlat/5       43860      43848     319554 535.1MB/s  cp      [ +1.2%]\n  BM_UFlat/6       21419      21413     653573 496.6MB/s  c       [ +1.0%]\n  BM_UFlat/7        6646       6645    2105405 534.1MB/s  lsp     [ +0.3%]\n  BM_UFlat/8     1828487    1827886       7658 537.3MB/s  xls     [ +2.6%]\n  BM_UFlat/9      391824     391714      35708 370.3MB/s  txt1    [ +2.2%]\n  BM_UFlat/10     334913     334816      41885 356.6MB/s  txt2    [ +1.7%]\n  BM_UFlat/11    1042062    1041674      10000 390.7MB/s  txt3    [ +1.1%]\n  BM_UFlat/12    1398902    1398456      10000 328.6MB/s  txt4    [ +1.7%]\n  BM_UFlat/13     545706     545530      25669 897.2MB/s  bin     [ -0.4%]\n  BM_UFlat/14      71512      71505     196035 510.0MB/s  sum     [ +1.4%]\n  BM_UFlat/15       8422       8421    1665036 478.7MB/s  man     [ +2.6%]\n  BM_UFlat/16     112053     112048     100000 1009.3MB/s  pb     [ -0.4%]\n  BM_UFlat/17     416723     416713      33612 421.8MB/s  gaviota [ -2.0%]\n\nR=sanjay\n\n------------------------------------------------------------------------\nr52 | snappy.mirrorbot@gmail.com | 2011-11-08 15:46:39 +0100 (Tue, 08 Nov 2011) | 5 lines\n\nFix public issue #53: Update the README to the API we actually open-sourced\nwith.\n\nR=sanjay\n\n------------------------------------------------------------------------\nr51 | snappy.mirrorbot@gmail.com | 2011-10-05 14:27:12 +0200 (Wed, 05 Oct 2011) | 5 lines\n\nIn the format description, use a clearer example to emphasize that varints are\nstored in little-endian. Patch from Christian von Roques.\n\nR=csilvers\n\n------------------------------------------------------------------------\nr50 | snappy.mirrorbot@gmail.com | 2011-09-15 21:34:06 +0200 (Thu, 15 Sep 2011) | 4 lines\n\nRelease Snappy 1.0.4.\n\nR=sanjay\n\n------------------------------------------------------------------------\nr49 | snappy.mirrorbot@gmail.com | 2011-09-15 11:50:05 +0200 (Thu, 15 Sep 2011) | 5 lines\n\nFix public issue #50: Include generic byteswap macros.\nAlso include Solaris 10 and FreeBSD versions.\n\nR=csilvers\n\n------------------------------------------------------------------------\nr48 | snappy.mirrorbot@gmail.com | 2011-08-10 20:57:27 +0200 (Wed, 10 Aug 2011) | 5 lines\n\nPartially fix public issue 50: Remove an extra comma from the end of some\nenum declarations, as it seems the Sun compiler does not like it.\n\nBased on patch by Travis Vitek.\n\n------------------------------------------------------------------------\nr47 | snappy.mirrorbot@gmail.com | 2011-08-10 20:44:16 +0200 (Wed, 10 Aug 2011) | 4 lines\n\nUse the right #ifdef test for sys/mman.h.\n\nBased on patch by Travis Vitek.\n\n------------------------------------------------------------------------\nr46 | snappy.mirrorbot@gmail.com | 2011-08-10 03:22:09 +0200 (Wed, 10 Aug 2011) | 6 lines\n\nFix public issue #47: Small comment cleanups in the unit test.\n\nOriginally based on a patch by Patrick Pelletier.\n\nR=sanjay\n\n------------------------------------------------------------------------\nr45 | snappy.mirrorbot@gmail.com | 2011-08-10 03:14:43 +0200 (Wed, 10 Aug 2011) | 8 lines\n\nFix public issue #46: Format description said \"3-byte offset\"\ninstead of \"4-byte offset\" for the longest copies.\n\nAlso fix an inconsistency in the heading for section 2.2.3.\nBoth patches by Patrick Pelletier.\n\nR=csilvers\n\n------------------------------------------------------------------------\nr44 | snappy.mirrorbot@gmail.com | 2011-06-28 13:40:25 +0200 (Tue, 28 Jun 2011) | 8 lines\n\nFix public issue #44: Make the definition and declaration of CompressFragment\nidentical, even regarding cv-qualifiers.\n\nThis is required to work around a bug in the Solaris Studio C++ compiler\n(it does not properly disregard cv-qualifiers when doing name mangling).\n\nR=sanjay\n\n------------------------------------------------------------------------\nr43 | snappy.mirrorbot@gmail.com | 2011-06-04 12:19:05 +0200 (Sat, 04 Jun 2011) | 7 lines\n\nCorrect an inaccuracy in the Snappy format description. \n(I stumbled into this when changing the way we decompress literals.) \n\nR=csilvers\n\nRevision created by MOE tool push_codebase.\n\n------------------------------------------------------------------------\nr42 | snappy.mirrorbot@gmail.com | 2011-06-03 22:53:06 +0200 (Fri, 03 Jun 2011) | 50 lines\n\nSpeed up decompression by removing a fast-path attempt.\n\nWhenever we try to enter a copy fast-path, there is a certain cost in checking\nthat all the preconditions are in place, but it's normally offset by the fact\nthat we can usually take the cheaper path. However, in a certain path we've\nalready established that \"avail < literal_length\", which usually means that\neither the available space is small, or the literal is big. Both will disqualify\nus from taking the fast path, and thus we take the hit from the precondition\nchecking without gaining much from having a fast path. Thus, simply don't try\nthe fast path in this situation -- we're already on a slow path anyway\n(one where we need to refill more data from the reader).\n\nI'm a bit surprised at how much this gained; it could be that this path is\nmore common than I thought, or that the simpler structure somehow makes the\ncompiler happier. I haven't looked at the assembler, but it's a win across\nthe board on both Core 2, Core i7 and Opteron, at least for the cases we\ntypically care about. The gains seem to be the largest on Core i7, though.\nResults from my Core i7 workstation:\n\n\n  Benchmark            Time(ns)    CPU(ns) Iterations\n  ---------------------------------------------------\n  BM_UFlat/0              73337      73091     190996 1.3GB/s  html      [ +1.7%]\n  BM_UFlat/1             696379     693501      20173 965.5MB/s  urls    [ +2.7%]\n  BM_UFlat/2               9765       9734    1472135 12.1GB/s  jpg      [ +0.7%]\n  BM_UFlat/3              29720      29621     472973 3.0GB/s  pdf       [ +1.8%]\n  BM_UFlat/4             294636     293834      47782 1.3GB/s  html4     [ +2.3%]\n  BM_UFlat/5              28399      28320     494700 828.5MB/s  cp      [ +3.5%]\n  BM_UFlat/6              12795      12760    1000000 833.3MB/s  c       [ +1.2%]\n  BM_UFlat/7               3984       3973    3526448 893.2MB/s  lsp     [ +5.7%]\n  BM_UFlat/8             991996     989322      14141 992.6MB/s  xls     [ +3.3%]\n  BM_UFlat/9             228620     227835      61404 636.6MB/s  txt1    [ +4.0%]\n  BM_UFlat/10            197114     196494      72165 607.5MB/s  txt2    [ +3.5%]\n  BM_UFlat/11            605240     603437      23217 674.4MB/s  txt3    [ +3.7%]\n  BM_UFlat/12            804157     802016      17456 573.0MB/s  txt4    [ +3.9%]\n  BM_UFlat/13            347860     346998      40346 1.4GB/s  bin       [ +1.2%]\n  BM_UFlat/14             44684      44559     315315 818.4MB/s  sum     [ +2.3%]\n  BM_UFlat/15              5120       5106    2739726 789.4MB/s  man     [ +3.3%]\n  BM_UFlat/16             76591      76355     183486 1.4GB/s  pb        [ +2.8%]\n  BM_UFlat/17            238564     237828      58824 739.1MB/s  gaviota [ +1.6%]\n  BM_UValidate/0          42194      42060     333333 2.3GB/s  html      [ -0.1%]\n  BM_UValidate/1         433182     432005      32407 1.5GB/s  urls      [ -0.1%]\n  BM_UValidate/2            197        196   71428571 603.3GB/s  jpg     [ +0.5%]\n  BM_UValidate/3          14494      14462     972222 6.1GB/s  pdf       [ +0.5%]\n  BM_UValidate/4         168444     167836      83832 2.3GB/s  html4     [ +0.1%]\n\t\nR=jeff\n\nRevision created by MOE tool push_codebase.\n\n------------------------------------------------------------------------\nr41 | snappy.mirrorbot@gmail.com | 2011-06-03 22:47:14 +0200 (Fri, 03 Jun 2011) | 43 lines\n\nSpeed up decompression by not needing a lookup table for literal items.\n\nLooking up into and decoding the values from char_table has long shown up as a\nhotspot in the decompressor. While it turns out that it's hard to make a more\nefficient decoder for the copy ops, the literals are simple enough that we can\ndecode them without needing a table lookup. (This means that 1/4 of the table\nis now unused, although that in itself doesn't buy us anything.)\n\nThe gains are small, but definitely present; some tests win as much as 10%,\nbut 1-4% is more typical. These results are from Core i7, in 64-bit mode;\nCore 2 and Opteron show similar results. (I've run with more iterations\nthan unusual to make sure the smaller gains don't drown entirely in noise.)\n\n  Benchmark            Time(ns)    CPU(ns) Iterations\n  ---------------------------------------------------\n  BM_UFlat/0              74665      74428     182055 1.3GB/s  html      [ +3.1%]\n  BM_UFlat/1             714106     711997      19663 940.4MB/s  urls    [ +4.4%]\n  BM_UFlat/2               9820       9789    1427115 12.1GB/s  jpg      [ -1.2%]\n  BM_UFlat/3              30461      30380     465116 2.9GB/s  pdf       [ +0.8%]\n  BM_UFlat/4             301445     300568      46512 1.3GB/s  html4     [ +2.2%]\n  BM_UFlat/5              29338      29263     479452 801.8MB/s  cp      [ +1.6%]\n  BM_UFlat/6              13004      12970    1000000 819.9MB/s  c       [ +2.1%]\n  BM_UFlat/7               4180       4168    3349282 851.4MB/s  lsp     [ +1.3%]\n  BM_UFlat/8            1026149    1024000      10000 959.0MB/s  xls     [+10.7%]\n  BM_UFlat/9             237441     236830      59072 612.4MB/s  txt1    [ +0.3%]\n  BM_UFlat/10            203966     203298      69307 587.2MB/s  txt2    [ +0.8%]\n  BM_UFlat/11            627230     625000      22400 651.2MB/s  txt3    [ +0.7%]\n  BM_UFlat/12            836188     833979      16787 551.0MB/s  txt4    [ +1.3%]\n  BM_UFlat/13            351904     350750      39886 1.4GB/s  bin       [ +3.8%]\n  BM_UFlat/14             45685      45562     308370 800.4MB/s  sum     [ +5.9%]\n  BM_UFlat/15              5286       5270    2656546 764.9MB/s  man     [ +1.5%]\n  BM_UFlat/16             78774      78544     178117 1.4GB/s  pb        [ +4.3%]\n  BM_UFlat/17            242270     241345      58091 728.3MB/s  gaviota [ +1.2%]\n  BM_UValidate/0          42149      42000     333333 2.3GB/s  html      [ -3.0%]\n  BM_UValidate/1         432741     431303      32483 1.5GB/s  urls      [ +7.8%]\n  BM_UValidate/2            198        197   71428571 600.7GB/s  jpg     [+16.8%]\n  BM_UValidate/3          14560      14521     965517 6.1GB/s  pdf       [ -4.1%]\n  BM_UValidate/4         169065     168671      83832 2.3GB/s  html4     [ -2.9%]\n\nR=jeff\n\nRevision created by MOE tool push_codebase.\n\n------------------------------------------------------------------------\nr40 | snappy.mirrorbot@gmail.com | 2011-06-03 00:57:41 +0200 (Fri, 03 Jun 2011) | 2 lines\n\nRelease Snappy 1.0.3.\n\n------------------------------------------------------------------------\nr39 | snappy.mirrorbot@gmail.com | 2011-06-02 20:06:54 +0200 (Thu, 02 Jun 2011) | 11 lines\n\nRemove an unneeded goto in the decompressor; it turns out that the\nstate of ip_ after decompression (or attempted decompresion) is\ncompletely irrelevant, so we don't need the trailer.\n\nPerformance is, as expected, mostly flat -- there's a curious ~3-5%\nloss in the \"lsp\" test, but that test case is so short it is hard to say\nanything definitive about why (most likely, it's some sort of\nunrelated effect).\n\nR=jeff\n\n------------------------------------------------------------------------\nr38 | snappy.mirrorbot@gmail.com | 2011-06-02 19:59:40 +0200 (Thu, 02 Jun 2011) | 52 lines\n\nSpeed up decompression by caching ip_.\n\nIt is seemingly hard for the compiler to understand that ip_, the current input\npointer into the compressed data stream, can not alias on anything else, and\nthus using it directly will incur memory traffic as it cannot be kept in a\nregister. The code already knew about this and cached it into a local\nvariable, but since Step() only decoded one tag, it had to move ip_ back into\nplace between every tag. This seems to have cost us a significant amount of\nperformance, so changing Step() into a function that decodes as much as it can\nbefore it saves ip_ back and returns. (Note that Step() was already inlined,\nso it is not the manual inlining that buys the performance here.)\n\nThe wins are about 3-6% for Core 2, 6-13% on Core i7 and 5-12% on Opteron\n(for plain array-to-array decompression, in 64-bit opt mode).\n\nThere is a tiny difference in the behavior here; if an invalid literal is\nencountered (ie., the writer refuses the Append() operation), ip_ will now\npoint to the byte past the tag byte, instead of where the literal was\noriginally thought to end. However, we don't use ip_ for anything after\nDecompressAllTags() has returned, so this should not change external behavior\nin any way.\n\nMicrobenchmark results for Core i7, 64-bit (Opteron results are similar):\n\nBenchmark            Time(ns)    CPU(ns) Iterations\n---------------------------------------------------\nBM_UFlat/0              79134      79110       8835 1.2GB/s  html      [ +6.2%]\nBM_UFlat/1             786126     786096        891 851.8MB/s  urls    [+10.0%]\nBM_UFlat/2               9948       9948      69125 11.9GB/s  jpg      [ -1.3%]\nBM_UFlat/3              31999      31998      21898 2.7GB/s  pdf       [ +6.5%]\nBM_UFlat/4             318909     318829       2204 1.2GB/s  html4     [ +6.5%]\nBM_UFlat/5              31384      31390      22363 747.5MB/s  cp      [ +9.2%]\nBM_UFlat/6              14037      14034      49858 757.7MB/s  c       [+10.6%]\nBM_UFlat/7               4612       4612     151395 769.5MB/s  lsp     [ +9.5%]\nBM_UFlat/8            1203174    1203007        582 816.3MB/s  xls     [+19.3%]\nBM_UFlat/9             253869     253955       2757 571.1MB/s  txt1    [+11.4%]\nBM_UFlat/10            219292     219290       3194 544.4MB/s  txt2    [+12.1%]\nBM_UFlat/11            672135     672131       1000 605.5MB/s  txt3    [+11.2%]\nBM_UFlat/12            902512     902492        776 509.2MB/s  txt4    [+12.5%]\nBM_UFlat/13            372110     371998       1881 1.3GB/s  bin       [ +5.8%]\nBM_UFlat/14             50407      50407      10000 723.5MB/s  sum     [+13.5%]\nBM_UFlat/15              5699       5701     100000 707.2MB/s  man     [+12.4%]\nBM_UFlat/16             83448      83424       8383 1.3GB/s  pb        [ +5.7%]\nBM_UFlat/17            256958     256963       2723 684.1MB/s  gaviota [ +7.9%]\nBM_UValidate/0          42795      42796      16351 2.2GB/s  html      [+25.8%]\nBM_UValidate/1         490672     490622       1427 1.3GB/s  urls      [+22.7%]\nBM_UValidate/2            237        237    2950297 499.0GB/s  jpg     [+24.9%]\nBM_UValidate/3          14610      14611      47901 6.0GB/s  pdf       [+26.8%]\nBM_UValidate/4         171973     171990       4071 2.2GB/s  html4     [+25.7%]\n\n\n\n------------------------------------------------------------------------\nr37 | snappy.mirrorbot@gmail.com | 2011-05-17 10:48:25 +0200 (Tue, 17 May 2011) | 10 lines\n\n\nFix the numbering of the headlines in the Snappy format description.\n\nR=csilvers\nDELTA=4  (0 added, 0 deleted, 4 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1906\n\n------------------------------------------------------------------------\nr36 | snappy.mirrorbot@gmail.com | 2011-05-16 10:59:18 +0200 (Mon, 16 May 2011) | 12 lines\n\n\nFix public issue #32: Add compressed format documentation for Snappy.\nThis text is new, but an earlier version from Zeev Tarantov was used\nas reference.\n\nR=csilvers\nDELTA=112  (111 added, 0 deleted, 1 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1867\n\n------------------------------------------------------------------------\nr35 | snappy.mirrorbot@gmail.com | 2011-05-09 23:29:02 +0200 (Mon, 09 May 2011) | 12 lines\n\n\nFix public issue #39: Pick out the median runs based on CPU time,\nnot real time. Also, use nth_element instead of sort, since we\nonly need one element.\n\nR=csilvers\nDELTA=5  (3 added, 0 deleted, 2 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1799\n\n------------------------------------------------------------------------\nr34 | snappy.mirrorbot@gmail.com | 2011-05-09 23:28:45 +0200 (Mon, 09 May 2011) | 19 lines\n\n\nFix public issue #38: Make the microbenchmark framework handle\nproperly cases where gettimeofday() can stand return the same\nresult twice (as sometimes on GNU/Hurd) or go backwards\n(as when the user adjusts the clock). We avoid a division-by-zero,\nand put a lower bound on the number of iterations -- the same\namount as we use to calibrate.\n\nWe should probably use CLOCK_MONOTONIC for platforms that support\nit, to be robust against clock adjustments; we already use Windows'\nmonotonic timers. However, that's for a later changelist.\n\nR=csilvers\nDELTA=7  (5 added, 0 deleted, 2 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1798\n\n------------------------------------------------------------------------\nr33 | snappy.mirrorbot@gmail.com | 2011-05-04 01:22:52 +0200 (Wed, 04 May 2011) | 11 lines\n\n\nFix public issue #37: Only link snappy_unittest against -lz and other autodetected\nlibraries, not libsnappy.so (which doesn't need any such dependency).\n\nR=csilvers\nDELTA=20  (14 added, 0 deleted, 6 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1710\n\n------------------------------------------------------------------------\nr32 | snappy.mirrorbot@gmail.com | 2011-05-04 01:22:33 +0200 (Wed, 04 May 2011) | 11 lines\n\n\nRelease Snappy 1.0.2, to get the license change and various other fixes into\na release.\n\nR=csilvers\nDELTA=239  (236 added, 0 deleted, 3 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1709\n\n------------------------------------------------------------------------\nr31 | snappy.mirrorbot@gmail.com | 2011-04-26 14:34:55 +0200 (Tue, 26 Apr 2011) | 15 lines\n\n\nFix public issue #30: Stop using gettimeofday() altogether on Win32,\nas MSVC doesn't include it. Replace with QueryPerformanceCounter(),\nwhich is monotonic and probably reasonably high-resolution.\n(Some machines have traditionally had bugs in QPC, but they should\nbe relatively rare these days, and there's really no much better\nalternative that I know of.)\n\nR=csilvers\nDELTA=74  (55 added, 19 deleted, 0 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1556\n\n------------------------------------------------------------------------\nr30 | snappy.mirrorbot@gmail.com | 2011-04-26 14:34:37 +0200 (Tue, 26 Apr 2011) | 11 lines\n\n\nFix public issue #31: Don't reset PATH in autogen.sh; instead, do the trickery\nwe need for our own build system internally.\n\nR=csilvers\nDELTA=16  (13 added, 1 deleted, 2 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1555\n\n------------------------------------------------------------------------\nr29 | snappy.mirrorbot@gmail.com | 2011-04-16 00:55:56 +0200 (Sat, 16 Apr 2011) | 12 lines\n\n\nWhen including <windows.h>, define WIN32_LEAN_AND_MEAN first,\nso we won't pull in macro definitions of things like min() and max(),\nwhich can conflict with <algorithm>.\n\nR=csilvers\nDELTA=1  (1 added, 0 deleted, 0 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1485\n\n------------------------------------------------------------------------\nr28 | snappy.mirrorbot@gmail.com | 2011-04-11 11:07:01 +0200 (Mon, 11 Apr 2011) | 15 lines\n\n\nFix public issue #29: Write CPU timing code for Windows, based on GetProcessTimes()\ninstead of getursage().\n\nI thought I'd already committed this patch, so that the 1.0.1 release already\nwould have a Windows-compatible snappy_unittest, but I'd seemingly deleted it\ninstead, so this is a reconstruction.\n\nR=csilvers\nDELTA=43  (39 added, 3 deleted, 1 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1295\n\n------------------------------------------------------------------------\nr27 | snappy.mirrorbot@gmail.com | 2011-04-08 11:51:53 +0200 (Fri, 08 Apr 2011) | 22 lines\n\n\nInclude C bindings of Snappy, contributed by Martin Gieseking.\n\nI've made a few changes since Martin's version; mostly style nits, but also\na semantic change -- most functions that return bool in the C++ version now\nreturn an enum, to better match typical C (and zlib) semantics.\n\nI've kept the copyright notice, since Martin is obviously the author here;\nhe has signed the contributor license agreement, though, so this should not\nhinder Google's use in the future.\n\nWe'll need to update the libtool version number to match the added interface,\nbut as of http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html\nI'm going to wait until public release.\n\nR=csilvers\nDELTA=238  (233 added, 0 deleted, 5 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1294\n\n------------------------------------------------------------------------\nr26 | snappy.mirrorbot@gmail.com | 2011-04-07 18:36:43 +0200 (Thu, 07 Apr 2011) | 13 lines\n\n\nReplace geo.protodata with a newer version.\n\nThe data compresses/decompresses slightly faster than the old data, and has\nsimilar density.\n\nR=lookingbill\nDELTA=1  (0 added, 0 deleted, 1 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1288\n\n------------------------------------------------------------------------\nr25 | snappy.mirrorbot@gmail.com | 2011-03-30 22:27:53 +0200 (Wed, 30 Mar 2011) | 12 lines\n\n\nFix public issue #27: Add HAVE_CONFIG_H tests around the config.h\ninclusion in snappy-stubs-internal.h, which eases compiling outside the\nautomake/autoconf framework.\n\nR=csilvers\nDELTA=5  (4 added, 1 deleted, 0 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1152\n\n------------------------------------------------------------------------\nr24 | snappy.mirrorbot@gmail.com | 2011-03-30 22:27:39 +0200 (Wed, 30 Mar 2011) | 13 lines\n\n\nFix public issue #26: Take memory allocation and reallocation entirely out of the\nMeasure() loop. This gives all algorithms a small speed boost, except Snappy which\nalready didn't do reallocation (so the measurements were slightly biased in its\nfavor).\n\nR=csilvers\nDELTA=92  (69 added, 9 deleted, 14 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1151\n\n------------------------------------------------------------------------\nr23 | snappy.mirrorbot@gmail.com | 2011-03-30 22:25:09 +0200 (Wed, 30 Mar 2011) | 18 lines\n\n\nRenamed \"namespace zippy\" to \"namespace snappy\" to reduce\nthe differences from the opensource code.  Will make it easier\nin the future to mix-and-match third-party code that uses\nsnappy with google code.\n\nCurrently, csearch shows that the only external user of\n\"namespace zippy\" is some bigtable code that accesses\na TEST variable, which is temporarily kept in the zippy\nnamespace.\n\nR=sesse\nDELTA=123  (18 added, 3 deleted, 102 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1150\n\n------------------------------------------------------------------------\nr22 | snappy.mirrorbot@gmail.com | 2011-03-29 00:17:04 +0200 (Tue, 29 Mar 2011) | 11 lines\n\n\nPut back the final few lines of what was truncated during the\nlicense header change.\n\nR=csilvers\nDELTA=5  (4 added, 0 deleted, 1 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1094\n\n------------------------------------------------------------------------\nr21 | snappy.mirrorbot@gmail.com | 2011-03-26 03:34:34 +0100 (Sat, 26 Mar 2011) | 20 lines\n\n\nChange on 2011-03-25 19:18:00-07:00 by sesse\n\n\tReplace the Apache 2.0 license header by the BSD-type license header;\n\tsomehow a lot of the files were missed in the last round.\n\n\tR=dannyb,csilvers\n\tDELTA=147  (74 added, 2 deleted, 71 changed)\n\nChange on 2011-03-25 19:25:07-07:00 by sesse\n\n\tUnbreak the build; the relicensing removed a bit too much (only comments\n\twere intended, but I also accidentially removed some of the top lines of\n\tthe actual source).\n\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1072\n\n------------------------------------------------------------------------\nr20 | snappy.mirrorbot@gmail.com | 2011-03-25 17:14:41 +0100 (Fri, 25 Mar 2011) | 10 lines\n\n\nChange Snappy from the Apache 2.0 to a BSD-type license.\n\nR=dannyb\nDELTA=328  (80 added, 184 deleted, 64 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1061\n\n------------------------------------------------------------------------\nr19 | snappy.mirrorbot@gmail.com | 2011-03-25 01:39:01 +0100 (Fri, 25 Mar 2011) | 11 lines\n\n\nRelease Snappy 1.0.1, to soup up all the various small changes\nthat have been made since release.\n\nR=csilvers\nDELTA=266  (260 added, 0 deleted, 6 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1057\n\n------------------------------------------------------------------------\nr18 | snappy.mirrorbot@gmail.com | 2011-03-24 20:15:54 +0100 (Thu, 24 Mar 2011) | 11 lines\n\n\nFix a microbenchmark crash on mingw32; seemingly %lld is not universally\nsupported on Windows, and %I64d is recommended instead.\n\nR=csilvers\nDELTA=6  (5 added, 0 deleted, 1 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1034\n\n------------------------------------------------------------------------\nr17 | snappy.mirrorbot@gmail.com | 2011-03-24 20:15:27 +0100 (Thu, 24 Mar 2011) | 13 lines\n\n\nFix public issue #19: Fix unit test when Google Test is installed but the\ngflags package isn't (Google Test is not properly initialized).\n\nPatch by Martin Gieseking.\n\nR=csilvers\nDELTA=2  (1 added, 0 deleted, 1 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1033\n\n------------------------------------------------------------------------\nr16 | snappy.mirrorbot@gmail.com | 2011-03-24 20:13:57 +0100 (Thu, 24 Mar 2011) | 15 lines\n\n\nMake the unit test work on systems without mmap(). This is required for,\namong others, Windows support. For Windows in specific, we could have used\nCreateFileMapping/MapViewOfFile, but this should at least get us a bit closer\nto compiling, and is of course also relevant for embedded systems with no MMU.\n\n(Part 2/2)\n\nR=csilvers\nDELTA=15  (12 added, 3 deleted, 0 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1032\n\n------------------------------------------------------------------------\nr15 | snappy.mirrorbot@gmail.com | 2011-03-24 20:12:27 +0100 (Thu, 24 Mar 2011) | 15 lines\n\n\nMake the unit test work on systems without mmap(). This is required for,\namong others, Windows support. For Windows in specific, we could have used\nCreateFileMapping/MapViewOfFile, but this should at least get us a bit closer\nto compiling, and is of course also relevant for embedded systems with no MMU.\n\n(Part 1/2)\n\nR=csilvers\nDELTA=9  (8 added, 0 deleted, 1 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1031\n\n------------------------------------------------------------------------\nr14 | snappy.mirrorbot@gmail.com | 2011-03-24 00:17:36 +0100 (Thu, 24 Mar 2011) | 14 lines\n\n\nFix public issue #12: Don't keep autogenerated auto* files in Subversion;\nit causes problems with others sending patches etc..\n\nWe can't get this 100% hermetic anyhow, due to files like lt~obsolete.m4,\nso we can just as well go cleanly in the other direction.\n\nR=csilvers\nDELTA=21038  (0 added, 21036 deleted, 2 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=1012\n\n------------------------------------------------------------------------\nr13 | snappy.mirrorbot@gmail.com | 2011-03-23 18:50:49 +0100 (Wed, 23 Mar 2011) | 11 lines\n\n\nFix public issue tracker bug #3: Call AC_SUBST([LIBTOOL_DEPS]), or the rule\nto rebuild libtool in Makefile.am won't work.\n\nR=csilvers\nDELTA=1  (1 added, 0 deleted, 0 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=997\n\n------------------------------------------------------------------------\nr12 | snappy.mirrorbot@gmail.com | 2011-03-23 12:16:39 +0100 (Wed, 23 Mar 2011) | 11 lines\n\n\nFix public issue #10: Don't add GTEST_CPPFLAGS to snappy_unittest_CXXFLAGS;\nit's not needed (CPPFLAGS are always included when compiling).\n\nR=csilvers\nDELTA=1  (0 added, 1 deleted, 0 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=994\n\n------------------------------------------------------------------------\nr11 | snappy.mirrorbot@gmail.com | 2011-03-23 12:16:18 +0100 (Wed, 23 Mar 2011) | 11 lines\n\n\nFix public issue #9: Add -Wall -Werror to automake flags.\n(This concerns automake itself, not the C++ compiler.)\n\nR=csilvers\nDELTA=4  (3 added, 0 deleted, 1 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=993\n\n------------------------------------------------------------------------\nr10 | snappy.mirrorbot@gmail.com | 2011-03-23 12:13:37 +0100 (Wed, 23 Mar 2011) | 10 lines\n\n\nFix a typo in the Snappy README file.\n\nR=csilvers\nDELTA=1  (0 added, 0 deleted, 1 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=992\n\n------------------------------------------------------------------------\nr9 | snappy.mirrorbot@gmail.com | 2011-03-23 12:13:13 +0100 (Wed, 23 Mar 2011) | 11 lines\n\n\nFix public issue #6: Add a --with-gflags for disabling gflags autodetection\nand using a manually given setting (use/don't use) instead.\n\nR=csilvers\nDELTA=16  (13 added, 0 deleted, 3 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=991\n\n------------------------------------------------------------------------\nr8 | snappy.mirrorbot@gmail.com | 2011-03-23 12:12:44 +0100 (Wed, 23 Mar 2011) | 12 lines\n\n\nFix public issue #5: Replace the EXTRA_LIBSNAPPY_LDFLAGS setup with something\nslightly more standard, that also doesn't leak libtool command-line into\nconfigure.ac.\n\nR=csilvers\nDELTA=7  (0 added, 4 deleted, 3 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=990\n\n------------------------------------------------------------------------\nr7 | snappy.mirrorbot@gmail.com | 2011-03-23 12:12:22 +0100 (Wed, 23 Mar 2011) | 10 lines\n\n\nFix public issue #4: Properly quote all macro arguments in configure.ac.\n\nR=csilvers\nDELTA=16  (0 added, 0 deleted, 16 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=989\n\n------------------------------------------------------------------------\nr6 | snappy.mirrorbot@gmail.com | 2011-03-23 12:11:54 +0100 (Wed, 23 Mar 2011) | 11 lines\n\n\nFix public issue #7: Don't use internal variables named ac_*, as those belong\nto autoconf's namespace.\n\nR=csilvers\nDELTA=6  (0 added, 0 deleted, 6 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=988\n\n------------------------------------------------------------------------\nr5 | snappy.mirrorbot@gmail.com | 2011-03-23 12:11:09 +0100 (Wed, 23 Mar 2011) | 10 lines\n\n\nAdd missing licensing headers to a few files. (Part 2/2.)\n\nR=csilvers\nDELTA=12  (12 added, 0 deleted, 0 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=987\n\n------------------------------------------------------------------------\nr4 | snappy.mirrorbot@gmail.com | 2011-03-23 12:10:39 +0100 (Wed, 23 Mar 2011) | 10 lines\n\n\nAdd mising licensing headers to a few files. (Part 1/2.)\n\nR=csilvers\nDELTA=24  (24 added, 0 deleted, 0 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=986\n\n------------------------------------------------------------------------\nr3 | snappy.mirrorbot@gmail.com | 2011-03-23 12:10:04 +0100 (Wed, 23 Mar 2011) | 11 lines\n\n\nUse the correct license file for the Apache 2.0 license;\nspotted by Florian Weimer.\n\nR=csilvers\nDELTA=202  (174 added, 0 deleted, 28 changed)\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=985\n\n------------------------------------------------------------------------\nr2 | snappy.mirrorbot@gmail.com | 2011-03-18 18:14:15 +0100 (Fri, 18 Mar 2011) | 6 lines\n\n\n\n\nRevision created by MOE tool push_codebase.\nMOE_MIGRATION=\n\n------------------------------------------------------------------------\nr1 | sesse@google.com | 2011-03-18 18:13:52 +0100 (Fri, 18 Mar 2011) | 2 lines\n\nCreate trunk directory.\n\n------------------------------------------------------------------------\n"
  },
  {
    "path": "deps/snappy-1.1.0/INSTALL",
    "content": "Installation Instructions\n*************************\n\nCopyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,\nInc.\n\n   Copying and distribution of this file, with or without modification,\nare permitted in any medium without royalty provided the copyright\nnotice and this notice are preserved.  This file is offered as-is,\nwithout warranty of any kind.\n\nBasic Installation\n==================\n\n   Briefly, the shell commands `./configure; make; make install' should\nconfigure, build, and install this package.  The following\nmore-detailed instructions are generic; see the `README' file for\ninstructions specific to this package.  Some packages provide this\n`INSTALL' file but do not implement all of the features documented\nbelow.  The lack of an optional feature in a given package is not\nnecessarily a bug.  More recommendations for GNU packages can be found\nin *note Makefile Conventions: (standards)Makefile Conventions.\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 need `configure.ac' if\nyou want to change it or regenerate `configure' using a newer version\nof `autoconf'.\n\n   The 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.\n\n     Running `configure' might take a while.  While running, it prints\n     some 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, generally using the just-built uninstalled binaries.\n\n  4. Type `make install' to install the programs and any data files and\n     documentation.  When installing into a prefix owned by root, it is\n     recommended that the package be configured and built as a regular\n     user, and only the `make install' phase executed with root\n     privileges.\n\n  5. Optionally, type `make installcheck' to repeat any self-tests, but\n     this time using the binaries in their final installed location.\n     This target does not install anything.  Running this target as a\n     regular user, particularly if the prior `make install' required\n     root privileges, verifies that the installation completed\n     correctly.\n\n  6. 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\n  7. Often, you can also type `make uninstall' to remove the installed\n     files again.  In practice, not all packages have tested that\n     uninstallation works correctly, even though it is required by the\n     GNU Coding Standards.\n\n  8. Some packages, particularly those that use Automake, provide `make\n     distcheck', which can by used by developers to test that all other\n     targets like `make install' and `make uninstall' work correctly.\n     This target is generally not run by end users.\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=c99 CFLAGS=-g 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 can use 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 `..'.  This\nis known as a \"VPATH\" build.\n\n   With a non-GNU `make', it is safer to compile the package for one\narchitecture at a time in the source code directory.  After you have\ninstalled the package for one architecture, use `make distclean' before\nreconfiguring for another architecture.\n\n   On MacOS X 10.5 and later systems, you can create libraries and\nexecutables that work on multiple system types--known as \"fat\" or\n\"universal\" binaries--by specifying multiple `-arch' options to the\ncompiler but only a single `-arch' option to the preprocessor.  Like\nthis:\n\n     ./configure CC=\"gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64\" \\\n                 CXX=\"g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64\" \\\n                 CPP=\"gcc -E\" CXXCPP=\"g++ -E\"\n\n   This is not guaranteed to produce working output in all cases, you\nmay have to build one architecture at a time and combine the results\nusing the `lipo' tool if you have problems.\n\nInstallation Names\n==================\n\n   By default, `make install' installs the package's commands under\n`/usr/local/bin', include files under `/usr/local/include', etc.  You\ncan specify an installation prefix other than `/usr/local' by giving\n`configure' the option `--prefix=PREFIX', where PREFIX must be an\nabsolute file name.\n\n   You can specify separate installation prefixes for\narchitecture-specific files and architecture-independent files.  If you\npass the option `--exec-prefix=PREFIX' to `configure', the package uses\nPREFIX as the prefix for installing programs and libraries.\nDocumentation and other data files still use the regular prefix.\n\n   In addition, if you use an unusual directory layout you can give\noptions like `--bindir=DIR' 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.  In general, the\ndefault for these options is expressed in terms of `${prefix}', so that\nspecifying just `--prefix' will affect all of the other directory\nspecifications that were not explicitly provided.\n\n   The most portable way to affect installation locations is to pass the\ncorrect locations to `configure'; however, many packages provide one or\nboth of the following shortcuts of passing variable assignments to the\n`make install' command line to change installation locations without\nhaving to reconfigure or recompile.\n\n   The first method involves providing an override variable for each\naffected directory.  For example, `make install\nprefix=/alternate/directory' will choose an alternate location for all\ndirectory configuration variables that were expressed in terms of\n`${prefix}'.  Any directories that were specified during `configure',\nbut not in terms of `${prefix}', must each be overridden at install\ntime for the entire installation to be relocated.  The approach of\nmakefile variable overrides for each directory variable is required by\nthe GNU Coding Standards, and ideally causes no recompilation.\nHowever, some platforms have known limitations with the semantics of\nshared libraries that end up requiring recompilation when using this\nmethod, particularly noticeable in packages that use GNU Libtool.\n\n   The second method involves providing the `DESTDIR' variable.  For\nexample, `make install DESTDIR=/alternate/directory' will prepend\n`/alternate/directory' before all installation names.  The approach of\n`DESTDIR' overrides is not required by the GNU Coding Standards, and\ndoes not work on platforms that have drive letters.  On the other hand,\nit does better at avoiding recompilation issues, and works well even\nwhen some directory options were not specified in terms of `${prefix}'\nat `configure' time.\n\nOptional Features\n=================\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\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\n   Some packages offer the ability to configure how verbose the\nexecution of `make' will be.  For these packages, running `./configure\n--enable-silent-rules' sets the default to minimal output, which can be\noverridden with `make V=1'; while running `./configure\n--disable-silent-rules' sets the default to verbose, which can be\noverridden with `make V=0'.\n\nParticular systems\n==================\n\n   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU\nCC is not installed, it is recommended to use the following options in\norder to use an ANSI C compiler:\n\n     ./configure CC=\"cc -Ae -D_XOPEN_SOURCE=500\"\n\nand if that doesn't work, install pre-built binaries of GCC for HP-UX.\n\n   HP-UX `make' updates targets which have the same time stamps as\ntheir prerequisites, which makes it generally unusable when shipped\ngenerated files such as `configure' are involved.  Use GNU `make'\ninstead.\n\n   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot\nparse its `<wchar.h>' header file.  The option `-nodtk' can be used as\na workaround.  If GNU CC is not installed, it is therefore recommended\nto try\n\n     ./configure CC=\"cc\"\n\nand if that doesn't work, try\n\n     ./configure CC=\"cc -nodtk\"\n\n   On Solaris, don't put `/usr/ucb' early in your `PATH'.  This\ndirectory contains several dysfunctional programs; working variants of\nthese programs are available in `/usr/bin'.  So, if you need `/usr/ucb'\nin your `PATH', put it _after_ `/usr/bin'.\n\n   On Haiku, software installed for all users goes in `/boot/common',\nnot `/usr/local'.  It is recommended to use the following options:\n\n     ./configure --prefix=/boot/common\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\n     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 option `--target=TYPE' 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\ncauses the specified `gcc' to be used as the C compiler (unless it is\noverridden in the site shell script).\n\nUnfortunately, this technique does not work for `CONFIG_SHELL' due to\nan Autoconf bug.  Until the bug is fixed you can use this workaround:\n\n     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash\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 all of the options to `configure', and exit.\n\n`--help=short'\n`--help=recursive'\n     Print a summary of the options unique to this package's\n     `configure', and exit.  The `short' variant lists options used\n     only in the top level, while the `recursive' variant lists options\n     also present in any nested packages.\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`--prefix=DIR'\n     Use DIR as the installation prefix.  *note Installation Names::\n     for more details, including other options available for fine-tuning\n     the installation locations.\n\n`--no-create'\n`-n'\n     Run the configure checks, but stop before creating any output\n     files.\n\n`configure' also accepts some other, not widely useful, options.  Run\n`configure --help' for more details.\n\n"
  },
  {
    "path": "deps/snappy-1.1.0/Makefile-ios",
    "content": "PLATFORMSROOT=/Applications/Xcode.app/Contents/Developer/Platforms\nSIMULATORROOT=$(PLATFORMSROOT)/iPhoneSimulator.platform/Developer\nDEVICEROOT=$(PLATFORMSROOT)/iPhoneOS.platform/Developer\nIOSVERSION=$(shell defaults read $(PLATFORMSROOT)/iPhoneOS.platform/version CFBundleShortVersionString)\nSIMULATOR_SDK=$(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk\nDEVICE_SDK=$(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk\n\nCFLAGS= -miphoneos-version-min=7.0 -stdlib=libc++ -DHAVE_CONFIG_H -I. -O2\nSIMULATOR_CFLAGS=$(CFLAGS) -isysroot $(SIMULATOR_SDK) -arch i386 -arch x86_64\nDEVICE_CFLAGS=$(CFLAGS) -isysroot $(DEVICE_SDK) -arch armv6 -arch armv7 -arch armv7s -arch arm64\n\n#OBJS = $(patsubst %.cc, %.o, $(wildcard *.cc))\nOBJS = snappy-c.o snappy-sinksource.o snappy-stubs-internal.o snappy.o\n\nall: $(OBJS)\n\trm -f libsnappy-ios.a\n\tar -rs libsnappy-ios.a $(OBJS)\n\n.cc.o:\n\tmkdir -p ios-x86\n\tmkdir -p ios-arm\n\txcrun -sdk iphonesimulator clang++ $(SIMULATOR_CFLAGS) -c $< -o ios-x86/$@\n\txcrun -sdk iphoneos clang++ $(DEVICE_CFLAGS) -c $< -o ios-arm/$@\n\tlipo ios-x86/$@ ios-arm/$@ -create -output $@\n\nclean:\n\trm -rf *.o *.a ios-x86 ios-arm\n\n"
  },
  {
    "path": "deps/snappy-1.1.0/Makefile.am",
    "content": "ACLOCAL_AMFLAGS = -I m4\n\n# Library.\nlib_LTLIBRARIES = libsnappy.la\nlibsnappy_la_SOURCES = snappy.cc snappy-sinksource.cc snappy-stubs-internal.cc snappy-c.cc\nlibsnappy_la_LDFLAGS = -version-info $(SNAPPY_LTVERSION)\n\ninclude_HEADERS = snappy.h snappy-sinksource.h snappy-stubs-public.h snappy-c.h\nnoinst_HEADERS = snappy-internal.h snappy-stubs-internal.h snappy-test.h\n\n# Unit tests and benchmarks.\nsnappy_unittest_CPPFLAGS = $(gflags_CFLAGS) $(GTEST_CPPFLAGS)\nsnappy_unittest_SOURCES = snappy_unittest.cc snappy-test.cc\nsnappy_unittest_LDFLAGS = $(GTEST_LDFLAGS)\nsnappy_unittest_LDADD = libsnappy.la $(UNITTEST_LIBS) $(gflags_LIBS) $(GTEST_LIBS)\nTESTS = snappy_unittest\nnoinst_PROGRAMS = $(TESTS)\n\nEXTRA_DIST = autogen.sh testdata/alice29.txt testdata/asyoulik.txt testdata/baddata1.snappy testdata/baddata2.snappy testdata/baddata3.snappy testdata/cp.html testdata/fields.c testdata/geo.protodata testdata/grammar.lsp testdata/house.jpg testdata/html testdata/html_x_4 testdata/kennedy.xls testdata/kppkn.gtb testdata/lcet10.txt testdata/mapreduce-osdi-1.pdf testdata/plrabn12.txt testdata/ptt5 testdata/sum testdata/urls.10K testdata/xargs.1 \ndist_doc_DATA = ChangeLog COPYING INSTALL NEWS README format_description.txt framing_format.txt\n\nlibtool: $(LIBTOOL_DEPS)\n\t$(SHELL) ./config.status --recheck\n"
  },
  {
    "path": "deps/snappy-1.1.0/Makefile.in",
    "content": "# Makefile.in generated by automake 1.11.3 from Makefile.am.\n# @configure_input@\n\n# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,\n# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software\n# 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\n\n\nVPATH = @srcdir@\npkgdatadir = $(datadir)/@PACKAGE@\npkgincludedir = $(includedir)/@PACKAGE@\npkglibdir = $(libdir)/@PACKAGE@\npkglibexecdir = $(libexecdir)/@PACKAGE@\nam__cd = CDPATH=\"$${ZSH_VERSION+.}$(PATH_SEPARATOR)\" && cd\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@\nTESTS = snappy_unittest$(EXEEXT)\nnoinst_PROGRAMS = $(am__EXEEXT_1)\nsubdir = .\nDIST_COMMON = README $(am__configure_deps) $(dist_doc_DATA) \\\n\t$(include_HEADERS) $(noinst_HEADERS) $(srcdir)/Makefile.am \\\n\t$(srcdir)/Makefile.in $(srcdir)/config.h.in \\\n\t$(srcdir)/snappy-stubs-public.h.in $(top_srcdir)/configure \\\n\tAUTHORS COPYING ChangeLog INSTALL NEWS config.guess config.sub \\\n\tdepcomp install-sh ltmain.sh missing\nACLOCAL_M4 = $(top_srcdir)/aclocal.m4\nam__aclocal_m4_deps = $(top_srcdir)/m4/gtest.m4 \\\n\t$(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 config.status.lineno\nmkinstalldirs = $(install_sh) -d\nCONFIG_HEADER = config.h\nCONFIG_CLEAN_FILES = snappy-stubs-public.h\nCONFIG_CLEAN_VPATH_FILES =\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 = f=`echo $$p | sed -e 's|^.*/||'`;\nam__install_max = 40\nam__nobase_strip_setup = \\\n  srcdirstrip=`echo \"$(srcdir)\" | sed 's/[].[^$$\\\\*|]/\\\\\\\\&/g'`\nam__nobase_strip = \\\n  for p in $$list; do echo \"$$p\"; done | sed -e \"s|$$srcdirstrip/||\"\nam__nobase_list = $(am__nobase_strip_setup); \\\n  for p in $$list; do echo \"$$p $$p\"; done | \\\n  sed \"s| $$srcdirstrip/| |;\"' / .*\\//!s/ .*/ ./; s,\\( .*\\)/[^/]*$$,\\1,' | \\\n  $(AWK) 'BEGIN { files[\".\"] = \"\" } { files[$$2] = files[$$2] \" \" $$1; \\\n    if (++n[$$2] == $(am__install_max)) \\\n      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = \"\" } } \\\n    END { for (dir in files) print dir, files[dir] }'\nam__base_list = \\\n  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\\n/ /g' | \\\n  sed '$$!N;$$!N;$$!N;$$!N;s/\\n/ /g'\nam__uninstall_files_from_dir = { \\\n  test -z \"$$files\" \\\n    || { test ! -d \"$$dir\" && test ! -f \"$$dir\" && test ! -r \"$$dir\"; } \\\n    || { echo \" ( cd '$$dir' && rm -f\" $$files \")\"; \\\n         $(am__cd) \"$$dir\" && rm -f $$files; }; \\\n  }\nam__installdirs = \"$(DESTDIR)$(libdir)\" \"$(DESTDIR)$(docdir)\" \\\n\t\"$(DESTDIR)$(includedir)\"\nLTLIBRARIES = $(lib_LTLIBRARIES)\nlibsnappy_la_LIBADD =\nam_libsnappy_la_OBJECTS = snappy.lo snappy-sinksource.lo \\\n\tsnappy-stubs-internal.lo snappy-c.lo\nlibsnappy_la_OBJECTS = $(am_libsnappy_la_OBJECTS)\nlibsnappy_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \\\n\t$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \\\n\t$(CXXFLAGS) $(libsnappy_la_LDFLAGS) $(LDFLAGS) -o $@\nam__EXEEXT_1 = snappy_unittest$(EXEEXT)\nPROGRAMS = $(noinst_PROGRAMS)\nam_snappy_unittest_OBJECTS =  \\\n\tsnappy_unittest-snappy_unittest.$(OBJEXT) \\\n\tsnappy_unittest-snappy-test.$(OBJEXT)\nsnappy_unittest_OBJECTS = $(am_snappy_unittest_OBJECTS)\nam__DEPENDENCIES_1 =\nsnappy_unittest_DEPENDENCIES = libsnappy.la $(am__DEPENDENCIES_1) \\\n\t$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)\nsnappy_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \\\n\t$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \\\n\t$(CXXFLAGS) $(snappy_unittest_LDFLAGS) $(LDFLAGS) -o $@\nDEFAULT_INCLUDES = -I.@am__isrc@\ndepcomp = $(SHELL) $(top_srcdir)/depcomp\nam__depfiles_maybe = depfiles\nam__mv = mv -f\nCXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \\\n\t$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)\nLTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \\\n\t--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \\\n\t$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)\nCXXLD = $(CXX)\nCXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \\\n\t--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \\\n\t$(LDFLAGS) -o $@\nSOURCES = $(libsnappy_la_SOURCES) $(snappy_unittest_SOURCES)\nDIST_SOURCES = $(libsnappy_la_SOURCES) $(snappy_unittest_SOURCES)\nDATA = $(dist_doc_DATA)\nHEADERS = $(include_HEADERS) $(noinst_HEADERS)\nETAGS = etags\nCTAGS = ctags\nam__tty_colors = \\\nred=; grn=; lgn=; blu=; std=\nDISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)\ndistdir = $(PACKAGE)-$(VERSION)\ntop_distdir = $(distdir)\nam__remove_distdir = \\\n  if test -d \"$(distdir)\"; then \\\n    find \"$(distdir)\" -type d ! -perm -200 -exec chmod u+w {} ';' \\\n      && rm -rf \"$(distdir)\" \\\n      || { sleep 5 && rm -rf \"$(distdir)\"; }; \\\n  else :; fi\nDIST_ARCHIVES = $(distdir).tar.gz\nGZIP_ENV = --best\ndistuninstallcheck_listfiles = find . -type f -print\nam__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \\\n  | sed 's|^\\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'\ndistcleancheck_listfiles = find . -type f -print\nACLOCAL = @ACLOCAL@\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@\nDLLTOOL = @DLLTOOL@\nDSYMUTIL = @DSYMUTIL@\nDUMPBIN = @DUMPBIN@\nECHO_C = @ECHO_C@\nECHO_N = @ECHO_N@\nECHO_T = @ECHO_T@\nEGREP = @EGREP@\nEXEEXT = @EXEEXT@\nFGREP = @FGREP@\nGREP = @GREP@\nGTEST_CONFIG = @GTEST_CONFIG@\nGTEST_CPPFLAGS = @GTEST_CPPFLAGS@\nGTEST_CXXFLAGS = @GTEST_CXXFLAGS@\nGTEST_LDFLAGS = @GTEST_LDFLAGS@\nGTEST_LIBS = @GTEST_LIBS@\nGTEST_VERSION = @GTEST_VERSION@\nHAVE_GTEST = @HAVE_GTEST@\nINSTALL = @INSTALL@\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@\nLIBTOOL = @LIBTOOL@\nLIBTOOL_DEPS = @LIBTOOL_DEPS@\nLIPO = @LIPO@\nLN_S = @LN_S@\nLTLIBOBJS = @LTLIBOBJS@\nMAKEINFO = @MAKEINFO@\nMANIFEST_TOOL = @MANIFEST_TOOL@\nMKDIR_P = @MKDIR_P@\nNM = @NM@\nNMEDIT = @NMEDIT@\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@\nPKG_CONFIG = @PKG_CONFIG@\nPKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@\nPKG_CONFIG_PATH = @PKG_CONFIG_PATH@\nRANLIB = @RANLIB@\nSED = @SED@\nSET_MAKE = @SET_MAKE@\nSHELL = @SHELL@\nSNAPPY_LTVERSION = @SNAPPY_LTVERSION@\nSNAPPY_MAJOR = @SNAPPY_MAJOR@\nSNAPPY_MINOR = @SNAPPY_MINOR@\nSNAPPY_PATCHLEVEL = @SNAPPY_PATCHLEVEL@\nSTRIP = @STRIP@\nUNITTEST_LIBS = @UNITTEST_LIBS@\nVERSION = @VERSION@\nabs_builddir = @abs_builddir@\nabs_srcdir = @abs_srcdir@\nabs_top_builddir = @abs_top_builddir@\nabs_top_srcdir = @abs_top_srcdir@\nac_ct_AR = @ac_ct_AR@\nac_ct_CC = @ac_ct_CC@\nac_ct_CXX = @ac_ct_CXX@\nac_ct_DUMPBIN = @ac_ct_DUMPBIN@\nac_cv_have_stddef_h = @ac_cv_have_stddef_h@\nac_cv_have_stdint_h = @ac_cv_have_stdint_h@\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@\nbuilddir = @builddir@\ndatadir = @datadir@\ndatarootdir = @datarootdir@\ndocdir = @docdir@\ndvidir = @dvidir@\nexec_prefix = @exec_prefix@\ngflags_CFLAGS = @gflags_CFLAGS@\ngflags_LIBS = @gflags_LIBS@\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@\nmandir = @mandir@\nmkdir_p = @mkdir_p@\noldincludedir = @oldincludedir@\npdfdir = @pdfdir@\nprefix = @prefix@\nprogram_transform_name = @program_transform_name@\npsdir = @psdir@\nsbindir = @sbindir@\nsharedstatedir = @sharedstatedir@\nsrcdir = @srcdir@\nsysconfdir = @sysconfdir@\ntarget_alias = @target_alias@\ntop_build_prefix = @top_build_prefix@\ntop_builddir = @top_builddir@\ntop_srcdir = @top_srcdir@\nACLOCAL_AMFLAGS = -I m4\n\n# Library.\nlib_LTLIBRARIES = libsnappy.la\nlibsnappy_la_SOURCES = snappy.cc snappy-sinksource.cc snappy-stubs-internal.cc snappy-c.cc\nlibsnappy_la_LDFLAGS = -version-info $(SNAPPY_LTVERSION)\ninclude_HEADERS = snappy.h snappy-sinksource.h snappy-stubs-public.h snappy-c.h\nnoinst_HEADERS = snappy-internal.h snappy-stubs-internal.h snappy-test.h\n\n# Unit tests and benchmarks.\nsnappy_unittest_CPPFLAGS = $(gflags_CFLAGS) $(GTEST_CPPFLAGS)\nsnappy_unittest_SOURCES = snappy_unittest.cc snappy-test.cc\nsnappy_unittest_LDFLAGS = $(GTEST_LDFLAGS)\nsnappy_unittest_LDADD = libsnappy.la $(UNITTEST_LIBS) $(gflags_LIBS) $(GTEST_LIBS)\nEXTRA_DIST = autogen.sh testdata/alice29.txt testdata/asyoulik.txt testdata/baddata1.snappy testdata/baddata2.snappy testdata/baddata3.snappy testdata/cp.html testdata/fields.c testdata/geo.protodata testdata/grammar.lsp testdata/house.jpg testdata/html testdata/html_x_4 testdata/kennedy.xls testdata/kppkn.gtb testdata/lcet10.txt testdata/mapreduce-osdi-1.pdf testdata/plrabn12.txt testdata/ptt5 testdata/sum testdata/urls.10K testdata/xargs.1 \ndist_doc_DATA = ChangeLog COPYING INSTALL NEWS README format_description.txt framing_format.txt\nall: config.h\n\t$(MAKE) $(AM_MAKEFLAGS) all-am\n\n.SUFFIXES:\n.SUFFIXES: .cc .lo .o .obj\nam--refresh: Makefile\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      $(am__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\t$(am__cd) $(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\t$(am__cd) $(srcdir) && $(AUTOCONF)\n$(ACLOCAL_M4):  $(am__aclocal_m4_deps)\n\t$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)\n$(am__aclocal_m4_deps):\n\nconfig.h: stamp-h1\n\t@if test ! -f $@; then rm -f stamp-h1; else :; fi\n\t@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi\n\nstamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status\n\t@rm -f stamp-h1\n\tcd $(top_builddir) && $(SHELL) ./config.status config.h\n$(srcdir)/config.h.in:  $(am__configure_deps) \n\t($(am__cd) $(top_srcdir) && $(AUTOHEADER))\n\trm -f stamp-h1\n\ttouch $@\n\ndistclean-hdr:\n\t-rm -f config.h stamp-h1\nsnappy-stubs-public.h: $(top_builddir)/config.status $(srcdir)/snappy-stubs-public.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)'; test -n \"$(libdir)\" || list=; \\\n\tlist2=; for p in $$list; do \\\n\t  if test -f $$p; then \\\n\t    list2=\"$$list2 $$p\"; \\\n\t  else :; fi; \\\n\tdone; \\\n\ttest -z \"$$list2\" || { \\\n\t  echo \" $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'\"; \\\n\t  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 \"$(DESTDIR)$(libdir)\"; \\\n\t}\n\nuninstall-libLTLIBRARIES:\n\t@$(NORMAL_UNINSTALL)\n\t@list='$(lib_LTLIBRARIES)'; test -n \"$(libdir)\" || list=; \\\n\tfor p in $$list; do \\\n\t  $(am__strip_dir) \\\n\t  echo \" $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'\"; \\\n\t  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f \"$(DESTDIR)$(libdir)/$$f\"; \\\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\nlibsnappy.la: $(libsnappy_la_OBJECTS) $(libsnappy_la_DEPENDENCIES) $(EXTRA_libsnappy_la_DEPENDENCIES) \n\t$(libsnappy_la_LINK) -rpath $(libdir) $(libsnappy_la_OBJECTS) $(libsnappy_la_LIBADD) $(LIBS)\n\nclean-noinstPROGRAMS:\n\t@list='$(noinst_PROGRAMS)'; test -n \"$$list\" || exit 0; \\\n\techo \" rm -f\" $$list; \\\n\trm -f $$list || exit $$?; \\\n\ttest -n \"$(EXEEXT)\" || exit 0; \\\n\tlist=`for p in $$list; do echo \"$$p\"; done | sed 's/$(EXEEXT)$$//'`; \\\n\techo \" rm -f\" $$list; \\\n\trm -f $$list\nsnappy_unittest$(EXEEXT): $(snappy_unittest_OBJECTS) $(snappy_unittest_DEPENDENCIES) $(EXTRA_snappy_unittest_DEPENDENCIES) \n\t@rm -f snappy_unittest$(EXEEXT)\n\t$(snappy_unittest_LINK) $(snappy_unittest_OBJECTS) $(snappy_unittest_LDADD) $(LIBS)\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)/snappy-c.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snappy-sinksource.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snappy-stubs-internal.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snappy.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snappy_unittest-snappy-test.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snappy_unittest-snappy_unittest.Po@am__quote@\n\n.cc.o:\n@am__fastdepCXX_TRUE@\t$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<\n@am__fastdepCXX_TRUE@\t$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po\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@\t$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`\n@am__fastdepCXX_TRUE@\t$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po\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@\t$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<\n@am__fastdepCXX_TRUE@\t$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo\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\nsnappy_unittest-snappy_unittest.o: snappy_unittest.cc\n@am__fastdepCXX_TRUE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(snappy_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT snappy_unittest-snappy_unittest.o -MD -MP -MF $(DEPDIR)/snappy_unittest-snappy_unittest.Tpo -c -o snappy_unittest-snappy_unittest.o `test -f 'snappy_unittest.cc' || echo '$(srcdir)/'`snappy_unittest.cc\n@am__fastdepCXX_TRUE@\t$(am__mv) $(DEPDIR)/snappy_unittest-snappy_unittest.Tpo $(DEPDIR)/snappy_unittest-snappy_unittest.Po\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='snappy_unittest.cc' object='snappy_unittest-snappy_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) $(snappy_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o snappy_unittest-snappy_unittest.o `test -f 'snappy_unittest.cc' || echo '$(srcdir)/'`snappy_unittest.cc\n\nsnappy_unittest-snappy_unittest.obj: snappy_unittest.cc\n@am__fastdepCXX_TRUE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(snappy_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT snappy_unittest-snappy_unittest.obj -MD -MP -MF $(DEPDIR)/snappy_unittest-snappy_unittest.Tpo -c -o snappy_unittest-snappy_unittest.obj `if test -f 'snappy_unittest.cc'; then $(CYGPATH_W) 'snappy_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/snappy_unittest.cc'; fi`\n@am__fastdepCXX_TRUE@\t$(am__mv) $(DEPDIR)/snappy_unittest-snappy_unittest.Tpo $(DEPDIR)/snappy_unittest-snappy_unittest.Po\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='snappy_unittest.cc' object='snappy_unittest-snappy_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) $(snappy_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o snappy_unittest-snappy_unittest.obj `if test -f 'snappy_unittest.cc'; then $(CYGPATH_W) 'snappy_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/snappy_unittest.cc'; fi`\n\nsnappy_unittest-snappy-test.o: snappy-test.cc\n@am__fastdepCXX_TRUE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(snappy_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT snappy_unittest-snappy-test.o -MD -MP -MF $(DEPDIR)/snappy_unittest-snappy-test.Tpo -c -o snappy_unittest-snappy-test.o `test -f 'snappy-test.cc' || echo '$(srcdir)/'`snappy-test.cc\n@am__fastdepCXX_TRUE@\t$(am__mv) $(DEPDIR)/snappy_unittest-snappy-test.Tpo $(DEPDIR)/snappy_unittest-snappy-test.Po\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='snappy-test.cc' object='snappy_unittest-snappy-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) $(snappy_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o snappy_unittest-snappy-test.o `test -f 'snappy-test.cc' || echo '$(srcdir)/'`snappy-test.cc\n\nsnappy_unittest-snappy-test.obj: snappy-test.cc\n@am__fastdepCXX_TRUE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(snappy_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT snappy_unittest-snappy-test.obj -MD -MP -MF $(DEPDIR)/snappy_unittest-snappy-test.Tpo -c -o snappy_unittest-snappy-test.obj `if test -f 'snappy-test.cc'; then $(CYGPATH_W) 'snappy-test.cc'; else $(CYGPATH_W) '$(srcdir)/snappy-test.cc'; fi`\n@am__fastdepCXX_TRUE@\t$(am__mv) $(DEPDIR)/snappy_unittest-snappy-test.Tpo $(DEPDIR)/snappy_unittest-snappy-test.Po\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='snappy-test.cc' object='snappy_unittest-snappy-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) $(snappy_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o snappy_unittest-snappy-test.obj `if test -f 'snappy-test.cc'; then $(CYGPATH_W) 'snappy-test.cc'; else $(CYGPATH_W) '$(srcdir)/snappy-test.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 config.lt\ninstall-dist_docDATA: $(dist_doc_DATA)\n\t@$(NORMAL_INSTALL)\n\ttest -z \"$(docdir)\" || $(MKDIR_P) \"$(DESTDIR)$(docdir)\"\n\t@list='$(dist_doc_DATA)'; test -n \"$(docdir)\" || list=; \\\n\tfor p in $$list; do \\\n\t  if test -f \"$$p\"; then d=; else d=\"$(srcdir)/\"; fi; \\\n\t  echo \"$$d$$p\"; \\\n\tdone | $(am__base_list) | \\\n\twhile read files; do \\\n\t  echo \" $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'\"; \\\n\t  $(INSTALL_DATA) $$files \"$(DESTDIR)$(docdir)\" || exit $$?; \\\n\tdone\n\nuninstall-dist_docDATA:\n\t@$(NORMAL_UNINSTALL)\n\t@list='$(dist_doc_DATA)'; test -n \"$(docdir)\" || list=; \\\n\tfiles=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \\\n\tdir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir)\ninstall-includeHEADERS: $(include_HEADERS)\n\t@$(NORMAL_INSTALL)\n\ttest -z \"$(includedir)\" || $(MKDIR_P) \"$(DESTDIR)$(includedir)\"\n\t@list='$(include_HEADERS)'; test -n \"$(includedir)\" || list=; \\\n\tfor p in $$list; do \\\n\t  if test -f \"$$p\"; then d=; else d=\"$(srcdir)/\"; fi; \\\n\t  echo \"$$d$$p\"; \\\n\tdone | $(am__base_list) | \\\n\twhile read files; do \\\n\t  echo \" $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'\"; \\\n\t  $(INSTALL_HEADER) $$files \"$(DESTDIR)$(includedir)\" || exit $$?; \\\n\tdone\n\nuninstall-includeHEADERS:\n\t@$(NORMAL_UNINSTALL)\n\t@list='$(include_HEADERS)'; test -n \"$(includedir)\" || list=; \\\n\tfiles=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \\\n\tdir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)\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; nonempty = 1; } \\\n\t      END { if (nonempty) { for (i in files) print i; }; }'`; \\\n\tmkid -fID $$unique\ntags: TAGS\n\nTAGS:  $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \\\n\t\t$(TAGS_FILES) $(LISP)\n\tset x; \\\n\there=`pwd`; \\\n\tlist='$(SOURCES) $(HEADERS) config.h.in $(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; nonempty = 1; } \\\n\t      END { if (nonempty) { for (i in files) print i; }; }'`; \\\n\tshift; \\\n\tif test -z \"$(ETAGS_ARGS)$$*$$unique\"; then :; else \\\n\t  test -n \"$$unique\" || unique=$$empty_fix; \\\n\t  if test $$# -gt 0; then \\\n\t    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \\\n\t      \"$$@\" $$unique; \\\n\t  else \\\n\t    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \\\n\t      $$unique; \\\n\t  fi; \\\n\tfi\nctags: CTAGS\nCTAGS:  $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \\\n\t\t$(TAGS_FILES) $(LISP)\n\tlist='$(SOURCES) $(HEADERS) config.h.in $(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; nonempty = 1; } \\\n\t      END { if (nonempty) { for (i in files) print i; }; }'`; \\\n\ttest -z \"$(CTAGS_ARGS)$$unique\" \\\n\t  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \\\n\t     $$unique\n\nGTAGS:\n\there=`$(am__cd) $(top_builddir) && pwd` \\\n\t  && $(am__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\t$(am__tty_colors); \\\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      *[\\ \\\t]$$tst[\\ \\\t]*) \\\n\t\txpass=`expr $$xpass + 1`; \\\n\t\tfailed=`expr $$failed + 1`; \\\n\t\tcol=$$red; res=XPASS; \\\n\t      ;; \\\n\t      *) \\\n\t\tcol=$$grn; res=PASS; \\\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      *[\\ \\\t]$$tst[\\ \\\t]*) \\\n\t\txfail=`expr $$xfail + 1`; \\\n\t\tcol=$$lgn; res=XFAIL; \\\n\t      ;; \\\n\t      *) \\\n\t\tfailed=`expr $$failed + 1`; \\\n\t\tcol=$$red; res=FAIL; \\\n\t      ;; \\\n\t      esac; \\\n\t    else \\\n\t      skip=`expr $$skip + 1`; \\\n\t      col=$$blu; res=SKIP; \\\n\t    fi; \\\n\t    echo \"$${col}$$res$${std}: $$tst\"; \\\n\t  done; \\\n\t  if test \"$$all\" -eq 1; then \\\n\t    tests=\"test\"; \\\n\t    All=\"\"; \\\n\t  else \\\n\t    tests=\"tests\"; \\\n\t    All=\"All \"; \\\n\t  fi; \\\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      if test \"$$xfail\" -eq 1; then failures=failure; else failures=failures; fi; \\\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      if test \"$$xpass\" -eq 1; then passes=pass; else passes=passes; fi; \\\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    if test \"$$skip\" -eq 1; then \\\n\t      skipped=\"($$skip test was not run)\"; \\\n\t    else \\\n\t      skipped=\"($$skip tests were not run)\"; \\\n\t    fi; \\\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  if test \"$$failed\" -eq 0; then \\\n\t    col=\"$$grn\"; \\\n\t  else \\\n\t    col=\"$$red\"; \\\n\t  fi; \\\n\t  echo \"$${col}$$dashes$${std}\"; \\\n\t  echo \"$${col}$$banner$${std}\"; \\\n\t  test -z \"$$skipped\" || echo \"$${col}$$skipped$${std}\"; \\\n\t  test -z \"$$report\" || echo \"$${col}$$report$${std}\"; \\\n\t  echo \"$${col}$$dashes$${std}\"; \\\n\t  test \"$$failed\" -eq 0; \\\n\telse :; fi\n\ndistdir: $(DISTFILES)\n\t$(am__remove_distdir)\n\ttest -d \"$(distdir)\" || mkdir \"$(distdir)\"\n\t@srcdirstrip=`echo \"$(srcdir)\" | sed 's/[].[^$$\\\\*]/\\\\\\\\&/g'`; \\\n\ttopsrcdirstrip=`echo \"$(top_srcdir)\" | sed 's/[].[^$$\\\\*]/\\\\\\\\&/g'`; \\\n\tlist='$(DISTFILES)'; \\\n\t  dist_files=`for file in $$list; do echo $$file; done | \\\n\t  sed -e \"s|^$$srcdirstrip/||;t\" \\\n\t      -e \"s|^$$topsrcdirstrip/|$(top_builddir)/|;t\"`; \\\n\tcase $$dist_files in \\\n\t  */*) $(MKDIR_P) `echo \"$$dist_files\" | \\\n\t\t\t   sed '/\\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \\\n\t\t\t   sort -u` ;; \\\n\tesac; \\\n\tfor file in $$dist_files; do \\\n\t  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \\\n\t  if test -d $$d/$$file; then \\\n\t    dir=`echo \"/$$file\" | sed -e 's,/[^/]*$$,,'`; \\\n\t    if test -d \"$(distdir)/$$file\"; then \\\n\t      find \"$(distdir)/$$file\" -type d ! -perm -700 -exec chmod u+rwx {} \\;; \\\n\t    fi; \\\n\t    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \\\n\t      cp -fpR $(srcdir)/$$file \"$(distdir)$$dir\" || exit 1; \\\n\t      find \"$(distdir)/$$file\" -type d ! -perm -700 -exec chmod u+rwx {} \\;; \\\n\t    fi; \\\n\t    cp -fpR $$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-test -n \"$(am__skip_mode_fix)\" \\\n\t|| find \"$(distdir)\" -type d ! -perm -755 \\\n\t\t-exec chmod u+rwx,go+rx {} \\; -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 $(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=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2\n\t$(am__remove_distdir)\n\ndist-lzip: distdir\n\ttardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz\n\t$(am__remove_distdir)\n\ndist-lzma: distdir\n\ttardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma\n\t$(am__remove_distdir)\n\ndist-xz: distdir\n\ttardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz\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)\n\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$(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) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\\\n\t*.tar.bz2*) \\\n\t  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\\\n\t*.tar.lzma*) \\\n\t  lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\\\n\t*.tar.lz*) \\\n\t  lzip -dc $(distdir).tar.lz | $(am__untar) ;;\\\n\t*.tar.xz*) \\\n\t  xz -dc $(distdir).tar.xz | $(am__untar) ;;\\\n\t*.tar.Z*) \\\n\t  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\\\n\t*.shar.gz*) \\\n\t  GZIP=$(GZIP_ENV) gzip -dc $(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\ttest -d $(distdir)/_build || exit 0; \\\n\tdc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\\\/]:[\\\\/],/,'` \\\n\t  && dc_destdir=\"$${TMPDIR-/tmp}/am-dc-$$$$/\" \\\n\t  && am__cwd=`pwd` \\\n\t  && $(am__cd) $(distdir)/_build \\\n\t  && ../configure --srcdir=.. --prefix=\"$$dc_install_base\" \\\n\t    $(AM_DISTCHECK_CONFIGURE_FLAGS) \\\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  && cd \"$$am__cwd\" \\\n\t  || exit 1\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 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'\ndistuninstallcheck:\n\t@test -n '$(distuninstallcheck_dir)' || { \\\n\t  echo 'ERROR: trying to run $@ with an empty' \\\n\t       '$$(distuninstallcheck_dir)' >&2; \\\n\t  exit 1; \\\n\t}; \\\n\t$(am__cd) '$(distuninstallcheck_dir)' || { \\\n\t  echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \\\n\t  exit 1; \\\n\t}; \\\n\ttest `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \\\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-TESTS\ncheck: check-am\nall-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) $(HEADERS) \\\n\t\tconfig.h\ninstalldirs:\n\tfor dir in \"$(DESTDIR)$(libdir)\" \"$(DESTDIR)$(docdir)\" \"$(DESTDIR)$(includedir)\"; 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\tif test -z '$(STRIP)'; then \\\n\t  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" \\\n\t    install_sh_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" INSTALL_STRIP_FLAG=-s \\\n\t      install; \\\n\telse \\\n\t  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" \\\n\t    install_sh_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" INSTALL_STRIP_FLAG=-s \\\n\t    \"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'\" install; \\\n\tfi\nmostlyclean-generic:\n\nclean-generic:\n\ndistclean-generic:\n\t-test -z \"$(CONFIG_CLEAN_FILES)\" || rm -f $(CONFIG_CLEAN_FILES)\n\t-test . = \"$(srcdir)\" || test -z \"$(CONFIG_CLEAN_VPATH_FILES)\" || rm -f $(CONFIG_CLEAN_VPATH_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-generic clean-libLTLIBRARIES clean-libtool \\\n\tclean-noinstPROGRAMS mostlyclean-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\nhtml-am:\n\ninfo: info-am\n\ninfo-am:\n\ninstall-data-am: install-dist_docDATA install-includeHEADERS\n\ninstall-dvi: install-dvi-am\n\ninstall-dvi-am:\n\ninstall-exec-am: install-libLTLIBRARIES\n\ninstall-html: install-html-am\n\ninstall-html-am:\n\ninstall-info: install-info-am\n\ninstall-info-am:\n\ninstall-man:\n\ninstall-pdf: install-pdf-am\n\ninstall-pdf-am:\n\ninstall-ps: install-ps-am\n\ninstall-ps-am:\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-dist_docDATA uninstall-includeHEADERS \\\n\tuninstall-libLTLIBRARIES\n\n.MAKE: all check-am install-am install-strip\n\n.PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \\\n\tclean clean-generic clean-libLTLIBRARIES clean-libtool \\\n\tclean-noinstPROGRAMS ctags dist dist-all dist-bzip2 dist-gzip \\\n\tdist-lzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \\\n\tdistcheck distclean distclean-compile distclean-generic \\\n\tdistclean-hdr distclean-libtool distclean-tags distcleancheck \\\n\tdistdir distuninstallcheck dvi dvi-am html html-am info \\\n\tinfo-am install install-am install-data install-data-am \\\n\tinstall-dist_docDATA install-dvi install-dvi-am install-exec \\\n\tinstall-exec-am install-html install-html-am \\\n\tinstall-includeHEADERS install-info install-info-am \\\n\tinstall-libLTLIBRARIES install-man install-pdf install-pdf-am \\\n\tinstall-ps install-ps-am install-strip installcheck \\\n\tinstallcheck-am installdirs maintainer-clean \\\n\tmaintainer-clean-generic mostlyclean mostlyclean-compile \\\n\tmostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \\\n\ttags uninstall uninstall-am uninstall-dist_docDATA \\\n\tuninstall-includeHEADERS uninstall-libLTLIBRARIES\n\n\nlibtool: $(LIBTOOL_DEPS)\n\t$(SHELL) ./config.status --recheck\n\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": "deps/snappy-1.1.0/NEWS",
    "content": "Snappy v1.1.0, January 18th 2013:\n\n  * Snappy now uses 64 kB block size instead of 32 kB. On average,\n    this means it compresses about 3% denser (more so for some\n    inputs), at the same or better speeds.\n\n  * libsnappy no longer depends on iostream.\n\n  * Some small performance improvements in compression on x86\n    (0.5–1%).\n\n  * Various portability fixes for ARM-based platforms, for MSVC,\n    and for GNU/Hurd.\n\n\nSnappy v1.0.5, February 24th 2012:\n\n  * More speed improvements. Exactly how big will depend on\n    the architecture:\n\n    - 3–10% faster decompression for the base case (x86-64).\n\n    - ARMv7 and higher can now use unaligned accesses,\n      and will see about 30% faster decompression and\n      20–40% faster compression.\n\n    - 32-bit platforms (ARM and 32-bit x86) will see 2–5%\n      faster compression.\n\n    These are all cumulative (e.g., ARM gets all three speedups).\n\n  * Fixed an issue where the unit test would crash on system\n    with less than 256 MB address space available,\n    e.g. some embedded platforms.\n\n  * Added a framing format description, for use over e.g. HTTP,\n    or for a command-line compressor. We do not have any\n    implementations of this at the current point, but there seems\n    to be enough of a general interest in the topic.\n    Also make the format description slightly clearer.\n\n  * Remove some compile-time warnings in -Wall\n    (mostly signed/unsigned comparisons), for easier embedding\n    into projects that use -Wall -Werror.\n\n\nSnappy v1.0.4, September 15th 2011:\n\n  * Speeded up the decompressor somewhat; typically about 2–8%\n    for Core i7, in 64-bit mode (comparable for Opteron).\n    Somewhat more for some tests, almost no gain for others.\n  \n  * Make Snappy compile on certain platforms it didn't before\n    (Solaris with SunPro C++, HP-UX, AIX).\n\n  * Correct some minor errors in the format description.\n\n\nSnappy v1.0.3, June 2nd 2011:\n\n  * Speeded up the decompressor somewhat; about 3-6% for Core 2,\n    6-13% for Core i7, and 5-12% for Opteron (all in 64-bit mode).\n\n  * Added compressed format documentation. This text is new,\n    but an earlier version from Zeev Tarantov was used as reference.\n\n  * Only link snappy_unittest against -lz and other autodetected\n    libraries, not libsnappy.so (which doesn't need any such dependency).\n\n  * Fixed some display issues in the microbenchmarks, one of which would\n    frequently make the test crash on GNU/Hurd.\n\n\nSnappy v1.0.2, April 29th 2011:\n\n  * Relicense to a BSD-type license.\n\n  * Added C bindings, contributed by Martin Gieseking.\n\n  * More Win32 fixes, in particular for MSVC.\n\n  * Replace geo.protodata with a newer version.\n\n  * Fix timing inaccuracies in the unit test when comparing Snappy\n    to other algorithms.\n\n\nSnappy v1.0.1, March 25th 2011:\n\nThis is a maintenance release, mostly containing minor fixes.\nThere is no new functionality. The most important fixes include:\n\n  * The COPYING file and all licensing headers now correctly state that\n    Snappy is licensed under the Apache 2.0 license.\n\n  * snappy_unittest should now compile natively under Windows,\n    as well as on embedded systems with no mmap().\n\n  * Various autotools nits have been fixed.\n\n\nSnappy v1.0, March 17th 2011:\n\n  * Initial version.\n"
  },
  {
    "path": "deps/snappy-1.1.0/README",
    "content": "Snappy, a fast compressor/decompressor.\n\n\nIntroduction\n============\n\nSnappy is a compression/decompression library. It does not aim for maximum\ncompression, or compatibility with any other compression library; instead,\nit aims for very high speeds and reasonable compression. For instance,\ncompared to the fastest mode of zlib, Snappy is an order of magnitude faster\nfor most inputs, but the resulting compressed files are anywhere from 20% to\n100% bigger. (For more information, see \"Performance\", below.)\n\nSnappy has the following properties:\n\n * Fast: Compression speeds at 250 MB/sec and beyond, with no assembler code.\n   See \"Performance\" below.\n * Stable: Over the last few years, Snappy has compressed and decompressed\n   petabytes of data in Google's production environment. The Snappy bitstream\n   format is stable and will not change between versions.\n * Robust: The Snappy decompressor is designed not to crash in the face of\n   corrupted or malicious input.\n * Free and open source software: Snappy is licensed under a BSD-type license.\n   For more information, see the included COPYING file.\n\nSnappy has previously been called \"Zippy\" in some Google presentations\nand the like.\n\n\nPerformance\n===========\n \nSnappy is intended to be fast. On a single core of a Core i7 processor\nin 64-bit mode, it compresses at about 250 MB/sec or more and decompresses at\nabout 500 MB/sec or more. (These numbers are for the slowest inputs in our\nbenchmark suite; others are much faster.) In our tests, Snappy usually\nis faster than algorithms in the same class (e.g. LZO, LZF, FastLZ, QuickLZ,\netc.) while achieving comparable compression ratios.\n\nTypical compression ratios (based on the benchmark suite) are about 1.5-1.7x\nfor plain text, about 2-4x for HTML, and of course 1.0x for JPEGs, PNGs and\nother already-compressed data. Similar numbers for zlib in its fastest mode\nare 2.6-2.8x, 3-7x and 1.0x, respectively. More sophisticated algorithms are\ncapable of achieving yet higher compression rates, although usually at the\nexpense of speed. Of course, compression ratio will vary significantly with\nthe input.\n\nAlthough Snappy should be fairly portable, it is primarily optimized\nfor 64-bit x86-compatible processors, and may run slower in other environments.\nIn particular:\n\n - Snappy uses 64-bit operations in several places to process more data at\n   once than would otherwise be possible.\n - Snappy assumes unaligned 32- and 64-bit loads and stores are cheap.\n   On some platforms, these must be emulated with single-byte loads \n   and stores, which is much slower.\n - Snappy assumes little-endian throughout, and needs to byte-swap data in\n   several places if running on a big-endian platform.\n\nExperience has shown that even heavily tuned code can be improved.\nPerformance optimizations, whether for 64-bit x86 or other platforms,\nare of course most welcome; see \"Contact\", below.\n\n\nUsage\n=====\n\nNote that Snappy, both the implementation and the main interface,\nis written in C++. However, several third-party bindings to other languages\nare available; see the Google Code page at http://code.google.com/p/snappy/\nfor more information. Also, if you want to use Snappy from C code, you can\nuse the included C bindings in snappy-c.h.\n\nTo use Snappy from your own C++ program, include the file \"snappy.h\" from\nyour calling file, and link against the compiled library.\n\nThere are many ways to call Snappy, but the simplest possible is\n\n  snappy::Compress(input.data(), input.size(), &output);\n\nand similarly\n\n  snappy::Uncompress(input.data(), input.size(), &output);\n\nwhere \"input\" and \"output\" are both instances of std::string.\n\nThere are other interfaces that are more flexible in various ways, including\nsupport for custom (non-array) input sources. See the header file for more\ninformation.\n\n\nTests and benchmarks\n====================\n\nWhen you compile Snappy, snappy_unittest is compiled in addition to the\nlibrary itself. You do not need it to use the compressor from your own library,\nbut it contains several useful components for Snappy development.\n\nFirst of all, it contains unit tests, verifying correctness on your machine in\nvarious scenarios. If you want to change or optimize Snappy, please run the\ntests to verify you have not broken anything. Note that if you have the\nGoogle Test library installed, unit test behavior (especially failures) will be\nsignificantly more user-friendly. You can find Google Test at\n\n  http://code.google.com/p/googletest/\n\nYou probably also want the gflags library for handling of command-line flags;\nyou can find it at\n\n  http://code.google.com/p/google-gflags/\n\nIn addition to the unit tests, snappy contains microbenchmarks used to\ntune compression and decompression performance. These are automatically run\nbefore the unit tests, but you can disable them using the flag\n--run_microbenchmarks=false if you have gflags installed (otherwise you will\nneed to edit the source).\n\nFinally, snappy can benchmark Snappy against a few other compression libraries\n(zlib, LZO, LZF, FastLZ and QuickLZ), if they were detected at configure time.\nTo benchmark using a given file, give the compression algorithm you want to test\nSnappy against (e.g. --zlib) and then a list of one or more file names on the\ncommand line. The testdata/ directory contains the files used by the\nmicrobenchmark, which should provide a reasonably balanced starting point for\nbenchmarking. (Note that baddata[1-3].snappy are not intended as benchmarks; they\nare used to verify correctness in the presence of corrupted data in the unit\ntest.)\n\n\nContact\n=======\n\nSnappy is distributed through Google Code. For the latest version, a bug tracker,\nand other information, see\n\n  http://code.google.com/p/snappy/\n"
  },
  {
    "path": "deps/snappy-1.1.0/aclocal.m4",
    "content": "# generated automatically by aclocal 1.11.3 -*- Autoconf -*-\n\n# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,\n# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,\n# 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\nm4_ifndef([AC_AUTOCONF_VERSION],\n  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl\nm4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],,\n[m4_warning([this file was generated for autoconf 2.68.\nYou have another version of autoconf.  It may work, but is not guaranteed to.\nIf you have problems, you may need to regenerate the build system entirely.\nTo do so, use the procedure documented by the package, typically `autoreconf'.])])\n\n# 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, 2009, 2010, 2011 Free Software\n#                 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, 2009, 2010, 2011 Free Software\n#                 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 57 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_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl\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\n_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])\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 \"$cc_temp\" | $SED \"s%.*/%%; 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\nAC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl\nAC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl\n\n_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl\ndnl\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_PATH_CONVERSION_FUNCTIONS])dnl\nm4_require([_LT_CMD_RELOAD])dnl\nm4_require([_LT_CHECK_MAGIC_METHOD])dnl\nm4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl\nm4_require([_LT_CMD_OLD_ARCHIVE])dnl\nm4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl\nm4_require([_LT_WITH_SYSROOT])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\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# 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_PREPARE_SED_QUOTE_VARS\n# --------------------------\n# Define a few sed substitution that help us do robust quoting.\nm4_defun([_LT_PREPARE_SED_QUOTE_VARS],\n[# Backslashify metacharacters that are still active within\n# 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\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# 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\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 \"$][$1\" | $SED \"$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 \"$<var>\" | $SED \"$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# A function that is used when there is no print builtin or printf.\nfunc_fallback_echo ()\n{\n  eval 'cat <<_LTECHO_EOF\n\\$[]1\n_LTECHO_EOF'\n}\n\n# Quote evaled strings.\nfor var in lt_decl_all_varnames([[ \\\n]], lt_decl_quote_varnames); do\n    case \\`eval \\\\\\\\\\$ECHO \\\\\\\\\"\"\\\\\\\\\\$\\$var\"\\\\\\\\\"\\` in\n    *[[\\\\\\\\\\\\\\`\\\\\"\\\\\\$]]*)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\`\\\\\\$ECHO \\\\\"\\\\\\$\\$var\\\\\" | \\\\\\$SED \\\\\"\\\\\\$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 \\\\\\\\\"\"\\\\\\\\\\$\\$var\"\\\\\\\\\"\\` in\n    *[[\\\\\\\\\\\\\\`\\\\\"\\\\\\$]]*)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\`\\\\\\$ECHO \\\\\"\\\\\\$\\$var\\\\\" | \\\\\\$SED -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_LT_OUTPUT_LIBTOOL_INIT\n])\n\n# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])\n# ------------------------------------\n# Generate a child script FILE with all initialization necessary to\n# reuse the environment learned by the parent script, and make the\n# file executable.  If COMMENT is supplied, it is inserted after the\n# `#!' sequence but before initialization text begins.  After this\n# macro, additional text can be appended to FILE to form the body of\n# the child script.  The macro ends with non-zero status if the\n# file could not be fully written (such as if the disk is full).\nm4_ifdef([AS_INIT_GENERATED],\n[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],\n[m4_defun([_LT_GENERATED_FILE_INIT],\n[m4_require([AS_PREPARE])]dnl\n[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl\n[lt_write_fail=0\ncat >$1 <<_ASEOF || lt_write_fail=1\n#! $SHELL\n# Generated by $as_me.\n$2\nSHELL=\\${CONFIG_SHELL-$SHELL}\nexport SHELL\n_ASEOF\ncat >>$1 <<\\_ASEOF || lt_write_fail=1\nAS_SHELL_SANITIZE\n_AS_PREPARE\nexec AS_MESSAGE_FD>&1\n_ASEOF\ntest $lt_write_fail = 0 && chmod +x $1[]dnl\nm4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT\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])\n_LT_GENERATED_FILE_INIT([\"$CONFIG_LT\"],\n[# Run this file to recreate a libtool stub with the current configuration.])\n\ncat >>\"$CONFIG_LT\" <<\\_LTEOF\nlt_cl_silent=false\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) 2011 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.\nlt_cl_success=:\ntest \"$silent\" = yes &&\n  lt_config_lt_args=\"$lt_config_lt_args --quiet\"\nexec AS_MESSAGE_LOG_FD>/dev/null\n$SHELL \"$CONFIG_LT\" $lt_config_lt_args || lt_cl_success=false\nexec AS_MESSAGE_LOG_FD>>config.log\n$lt_cl_success || AS_EXIT(1)\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 '$q' \"$ltmain\" >> \"$cfgfile\" \\\n     || (rm -f \"$cfgfile\"; exit 1)\n\n  _LT_PROG_REPLACE_SHELLFNS\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  [Go],\t\t\t[_LT_LANG(GO)],\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\nm4_ifndef([AC_PROG_GO], [\n# NOTE: This macro has been submitted for inclusion into   #\n#  GNU Autoconf as AC_PROG_GO.  When it is available in    #\n#  a released version of Autoconf we should remove this    #\n#  macro and use it instead.                               #\nm4_defun([AC_PROG_GO],\n[AC_LANG_PUSH(Go)dnl\nAC_ARG_VAR([GOC],     [Go compiler command])dnl\nAC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl\n_AC_ARG_VAR_LDFLAGS()dnl\nAC_CHECK_TOOL(GOC, gccgo)\nif test -z \"$GOC\"; then\n  if test -n \"$ac_tool_prefix\"; then\n    AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])\n  fi\nfi\nif test -z \"$GOC\"; then\n  AC_CHECK_PROG(GOC, gccgo, gccgo, false)\nfi\n])#m4_defun\n])#m4_ifndef\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([AC_PROG_GO],\n  [LT_LANG(GO)],\n  [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])\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)])\nAU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])\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], [])\ndnl AC_DEFUN([AC_LIBTOOL_RC], [])\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\t# If there is a non-empty error log, and \"single_module\"\n\t# appears in it, assume the flag caused a linker warning\n        if test -s conftest.err && $GREP single_module conftest.err; then\n\t  cat conftest.err >&AS_MESSAGE_LOG_FD\n\t# Otherwise, if the output was created with a 0 exit code from\n\t# the compiler, it worked.\n\telif test -f libconftest.dylib && test $_lt_result -eq 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\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\n    AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],\n      [lt_cv_ld_force_load=no\n      cat > conftest.c << _LT_EOF\nint forced_loaded() { return 2;}\n_LT_EOF\n      echo \"$LTCC $LTCFLAGS -c -o conftest.o conftest.c\" >&AS_MESSAGE_LOG_FD\n      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD\n      echo \"$AR cru libconftest.a conftest.o\" >&AS_MESSAGE_LOG_FD\n      $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD\n      echo \"$RANLIB libconftest.a\" >&AS_MESSAGE_LOG_FD\n      $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD\n      cat > conftest.c << _LT_EOF\nint main() { return 0;}\n_LT_EOF\n      echo \"$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a\" >&AS_MESSAGE_LOG_FD\n      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err\n      _lt_result=$?\n      if test -s conftest.err && $GREP force_load conftest.err; then\n\tcat conftest.err >&AS_MESSAGE_LOG_FD\n      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then\n\tlt_cv_ld_force_load=yes\n      else\n\tcat conftest.err >&AS_MESSAGE_LOG_FD\n      fi\n        rm -f conftest.err libconftest.a conftest conftest.c\n        rm -rf conftest.dSYM\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\" != \":\" && test \"$lt_cv_ld_force_load\" = \"no\"; then\n      _lt_dsymutil='~$DSYMUTIL $lib || :'\n    else\n      _lt_dsymutil=\n    fi\n    ;;\n  esac\n])\n\n\n# _LT_DARWIN_LINKER_FEATURES([TAG])\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  if test \"$lt_cv_ld_force_load\" = \"yes\"; then\n    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience ${wl}-force_load,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"`'\n    m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],\n                  [FC],  [_LT_TAGVAR(compiler_needs_object, $1)=yes])\n  else\n    _LT_TAGVAR(whole_archive_flag_spec, $1)=''\n  fi\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=func_echo_all\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([TAGNAME])\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.\n# Store the results from the different compilers for each TAGNAME.\n# Allow to override them for all tags through lt_cv_aix_libpath.\nm4_defun([_LT_SYS_MODULE_PATH_AIX],\n[m4_require([_LT_DECL_SED])dnl\nif test \"${lt_cv_aix_libpath+set}\" = set; then\n  aix_libpath=$lt_cv_aix_libpath\nelse\n  AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],\n  [AC_LINK_IFELSE([AC_LANG_PROGRAM],[\n  lt_aix_libpath_sed='[\n      /Import File Strings/,/^$/ {\n\t  /^0/ {\n\t      s/^0  *\\([^ ]*\\) *$/\\1/\n\t      p\n\t  }\n      }]'\n  _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`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.\n  if test -z \"$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])\"; then\n    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\n  fi],[])\n  if test -z \"$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])\"; then\n    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=\"/usr/lib:/lib\"\n  fi\n  ])\n  aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])\nfi\n])# _LT_SYS_MODULE_PATH_AIX\n\n\n# _LT_SHELL_INIT(ARG)\n# -------------------\nm4_define([_LT_SHELL_INIT],\n[m4_divert_text([M4SH-INIT], [$1\n])])# _LT_SHELL_INIT\n\n\n\n# _LT_PROG_ECHO_BACKSLASH\n# -----------------------\n# Find how we can fake an echo command that does not interpret backslash.\n# In particular, with Autoconf 2.60 or later we add some code to the start\n# of the generated configure script which will find a shell with a builtin\n# printf (which we can use as an echo command).\nm4_defun([_LT_PROG_ECHO_BACKSLASH],\n[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\nECHO=$ECHO$ECHO$ECHO$ECHO$ECHO\nECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO\n\nAC_MSG_CHECKING([how to print strings])\n# Test print first, because it will be a builtin if present.\nif test \"X`( print -r -- -n ) 2>/dev/null`\" = X-n && \\\n   test \"X`print -r -- $ECHO 2>/dev/null`\" = \"X$ECHO\"; then\n  ECHO='print -r --'\nelif test \"X`printf %s $ECHO 2>/dev/null`\" = \"X$ECHO\"; then\n  ECHO='printf %s\\n'\nelse\n  # Use this function as a fallback that always works.\n  func_fallback_echo ()\n  {\n    eval 'cat <<_LTECHO_EOF\n$[]1\n_LTECHO_EOF'\n  }\n  ECHO='func_fallback_echo'\nfi\n\n# func_echo_all arg...\n# Invoke $ECHO with all args, space-separated.\nfunc_echo_all ()\n{\n    $ECHO \"$*\" \n}\n\ncase \"$ECHO\" in\n  printf*) AC_MSG_RESULT([printf]) ;;\n  print*) AC_MSG_RESULT([print -r]) ;;\n  *) AC_MSG_RESULT([cat]) ;;\nesac\n\nm4_ifdef([_AS_DETECT_SUGGESTED],\n[_AS_DETECT_SUGGESTED([\n  test -n \"${ZSH_VERSION+set}${BASH_VERSION+set}\" || (\n    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\n    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO\n    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO\n    PATH=/empty FPATH=/empty; export PATH FPATH\n    test \"X`printf %s $ECHO`\" = \"X$ECHO\" \\\n      || test \"X`print -r -- $ECHO`\" = \"X$ECHO\" )])])\n\n_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])\n_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])\n])# _LT_PROG_ECHO_BACKSLASH\n\n\n# _LT_WITH_SYSROOT\n# ----------------\nAC_DEFUN([_LT_WITH_SYSROOT],\n[AC_MSG_CHECKING([for sysroot])\nAC_ARG_WITH([sysroot],\n[  --with-sysroot[=DIR] Search for dependent libraries within DIR\n                        (or the compiler's sysroot if not specified).],\n[], [with_sysroot=no])\n\ndnl lt_sysroot will always be passed unquoted.  We quote it here\ndnl in case the user passed a directory name.\nlt_sysroot=\ncase ${with_sysroot} in #(\n yes)\n   if test \"$GCC\" = yes; then\n     lt_sysroot=`$CC --print-sysroot 2>/dev/null`\n   fi\n   ;; #(\n /*)\n   lt_sysroot=`echo \"$with_sysroot\" | sed -e \"$sed_quote_subst\"`\n   ;; #(\n no|'')\n   ;; #(\n *)\n   AC_MSG_RESULT([${with_sysroot}])\n   AC_MSG_ERROR([The sysroot must be an absolute path.])\n   ;;\nesac\n\n AC_MSG_RESULT([${lt_sysroot:-no}])\n_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl\n[dependent libraries, and in which our libraries should be installed.])])\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 '$LINENO' \"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  ;;\n*-*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*)\n        case $host in\n        i?86-*-solaris*)\n          LD=\"${LD-ld} -m elf_x86_64\"\n          ;;\n        sparc*-*-solaris*)\n          LD=\"${LD-ld} -m elf64_sparc\"\n          ;;\n        esac\n        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.\n        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then\n          LD=\"${LD-ld}_sol2\"\n        fi\n        ;;\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_PROG_AR\n# -----------\nm4_defun([_LT_PROG_AR],\n[AC_CHECK_TOOLS(AR, [ar], false)\n: ${AR=ar}\n: ${AR_FLAGS=cru}\n_LT_DECL([], [AR], [1], [The archiver])\n_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])\n\nAC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],\n  [lt_cv_ar_at_file=no\n   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],\n     [echo conftest.$ac_objext > conftest.lst\n      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'\n      AC_TRY_EVAL([lt_ar_try])\n      if test \"$ac_status\" -eq 0; then\n\t# Ensure the archiver fails upon bogus file names.\n\trm -f conftest.$ac_objext libconftest.a\n\tAC_TRY_EVAL([lt_ar_try])\n\tif test \"$ac_status\" -ne 0; then\n          lt_cv_ar_at_file=@\n        fi\n      fi\n      rm -f conftest.* libconftest.a\n     ])\n  ])\n\nif test \"x$lt_cv_ar_at_file\" = xno; then\n  archiver_list_spec=\nelse\n  archiver_list_spec=$lt_cv_ar_at_file\nfi\n_LT_DECL([], [archiver_list_spec], [1],\n  [How to feed a file listing to the archiver])\n])# _LT_PROG_AR\n\n\n# _LT_CMD_OLD_ARCHIVE\n# -------------------\nm4_defun([_LT_CMD_OLD_ARCHIVE],\n[_LT_PROG_AR\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 \\$tool_oldlib\"\n    ;;\n  *)\n    old_postinstall_cmds=\"$old_postinstall_cmds~\\$RANLIB \\$tool_oldlib\"\n    ;;\n  esac\n  old_archive_cmds=\"$old_archive_cmds~\\$RANLIB \\$tool_oldlib\"\nfi\n\ncase $host_os in\n  darwin*)\n    lock_old_archive_extraction=yes ;;\n  *)\n    lock_old_archive_extraction=no ;;\nesac\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_DECL([], [lock_old_archive_extraction], [0],\n    [Whether to use a lock for old archive extraction])\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:$LINENO: $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:$LINENO: \\$? = $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 \"$_lt_compiler_boilerplate\" | $SED '/^$/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 \"$_lt_linker_boilerplate\" | $SED '/^$/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  mint*)\n    # On MiNT this can take a long time and run out of memory.\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  os2*)\n    # The test takes a long time on OS/2.\n    lt_cv_sys_max_cmd_len=8192\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\"`env echo \"$teststring$teststring\" 2>/dev/null` \\\n\t         = \"X$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 $LINENO \"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\n/* When -fvisbility=hidden is used, assume the code has been annotated\n   correspondingly for the symbols needed.  */\n#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))\nint fnord () __attribute__((visibility(\"default\")));\n#endif\n\nint fnord () { return 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\n        {\n\t  if (dlsym( self,\"_fnord\"))  status = $lt_dlneed_uscore;\n          else puts (dlerror ());\n\t}\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:$LINENO: $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:$LINENO: \\$? = $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 \"$_lt_compiler_boilerplate\" | $SED '/^$/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\nm4_require([_LT_CHECK_SHELL_FEATURES])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  case $host_os in\n    mingw* | cegcc*) lt_sed_strip_eq=\"s,=\\([[A-Za-z]]:\\),\\1,g\" ;;\n    *) lt_sed_strip_eq=\"s,=/,/,g\" ;;\n  esac\n  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e \"s/^libraries://\" -e $lt_sed_strip_eq`\n  case $lt_search_path_spec in\n  *\\;*)\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 's/;/ /g'`\n    ;;\n  *)\n    lt_search_path_spec=`$ECHO \"$lt_search_path_spec\" | $SED \"s/$PATH_SEPARATOR/ /g\"`\n    ;;\n  esac\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  # AWK program above erroneously prepends '/' to C:/dos/paths\n  # for these hosts.\n  case $host_os in\n    mingw* | cegcc*) lt_search_path_spec=`$ECHO \"$lt_search_path_spec\" |\\\n      $SED 's,/\\([[A-Za-z]]:\\),\\1,g'` ;;\n  esac\n  sys_lib_search_path_spec=`$ECHO \"$lt_search_path_spec\" | $lt_NL2SP`\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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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=`func_echo_all \"$lib\" | $SED '\\''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 # correct to gnu/linux during the next big refactor\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,$cc_basename in\n  yes,*)\n    # gcc\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}'\nm4_if([$1], [],[\n      sys_lib_search_path_spec=\"$sys_lib_search_path_spec /usr/lib/w32api\"])\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      ;;\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    dynamic_linker='Win32 ld.exe'\n    ;;\n\n  *,cl*)\n    # Native MSVC\n    libname_spec='$name'\n    soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'\n    library_names_spec='${libname}.dll.lib'\n\n    case $build_os in\n    mingw*)\n      sys_lib_search_path_spec=\n      lt_save_ifs=$IFS\n      IFS=';'\n      for lt_path in $LIB\n      do\n        IFS=$lt_save_ifs\n        # Let DOS variable expansion print the short 8.3 style file name.\n        lt_path=`cd \"$lt_path\" 2>/dev/null && cmd //C \"for %i in (\".\") do @echo %~si\"`\n        sys_lib_search_path_spec=\"$sys_lib_search_path_spec $lt_path\"\n      done\n      IFS=$lt_save_ifs\n      # Convert to MSYS style.\n      sys_lib_search_path_spec=`$ECHO \"$sys_lib_search_path_spec\" | sed -e 's|\\\\\\\\|/|g' -e 's| \\\\([[a-zA-Z]]\\\\):| /\\\\1|g' -e 's|^ ||'`\n      ;;\n    cygwin*)\n      # Convert to unix form, then to dos form, then back to unix form\n      # but this time dos style (no spaces!) so that the unix form looks\n      # like /cygdrive/c/PROGRA~1:/cygdr...\n      sys_lib_search_path_spec=`cygpath --path --unix \"$LIB\"`\n      sys_lib_search_path_spec=`cygpath --path --dos \"$sys_lib_search_path_spec\" 2>/dev/null`\n      sys_lib_search_path_spec=`cygpath --path --unix \"$sys_lib_search_path_spec\" | $SED -e \"s/$PATH_SEPARATOR/ /g\"`\n      ;;\n    *)\n      sys_lib_search_path_spec=\"$LIB\"\n      if $ECHO \"$sys_lib_search_path_spec\" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then\n        # It is most probably a Windows format PATH.\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      # FIXME: find the short name or the path components, as spaces are\n      # common. (e.g. \"Program Files\" -> \"PROGRA~1\")\n      ;;\n    esac\n\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    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\\''. $file; echo \\$dlname'\\''`~\n      dlpath=$dir/\\$dldll~\n       $RM \\$dlpath'\n    shlibpath_overrides_runpath=yes\n    dynamic_linker='Win32 link.exe'\n    ;;\n\n  *)\n    # Assume MSVC wrapper\n    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'\n    dynamic_linker='Win32 ld.exe'\n    ;;\n  esac\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 # correct to gnu/linux during the next big refactor\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\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[[23]].*) 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 # correct to gnu/linux during the next big refactor\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  ;;\n\nhaiku*)\n  version_type=linux # correct to gnu/linux during the next big refactor\n  need_lib_prefix=no\n  need_version=no\n  dynamic_linker=\"$host_os runtime_loader\"\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=LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'\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  # or fails outright, so override atomically:\n  install_override_mode=555\n  ;;\n\ninterix[[3-9]]*)\n  version_type=linux # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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 glibc/ELF.\nlinux* | k*bsd*-gnu | kopensolaris*-gnu)\n  version_type=linux # correct to gnu/linux during the next big refactor\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\n  # Some binutils ld are patched to set DT_RUNPATH\n  AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],\n    [lt_cv_shlibpath_overrides_runpath=no\n    save_LDFLAGS=$LDFLAGS\n    save_libdir=$libdir\n    eval \"libdir=/foo; wl=\\\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\\\"; \\\n\t 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\t [lt_cv_shlibpath_overrides_runpath=yes])])\n    LDFLAGS=$save_LDFLAGS\n    libdir=$save_libdir\n    ])\n  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath\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;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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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([], [install_override_mode], [1],\n    [Permission mode override for installation of shared libraries])\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\nm4_require([_LT_PROG_ECHO_BACKSLASH])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  cygwin* | mingw* | pw32* | cegcc*)\n    if test \"$GCC\" != yes; then\n      reload_cmds=false\n    fi\n    ;;\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_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl\n_LT_TAGDECL([], [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  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.\n  if ( test \"$lt_cv_nm_interface\" = \"BSD nm\" && 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    # Keep this pattern in sync with the one in func_win32_libid.\n    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'\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\nhaiku*)\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])(-bit)?( [LM]SB)? 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 glibc/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])\n\nfile_magic_glob=\nwant_nocaseglob=no\nif test \"$build\" = \"$host\"; then\n  case $host_os in\n  mingw* | pw32*)\n    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then\n      want_nocaseglob=yes\n    else\n      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e \"s/\\(..\\)/s\\/[[\\1]]\\/[[\\1]]\\/g;/g\"`\n    fi\n    ;;\n  esac\nfi\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_DECL([], [file_magic_glob], [1],\n    [How to find potential files when deplibs_check_method = \"file_magic\"])\n_LT_DECL([], [want_nocaseglob], [1],\n    [Find potential files using nocaseglob 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  if test -n \"$DUMPBIN\"; then :\n    # Let the user override the test.\n  else\n    AC_CHECK_TOOLS(DUMPBIN, [dumpbin \"link -dump\"], :)\n    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in\n    *COFF*)\n      DUMPBIN=\"$DUMPBIN -symbols\"\n      ;;\n    *)\n      DUMPBIN=:\n      ;;\n    esac\n  fi\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:$LINENO: $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:$LINENO: $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:$LINENO: 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# _LT_CHECK_SHAREDLIB_FROM_LINKLIB\n# --------------------------------\n# how to determine the name of the shared library\n# associated with a specific link library.\n#  -- PORTME fill in with the dynamic library characteristics\nm4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],\n[m4_require([_LT_DECL_EGREP])\nm4_require([_LT_DECL_OBJDUMP])\nm4_require([_LT_DECL_DLLTOOL])\nAC_CACHE_CHECK([how to associate runtime and link libraries],\nlt_cv_sharedlib_from_linklib_cmd,\n[lt_cv_sharedlib_from_linklib_cmd='unknown'\n\ncase $host_os in\ncygwin* | mingw* | pw32* | cegcc*)\n  # two different shell functions defined in ltmain.sh\n  # decide which to use based on capabilities of $DLLTOOL\n  case `$DLLTOOL --help 2>&1` in\n  *--identify-strict*)\n    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib\n    ;;\n  *)\n    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback\n    ;;\n  esac\n  ;;\n*)\n  # fallback: assume linklib IS sharedlib\n  lt_cv_sharedlib_from_linklib_cmd=\"$ECHO\"\n  ;;\nesac\n])\nsharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd\ntest -z \"$sharedlib_from_linklib_cmd\" && sharedlib_from_linklib_cmd=$ECHO\n\n_LT_DECL([], [sharedlib_from_linklib_cmd], [1],\n    [Command to associate shared and link libraries])\n])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB\n\n\n# _LT_PATH_MANIFEST_TOOL\n# ----------------------\n# locate the manifest tool\nm4_defun([_LT_PATH_MANIFEST_TOOL],\n[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)\ntest -z \"$MANIFEST_TOOL\" && MANIFEST_TOOL=mt\nAC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],\n  [lt_cv_path_mainfest_tool=no\n  echo \"$as_me:$LINENO: $MANIFEST_TOOL '-?'\" >&AS_MESSAGE_LOG_FD\n  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out\n  cat conftest.err >&AS_MESSAGE_LOG_FD\n  if $GREP 'Manifest Tool' conftest.out > /dev/null; then\n    lt_cv_path_mainfest_tool=yes\n  fi\n  rm -f conftest*])\nif test \"x$lt_cv_path_mainfest_tool\" != xyes; then\n  MANIFEST_TOOL=:\nfi\n_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl\n])# _LT_PATH_MANIFEST_TOOL\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* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-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  case $cc_basename in\n  nvcc*)\n    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;\n  *)\n    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;\n  esac\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([AC_PROG_AWK])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\"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};\"\\\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  lt_cv_sys_global_symbol_pipe=\"$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'\"\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/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */\n#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)\n/* DATA imports from DLLs on WIN32 con't be const, because runtime\n   relocations are performed -- see ld's documentation on pseudo-relocs.  */\n# define LT@&t@_DLSYM_CONST\n#elif defined(__osf__)\n/* This system does not cope well with relocations in const data.  */\n# define LT@&t@_DLSYM_CONST\n#else\n# define LT@&t@_DLSYM_CONST const\n#endif\n\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.  */\nLT@&t@_DLSYM_CONST 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_globsym_save_LIBS=$LIBS\n\t  lt_globsym_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_globsym_save_LIBS\n\t  CFLAGS=$lt_globsym_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# Response file support.\nif test \"$lt_cv_nm_interface\" = \"MS dumpbin\"; then\n  nm_file_list_spec='@'\nelif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then\n  nm_file_list_spec='@'\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_DECL([], [nm_file_list_spec], [1],\n    [Specify filename containing input files for $NM])\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\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    haiku*)\n      # PIC is the default for Haiku.\n      # The \"-static\" flag exists, but is broken.\n      _LT_TAGVAR(lt_prog_compiler_static, $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      mingw* | cygwin* | os2* | pw32* | cegcc*)\n\t# This hack is so that the source file can tell whether it is being\n\t# built for inclusion in a dll (and should export symbols for example).\n\tm4_if([$1], [GCJ], [],\n\t  [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])\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* | bgxl[[cC]]* | mpixl[[cC]]*)\n\t    # IBM XL 8.0, 9.0 on PPC and BlueGene\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* | sunCC*)\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    haiku*)\n      # PIC is the default for Haiku.\n      # The \"-static\" flag exists, but is broken.\n      _LT_TAGVAR(lt_prog_compiler_static, $1)=\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\n    case $cc_basename in\n    nvcc*) # Cuda Compiler Driver 2.2\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '\n      if test -n \"$_LT_TAGVAR(lt_prog_compiler_pic, $1)\"; then\n        _LT_TAGVAR(lt_prog_compiler_pic, $1)=\"-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)\"\n      fi\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      nagfor*)\n\t# NAG Fortran compiler\n\t_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t;;\n      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)\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* | bgxl* | bgf* | mpixl*)\n\t# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene\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\\ Ceres\\ Fortran* | *Sun*Fortran*\\ [[1-7]].* | *Sun*Fortran*\\ 8.[[0-3]]*)\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\t*Sun\\ F* | *Sun*Fortran*)\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*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        *Intel*\\ [[CF]]*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)='-static'\n\t  ;;\n\t*Portland\\ Group*)\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\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* | sunf77* | sunf90* | sunf95*)\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\n\nAC_CACHE_CHECK([for $compiler option to produce PIC],\n  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],\n  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])\n_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)\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_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],\n\t[How to pass a linker flag through the compiler])\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_PATH_MANIFEST_TOOL])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  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']\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    # Also, AIX nm treats weak defined symbols like other global defined\n    # symbols, whereas GNU nm marks them as \"W\".\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\") || (\\$ 2 == \"W\")) && ([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    case $cc_basename in\n    cl*)\n      _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'\n      ;;\n    *)\n      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\\([[^ ]]*\\)/\\1 DATA/;s/^.*[[ ]]__nm__\\([[^ ]]*\\)[[ ]][[^ ]]*/\\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\\'' | sort | uniq > $export_symbols'\n      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']\n      ;;\n    esac\n    ;;\n  linux* | k*bsd*-gnu | 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], [\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_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 | gnu*)\n    _LT_TAGVAR(link_all_deplibs, $1)=no\n    ;;\n  esac\n\n  _LT_TAGVAR(ld_shlibs, $1)=yes\n\n  # On some targets, GNU ld is compatible enough with the native linker\n  # that we're better off using the native interface for both.\n  lt_use_gnu_ld_interface=no\n  if test \"$with_gnu_ld\" = yes; then\n    case $host_os in\n      aix*)\n\t# The AIX port of GNU ld has always aspired to compatibility\n\t# with the native linker.  However, as the warning in the GNU ld\n\t# block says, versions before 2.19.5* couldn't really create working\n\t# shared libraries, regardless of the interface used.\n\tcase `$LD -v 2>&1` in\n\t  *\\ \\(GNU\\ Binutils\\)\\ 2.19.5*) ;;\n\t  *\\ \\(GNU\\ Binutils\\)\\ 2.[[2-9]]*) ;;\n\t  *\\ \\(GNU\\ Binutils\\)\\ [[3-9]]*) ;;\n\t  *)\n\t    lt_use_gnu_ld_interface=yes\n\t    ;;\n\tesac\n\t;;\n      *)\n\tlt_use_gnu_ld_interface=yes\n\t;;\n    esac\n  fi\n\n  if test \"$lt_use_gnu_ld_interface\" = 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.19, 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 install binutils\n*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.\n*** You will then need to restart the configuration process.\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(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'\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/;s/^.*[[ ]]__nm__\\([[^ ]]*\\)[[ ]][[^ ]]*/\\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\\'' | sort | uniq > $export_symbols'\n      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']\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    haiku*)\n      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n      _LT_TAGVAR(link_all_deplibs, $1)=yes\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=' $pic_flag'\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; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  tmp_addflag=' $pic_flag'\n\t  ;;\n\tpgf77* | pgf90* | pgf95* | pgfortran*)\n\t\t\t\t\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; func_echo_all \\\"$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]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)\n\t  tmp_sharedflag='-qmkshrobj'\n\t  tmp_addflag= ;;\n\tnvcc*)\t# Cuda Compiler Driver 2.2\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; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  _LT_TAGVAR(compiler_needs_object, $1)=yes\n\t  ;;\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; func_echo_all \\\"$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* | bgf* | bgxlf* | mpixlf*)\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)='${wl}-rpath ${wl}$libdir'\n\t  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_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 $linker_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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $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\t# Also, AIX nm treats weak defined symbols like other global\n\t# defined symbols, whereas GNU nm marks them as \"W\".\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\") || (\\$ 2 == \"W\")) && ([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([$1])\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 func_echo_all \"${wl}${allow_undefined_flag}\"; 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([$1])\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  if test \"$with_gnu_ld\" = yes; then\n\t    # We only use this code for GNU lds that support --whole-archive.\n\t    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'\n\t  else\n\t    # Exported symbols can be pulled into shared objects from archives\n\t    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'\n\t  fi\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      case $cc_basename in\n      cl*)\n\t# Native MSVC\n\t_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '\n\t_LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n\t_LT_TAGVAR(always_export_symbols, $1)=yes\n\t_LT_TAGVAR(file_list_spec, $1)='@'\n\t# Tell ltmain to make .lib files, not .a files.\n\tlibext=lib\n\t# Tell ltmain to make .dll files, not .so files.\n\tshrext_cmds=\".dll\"\n\t# FIXME: Setting linknames here is a bad hack.\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='if test \"x`$SED 1q $export_symbols`\" = xEXPORTS; then\n\t    sed -n -e 's/\\\\\\\\\\\\\\(.*\\\\\\\\\\\\\\)/-link\\\\\\ -EXPORT:\\\\\\\\\\\\\\1/' -e '1\\\\\\!p' < $export_symbols > $output_objdir/$soname.exp;\n\t  else\n\t    sed -e 's/\\\\\\\\\\\\\\(.*\\\\\\\\\\\\\\)/-link\\\\\\ -EXPORT:\\\\\\\\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;\n\t  fi~\n\t  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs \"@$tool_output_objdir$soname.exp\" -Wl,-DLL,-IMPLIB:\"$tool_output_objdir$libname.dll.lib\"~\n\t  linknames='\n\t# The linker will not automatically build a static lib if we build a DLL.\n\t# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'\n\t_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes\n\t_LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'\n\t_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\t# Don't use ranlib\n\t_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'\n\t_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile=\"@OUTPUT@\"~\n\t  lt_tool_outputfile=\"@TOOL_OUTPUT@\"~\n\t  case $lt_outputfile in\n\t    *.exe|*.EXE) ;;\n\t    *)\n\t      lt_outputfile=\"$lt_outputfile.exe\"\n\t      lt_tool_outputfile=\"$lt_tool_outputfile.exe\"\n\t      ;;\n\t  esac~\n\t  if test \"$MANIFEST_TOOL\" != \":\" && test -f \"$lt_outputfile.manifest\"; then\n\t    $MANIFEST_TOOL -manifest \"$lt_tool_outputfile.manifest\" -outputresource:\"$lt_tool_outputfile\" || exit 1;\n\t    $RM \"$lt_outputfile.manifest\";\n\t  fi'\n\t;;\n      *)\n\t# Assume MSVC wrapper\n\t_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '\n\t_LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n\t# Tell ltmain to make .lib files, not .a files.\n\tlibext=lib\n\t# Tell ltmain to make .dll files, not .so files.\n\tshrext_cmds=\".dll\"\n\t# FIXME: Setting linknames here is a bad hack.\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all \"$deplibs\" | $SED '\\''s/ -lc$//'\\''` -link -dll~linknames='\n\t# The linker will automatically build a .lib file if we build a DLL.\n\t_LT_TAGVAR(old_archive_from_new_cmds, $1)='true'\n\t# FIXME: Should let the user specify the lib program.\n\t_LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'\n\t_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes\n\t;;\n      esac\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    # 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 $pic_flag -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 $pic_flag ${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 && test \"$with_gnu_ld\" = no; then\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${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_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 && test \"$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 $pic_flag ${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 $pic_flag ${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\tm4_if($1, [], [\n\t  # Older versions of the 11.00 compiler do not understand -b yet\n\t  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)\n\t  _LT_LINKER_OPTION([if $CC understands -b],\n\t    _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],\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    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],\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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${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\t# This should be the same for all languages, so no per-tag cache variable.\n\tAC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],\n\t  [lt_cv_irix_exported_symbol],\n\t  [save_LDFLAGS=\"$LDFLAGS\"\n\t   LDFLAGS=\"$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null\"\n\t   AC_LINK_IFELSE(\n\t     [AC_LANG_SOURCE(\n\t        [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],\n\t\t\t      [C++], [[int foo (void) { return 0; }]],\n\t\t\t      [Fortran 77], [[\n      subroutine foo\n      end]],\n\t\t\t      [Fortran], [[\n      subroutine foo\n      end]])])],\n\t      [lt_cv_irix_exported_symbol=yes],\n\t      [lt_cv_irix_exported_symbol=no])\n           LDFLAGS=\"$save_LDFLAGS\"])\n\tif test \"$lt_cv_irix_exported_symbol\" = yes; then\n          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'\n\tfi\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -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\" && func_echo_all \"-set_version $verstring\"` -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\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${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\" && func_echo_all \"-set_version $verstring\"` -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} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${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\" && func_echo_all \"-set_version $verstring\"` -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 \"-set_version $verstring\"` -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 $pic_flag ${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 $pic_flag ${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_CACHE_CHECK([whether -lc should be explicitly linked in],\n\t[lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),\n\t[$RM conftest*\n\techo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n\tif AC_TRY_EVAL(ac_compile) 2>conftest.err; then\n\t  soname=conftest\n\t  lib=conftest\n\t  libobjs=conftest.$ac_objext\n\t  deplibs=\n\t  wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)\n\t  pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)\n\t  compiler_flags=-v\n\t  linker_flags=-v\n\t  verstring=\n\t  output_objdir=.\n\t  libname=conftest\n\t  lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)\n\t  _LT_TAGVAR(allow_undefined_flag, $1)=\n\t  if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\\>\\&1 \\| $GREP \\\" -lc \\\" \\>/dev/null 2\\>\\&1)\n\t  then\n\t    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no\n\t  else\n\t    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes\n\t  fi\n\t  _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag\n\telse\n\t  cat conftest.err 1>&5\n\tfi\n\t$RM conftest*\n\t])\n      _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_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_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([], [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([], [postlink_cmds], [2],\n    [Commands necessary for finishing linking programs])\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\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_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[m4_require([_LT_FILEUTILS_DEFAULTS])dnl\nm4_require([_LT_DECL_EGREP])dnl\nm4_require([_LT_PATH_MANIFEST_TOOL])dnl\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\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_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(reload_flag, $1)=$reload_flag\n_LT_TAGVAR(reload_cmds, $1)=$reload_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_CFLAGS=$CFLAGS\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  CFLAGS=$CXXFLAGS\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 $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'\n        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -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 -v \"^Configured with:\" | $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([$1])\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 func_echo_all \"${wl}${allow_undefined_flag}\"; 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([$1])\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    if test \"$with_gnu_ld\" = yes; then\n\t      # We only use this code for GNU lds that support --whole-archive.\n\t      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'\n\t    else\n\t      # Exported symbols can be pulled into shared objects from archives\n\t      _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'\n\t    fi\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\tcase $GXX,$cc_basename in\n\t,cl* | no,cl*)\n\t  # Native MSVC\n\t  # hardcode_libdir_flag_spec is actually meaningless, as there is\n\t  # no search path for DLLs.\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '\n\t  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n\t  _LT_TAGVAR(always_export_symbols, $1)=yes\n\t  _LT_TAGVAR(file_list_spec, $1)='@'\n\t  # Tell ltmain to make .lib files, not .a files.\n\t  libext=lib\n\t  # Tell ltmain to make .dll files, not .so files.\n\t  shrext_cmds=\".dll\"\n\t  # FIXME: Setting linknames here is a bad hack.\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='\n\t  _LT_TAGVAR(archive_expsym_cmds, $1)='if test \"x`$SED 1q $export_symbols`\" = xEXPORTS; then\n\t      $SED -n -e 's/\\\\\\\\\\\\\\(.*\\\\\\\\\\\\\\)/-link\\\\\\ -EXPORT:\\\\\\\\\\\\\\1/' -e '1\\\\\\!p' < $export_symbols > $output_objdir/$soname.exp;\n\t    else\n\t      $SED -e 's/\\\\\\\\\\\\\\(.*\\\\\\\\\\\\\\)/-link\\\\\\ -EXPORT:\\\\\\\\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;\n\t    fi~\n\t    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs \"@$tool_output_objdir$soname.exp\" -Wl,-DLL,-IMPLIB:\"$tool_output_objdir$libname.dll.lib\"~\n\t    linknames='\n\t  # The linker will not automatically build a static lib if we build a DLL.\n\t  # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'\n\t  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes\n\t  # Don't use ranlib\n\t  _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'\n\t  _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile=\"@OUTPUT@\"~\n\t    lt_tool_outputfile=\"@TOOL_OUTPUT@\"~\n\t    case $lt_outputfile in\n\t      *.exe|*.EXE) ;;\n\t      *)\n\t\tlt_outputfile=\"$lt_outputfile.exe\"\n\t\tlt_tool_outputfile=\"$lt_tool_outputfile.exe\"\n\t\t;;\n\t    esac~\n\t    func_to_tool_file \"$lt_outputfile\"~\n\t    if test \"$MANIFEST_TOOL\" != \":\" && test -f \"$lt_outputfile.manifest\"; then\n\t      $MANIFEST_TOOL -manifest \"$lt_tool_outputfile.manifest\" -outputresource:\"$lt_tool_outputfile\" || exit 1;\n\t      $RM \"$lt_outputfile.manifest\";\n\t    fi'\n\t  ;;\n\t*)\n\t  # g++\n\t  # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,\n\t  # as there is no search path for DLLs.\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n\t  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'\n\t  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n\t  _LT_TAGVAR(always_export_symbols, $1)=no\n\t  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes\n\n\t  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then\n\t    _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\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\t    else\n\t      echo EXPORTS > $output_objdir/$soname.def;\n\t      cat $export_symbols >> $output_objdir/$soname.def;\n\t    fi~\n\t    $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\t  else\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t  fi\n\t  ;;\n\tesac\n\t;;\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      freebsd2.*)\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      haiku*)\n        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n        _LT_TAGVAR(link_all_deplibs, $1)=yes\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; func_echo_all \"$list\"'\n            ;;\n          *)\n            if test \"$GXX\" = yes; then\n              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${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; func_echo_all \"$list\"'\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 $pic_flag ${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 $pic_flag ${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\" && func_echo_all \"-set_version $verstring\"` -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 $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t      else\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` -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; func_echo_all \"$list\"'\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 | sort | $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 | sort | $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 | sort | $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 | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'\n\t      ;;\n\t    *) # Version 6 and above 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; func_echo_all \\\"$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=`func_echo_all \"$templist\" | $SED \"s/\\(^.*ld.*\\)\\( .*ld .*$\\)/\\1/\"`; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; func_echo_all \"X$list\" | $Xsed'\n\t    ;;\n\t  xl* | mpixl* | bgxl*)\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; func_echo_all \\\"$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='func_echo_all'\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=func_echo_all\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\" && func_echo_all \"${wl}-set_version $verstring\"` -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\" && func_echo_all \"-set_version $verstring\"` -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 \"-set_version $verstring\"` -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=`func_echo_all \"$templist\" | $SED \"s/\\(^.*ld.*\\)\\( .*ld.*$\\)/\\1/\"`; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; func_echo_all \"$list\"'\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\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t\t  ;;\n\t        *)\n\t          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${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 -v \"^Configured with:\" | $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* | sunCC*)\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='func_echo_all'\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 $pic_flag -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 $pic_flag -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 -v \"^Configured with:\" | $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 -v \"^Configured with:\" | $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    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~\n\t      '\"$_LT_TAGVAR(old_archive_cmds, $1)\"\n\t    _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~\n\t      '\"$_LT_TAGVAR(reload_cmds, $1)\"\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  CFLAGS=$lt_save_CFLAGS\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_FUNC_STRIPNAME_CNF\n# ----------------------\n# func_stripname_cnf 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#\n# This function is identical to the (non-XSI) version of func_stripname,\n# except this one can be used by m4 code that may be executed by configure,\n# rather than the libtool script.\nm4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl\nAC_REQUIRE([_LT_DECL_SED])\nAC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])\nfunc_stripname_cnf ()\n{\n  case ${2} in\n  .*) func_stripname_result=`$ECHO \"${3}\" | $SED \"s%^${1}%%; s%\\\\\\\\${2}\\$%%\"`;;\n  *)  func_stripname_result=`$ECHO \"${3}\" | $SED \"s%^${1}%%; s%${2}\\$%%\"`;;\n  esac\n} # func_stripname_cnf\n])# _LT_FUNC_STRIPNAME_CNF\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\nAC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])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], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF\npackage foo\nfunc foo() {\n}\n_LT_EOF\n])\n\n_lt_libdeps_save_CFLAGS=$CFLAGS\ncase \"$CC $CFLAGS \" in #(\n*\\ -flto*\\ *) CFLAGS=\"$CFLAGS -fno-lto\" ;;\n*\\ -fwhopr*\\ *) CFLAGS=\"$CFLAGS -fno-whopr\" ;;\n*\\ -fuse-linker-plugin*\\ *) CFLAGS=\"$CFLAGS -fno-use-linker-plugin\" ;;\nesac\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 ${prev}${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       fi\n\n       # Expand the sysroot to ease extracting the directories later.\n       if test -z \"$prev\"; then\n         case $p in\n         -L*) func_stripname_cnf '-L' '' \"$p\"; prev=-L; p=$func_stripname_result ;;\n         -R*) func_stripname_cnf '-R' '' \"$p\"; prev=-R; p=$func_stripname_result ;;\n         -l*) func_stripname_cnf '-l' '' \"$p\"; prev=-l; p=$func_stripname_result ;;\n         esac\n       fi\n       case $p in\n       =*) func_stripname_cnf '=' '' \"$p\"; p=$lt_sysroot$func_stripname_result ;;\n       esac\n       if test \"$pre_test_object_deps_done\" = no; then\n\t case ${prev} 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       prev=\n       ;;\n\n    *.lto.$objext) ;; # Ignore GCC LTO objects\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\nCFLAGS=$_lt_libdeps_save_CFLAGS\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* | sunCC*)\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_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_LANG_PUSH(Fortran 77)\nif test -z \"$F77\" || test \"X$F77\" = \"Xno\"; then\n  _lt_disable_F77=yes\nfi\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_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(reload_flag, $1)=$reload_flag\n_LT_TAGVAR(reload_cmds, $1)=$reload_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  lt_save_CFLAGS=$CFLAGS\n  CC=${F77-\"f77\"}\n  CFLAGS=$FFLAGS\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\"\n  CFLAGS=\"$lt_save_CFLAGS\"\nfi # test \"$_lt_disable_F77\" != yes\n\nAC_LANG_POP\n])# _LT_LANG_F77_CONFIG\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_LANG_PUSH(Fortran)\n\nif test -z \"$FC\" || test \"X$FC\" = \"Xno\"; then\n  _lt_disable_FC=yes\nfi\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_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(reload_flag, $1)=$reload_flag\n_LT_TAGVAR(reload_cmds, $1)=$reload_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  lt_save_CFLAGS=$CFLAGS\n  CC=${FC-\"f95\"}\n  CFLAGS=$FCFLAGS\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\n  CFLAGS=$lt_save_CFLAGS\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_CFLAGS=$CFLAGS\nlt_save_GCC=$GCC\nGCC=yes\nCC=${GCJ-\"gcj\"}\nCFLAGS=$GCJFLAGS\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_LT_TAGVAR(reload_flag, $1)=$reload_flag\n_LT_TAGVAR(reload_cmds, $1)=$reload_cmds\n\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\nCFLAGS=$lt_save_CFLAGS\n])# _LT_LANG_GCJ_CONFIG\n\n\n# _LT_LANG_GO_CONFIG([TAG])\n# --------------------------\n# Ensure that the configuration variables for the GNU Go 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_GO_CONFIG],\n[AC_REQUIRE([LT_PROG_GO])dnl\nAC_LANG_SAVE\n\n# Source file extension for Go test sources.\nac_ext=go\n\n# Object file extension for compiled Go 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=\"package main; func main() { }\"\n\n# Code to be used in simple link tests\nlt_simple_link_test_code='package main; func main() { }'\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_CFLAGS=$CFLAGS\nlt_save_GCC=$GCC\nGCC=yes\nCC=${GOC-\"gccgo\"}\nCFLAGS=$GOFLAGS\ncompiler=$CC\n_LT_TAGVAR(compiler, $1)=$CC\n_LT_TAGVAR(LD, $1)=\"$LD\"\n_LT_CC_BASENAME([$compiler])\n\n# Go 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_LT_TAGVAR(reload_flag, $1)=$reload_flag\n_LT_TAGVAR(reload_cmds, $1)=$reload_cmds\n\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\nCFLAGS=$lt_save_CFLAGS\n])# _LT_LANG_GO_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_CFLAGS=$CFLAGS\nlt_save_GCC=$GCC\nGCC=\nCC=${RC-\"windres\"}\nCFLAGS=\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\nCFLAGS=$lt_save_CFLAGS\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_GO\n# ----------\nAC_DEFUN([LT_PROG_GO],\n[AC_CHECK_TOOL(GOC, gccgo,)\n])\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# _LT_DECL_DLLTOOL\n# ----------------\n# Ensure DLLTOOL variable is set.\nm4_defun([_LT_DECL_DLLTOOL],\n[AC_CHECK_TOOL(DLLTOOL, dlltool, false)\ntest -z \"$DLLTOOL\" && DLLTOOL=dlltool\n_LT_DECL([], [DLLTOOL], [1], [DLL creation program])\nAC_SUBST([DLLTOOL])\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# 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\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%\"$_lt_dummy\"}, \\\n      = c,a/b,b/c, \\\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_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)\n# ------------------------------------------------------\n# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and\n# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.\nm4_defun([_LT_PROG_FUNCTION_REPLACE],\n[dnl {\nsed -e '/^$1 ()$/,/^} # $1 /c\\\n$1 ()\\\n{\\\nm4_bpatsubsts([$2], [$], [\\\\], [^\\([\t ]\\)], [\\\\\\1])\n} # Extended-shell $1 implementation' \"$cfgfile\" > $cfgfile.tmp \\\n  && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\ntest 0 -eq $? || _lt_function_replace_fail=:\n])\n\n\n# _LT_PROG_REPLACE_SHELLFNS\n# -------------------------\n# Replace existing portable implementations of several shell functions with\n# equivalent extended shell implementations where those features are available..\nm4_defun([_LT_PROG_REPLACE_SHELLFNS],\n[if test x\"$xsi_shell\" = xyes; then\n  _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl\n    case ${1} in\n      */*) func_dirname_result=\"${1%/*}${2}\" ;;\n      *  ) func_dirname_result=\"${3}\" ;;\n    esac])\n\n  _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl\n    func_basename_result=\"${1##*/}\"])\n\n  _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl\n    case ${1} in\n      */*) func_dirname_result=\"${1%/*}${2}\" ;;\n      *  ) func_dirname_result=\"${3}\" ;;\n    esac\n    func_basename_result=\"${1##*/}\"])\n\n  _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl\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  _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl\n    func_split_long_opt_name=${1%%=*}\n    func_split_long_opt_arg=${1#*=}])\n\n  _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl\n    func_split_short_opt_arg=${1#??}\n    func_split_short_opt_name=${1%\"$func_split_short_opt_arg\"}])\n\n  _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl\n    case ${1} in\n      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\n      *)    func_lo2o_result=${1} ;;\n    esac])\n\n  _LT_PROG_FUNCTION_REPLACE([func_xform], [    func_xform_result=${1%.*}.lo])\n\n  _LT_PROG_FUNCTION_REPLACE([func_arith], [    func_arith_result=$(( $[*] ))])\n\n  _LT_PROG_FUNCTION_REPLACE([func_len], [    func_len_result=${#1}])\nfi\n\nif test x\"$lt_shell_append\" = xyes; then\n  _LT_PROG_FUNCTION_REPLACE([func_append], [    eval \"${1}+=\\\\${2}\"])\n\n  _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl\n    func_quote_for_eval \"${2}\"\ndnl m4 expansion turns \\\\\\\\ into \\\\, and then the shell eval turns that into \\\n    eval \"${1}+=\\\\\\\\ \\\\$func_quote_for_eval_result\"])\n\n  # Save a `func_append' function call where possible by direct use of '+='\n  sed -e 's%func_append \\([[a-zA-Z_]]\\{1,\\}\\) \"%\\1+=\"%g' $cfgfile > $cfgfile.tmp \\\n    && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n      || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\n  test 0 -eq $? || _lt_function_replace_fail=:\nelse\n  # Save a `func_append' function call even when '+=' is not available\n  sed -e 's%func_append \\([[a-zA-Z_]]\\{1,\\}\\) \"%\\1=\"$\\1%g' $cfgfile > $cfgfile.tmp \\\n    && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n      || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\n  test 0 -eq $? || _lt_function_replace_fail=:\nfi\n\nif test x\"$_lt_function_replace_fail\" = x\":\"; then\n  AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])\nfi\n])\n\n# _LT_PATH_CONVERSION_FUNCTIONS\n# -----------------------------\n# Determine which file name conversion functions should be used by\n# func_to_host_file (and, implicitly, by func_to_host_path).  These are needed\n# for certain cross-compile configurations and native mingw.\nm4_defun([_LT_PATH_CONVERSION_FUNCTIONS],\n[AC_REQUIRE([AC_CANONICAL_HOST])dnl\nAC_REQUIRE([AC_CANONICAL_BUILD])dnl\nAC_MSG_CHECKING([how to convert $build file names to $host format])\nAC_CACHE_VAL(lt_cv_to_host_file_cmd,\n[case $host in\n  *-*-mingw* )\n    case $build in\n      *-*-mingw* ) # actually msys\n        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32\n        ;;\n      *-*-cygwin* )\n        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32\n        ;;\n      * ) # otherwise, assume *nix\n        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32\n        ;;\n    esac\n    ;;\n  *-*-cygwin* )\n    case $build in\n      *-*-mingw* ) # actually msys\n        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin\n        ;;\n      *-*-cygwin* )\n        lt_cv_to_host_file_cmd=func_convert_file_noop\n        ;;\n      * ) # otherwise, assume *nix\n        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin\n        ;;\n    esac\n    ;;\n  * ) # unhandled hosts (and \"normal\" native builds)\n    lt_cv_to_host_file_cmd=func_convert_file_noop\n    ;;\nesac\n])\nto_host_file_cmd=$lt_cv_to_host_file_cmd\nAC_MSG_RESULT([$lt_cv_to_host_file_cmd])\n_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],\n         [0], [convert $build file names to $host format])dnl\n\nAC_MSG_CHECKING([how to convert $build file names to toolchain format])\nAC_CACHE_VAL(lt_cv_to_tool_file_cmd,\n[#assume ordinary cross tools, or native build.\nlt_cv_to_tool_file_cmd=func_convert_file_noop\ncase $host in\n  *-*-mingw* )\n    case $build in\n      *-*-mingw* ) # actually msys\n        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32\n        ;;\n    esac\n    ;;\nesac\n])\nto_tool_file_cmd=$lt_cv_to_tool_file_cmd\nAC_MSG_RESULT([$lt_cv_to_tool_file_cmd])\n_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],\n         [0], [convert $build files to toolchain format])dnl\n])# _LT_PATH_CONVERSION_FUNCTIONS\n\n# Helper functions for option handling.                    -*- Autoconf -*-\n#\n#   Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,\n#   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 7 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# _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],      [1], [Assembler program])dnl\n\ntest -z \"$DLLTOOL\" && DLLTOOL=dlltool\n_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl\n\ntest -z \"$OBJDUMP\" && OBJDUMP=objdump\n_LT_DECL([], [OBJDUMP], [1], [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@<:@=PKGS@:>@],\n\t[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],\n    [lt_p=${PACKAGE-default}\n    case $withval in\n    yes|no) pic_mode=$withval ;;\n    *)\n      pic_mode=default\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 lt_pkg in $withval; do\n\tIFS=\"$lt_save_ifs\"\n\tif test \"X$lt_pkg\" = \"X$lt_p\"; then\n\t  pic_mode=yes\n\tfi\n      done\n      IFS=\"$lt_save_ifs\"\n      ;;\n    esac],\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\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\n# 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\n# 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# @configure_input@\n\n# serial 3337 ltversion.m4\n# This file is part of GNU Libtool\n\nm4_define([LT_PACKAGE_VERSION], [2.4.2])\nm4_define([LT_PACKAGE_REVISION], [1.3337])\n\nAC_DEFUN([LTVERSION_VERSION],\n[macro_version='2.4.2'\nmacro_revision='1.3337'\n_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])\n_LT_DECL(, macro_revision, 0)\n])\n\n# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-\n#\n#   Copyright (C) 2004, 2005, 2007, 2009 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 5 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_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])])\nm4_ifndef([_LT_REQUIRED_DARWIN_CHECKS],\t[AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])\nm4_ifndef([_LT_AC_PROG_CXXCPP],\t\t[AC_DEFUN([_LT_AC_PROG_CXXCPP])])\nm4_ifndef([_LT_PREPARE_SED_QUOTE_VARS],\t[AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])\nm4_ifndef([_LT_PROG_ECHO_BACKSLASH],\t[AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])\nm4_ifndef([_LT_PROG_F77],\t\t[AC_DEFUN([_LT_PROG_F77])])\nm4_ifndef([_LT_PROG_FC],\t\t[AC_DEFUN([_LT_PROG_FC])])\nm4_ifndef([_LT_PROG_CXX],\t\t[AC_DEFUN([_LT_PROG_CXX])])\n\n# pkg.m4 - Macros to locate and utilise pkg-config.            -*- Autoconf -*-\n# serial 1 (pkg-config-0.24)\n# \n# Copyright © 2004 Scott James Remnant <scott@netsplit.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 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# PKG_PROG_PKG_CONFIG([MIN-VERSION])\n# ----------------------------------\nAC_DEFUN([PKG_PROG_PKG_CONFIG],\n[m4_pattern_forbid([^_?PKG_[A-Z_]+$])\nm4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])\nm4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])\nAC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])\nAC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])\nAC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])\n\nif test \"x$ac_cv_env_PKG_CONFIG_set\" != \"xset\"; then\n\tAC_PATH_TOOL([PKG_CONFIG], [pkg-config])\nfi\nif test -n \"$PKG_CONFIG\"; then\n\t_pkg_min_version=m4_default([$1], [0.9.0])\n\tAC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])\n\tif $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then\n\t\tAC_MSG_RESULT([yes])\n\telse\n\t\tAC_MSG_RESULT([no])\n\t\tPKG_CONFIG=\"\"\n\tfi\nfi[]dnl\n])# PKG_PROG_PKG_CONFIG\n\n# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])\n#\n# Check to see whether a particular set of modules exists.  Similar\n# to PKG_CHECK_MODULES(), but does not set variables or print errors.\n#\n# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])\n# only at the first occurence in configure.ac, so if the first place\n# it's called might be skipped (such as if it is within an \"if\", you\n# have to call PKG_CHECK_EXISTS manually\n# --------------------------------------------------------------\nAC_DEFUN([PKG_CHECK_EXISTS],\n[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl\nif test -n \"$PKG_CONFIG\" && \\\n    AC_RUN_LOG([$PKG_CONFIG --exists --print-errors \"$1\"]); then\n  m4_default([$2], [:])\nm4_ifvaln([$3], [else\n  $3])dnl\nfi])\n\n# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])\n# ---------------------------------------------\nm4_define([_PKG_CONFIG],\n[if test -n \"$$1\"; then\n    pkg_cv_[]$1=\"$$1\"\n elif test -n \"$PKG_CONFIG\"; then\n    PKG_CHECK_EXISTS([$3],\n                     [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 \"$3\" 2>/dev/null`\n\t\t      test \"x$?\" != \"x0\" && pkg_failed=yes ],\n\t\t     [pkg_failed=yes])\n else\n    pkg_failed=untried\nfi[]dnl\n])# _PKG_CONFIG\n\n# _PKG_SHORT_ERRORS_SUPPORTED\n# -----------------------------\nAC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],\n[AC_REQUIRE([PKG_PROG_PKG_CONFIG])\nif $PKG_CONFIG --atleast-pkgconfig-version 0.20; then\n        _pkg_short_errors_supported=yes\nelse\n        _pkg_short_errors_supported=no\nfi[]dnl\n])# _PKG_SHORT_ERRORS_SUPPORTED\n\n\n# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],\n# [ACTION-IF-NOT-FOUND])\n#\n#\n# Note that if there is a possibility the first call to\n# PKG_CHECK_MODULES might not happen, you should be sure to include an\n# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac\n#\n#\n# --------------------------------------------------------------\nAC_DEFUN([PKG_CHECK_MODULES],\n[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl\nAC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl\nAC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl\n\npkg_failed=no\nAC_MSG_CHECKING([for $1])\n\n_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])\n_PKG_CONFIG([$1][_LIBS], [libs], [$2])\n\nm4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS\nand $1[]_LIBS to avoid the need to call pkg-config.\nSee the pkg-config man page for more details.])\n\nif test $pkg_failed = yes; then\n   \tAC_MSG_RESULT([no])\n        _PKG_SHORT_ERRORS_SUPPORTED\n        if test $_pkg_short_errors_supported = yes; then\n\t        $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs \"$2\" 2>&1`\n        else \n\t        $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs \"$2\" 2>&1`\n        fi\n\t# Put the nasty error message in config.log where it belongs\n\techo \"$$1[]_PKG_ERRORS\" >&AS_MESSAGE_LOG_FD\n\n\tm4_default([$4], [AC_MSG_ERROR(\n[Package requirements ($2) were not met:\n\n$$1_PKG_ERRORS\n\nConsider adjusting the PKG_CONFIG_PATH environment variable if you\ninstalled software in a non-standard prefix.\n\n_PKG_TEXT])[]dnl\n        ])\nelif test $pkg_failed = untried; then\n     \tAC_MSG_RESULT([no])\n\tm4_default([$4], [AC_MSG_FAILURE(\n[The pkg-config script could not be found or is too old.  Make sure it\nis in your PATH or set the PKG_CONFIG environment variable to the full\npath to pkg-config.\n\n_PKG_TEXT\n\nTo get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl\n        ])\nelse\n\t$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS\n\t$1[]_LIBS=$pkg_cv_[]$1[]_LIBS\n        AC_MSG_RESULT([yes])\n\t$3\nfi[]dnl\n])# PKG_CHECK_MODULES\n\n# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software\n# 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 1\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.\n# (This private macro should not be called outside this file.)\nAC_DEFUN([AM_AUTOMAKE_VERSION],\n[am__api_version='1.11'\ndnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to\ndnl require some minimum version.  Point them to the right macro.\nm4_if([$1], [1.11.3], [],\n      [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl\n])\n\n# _AM_AUTOCONF_VERSION(VERSION)\n# -----------------------------\n# aclocal traces this macro to find the Autoconf version.\n# This is a private macro too.  Using m4_define simplifies\n# the logic in aclocal, which can simply ignore this definition.\nm4_define([_AM_AUTOCONF_VERSION], [])\n\n# AM_SET_CURRENT_AUTOMAKE_VERSION\n# -------------------------------\n# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.\n# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.\nAC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],\n[AM_AUTOMAKE_VERSION([1.11.3])dnl\nm4_ifndef([AC_AUTOCONF_VERSION],\n  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl\n_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])\n\n# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-\n\n# Copyright (C) 2001, 2003, 2005, 2011 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 1\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, 2006, 2008\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 9\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])dnl\nAC_SUBST([$1_FALSE])dnl\n_AM_SUBST_NOTMAKE([$1_TRUE])dnl\n_AM_SUBST_NOTMAKE([$1_FALSE])dnl\nm4_define([_AM_COND_VALUE_$1], [$2])dnl\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# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009,\n# 2010, 2011 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# 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], UPC,  [depcc=\"$UPC\"  am_compiler_list=],\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  rm -rf conftest.dir\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  am__universal=false\n  m4_case([$1], [CC],\n    [case \" $depcc \" in #(\n     *\\ -arch\\ *\\ -arch\\ *) am__universal=true ;;\n     esac],\n    [CXX],\n    [case \" $depcc \" in #(\n     *\\ -arch\\ *\\ -arch\\ *) am__universal=true ;;\n     esac])\n\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    # 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.  Also, some Intel\n    # versions had trouble with output in subdirs\n    am__obj=sub/conftest.${OBJEXT-o}\n    am__minus_obj=\"-o $am__obj\"\n    case $depmode in\n    gcc)\n      # This depmode causes a compiler race in universal mode.\n      test \"$am__universal\" = false || continue\n      ;;\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    msvc7 | msvc7msys | msvisualcpp | msvcmsys)\n      # This compiler won't grok `-c -o', but also, the minuso test has\n      # not run yet.  These depmodes are late enough in the game, and\n      # so weak that their functioning should not be impacted.\n      am__obj=conftest.${OBJEXT-o}\n      am__minus_obj=\n      ;;\n    none) break ;;\n    esac\n    if depmode=$depmode \\\n       source=sub/conftest.c object=$am__obj \\\n       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \\\n       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \\\n         >/dev/null 2>conftest.err &&\n       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&\n       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&\n       grep $am__obj 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='\\'\n  am__nodep='_no'\nfi\nAM_CONDITIONAL([AMDEP], [test \"x$enable_dependency_tracking\" != xno])\nAC_SUBST([AMDEPBACKSLASH])dnl\n_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl\nAC_SUBST([am__nodep])dnl\n_AM_SUBST_NOTMAKE([am__nodep])dnl\n])\n\n# Generate code to set up dependency tracking.              -*- Autoconf -*-\n\n# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008\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 5\n\n# _AM_OUTPUT_DEPENDENCY_COMMANDS\n# ------------------------------\nAC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],\n[{\n  # Autoconf 2.62 quotes --file arguments for eval, but not when files\n  # are listed without --file.  Let's play safe and only enable the eval\n  # if we detect the quoting.\n  case $CONFIG_FILES in\n  *\\'*) eval set x \"$CONFIG_FILES\" ;;\n  *)   set x $CONFIG_FILES ;;\n  esac\n  shift\n  for mf\n  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    # Grep'ing the whole file is not good either: AIX grep has a line\n    # limit of 2048, but all sed's we know have understand at least 4000.\n    if sed -n 's,^#.*generated by automake.*,X,p' \"$mf\" | grep X >/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\t 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\n  done\n}\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# Do all the work for Automake.                             -*- Autoconf -*-\n\n# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,\n# 2005, 2006, 2008, 2009 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 16\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.62])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\nif test \"`cd $srcdir && pwd`\" != \"`pwd`\"; then\n  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output\n  # is not polluted with repeated \"-I.\"\n  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl\n  # test to see if srcdir already configured\n  if test -f $srcdir/config.status; then\n    AC_MSG_ERROR([source directory already configured; run \"make distclean\" there first])\n  fi\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\ndnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.\nm4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,\n  [m4_fatal([AC_INIT should be called with package and version arguments])])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)\nAC_REQUIRE([AM_PROG_INSTALL_SH])dnl\nAC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl\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\t      [_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\t\t  [_AM_DEPENDENCIES(CC)],\n\t\t  [define([AC_PROG_CC],\n\t\t\t  defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl\nAC_PROVIDE_IFELSE([AC_PROG_CXX],\n\t\t  [_AM_DEPENDENCIES(CXX)],\n\t\t  [define([AC_PROG_CXX],\n\t\t\t  defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl\nAC_PROVIDE_IFELSE([AC_PROG_OBJC],\n\t\t  [_AM_DEPENDENCIES(OBJC)],\n\t\t  [define([AC_PROG_OBJC],\n\t\t\t  defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl\n])\n_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl\ndnl The `parallel-tests' driver may need to know about EXEEXT, so add the\ndnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This macro\ndnl is hooked onto _AC_COMPILER_EXEEXT early, see below.\nAC_CONFIG_COMMANDS_PRE(dnl\n[m4_provide_if([_AM_COMPILER_EXEEXT],\n  [AM_CONDITIONAL([am__EXEEXT], [test -n \"$EXEEXT\"])])])dnl\n])\n\ndnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not\ndnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further\ndnl mangled by Autoconf and run in a shell conditional statement.\nm4_define([_AC_COMPILER_EXEEXT],\nm4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])\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_arg=$1\n_am_stamp_count=1\nfor _am_header in $config_headers :; do\n  case $_am_header in\n    $_am_arg | $_am_arg:* )\n      break ;;\n    * )\n      _am_stamp_count=`expr $_am_stamp_count + 1` ;;\n  esac\ndone\necho \"timestamp for $_am_arg\" >`AS_DIRNAME([\"$_am_arg\"])`/stamp-h[]$_am_stamp_count])\n\n# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation,\n# 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 1\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\nif test x\"${install_sh}\" != xset; then\n  case $am_aux_dir in\n  *\\ * | *\\\t*)\n    install_sh=\"\\${SHELL} '$am_aux_dir/install-sh'\" ;;\n  *)\n    install_sh=\"\\${SHELL} $am_aux_dir/install-sh\"\n  esac\nfi\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, 2009  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_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 this is the am__doit target\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# Ignore all kinds of additional output from `make'.\ncase `$am_make -s -f confmf 2> /dev/null` in #(\n*the\\ am__doit\\ target*)\n  am__include=include\n  am__quote=\n  _am_result=GNU\n  ;;\nesac\n# Now try BSD make style include.\nif test \"$am__include\" = \"#\"; then\n   echo '.include \"confinc\"' > confmf\n   case `$am_make -s -f confmf 2> /dev/null` in #(\n   *the\\ am__doit\\ target*)\n     am__include=.include\n     am__quote=\"\\\"\"\n     _am_result=BSD\n     ;;\n   esac\nfi\nAC_SUBST([am__include])\nAC_SUBST([am__quote])\nAC_MSG_RESULT([$_am_result])\nrm -f confinc confmf\n])\n\n# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-\n\n# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008\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 6\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\nAC_REQUIRE_AUX_FILE([missing])dnl\nif test x\"${MISSING+set}\" != xset; then\n  case $am_aux_dir in\n  *\\ * | *\\\t*)\n    MISSING=\"\\${SHELL} \\\"$am_aux_dir/missing\\\"\" ;;\n  *)\n    MISSING=\"\\${SHELL} $am_aux_dir/missing\" ;;\n  esac\nfi\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, 2006, 2011 Free Software Foundation,\n# 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 1\n\n# AM_PROG_MKDIR_P\n# ---------------\n# Check for `mkdir -p'.\nAC_DEFUN([AM_PROG_MKDIR_P],\n[AC_PREREQ([2.60])dnl\nAC_REQUIRE([AC_PROG_MKDIR_P])dnl\ndnl Automake 1.8 to 1.9.6 used to define mkdir_p.  We now use MKDIR_P,\ndnl while keeping a definition of mkdir_p for backward compatibility.\ndnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.\ndnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of\ndnl Makefile.ins that do not define MKDIR_P, so we do our own\ndnl adjustment using top_builddir (which is defined more often than\ndnl MKDIR_P).\nAC_SUBST([mkdir_p], [\"$MKDIR_P\"])dnl\ncase $mkdir_p in\n  [[\\\\/$]]* | ?:[[\\\\/]]*) ;;\n  */*) mkdir_p=\"\\$(top_builddir)/$mkdir_p\" ;;\nesac\n])\n\n# Helper functions for option handling.                     -*- Autoconf -*-\n\n# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software\n# 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 5\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[m4_foreach_w([_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, 2008\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 5\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# Reject unsafe characters in $srcdir or the absolute working directory\n# name.  Accept space and tab only in the latter.\nam_lf='\n'\ncase `pwd` in\n  *[[\\\\\\\"\\#\\$\\&\\'\\`$am_lf]]*)\n    AC_MSG_ERROR([unsafe absolute working directory name]);;\nesac\ncase $srcdir in\n  *[[\\\\\\\"\\#\\$\\&\\'\\`$am_lf\\ \\\t]]*)\n    AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;\nesac\n\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, 2011 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 1\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=\"\\$(install_sh) -c -s\"\nAC_SUBST([INSTALL_STRIP_PROGRAM])])\n\n# Copyright (C) 2006, 2008, 2010 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_SUBST_NOTMAKE(VARIABLE)\n# ---------------------------\n# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.\n# This macro is traced by Automake.\nAC_DEFUN([_AM_SUBST_NOTMAKE])\n\n# AM_SUBST_NOTMAKE(VARIABLE)\n# --------------------------\n# Public sister of _AM_SUBST_NOTMAKE.\nAC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])\n\n# Check how to create a tarball.                            -*- Autoconf -*-\n\n# Copyright (C) 2004, 2005, 2012 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.  Yes, it's still used\n# in the wild :-(  We should find a proper way to deprecate it ...\nAC_SUBST([AMTAR], ['$${TAR-tar}'])\nm4_if([$1], [v7],\n     [am__tar='$${TAR-tar} chof - \"$$tardir\"' am__untar='$${TAR-tar} 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/gtest.m4])\n"
  },
  {
    "path": "deps/snappy-1.1.0/autogen.sh",
    "content": "#! /bin/sh -e\nrm -rf autom4te.cache\naclocal -I m4\nautoheader\nlibtoolize --copy\nautomake --add-missing --copy\nautoconf\n"
  },
  {
    "path": "deps/snappy-1.1.0/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, 2007, 2008, 2009, 2010,\n#   2011, 2012 Free Software Foundation, Inc.\n\ntimestamp='2012-02-10'\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, see <http://www.gnu.org/licenses/>.\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.  Please send patches (context\n# diff format) to <config-patches@gnu.org> and include a ChangeLog\n# 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# You can get the latest version of this script from:\n# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD\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,\n2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012\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 tuples: *-*-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 -q __ELF__\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\tos=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\tUNAME_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\t# Reset EXIT trap before exiting to avoid spurious non-zero exit code.\n\texitcode=$?\n\ttrap '' 0\n\texit $exitcode ;;\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\techo 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    s390x:SunOS:*:*)\n\techo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit ;;\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:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)\n\techo i386-pc-auroraux${UNAME_RELEASE}\n\texit ;;\n    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)\n\teval $set_cc_for_build\n\tSUN_ARCH=\"i386\"\n\t# If there is a compiler, see if it is configured for 64-bit objects.\n\t# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.\n\t# This test works for both compilers.\n\tif [ \"$CC_FOR_BUILD\" != 'no_compiler_found' ]; then\n\t    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \\\n\t\t(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \\\n\t\tgrep IS_64BIT_ARCH >/dev/null\n\t    then\n\t\tSUN_ARCH=\"x86_64\"\n\t    fi\n\tfi\n\techo ${SUN_ARCH}-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\techo m68k-atari-mint${UNAME_RELEASE}\n\texit ;;\n    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)\n\techo m68k-atari-mint${UNAME_RELEASE}\n\texit ;;\n    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)\n\techo m68k-atari-mint${UNAME_RELEASE}\n\texit ;;\n    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)\n\techo m68k-milan-mint${UNAME_RELEASE}\n\texit ;;\n    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)\n\techo m68k-hades-mint${UNAME_RELEASE}\n\texit ;;\n    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)\n\techo m68k-unknown-mint${UNAME_RELEASE}\n\texit ;;\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\t# DG/UX returns AViiON for all architectures\n\tUNAME_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:*:[4567])\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\t\t    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`\n\t\t    case \"${sc_cpu_version}\" in\n\t\t      523) HP_ARCH=\"hppa1.0\" ;; # CPU_PA_RISC1_0\n\t\t      528) HP_ARCH=\"hppa1.1\" ;; # CPU_PA_RISC1_1\n\t\t      532)                      # CPU_PA_RISC2_0\n\t\t\tcase \"${sc_kernel_bits}\" in\n\t\t\t  32) HP_ARCH=\"hppa2.0n\" ;;\n\t\t\t  64) HP_ARCH=\"hppa2.0w\" ;;\n\t\t\t  '') HP_ARCH=\"hppa2.0\" ;;   # HP-UX 10.20\n\t\t\tesac ;;\n\t\t    esac\n\t\tfi\n\t\tif [ \"${HP_ARCH}\" = \"\" ]; then\n\t\t    eval $set_cc_for_build\n\t\t    sed 's/^\t\t//' << EOF >$dummy.c\n\n\t\t#define _HPUX_SOURCE\n\t\t#include <stdlib.h>\n\t\t#include <unistd.h>\n\n\t\tint main ()\n\t\t{\n\t\t#if defined(_SC_KERNEL_BITS)\n\t\t    long bits = sysconf(_SC_KERNEL_BITS);\n\t\t#endif\n\t\t    long cpu  = sysconf (_SC_CPU_VERSION);\n\n\t\t    switch (cpu)\n\t\t\t{\n\t\t\tcase CPU_PA_RISC1_0: puts (\"hppa1.0\"); break;\n\t\t\tcase CPU_PA_RISC1_1: puts (\"hppa1.1\"); break;\n\t\t\tcase CPU_PA_RISC2_0:\n\t\t#if defined(_SC_KERNEL_BITS)\n\t\t\t    switch (bits)\n\t\t\t\t{\n\t\t\t\tcase 64: puts (\"hppa2.0w\"); break;\n\t\t\t\tcase 32: puts (\"hppa2.0n\"); break;\n\t\t\t\tdefault: puts (\"hppa2.0\"); break;\n\t\t\t\t} break;\n\t\t#else  /* !defined(_SC_KERNEL_BITS) */\n\t\t\t    puts (\"hppa2.0\"); break;\n\t\t#endif\n\t\t\tdefault: puts (\"hppa1.0\"); break;\n\t\t\t}\n\t\t    exit (0);\n\t\t}\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 -q __LP64__\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\texit ;;\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\texit ;;\n    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)\n\techo c34-convex-bsd\n\texit ;;\n    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)\n\techo c38-convex-bsd\n\texit ;;\n    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)\n\techo c4-convex-bsd\n\texit ;;\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\tFUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\\///'`\n\tFUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`\n\techo \"${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}\"\n\texit ;;\n    5000:UNIX_System_V:4.*:*)\n\tFUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\\///'`\n\tFUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`\n\techo \"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\tUNAME_PROCESSOR=`/usr/bin/uname -p`\n\tcase ${UNAME_PROCESSOR} in\n\t    amd64)\n\t\techo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;\n\t    *)\n\t\techo ${UNAME_PROCESSOR}-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*:MSYS*:*)\n\techo ${UNAME_MACHINE}-pc-msys\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*:*)\n\tcase ${UNAME_MACHINE} in\n\t    x86)\n\t\techo i586-pc-interix${UNAME_RELEASE}\n\t\texit ;;\n\t    authenticamd | genuineintel | EM64T)\n\t\techo x86_64-unknown-interix${UNAME_RELEASE}\n\t\texit ;;\n\t    IA64)\n\t\techo ia64-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    8664:Windows_NT:*)\n\techo x86_64-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    aarch64:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    aarch64_be:Linux:*:*)\n\tUNAME_MACHINE=aarch64_be\n\techo ${UNAME_MACHINE}-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\tesac\n\tobjdump --private-headers /bin/sh | grep -q ld.so.1\n\tif test \"$?\" = 0 ; then LIBC=\"libc1\" ; else LIBC=\"\" ; fi\n\techo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}\n\texit ;;\n    arm*:Linux:*:*)\n\teval $set_cc_for_build\n\tif echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \\\n\t    | grep -q __ARM_EABI__\n\tthen\n\t    echo ${UNAME_MACHINE}-unknown-linux-gnu\n\telse\n\t    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \\\n\t\t| grep -q __ARM_PCS_VFP\n\t    then\n\t\techo ${UNAME_MACHINE}-unknown-linux-gnueabi\n\t    else\n\t\techo ${UNAME_MACHINE}-unknown-linux-gnueabihf\n\t    fi\n\tfi\n\texit ;;\n    avr32*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    cris:Linux:*:*)\n\techo ${UNAME_MACHINE}-axis-linux-gnu\n\texit ;;\n    crisv32:Linux:*:*)\n\techo ${UNAME_MACHINE}-axis-linux-gnu\n\texit ;;\n    frv:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    hexagon:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    i*86:Linux:*:*)\n\tLIBC=gnu\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\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\techo \"${UNAME_MACHINE}-pc-linux-${LIBC}\"\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:*:* | mips64:Linux:*:*)\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n\t#undef CPU\n\t#undef ${UNAME_MACHINE}\n\t#undef ${UNAME_MACHINE}el\n\t#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)\n\tCPU=${UNAME_MACHINE}el\n\t#else\n\t#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)\n\tCPU=${UNAME_MACHINE}\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; }\n\t;;\n    or32:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    padre:Linux:*:*)\n\techo sparc-unknown-linux-gnu\n\texit ;;\n    parisc64:Linux:*:* | hppa64:Linux:*:*)\n\techo hppa64-unknown-linux-gnu\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    ppc64:Linux:*:*)\n\techo powerpc64-unknown-linux-gnu\n\texit ;;\n    ppc:Linux:*:*)\n\techo powerpc-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    tile*: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 ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    xtensa*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\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\t# Unixware is an offshoot of SVR4, but it has its own version\n\t# number series starting with 2...\n\t# I am not positive that other SVR4 systems won't match this,\n\t# I just have to hope.  -- rms.\n\t# 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.[02]*:*)\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\t# uname -m prints for DJGPP always 'pc', but it prints nothing about\n\t# the processor, so we play safe by assuming i586.\n\t# Note: whatever this is, it MUST be the same as what config.sub\n\t# prints for the \"djgpp\" host, or else GDB configury will decide that\n\t# this is a cross-build.\n\techo i586-pc-msdosdjgpp\n\texit ;;\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\t/bin/uname -p 2>/dev/null | grep 86 >/dev/null \\\n\t  && { echo i486-ncr-sysv4; exit; } ;;\n    NCR*:*:4.2:* | MPRAS*:*:4.2:*)\n\tOS_REL='.3'\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\t/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \\\n\t    && { echo i586-ncr-sysv4.3${OS_REL}; 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.[02]*:*)\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*:*)\t# Unisys `ClearPath HMP IX 4000' SVR4/MP effort\n\t\t\t# says <Richard.M.Bartel@ccMail.Census.GOV>\n\techo i586-unisys-sysv4\n\texit ;;\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\techo mips-nec-sysv${UNAME_RELEASE}\n\telse\n\t\techo mips-unknown-sysv${UNAME_RELEASE}\n\tfi\n\texit ;;\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    BePC:Haiku:*:*)\t# Haiku running on Intel PC compatible.\n\techo i586-pc-haiku\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    i386)\n\t\teval $set_cc_for_build\n\t\tif [ \"$CC_FOR_BUILD\" != 'no_compiler_found' ]; then\n\t\t  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \\\n\t\t      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \\\n\t\t      grep IS_64BIT_ARCH >/dev/null\n\t\t  then\n\t\t      UNAME_PROCESSOR=\"x86_64\"\n\t\t  fi\n\t\tfi ;;\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    NEO-?:NONSTOP_KERNEL:*:*)\n\techo neo-tandem-nsk${UNAME_RELEASE}\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\techo 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 ;;\n    i*86:AROS:*:*)\n\techo ${UNAME_MACHINE}-pc-aros\n\texit ;;\n    x86_64:VMkernel:*:*)\n\techo ${UNAME_MACHINE}-unknown-esx\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\t\"4\"\n#else\n\t\"\"\n#endif\n\t); 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://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD\nand\n  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD\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": "deps/snappy-1.1.0/config.h.in",
    "content": "/* config.h.in.  Generated from configure.ac by autoheader.  */\n\n/* Define if building universal (internal helper macro) */\n#undef AC_APPLE_UNIVERSAL_BUILD\n\n/* Define to 1 if the compiler supports __builtin_ctz and friends. */\n#undef HAVE_BUILTIN_CTZ\n\n/* Define to 1 if the compiler supports __builtin_expect. */\n#undef HAVE_BUILTIN_EXPECT\n\n/* Define to 1 if you have the <byteswap.h> header file. */\n#undef HAVE_BYTESWAP_H\n\n/* Define to 1 if you have the <dlfcn.h> header file. */\n#undef HAVE_DLFCN_H\n\n/* Use the gflags package for command-line parsing. */\n#undef HAVE_GFLAGS\n\n/* Defined when Google Test is available. */\n#undef HAVE_GTEST\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 `fastlz' library (-lfastlz). */\n#undef HAVE_LIBFASTLZ\n\n/* Define to 1 if you have the `lzf' library (-llzf). */\n#undef HAVE_LIBLZF\n\n/* Define to 1 if you have the `lzo2' library (-llzo2). */\n#undef HAVE_LIBLZO2\n\n/* Define to 1 if you have the `quicklz' library (-lquicklz). */\n#undef HAVE_LIBQUICKLZ\n\n/* Define to 1 if you have the `z' library (-lz). */\n#undef HAVE_LIBZ\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 the <stddef.h> header file. */\n#undef HAVE_STDDEF_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 you have the <sys/byteswap.h> header file. */\n#undef HAVE_SYS_BYTESWAP_H\n\n/* Define to 1 if you have the <sys/endian.h> header file. */\n#undef HAVE_SYS_ENDIAN_H\n\n/* Define to 1 if you have the <sys/mman.h> header file. */\n#undef HAVE_SYS_MMAN_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/stat.h> header file. */\n#undef HAVE_SYS_STAT_H\n\n/* Define to 1 if you have the <sys/time.h> header file. */\n#undef HAVE_SYS_TIME_H\n\n/* Define to 1 if you have the <sys/types.h> header file. */\n#undef HAVE_SYS_TYPES_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 <windows.h> header file. */\n#undef HAVE_WINDOWS_H\n\n/* Define to the sub-directory in which libtool stores uninstalled libraries.\n   */\n#undef LT_OBJDIR\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/* Define to 1 if you have the ANSI C header files. */\n#undef STDC_HEADERS\n\n/* Version number of package */\n#undef VERSION\n\n/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most\n   significant byte first (like Motorola and SPARC, unlike Intel). */\n#if defined AC_APPLE_UNIVERSAL_BUILD\n# if defined __BIG_ENDIAN__\n#  define WORDS_BIGENDIAN 1\n# endif\n#else\n# ifndef WORDS_BIGENDIAN\n#  undef WORDS_BIGENDIAN\n# endif\n#endif\n"
  },
  {
    "path": "deps/snappy-1.1.0/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, 2007, 2008, 2009, 2010,\n#   2011, 2012 Free Software Foundation, Inc.\n\ntimestamp='2012-02-10'\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, see <http://www.gnu.org/licenses/>.\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 GNU 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# You can get the latest version of this script from:\n# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD\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,\n2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012\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-android* | linux-dietlibc | linux-newlib* | \\\n  linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \\\n  knetbsd*-gnu* | netbsd*-gnu* | \\\n  kopensolaris*-gnu* | \\\n  storm-chaos* | os2-emx* | rtmk-nova*)\n    os=-$maybe_os\n    basic_machine=`echo $1 | sed 's/^\\(.*\\)-\\([^-]*-[^-]*\\)$/\\1/'`\n    ;;\n  android-linux)\n    os=-linux-android\n    basic_machine=`echo $1 | sed 's/^\\(.*\\)-\\([^-]*-[^-]*\\)$/\\1/'`-unknown\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 | -microblaze)\n\t\tos=\n\t\tbasic_machine=$1\n\t\t;;\n\t-bluegene*)\n\t\tos=-cnk\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| aarch64 | aarch64_be \\\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        | be32 | be64 \\\n\t| bfin \\\n\t| c4x | clipper \\\n\t| d10v | d30v | dlx | dsp16xx \\\n\t| epiphany \\\n\t| fido | fr30 | frv \\\n\t| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \\\n\t| hexagon \\\n\t| i370 | i860 | i960 | ia64 \\\n\t| ip2k | iq2000 \\\n\t| le32 | le64 \\\n\t| lm32 \\\n\t| m32c | m32r | m32rle | m68000 | m68k | m88k \\\n\t| maxq | mb | microblaze | mcore | mep | metag \\\n\t| mips | mipsbe | mipseb | mipsel | mipsle \\\n\t| mips16 \\\n\t| mips64 | mips64el \\\n\t| mips64octeon | mips64octeonel \\\n\t| mips64orion | mips64orionel \\\n\t| mips64r5900 | mips64r5900el \\\n\t| mips64vr | mips64vrel \\\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| moxie \\\n\t| mt \\\n\t| msp430 \\\n\t| nds32 | nds32le | nds32be \\\n\t| nios | nios2 \\\n\t| ns16k | ns32k \\\n\t| open8 \\\n\t| or32 \\\n\t| pdp10 | pdp11 | pj | pjl \\\n\t| powerpc | powerpc64 | powerpc64le | powerpcle \\\n\t| pyramid \\\n\t| rl78 | rx \\\n\t| score \\\n\t| sh | sh[1234] | sh[24]a | sh[24]aeb | 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 \\\n\t| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \\\n\t| ubicom32 \\\n\t| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \\\n\t| we32k \\\n\t| x86 | xc16x | xstormy16 | xtensa \\\n\t| z8k | z80)\n\t\tbasic_machine=$basic_machine-unknown\n\t\t;;\n\tc54x)\n\t\tbasic_machine=tic54x-unknown\n\t\t;;\n\tc55x)\n\t\tbasic_machine=tic55x-unknown\n\t\t;;\n\tc6x)\n\t\tbasic_machine=tic6x-unknown\n\t\t;;\n\tm6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)\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\tstrongarm | thumb | xscale)\n\t\tbasic_machine=arm-unknown\n\t\t;;\n\txgate)\n\t\tbasic_machine=$basic_machine-unknown\n\t\tos=-none\n\t\t;;\n\txscaleeb)\n\t\tbasic_machine=armeb-unknown\n\t\t;;\n\n\txscaleel)\n\t\tbasic_machine=armel-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| aarch64-* | aarch64_be-* \\\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| be32-* | be64-* \\\n\t| bfin-* | bs2000-* \\\n\t| c[123]* | c30-* | [cjt]90-* | c4x-* \\\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| hexagon-* \\\n\t| i*86-* | i860-* | i960-* | ia64-* \\\n\t| ip2k-* | iq2000-* \\\n\t| le32-* | le64-* \\\n\t| lm32-* \\\n\t| m32c-* | m32r-* | m32rle-* \\\n\t| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \\\n\t| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \\\n\t| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \\\n\t| mips16-* \\\n\t| mips64-* | mips64el-* \\\n\t| mips64octeon-* | mips64octeonel-* \\\n\t| mips64orion-* | mips64orionel-* \\\n\t| mips64r5900-* | mips64r5900el-* \\\n\t| mips64vr-* | mips64vrel-* \\\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| nds32-* | nds32le-* | nds32be-* \\\n\t| nios-* | nios2-* \\\n\t| none-* | np1-* | ns16k-* | ns32k-* \\\n\t| open8-* \\\n\t| orion-* \\\n\t| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \\\n\t| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \\\n\t| pyramid-* \\\n\t| rl78-* | romp-* | rs6000-* | rx-* \\\n\t| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | 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-* | sv1-* | sx?-* \\\n\t| tahoe-* \\\n\t| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \\\n\t| tile*-* \\\n\t| tron-* \\\n\t| ubicom32-* \\\n\t| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \\\n\t| vax-* \\\n\t| we32k-* \\\n\t| x86-* | x86_64-* | xc16x-* | xps100-* \\\n\t| xstormy16-* | xtensa*-* \\\n\t| ymp-* \\\n\t| z8k-* | z80-*)\n\t\t;;\n\t# Recognize the basic CPU types without company name, with glob match.\n\txtensa*)\n\t\tbasic_machine=$basic_machine-unknown\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\taros)\n\t\tbasic_machine=i386-pc\n\t\tos=-aros\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\tblackfin)\n\t\tbasic_machine=bfin-unknown\n\t\tos=-linux\n\t\t;;\n\tblackfin-*)\n\t\tbasic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\tos=-linux\n\t\t;;\n\tbluegene*)\n\t\tbasic_machine=powerpc-ibm\n\t\tos=-cnk\n\t\t;;\n\tc54x-*)\n\t\tbasic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tc55x-*)\n\t\tbasic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tc6x-*)\n\t\tbasic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tc90)\n\t\tbasic_machine=c90-cray\n\t\tos=-unicos\n\t\t;;\n\tcegcc)\n\t\tbasic_machine=arm-unknown\n\t\tos=-cegcc\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 | cr16-*)\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\tdicos)\n\t\tbasic_machine=i686-pc\n\t\tos=-dicos\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\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\tm68knommu)\n\t\tbasic_machine=m68k-unknown\n\t\tos=-linux\n\t\t;;\n\tm68knommu-*)\n\t\tbasic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\tos=-linux\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\tmicroblaze)\n\t\tbasic_machine=microblaze-xilinx\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\tmsys)\n\t\tbasic_machine=i386-pc\n\t\tos=-msys\n\t\t;;\n\tmvs)\n\t\tbasic_machine=i370-ibm\n\t\tos=-mvs\n\t\t;;\n\tnacl)\n\t\tbasic_machine=le32-unknown\n\t\tos=-nacl\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\tneo-tandem)\n\t\tbasic_machine=neo-tandem\n\t\t;;\n\tnse-tandem)\n\t\tbasic_machine=nse-tandem\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\tparisc)\n\t\tbasic_machine=hppa-unknown\n\t\tos=-linux\n\t\t;;\n\tparisc-*)\n\t\tbasic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\tos=-linux\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 | ppcbe)\tbasic_machine=powerpc-unknown\n\t\t;;\n\tppc-* | ppcbe-*)\n\t\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\tstrongarm-* | thumb-*)\n\t\tbasic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`\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\ttile*)\n\t\tbasic_machine=$basic_machine-unknown\n\t\tos=-linux-gnu\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\txscale-* | xscalee[bl]-*)\n\t\tbasic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`\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\tz80-*-coff)\n\t\tbasic_machine=z80-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[24]aeb | 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\t# First match some system type aliases\n\t# that might get confused with valid system types.\n\t# -solaris* is a basic system type, with this one exception.\n\t-auroraux)\n\t\tos=-auroraux\n\t\t;;\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* | -cnk* | -sunos | -sunos[34]*\\\n\t      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \\\n\t      | -sym* | -kopensolaris* \\\n\t      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \\\n\t      | -aos* | -aros* \\\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* | -cegcc* \\\n\t      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \\\n\t      | -mingw32* | -linux-gnu* | -linux-android* \\\n\t      | -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* | -es*)\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\t-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\t-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-dicos*)\n\t\tos=-dicos\n\t\t;;\n\t-nacl*)\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\tscore-*)\n\t\tos=-elf\n\t\t;;\n\tspu-*)\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\tc4x-* | tic4x-*)\n\t\tos=-coff\n\t\t;;\n\ttic54x-*)\n\t\tos=-coff\n\t\t;;\n\ttic55x-*)\n\t\tos=-coff\n\t\t;;\n\ttic6x-*)\n\t\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;;\n\tm68*-cisco)\n\t\tos=-aout\n\t\t;;\n\tmep-*)\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-cnk*|-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": "deps/snappy-1.1.0/configure",
    "content": "#! /bin/sh\n# Guess values for system-dependent variables and create Makefiles.\n# Generated by GNU Autoconf 2.68 for snappy 1.1.0.\n#\n#\n# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,\n# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software\n# Foundation, 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.\nas_myself=\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\n\n  test -n \\\"\\${ZSH_VERSION+set}\\${BASH_VERSION+set}\\\" || (\n    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\n    ECHO=\\$ECHO\\$ECHO\\$ECHO\\$ECHO\\$ECHO\n    ECHO=\\$ECHO\\$ECHO\\$ECHO\\$ECHO\\$ECHO\\$ECHO\n    PATH=/empty FPATH=/empty; export PATH FPATH\n    test \\\"X\\`printf %s \\$ECHO\\`\\\" = \\\"X\\$ECHO\\\" \\\\\n      || test \\\"X\\`print -r -- \\$ECHO\\`\\\" = \\\"X\\$ECHO\\\" ) || 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\t# Preserve -v and -x to the replacement shell.\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\tcase $- in # ((((\n\t  *v*x* | *x*v* ) as_opts=-vx ;;\n\t  *v* ) as_opts=-v ;;\n\t  *x* ) as_opts=-x ;;\n\t  * ) as_opts= ;;\n\tesac\n\texec \"$CONFIG_SHELL\" $as_opts \"$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 about your system,\n$0: including any error possibly output before this\n$0: message. Then install a modern shell, or manually run\n$0: the script under such a 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 STATUS 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=$1; test $as_status -eq 0 && as_status=1\n  if test \"$4\"; then\n    as_lineno=${as_lineno-\"$3\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n    $as_echo \"$as_me:${as_lineno-$LINENO}: error: $2\" >&$4\n  fi\n  $as_echo \"$as_me: error: $2\" >&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\nSHELL=${CONFIG_SHELL-/bin/sh}\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, old GNU/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='snappy'\nPACKAGE_TARNAME='snappy'\nPACKAGE_VERSION='1.1.0'\nPACKAGE_STRING='snappy 1.1.0'\nPACKAGE_BUGREPORT=''\nPACKAGE_URL=''\n\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_subst_vars='am__EXEEXT_FALSE\nam__EXEEXT_TRUE\nLTLIBOBJS\nLIBOBJS\nSNAPPY_LTVERSION\nSNAPPY_PATCHLEVEL\nSNAPPY_MINOR\nSNAPPY_MAJOR\nac_cv_have_stddef_h\nac_cv_have_stdint_h\nUNITTEST_LIBS\ngflags_LIBS\ngflags_CFLAGS\nPKG_CONFIG_LIBDIR\nPKG_CONFIG_PATH\nPKG_CONFIG\nHAVE_GTEST_FALSE\nHAVE_GTEST_TRUE\nHAVE_GTEST\nGTEST_VERSION\nGTEST_LIBS\nGTEST_LDFLAGS\nGTEST_CXXFLAGS\nGTEST_CPPFLAGS\nGTEST_CONFIG\nCXXCPP\nam__fastdepCXX_FALSE\nam__fastdepCXX_TRUE\nCXXDEPMODE\nac_ct_CXX\nCXXFLAGS\nCXX\nLIBTOOL_DEPS\nCPP\nOTOOL64\nOTOOL\nLIPO\nNMEDIT\nDSYMUTIL\nMANIFEST_TOOL\nRANLIB\nac_ct_AR\nAR\nDLLTOOL\nOBJDUMP\nLN_S\nNM\nac_ct_DUMPBIN\nDUMPBIN\nLD\nFGREP\nEGREP\nGREP\nSED\nam__fastdepCC_FALSE\nam__fastdepCC_TRUE\nCCDEPMODE\nam__nodep\nAMDEPBACKSLASH\nAMDEP_FALSE\nAMDEP_TRUE\nam__quote\nam__include\nDEPDIR\nOBJEXT\nEXEEXT\nac_ct_CC\nCPPFLAGS\nLDFLAGS\nCFLAGS\nCC\nhost_os\nhost_vendor\nhost_cpu\nhost\nbuild_os\nbuild_vendor\nbuild_cpu\nbuild\nLIBTOOL\nam__untar\nam__tar\nAMTAR\nam__leading_dot\nSET_MAKE\nAWK\nmkdir_p\nMKDIR_P\nINSTALL_STRIP_PROGRAM\nSTRIP\ninstall_sh\nMAKEINFO\nAUTOHEADER\nAUTOMAKE\nAUTOCONF\nACLOCAL\nVERSION\nPACKAGE\nCYGPATH_W\nam__isrc\nINSTALL_DATA\nINSTALL_SCRIPT\nINSTALL_PROGRAM\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_shared\nenable_static\nwith_pic\nenable_fast_install\nenable_dependency_tracking\nwith_gnu_ld\nwith_sysroot\nenable_libtool_lock\nenable_gtest\nwith_gflags\n'\n      ac_precious_vars='build_alias\nhost_alias\ntarget_alias\nCC\nCFLAGS\nLDFLAGS\nLIBS\nCPPFLAGS\nCPP\nCXX\nCXXFLAGS\nCCC\nCXXCPP\nGTEST_CONFIG\nGTEST_CPPFLAGS\nGTEST_CXXFLAGS\nGTEST_LDFLAGS\nGTEST_LIBS\nGTEST_VERSION\nPKG_CONFIG\nPKG_CONFIG_PATH\nPKG_CONFIG_LIBDIR\ngflags_CFLAGS\ngflags_LIBS'\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  *=?*) ac_optarg=`expr \"X$ac_option\" : '[^=]*=\\(.*\\)'` ;;\n  *=)   ac_optarg= ;;\n  *)    ac_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 snappy 1.1.0 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 [DATAROOTDIR/doc/snappy]\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 snappy 1.1.0:\";;\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  --enable-shared[=PKGS]  build shared libraries [default=yes]\n  --enable-static[=PKGS]  build static libraries [default=yes]\n  --enable-fast-install[=PKGS]\n                          optimize for fast installation [default=yes]\n  --disable-dependency-tracking  speeds up one-time build\n  --enable-dependency-tracking   do not reject slow dependency extractors\n  --disable-libtool-lock  avoid locking (might break parallel builds)\n  --enable-gtest          Enable tests using the Google C++ Testing Framework.\n                          (Default is enabled.)\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[=PKGS]       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  --with-sysroot=DIR Search for dependent libraries within DIR\n                        (or the compiler's sysroot if not specified).\n  --with-gflags           use Google Flags package to enhance the unit test\n                          [default=check]\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  GTEST_CONFIG\n              The exact path of Google Test's 'gtest-config' script.\n  GTEST_CPPFLAGS\n              C-like preprocessor flags for Google Test.\n  GTEST_CXXFLAGS\n              C++ compile flags for Google Test.\n  GTEST_LDFLAGS\n              Linker path and option flags for Google Test.\n  GTEST_LIBS  Library linking flags for Google Test.\n  GTEST_VERSION\n              The version of Google Test available.\n  PKG_CONFIG  path to pkg-config utility\n  PKG_CONFIG_PATH\n              directories to add to pkg-config's search path\n  PKG_CONFIG_LIBDIR\n              path overriding pkg-config's built-in search path\n  gflags_CFLAGS\n              C compiler flags for gflags, overriding pkg-config\n  gflags_LIBS linker flags for gflags, overriding pkg-config\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 the package provider.\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\nsnappy configure 1.1.0\ngenerated by GNU Autoconf 2.68\n\nCopyright (C) 2010 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; ${as_lineno_stack:+:} unset as_lineno\n  as_fn_set_status $ac_retval\n\n} # ac_fn_c_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; ${as_lineno_stack:+:} 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 eval \\${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno\n\n} # ac_fn_c_check_header_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; } > conftest.i && {\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; ${as_lineno_stack:+:} unset as_lineno\n  as_fn_set_status $ac_retval\n\n} # ac_fn_c_try_cpp\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; ${as_lineno_stack:+:} 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 eval \\${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno\n\n} # ac_fn_c_check_func\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; ${as_lineno_stack:+:} unset as_lineno\n  as_fn_set_status $ac_retval\n\n} # ac_fn_cxx_try_compile\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; } > conftest.i && {\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; ${as_lineno_stack:+:} 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; ${as_lineno_stack:+:} unset as_lineno\n  as_fn_set_status $ac_retval\n\n} # ac_fn_cxx_try_link\n\n# ac_fn_cxx_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_cxx_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; ${as_lineno_stack:+:} unset as_lineno\n  as_fn_set_status $ac_retval\n\n} # ac_fn_cxx_try_run\n\n# ac_fn_cxx_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_cxx_check_header_mongrel ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  if eval \\${$3+:} false; then :\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif eval \\${$3+:} false; 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_cxx_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_cxx_try_cpp \"$LINENO\"; then :\n  ac_header_preproc=yes\nelse\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.i 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_cxx_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    ;;\nesac\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif eval \\${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno\n\n} # ac_fn_cxx_check_header_mongrel\n\n# ac_fn_cxx_check_func LINENO FUNC VAR\n# ------------------------------------\n# Tests whether FUNC exists, setting the cache variable VAR accordingly\nac_fn_cxx_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 eval \\${$3+:} false; 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_cxx_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; ${as_lineno_stack:+:} unset as_lineno\n\n} # ac_fn_cxx_check_func\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 snappy $as_me 1.1.0, which was\ngenerated by GNU Autoconf 2.68.  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    $as_echo \"## ---------------- ##\n## Cache variables. ##\n## ---------------- ##\"\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    $as_echo \"## ----------------- ##\n## Output variables. ##\n## ----------------- ##\"\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      $as_echo \"## ------------------- ##\n## File substitutions. ##\n## ------------------- ##\"\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      $as_echo \"## ----------- ##\n## confdefs.h. ##\n## ----------- ##\"\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  # We do not want a PATH search for config.site.\n  case $CONFIG_SITE in #((\n    -*)  ac_site_file1=./$CONFIG_SITE;;\n    */*) ac_site_file1=$CONFIG_SITE;;\n    *)   ac_site_file1=./$CONFIG_SITE;;\n  esac\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      || { { $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 $? \"failed to load site script $ac_site_file\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\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\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\n\n# These are flags passed to automake (though they look like gcc flags!)\nam__api_version='1.11'\n\nac_aux_dir=\nfor ac_dir in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"; do\n  if test -f \"$ac_dir/install-sh\"; then\n    ac_aux_dir=$ac_dir\n    ac_install_sh=\"$ac_aux_dir/install-sh -c\"\n    break\n  elif test -f \"$ac_dir/install.sh\"; then\n    ac_aux_dir=$ac_dir\n    ac_install_sh=\"$ac_aux_dir/install.sh -c\"\n    break\n  elif test -f \"$ac_dir/shtool\"; then\n    ac_aux_dir=$ac_dir\n    ac_install_sh=\"$ac_aux_dir/shtool install -c\"\n    break\n  fi\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# 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 ${ac_cv_path_install+:} false; 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# Reject unsafe characters in $srcdir or the absolute working directory\n# name.  Accept space and tab only in the latter.\nam_lf='\n'\ncase `pwd` in\n  *[\\\\\\\"\\#\\$\\&\\'\\`$am_lf]*)\n    as_fn_error $? \"unsafe absolute working directory name\" \"$LINENO\" 5;;\nesac\ncase $srcdir in\n  *[\\\\\\\"\\#\\$\\&\\'\\`$am_lf\\ \\\t]*)\n    as_fn_error $? \"unsafe srcdir value: \\`$srcdir'\" \"$LINENO\" 5;;\nesac\n\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\nif test x\"${MISSING+set}\" != xset; then\n  case $am_aux_dir in\n  *\\ * | *\\\t*)\n    MISSING=\"\\${SHELL} \\\"$am_aux_dir/missing\\\"\" ;;\n  *)\n    MISSING=\"\\${SHELL} $am_aux_dir/missing\" ;;\n  esac\nfi\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 test x\"${install_sh}\" != xset; then\n  case $am_aux_dir in\n  *\\ * | *\\\t*)\n    install_sh=\"\\${SHELL} '$am_aux_dir/install-sh'\" ;;\n  *)\n    install_sh=\"\\${SHELL} $am_aux_dir/install-sh\"\n  esac\nfi\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 ${ac_cv_prog_STRIP+:} false; 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 ${ac_cv_prog_ac_ct_STRIP+:} false; 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=\"\\$(install_sh) -c -s\"\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p\" >&5\n$as_echo_n \"checking for a thread-safe mkdir -p... \" >&6; }\nif test -z \"$MKDIR_P\"; then\n  if ${ac_cv_path_mkdir+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_prog in mkdir gmkdir; do\n\t for ac_exec_ext in '' $ac_executable_extensions; do\n\t   { test -f \"$as_dir/$ac_prog$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_prog$ac_exec_ext\"; } || continue\n\t   case `\"$as_dir/$ac_prog$ac_exec_ext\" --version 2>&1` in #(\n\t     'mkdir (GNU coreutils) '* | \\\n\t     'mkdir (coreutils) '* | \\\n\t     'mkdir (fileutils) '4.1*)\n\t       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext\n\t       break 3;;\n\t   esac\n\t done\n       done\n  done\nIFS=$as_save_IFS\n\nfi\n\n  test -d ./--version && rmdir ./--version\n  if test \"${ac_cv_path_mkdir+set}\" = set; then\n    MKDIR_P=\"$ac_cv_path_mkdir -p\"\n  else\n    # As a last resort, use the slow shell script.  Don't cache a\n    # value for MKDIR_P 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    MKDIR_P=\"$ac_install_sh -d\"\n  fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $MKDIR_P\" >&5\n$as_echo \"$MKDIR_P\" >&6; }\n\nmkdir_p=\"$MKDIR_P\"\ncase $mkdir_p in\n  [\\\\/$]* | ?:[\\\\/]*) ;;\n  */*) mkdir_p=\"\\$(top_builddir)/$mkdir_p\" ;;\nesac\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 ${ac_cv_prog_AWK+:} false; 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 eval \\${ac_cv_prog_make_${ac_make}_set+:} false; 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\nif test \"`cd $srcdir && pwd`\" != \"`pwd`\"; then\n  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output\n  # is not polluted with repeated \"-I.\"\n  am__isrc=' -I$(srcdir)'\n  # test to see if srcdir already configured\n  if test -f $srcdir/config.status; then\n    as_fn_error $? \"source directory already configured; run \\\"make distclean\\\" there first\" \"$LINENO\" 5\n  fi\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='snappy'\n VERSION='1.1.0'\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\n# We need awk for the \"check\" target.  The system \"awk\" is bad on\n# some platforms.\n# Always define AMTAR for backward compatibility.  Yes, it's still used\n# in the wild :-(  We should find a proper way to deprecate it ...\nAMTAR='$${TAR-tar}'\n\nam__tar='$${TAR-tar} chof - \"$$tardir\"' am__untar='$${TAR-tar} xf -'\n\n\n\n\n\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.4.2'\nmacro_revision='1.3337'\n\n\n\n\n\n\n\n\n\n\n\n\n\nltmain=\"$ac_aux_dir/ltmain.sh\"\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 ${ac_cv_build+:} false; 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 ${ac_cv_host+:} false; 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\n# Backslashify metacharacters that are still active within\n# 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\nECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\nECHO=$ECHO$ECHO$ECHO$ECHO$ECHO\nECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to print strings\" >&5\n$as_echo_n \"checking how to print strings... \" >&6; }\n# Test print first, because it will be a builtin if present.\nif test \"X`( print -r -- -n ) 2>/dev/null`\" = X-n && \\\n   test \"X`print -r -- $ECHO 2>/dev/null`\" = \"X$ECHO\"; then\n  ECHO='print -r --'\nelif test \"X`printf %s $ECHO 2>/dev/null`\" = \"X$ECHO\"; then\n  ECHO='printf %s\\n'\nelse\n  # Use this function as a fallback that always works.\n  func_fallback_echo ()\n  {\n    eval 'cat <<_LTECHO_EOF\n$1\n_LTECHO_EOF'\n  }\n  ECHO='func_fallback_echo'\nfi\n\n# func_echo_all arg...\n# Invoke $ECHO with all args, space-separated.\nfunc_echo_all ()\n{\n    $ECHO \"\"\n}\n\ncase \"$ECHO\" in\n  printf*) { $as_echo \"$as_me:${as_lineno-$LINENO}: result: printf\" >&5\n$as_echo \"printf\" >&6; } ;;\n  print*) { $as_echo \"$as_me:${as_lineno-$LINENO}: result: print -r\" >&5\n$as_echo \"print -r\" >&6; } ;;\n  *) { $as_echo \"$as_me:${as_lineno-$LINENO}: result: cat\" >&5\n$as_echo \"cat\" >&6; } ;;\nesac\n\n\n\n\n\n\n\n\n\n\n\n\n\n\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 this is the am__doit target\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# Ignore all kinds of additional output from `make'.\ncase `$am_make -s -f confmf 2> /dev/null` in #(\n*the\\ am__doit\\ target*)\n  am__include=include\n  am__quote=\n  _am_result=GNU\n  ;;\nesac\n# Now try BSD make style include.\nif test \"$am__include\" = \"#\"; then\n   echo '.include \"confinc\"' > confmf\n   case `$am_make -s -f confmf 2> /dev/null` in #(\n   *the\\ am__doit\\ target*)\n     am__include=.include\n     am__quote=\"\\\"\"\n     _am_result=BSD\n     ;;\n   esac\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='\\'\n  am__nodep='_no'\nfi\n if test \"x$enable_dependency_tracking\" != xno; then\n  AMDEP_TRUE=\n  AMDEP_FALSE='#'\nelse\n  AMDEP_TRUE='#'\n  AMDEP_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\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 ${ac_cv_prog_CC+:} false; 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 ${ac_cv_prog_ac_ct_CC+:} false; 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 ${ac_cv_prog_CC+:} false; 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 ${ac_cv_prog_CC+:} false; 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 ${ac_cv_prog_CC+:} false; 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 ${ac_cv_prog_ac_ct_CC+:} false; 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;}\nas_fn_error 77 \"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 ${ac_cv_objext+:} false; 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 ${ac_cv_c_compiler_gnu+:} false; 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 ${ac_cv_prog_cc_g+:} false; 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 ${ac_cv_prog_cc_c89+:} false; 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\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 ${am_cv_CC_dependencies_compiler_type+:} false; 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  rm -rf conftest.dir\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  am__universal=false\n  case \" $depcc \" in #(\n     *\\ -arch\\ *\\ -arch\\ *) am__universal=true ;;\n     esac\n\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    # 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.  Also, some Intel\n    # versions had trouble with output in subdirs\n    am__obj=sub/conftest.${OBJEXT-o}\n    am__minus_obj=\"-o $am__obj\"\n    case $depmode in\n    gcc)\n      # This depmode causes a compiler race in universal mode.\n      test \"$am__universal\" = false || continue\n      ;;\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    msvc7 | msvc7msys | msvisualcpp | msvcmsys)\n      # This compiler won't grok `-c -o', but also, the minuso test has\n      # not run yet.  These depmodes are late enough in the game, and\n      # so weak that their functioning should not be impacted.\n      am__obj=conftest.${OBJEXT-o}\n      am__minus_obj=\n      ;;\n    none) break ;;\n    esac\n    if depmode=$depmode \\\n       source=sub/conftest.c object=$am__obj \\\n       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \\\n       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \\\n         >/dev/null 2>conftest.err &&\n       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&\n       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&\n       grep $am__obj 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 if\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\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 ${ac_cv_path_SED+:} false; 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 ${ac_cv_path_GREP+:} false; 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 ${ac_cv_path_EGREP+:} false; 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 ${ac_cv_path_FGREP+:} false; 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 ${lt_cv_path_LD+:} false; 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 ${lt_cv_prog_gnu_ld+:} false; 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 ${lt_cv_path_NM+:} false; 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 \"$DUMPBIN\"; then :\n    # Let the user override the test.\n  else\n    if test -n \"$ac_tool_prefix\"; then\n  for ac_prog in dumpbin \"link -dump\"\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 ${ac_cv_prog_DUMPBIN+:} false; 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 \"link -dump\"\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 ${ac_cv_prog_ac_ct_DUMPBIN+:} false; 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    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in\n    *COFF*)\n      DUMPBIN=\"$DUMPBIN -symbols\"\n      ;;\n    *)\n      DUMPBIN=:\n      ;;\n    esac\n  fi\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 ${lt_cv_nm_interface+:} false; 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:$LINENO: $ac_compile\\\"\" >&5)\n  (eval \"$ac_compile\" 2>conftest.err)\n  cat conftest.err >&5\n  (eval echo \"\\\"\\$as_me:$LINENO: $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:$LINENO: 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 ${lt_cv_sys_max_cmd_len+:} false; 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  mint*)\n    # On MiNT this can take a long time and run out of memory.\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  os2*)\n    # The test takes a long time on OS/2.\n    lt_cv_sys_max_cmd_len=8192\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\"`env echo \"$teststring$teststring\" 2>/dev/null` \\\n\t         = \"X$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%\"$_lt_dummy\"}, \\\n      = c,a/b,b/c, \\\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 how to convert $build file names to $host format\" >&5\n$as_echo_n \"checking how to convert $build file names to $host format... \" >&6; }\nif ${lt_cv_to_host_file_cmd+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  case $host in\n  *-*-mingw* )\n    case $build in\n      *-*-mingw* ) # actually msys\n        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32\n        ;;\n      *-*-cygwin* )\n        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32\n        ;;\n      * ) # otherwise, assume *nix\n        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32\n        ;;\n    esac\n    ;;\n  *-*-cygwin* )\n    case $build in\n      *-*-mingw* ) # actually msys\n        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin\n        ;;\n      *-*-cygwin* )\n        lt_cv_to_host_file_cmd=func_convert_file_noop\n        ;;\n      * ) # otherwise, assume *nix\n        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin\n        ;;\n    esac\n    ;;\n  * ) # unhandled hosts (and \"normal\" native builds)\n    lt_cv_to_host_file_cmd=func_convert_file_noop\n    ;;\nesac\n\nfi\n\nto_host_file_cmd=$lt_cv_to_host_file_cmd\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd\" >&5\n$as_echo \"$lt_cv_to_host_file_cmd\" >&6; }\n\n\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format\" >&5\n$as_echo_n \"checking how to convert $build file names to toolchain format... \" >&6; }\nif ${lt_cv_to_tool_file_cmd+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  #assume ordinary cross tools, or native build.\nlt_cv_to_tool_file_cmd=func_convert_file_noop\ncase $host in\n  *-*-mingw* )\n    case $build in\n      *-*-mingw* ) # actually msys\n        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32\n        ;;\n    esac\n    ;;\nesac\n\nfi\n\nto_tool_file_cmd=$lt_cv_to_tool_file_cmd\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd\" >&5\n$as_echo \"$lt_cv_to_tool_file_cmd\" >&6; }\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 ${lt_cv_ld_reload_flag+:} false; 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  cygwin* | mingw* | pw32* | cegcc*)\n    if test \"$GCC\" != yes; then\n      reload_cmds=false\n    fi\n    ;;\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 ${ac_cv_prog_OBJDUMP+:} false; 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 ${ac_cv_prog_ac_ct_OBJDUMP+:} false; 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 ${lt_cv_deplibs_check_method+:} false; 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  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.\n  if ( test \"$lt_cv_nm_interface\" = \"BSD nm\" && 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    # Keep this pattern in sync with the one in func_win32_libid.\n    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'\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\nhaiku*)\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])(-bit)?( [LM]SB)? 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 glibc/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; }\n\nfile_magic_glob=\nwant_nocaseglob=no\nif test \"$build\" = \"$host\"; then\n  case $host_os in\n  mingw* | pw32*)\n    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then\n      want_nocaseglob=yes\n    else\n      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e \"s/\\(..\\)/s\\/[\\1]\\/[\\1]\\/g;/g\"`\n    fi\n    ;;\n  esac\nfi\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\n\n\n\n\n\n\n\n\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}dlltool\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}dlltool; 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 ${ac_cv_prog_DLLTOOL+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$DLLTOOL\"; then\n  ac_cv_prog_DLLTOOL=\"$DLLTOOL\" # 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_DLLTOOL=\"${ac_tool_prefix}dlltool\"\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\nDLLTOOL=$ac_cv_prog_DLLTOOL\nif test -n \"$DLLTOOL\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $DLLTOOL\" >&5\n$as_echo \"$DLLTOOL\" >&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_DLLTOOL\"; then\n  ac_ct_DLLTOOL=$DLLTOOL\n  # Extract the first word of \"dlltool\", so it can be a program name with args.\nset dummy dlltool; 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 ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_DLLTOOL\"; then\n  ac_cv_prog_ac_ct_DLLTOOL=\"$ac_ct_DLLTOOL\" # 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_DLLTOOL=\"dlltool\"\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_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL\nif test -n \"$ac_ct_DLLTOOL\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL\" >&5\n$as_echo \"$ac_ct_DLLTOOL\" >&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_DLLTOOL\" = x; then\n    DLLTOOL=\"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    DLLTOOL=$ac_ct_DLLTOOL\n  fi\nelse\n  DLLTOOL=\"$ac_cv_prog_DLLTOOL\"\nfi\n\ntest -z \"$DLLTOOL\" && DLLTOOL=dlltool\n\n\n\n\n\n\n\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries\" >&5\n$as_echo_n \"checking how to associate runtime and link libraries... \" >&6; }\nif ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_sharedlib_from_linklib_cmd='unknown'\n\ncase $host_os in\ncygwin* | mingw* | pw32* | cegcc*)\n  # two different shell functions defined in ltmain.sh\n  # decide which to use based on capabilities of $DLLTOOL\n  case `$DLLTOOL --help 2>&1` in\n  *--identify-strict*)\n    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib\n    ;;\n  *)\n    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback\n    ;;\n  esac\n  ;;\n*)\n  # fallback: assume linklib IS sharedlib\n  lt_cv_sharedlib_from_linklib_cmd=\"$ECHO\"\n  ;;\nesac\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd\" >&5\n$as_echo \"$lt_cv_sharedlib_from_linklib_cmd\" >&6; }\nsharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd\ntest -z \"$sharedlib_from_linklib_cmd\" && sharedlib_from_linklib_cmd=$ECHO\n\n\n\n\n\n\n\n\nif test -n \"$ac_tool_prefix\"; then\n  for ac_prog in ar\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 ${ac_cv_prog_AR+:} false; 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$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\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\n    test -n \"$AR\" && break\n  done\nfi\nif test -z \"$AR\"; then\n  ac_ct_AR=$AR\n  for ac_prog in ar\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 ${ac_cv_prog_ac_ct_AR+:} false; 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=\"$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_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\n  test -n \"$ac_ct_AR\" && break\ndone\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\nfi\n\n: ${AR=ar}\n: ${AR_FLAGS=cru}\n\n\n\n\n\n\n\n\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support\" >&5\n$as_echo_n \"checking for archiver @FILE support... \" >&6; }\nif ${lt_cv_ar_at_file+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_ar_at_file=no\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  echo conftest.$ac_objext > conftest.lst\n      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'\n      { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$lt_ar_try\\\"\"; } >&5\n  (eval $lt_ar_try) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\n      if test \"$ac_status\" -eq 0; then\n\t# Ensure the archiver fails upon bogus file names.\n\trm -f conftest.$ac_objext libconftest.a\n\t{ { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$lt_ar_try\\\"\"; } >&5\n  (eval $lt_ar_try) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\n\tif test \"$ac_status\" -ne 0; then\n          lt_cv_ar_at_file=@\n        fi\n      fi\n      rm -f conftest.* libconftest.a\n\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file\" >&5\n$as_echo \"$lt_cv_ar_at_file\" >&6; }\n\nif test \"x$lt_cv_ar_at_file\" = xno; then\n  archiver_list_spec=\nelse\n  archiver_list_spec=$lt_cv_ar_at_file\nfi\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 ${ac_cv_prog_STRIP+:} false; 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 ${ac_cv_prog_ac_ct_STRIP+:} false; 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 ${ac_cv_prog_RANLIB+:} false; 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 ${ac_cv_prog_ac_ct_RANLIB+:} false; 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 \\$tool_oldlib\"\n    ;;\n  *)\n    old_postinstall_cmds=\"$old_postinstall_cmds~\\$RANLIB \\$tool_oldlib\"\n    ;;\n  esac\n  old_archive_cmds=\"$old_archive_cmds~\\$RANLIB \\$tool_oldlib\"\nfi\n\ncase $host_os in\n  darwin*)\n    lock_old_archive_extraction=yes ;;\n  *)\n    lock_old_archive_extraction=no ;;\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# 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 ${lt_cv_sys_global_symbol_pipe+:} false; 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\"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};\"\\\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  lt_cv_sys_global_symbol_pipe=\"$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'\"\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/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */\n#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)\n/* DATA imports from DLLs on WIN32 con't be const, because runtime\n   relocations are performed -- see ld's documentation on pseudo-relocs.  */\n# define LT_DLSYM_CONST\n#elif defined(__osf__)\n/* This system does not cope well with relocations in const data.  */\n# define LT_DLSYM_CONST\n#else\n# define LT_DLSYM_CONST const\n#endif\n\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.  */\nLT_DLSYM_CONST 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_globsym_save_LIBS=$LIBS\n\t  lt_globsym_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_globsym_save_LIBS\n\t  CFLAGS=$lt_globsym_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# Response file support.\nif test \"$lt_cv_nm_interface\" = \"MS dumpbin\"; then\n  nm_file_list_spec='@'\nelif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then\n  nm_file_list_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{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for sysroot\" >&5\n$as_echo_n \"checking for sysroot... \" >&6; }\n\n# Check whether --with-sysroot was given.\nif test \"${with_sysroot+set}\" = set; then :\n  withval=$with_sysroot;\nelse\n  with_sysroot=no\nfi\n\n\nlt_sysroot=\ncase ${with_sysroot} in #(\n yes)\n   if test \"$GCC\" = yes; then\n     lt_sysroot=`$CC --print-sysroot 2>/dev/null`\n   fi\n   ;; #(\n /*)\n   lt_sysroot=`echo \"$with_sysroot\" | sed -e \"$sed_quote_subst\"`\n   ;; #(\n no|'')\n   ;; #(\n *)\n   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}\" >&5\n$as_echo \"${with_sysroot}\" >&6; }\n   as_fn_error $? \"The sysroot must be an absolute path.\" \"$LINENO\" 5\n   ;;\nesac\n\n { $as_echo \"$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}\" >&5\n$as_echo \"${lt_sysroot:-no}\" >&6; }\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 '$LINENO' \"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 ${lt_cv_cc_needs_belf+:} false; 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  ;;\n*-*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*)\n        case $host in\n        i?86-*-solaris*)\n          LD=\"${LD-ld} -m elf_x86_64\"\n          ;;\n        sparc*-*-solaris*)\n          LD=\"${LD-ld} -m elf64_sparc\"\n          ;;\n        esac\n        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.\n        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then\n          LD=\"${LD-ld}_sol2\"\n        fi\n        ;;\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\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}mt\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}mt; 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 ${ac_cv_prog_MANIFEST_TOOL+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$MANIFEST_TOOL\"; then\n  ac_cv_prog_MANIFEST_TOOL=\"$MANIFEST_TOOL\" # 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_MANIFEST_TOOL=\"${ac_tool_prefix}mt\"\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\nMANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL\nif test -n \"$MANIFEST_TOOL\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL\" >&5\n$as_echo \"$MANIFEST_TOOL\" >&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_MANIFEST_TOOL\"; then\n  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL\n  # Extract the first word of \"mt\", so it can be a program name with args.\nset dummy mt; 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 ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_MANIFEST_TOOL\"; then\n  ac_cv_prog_ac_ct_MANIFEST_TOOL=\"$ac_ct_MANIFEST_TOOL\" # 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_MANIFEST_TOOL=\"mt\"\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_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL\nif test -n \"$ac_ct_MANIFEST_TOOL\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL\" >&5\n$as_echo \"$ac_ct_MANIFEST_TOOL\" >&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_MANIFEST_TOOL\" = x; then\n    MANIFEST_TOOL=\":\"\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    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL\n  fi\nelse\n  MANIFEST_TOOL=\"$ac_cv_prog_MANIFEST_TOOL\"\nfi\n\ntest -z \"$MANIFEST_TOOL\" && MANIFEST_TOOL=mt\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool\" >&5\n$as_echo_n \"checking if $MANIFEST_TOOL is a manifest tool... \" >&6; }\nif ${lt_cv_path_mainfest_tool+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_path_mainfest_tool=no\n  echo \"$as_me:$LINENO: $MANIFEST_TOOL '-?'\" >&5\n  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out\n  cat conftest.err >&5\n  if $GREP 'Manifest Tool' conftest.out > /dev/null; then\n    lt_cv_path_mainfest_tool=yes\n  fi\n  rm -f conftest*\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool\" >&5\n$as_echo \"$lt_cv_path_mainfest_tool\" >&6; }\nif test \"x$lt_cv_path_mainfest_tool\" != xyes; then\n  MANIFEST_TOOL=:\nfi\n\n\n\n\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 ${ac_cv_prog_DSYMUTIL+:} false; 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 ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; 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 ${ac_cv_prog_NMEDIT+:} false; 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 ${ac_cv_prog_ac_ct_NMEDIT+:} false; 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 ${ac_cv_prog_LIPO+:} false; 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 ${ac_cv_prog_ac_ct_LIPO+:} false; 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 ${ac_cv_prog_OTOOL+:} false; 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 ${ac_cv_prog_ac_ct_OTOOL+:} false; 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 ${ac_cv_prog_OTOOL64+:} false; 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 ${ac_cv_prog_ac_ct_OTOOL64+:} false; 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 ${lt_cv_apple_cc_single_mod+:} false; 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\t# If there is a non-empty error log, and \"single_module\"\n\t# appears in it, assume the flag caused a linker warning\n        if test -s conftest.err && $GREP single_module conftest.err; then\n\t  cat conftest.err >&5\n\t# Otherwise, if the output was created with a 0 exit code from\n\t# the compiler, it worked.\n\telif test -f libconftest.dylib && test $_lt_result -eq 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\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 ${lt_cv_ld_exported_symbols_list+:} false; 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\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag\" >&5\n$as_echo_n \"checking for -force_load linker flag... \" >&6; }\nif ${lt_cv_ld_force_load+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_ld_force_load=no\n      cat > conftest.c << _LT_EOF\nint forced_loaded() { return 2;}\n_LT_EOF\n      echo \"$LTCC $LTCFLAGS -c -o conftest.o conftest.c\" >&5\n      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5\n      echo \"$AR cru libconftest.a conftest.o\" >&5\n      $AR cru libconftest.a conftest.o 2>&5\n      echo \"$RANLIB libconftest.a\" >&5\n      $RANLIB libconftest.a 2>&5\n      cat > conftest.c << _LT_EOF\nint main() { return 0;}\n_LT_EOF\n      echo \"$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a\" >&5\n      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err\n      _lt_result=$?\n      if test -s conftest.err && $GREP force_load conftest.err; then\n\tcat conftest.err >&5\n      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then\n\tlt_cv_ld_force_load=yes\n      else\n\tcat conftest.err >&5\n      fi\n        rm -f conftest.err libconftest.a conftest conftest.c\n        rm -rf conftest.dSYM\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load\" >&5\n$as_echo \"$lt_cv_ld_force_load\" >&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\" != \":\" && test \"$lt_cv_ld_force_load\" = \"no\"; then\n      _lt_dsymutil='~$DSYMUTIL $lib || :'\n    else\n      _lt_dsymutil=\n    fi\n    ;;\n  esac\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 ${ac_cv_prog_CPP+:} false; 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.i 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.i conftest.$ac_ext\n\ndone\n# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.\nrm -f conftest.i 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.i 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.i conftest.$ac_ext\n\ndone\n# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.\nrm -f conftest.i 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\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 ${ac_cv_header_stdc+:} false; 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\"\nif eval test \\\"x\\$\"$as_ac_Header\"\\\" = 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\" = xyes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_DLFCN_H 1\n_ACEOF\n\nfi\n\ndone\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; lt_p=${PACKAGE-default}\n    case $withval in\n    yes|no) pic_mode=$withval ;;\n    *)\n      pic_mode=default\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 lt_pkg in $withval; do\n\tIFS=\"$lt_save_ifs\"\n\tif test \"X$lt_pkg\" = \"X$lt_p\"; then\n\t  pic_mode=yes\n\tfi\n      done\n      IFS=\"$lt_save_ifs\"\n      ;;\n    esac\nelse\n  pic_mode=default\nfi\n\n\ntest -z \"$pic_mode\" && pic_mode=default\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\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\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 ${lt_cv_objdir+:} false; 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\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# 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 \"$cc_temp\" | $SED \"s%.*/%%; 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 ${lt_cv_path_MAGIC_CMD+:} false; 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 ${lt_cv_path_MAGIC_CMD+:} false; 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\nif test -n \"$compiler\"; then\n\nlt_prog_compiler_no_builtin_flag=\n\nif test \"$GCC\" = yes; then\n  case $cc_basename in\n  nvcc*)\n    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;\n  *)\n    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;\n  esac\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 ${lt_cv_prog_compiler_rtti_exceptions+:} false; 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:$LINENO: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>conftest.err)\n   ac_status=$?\n   cat conftest.err >&5\n   echo \"$as_me:$LINENO: \\$? = $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 \"$_lt_compiler_boilerplate\" | $SED '/^$/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\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    haiku*)\n      # PIC is the default for Haiku.\n      # The \"-static\" flag exists, but is broken.\n      lt_prog_compiler_static=\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\n    case $cc_basename in\n    nvcc*) # Cuda Compiler Driver 2.2\n      lt_prog_compiler_wl='-Xlinker '\n      if test -n \"$lt_prog_compiler_pic\"; then\n        lt_prog_compiler_pic=\"-Xcompiler $lt_prog_compiler_pic\"\n      fi\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      nagfor*)\n\t# NAG Fortran compiler\n\tlt_prog_compiler_wl='-Wl,-Wl,,'\n\tlt_prog_compiler_pic='-PIC'\n\tlt_prog_compiler_static='-Bstatic'\n\t;;\n      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)\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* | bgxl* | bgf* | mpixl*)\n\t# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene\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\\ Ceres\\ Fortran* | *Sun*Fortran*\\ [1-7].* | *Sun*Fortran*\\ 8.[0-3]*)\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\t*Sun\\ F* | *Sun*Fortran*)\n\t  lt_prog_compiler_pic='-KPIC'\n\t  lt_prog_compiler_static='-Bstatic'\n\t  lt_prog_compiler_wl='-Qoption ld '\n\t  ;;\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        *Intel*\\ [CF]*Compiler*)\n\t  lt_prog_compiler_wl='-Wl,'\n\t  lt_prog_compiler_pic='-fPIC'\n\t  lt_prog_compiler_static='-static'\n\t  ;;\n\t*Portland\\ Group*)\n\t  lt_prog_compiler_wl='-Wl,'\n\t  lt_prog_compiler_pic='-fpic'\n\t  lt_prog_compiler_static='-Bstatic'\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* | sunf77* | sunf90* | sunf95*)\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\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; }\nif ${lt_cv_prog_compiler_pic+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic\" >&5\n$as_echo \"$lt_cv_prog_compiler_pic\" >&6; }\nlt_prog_compiler_pic=$lt_cv_prog_compiler_pic\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 ${lt_cv_prog_compiler_pic_works+:} false; 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:$LINENO: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>conftest.err)\n   ac_status=$?\n   cat conftest.err >&5\n   echo \"$as_me:$LINENO: \\$? = $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 \"$_lt_compiler_boilerplate\" | $SED '/^$/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\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 ${lt_cv_prog_compiler_static_works+:} false; 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 \"$_lt_linker_boilerplate\" | $SED '/^$/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 ${lt_cv_prog_compiler_c_o+:} false; 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:$LINENO: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>out/conftest.err)\n   ac_status=$?\n   cat out/conftest.err >&5\n   echo \"$as_me:$LINENO: \\$? = $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 \"$_lt_compiler_boilerplate\" | $SED '/^$/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 ${lt_cv_prog_compiler_c_o+:} false; 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:$LINENO: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>out/conftest.err)\n   ac_status=$?\n   cat out/conftest.err >&5\n   echo \"$as_me:$LINENO: \\$? = $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 \"$_lt_compiler_boilerplate\" | $SED '/^$/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_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 | gnu*)\n    link_all_deplibs=no\n    ;;\n  esac\n\n  ld_shlibs=yes\n\n  # On some targets, GNU ld is compatible enough with the native linker\n  # that we're better off using the native interface for both.\n  lt_use_gnu_ld_interface=no\n  if test \"$with_gnu_ld\" = yes; then\n    case $host_os in\n      aix*)\n\t# The AIX port of GNU ld has always aspired to compatibility\n\t# with the native linker.  However, as the warning in the GNU ld\n\t# block says, versions before 2.19.5* couldn't really create working\n\t# shared libraries, regardless of the interface used.\n\tcase `$LD -v 2>&1` in\n\t  *\\ \\(GNU\\ Binutils\\)\\ 2.19.5*) ;;\n\t  *\\ \\(GNU\\ Binutils\\)\\ 2.[2-9]*) ;;\n\t  *\\ \\(GNU\\ Binutils\\)\\ [3-9]*) ;;\n\t  *)\n\t    lt_use_gnu_ld_interface=yes\n\t    ;;\n\tesac\n\t;;\n      *)\n\tlt_use_gnu_ld_interface=yes\n\t;;\n    esac\n  fi\n\n  if test \"$lt_use_gnu_ld_interface\" = 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.19, 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 install binutils\n*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.\n*** You will then need to restart the configuration process.\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      export_dynamic_flag_spec='${wl}--export-all-symbols'\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/;s/^.*[ ]__nm__\\([^ ]*\\)[ ][^ ]*/\\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\\'' | sort | uniq > $export_symbols'\n      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'\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    haiku*)\n      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n      link_all_deplibs=yes\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=' $pic_flag'\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; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  tmp_addflag=' $pic_flag'\n\t  ;;\n\tpgf77* | pgf90* | pgf95* | pgfortran*)\n\t\t\t\t\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; func_echo_all \\\"$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]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)\n\t  tmp_sharedflag='-qmkshrobj'\n\t  tmp_addflag= ;;\n\tnvcc*)\t# Cuda Compiler Driver 2.2\n\t  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  compiler_needs_object=yes\n\t  ;;\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; func_echo_all \\\"$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* | bgf* | bgxlf* | mpixlf*)\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='${wl}-rpath ${wl}$libdir'\n\t  archive_cmds='$LD -shared $libobjs $deplibs $linker_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 $linker_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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\tarchive_expsym_cmds='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\tarchive_expsym_cmds='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\tarchive_expsym_cmds='$CC -shared $pic_flag $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\t# Also, AIX nm treats weak defined symbols like other global\n\t# defined symbols, whereas GNU nm marks them as \"W\".\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\") || (\\$ 2 == \"W\")) && (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        if test \"${lt_cv_aix_libpath+set}\" = set; then\n  aix_libpath=$lt_cv_aix_libpath\nelse\n  if ${lt_cv_aix_libpath_+:} false; 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\nif ac_fn_c_try_link \"$LINENO\"; then :\n\n  lt_aix_libpath_sed='\n      /Import File Strings/,/^$/ {\n\t  /^0/ {\n\t      s/^0  *\\([^ ]*\\) *$/\\1/\n\t      p\n\t  }\n      }'\n  lt_cv_aix_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.\n  if test -z \"$lt_cv_aix_libpath_\"; then\n    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\n  fi\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n  if test -z \"$lt_cv_aix_libpath_\"; then\n    lt_cv_aix_libpath_=\"/usr/lib:/lib\"\n  fi\n\nfi\n\n  aix_libpath=$lt_cv_aix_libpath_\nfi\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 func_echo_all \"${wl}${allow_undefined_flag}\"; 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 if test \"${lt_cv_aix_libpath+set}\" = set; then\n  aix_libpath=$lt_cv_aix_libpath\nelse\n  if ${lt_cv_aix_libpath_+:} false; 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\nif ac_fn_c_try_link \"$LINENO\"; then :\n\n  lt_aix_libpath_sed='\n      /Import File Strings/,/^$/ {\n\t  /^0/ {\n\t      s/^0  *\\([^ ]*\\) *$/\\1/\n\t      p\n\t  }\n      }'\n  lt_cv_aix_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.\n  if test -z \"$lt_cv_aix_libpath_\"; then\n    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\n  fi\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n  if test -z \"$lt_cv_aix_libpath_\"; then\n    lt_cv_aix_libpath_=\"/usr/lib:/lib\"\n  fi\n\nfi\n\n  aix_libpath=$lt_cv_aix_libpath_\nfi\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  if test \"$with_gnu_ld\" = yes; then\n\t    # We only use this code for GNU lds that support --whole-archive.\n\t    whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'\n\t  else\n\t    # Exported symbols can be pulled into shared objects from archives\n\t    whole_archive_flag_spec='$convenience'\n\t  fi\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      case $cc_basename in\n      cl*)\n\t# Native MSVC\n\thardcode_libdir_flag_spec=' '\n\tallow_undefined_flag=unsupported\n\talways_export_symbols=yes\n\tfile_list_spec='@'\n\t# Tell ltmain to make .lib files, not .a files.\n\tlibext=lib\n\t# Tell ltmain to make .dll files, not .so files.\n\tshrext_cmds=\".dll\"\n\t# FIXME: Setting linknames here is a bad hack.\n\tarchive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='\n\tarchive_expsym_cmds='if test \"x`$SED 1q $export_symbols`\" = xEXPORTS; then\n\t    sed -n -e 's/\\\\\\\\\\\\\\(.*\\\\\\\\\\\\\\)/-link\\\\\\ -EXPORT:\\\\\\\\\\\\\\1/' -e '1\\\\\\!p' < $export_symbols > $output_objdir/$soname.exp;\n\t  else\n\t    sed -e 's/\\\\\\\\\\\\\\(.*\\\\\\\\\\\\\\)/-link\\\\\\ -EXPORT:\\\\\\\\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;\n\t  fi~\n\t  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs \"@$tool_output_objdir$soname.exp\" -Wl,-DLL,-IMPLIB:\"$tool_output_objdir$libname.dll.lib\"~\n\t  linknames='\n\t# The linker will not automatically build a static lib if we build a DLL.\n\t# _LT_TAGVAR(old_archive_from_new_cmds, )='true'\n\tenable_shared_with_static_runtimes=yes\n\texclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'\n\texport_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\\''/^[BCDGRS][ ]/s/.*[ ]\\([^ ]*\\)/\\1,DATA/'\\'' | $SED -e '\\''/^[AITW][ ]/s/.*[ ]//'\\'' | sort | uniq > $export_symbols'\n\t# Don't use ranlib\n\told_postinstall_cmds='chmod 644 $oldlib'\n\tpostlink_cmds='lt_outputfile=\"@OUTPUT@\"~\n\t  lt_tool_outputfile=\"@TOOL_OUTPUT@\"~\n\t  case $lt_outputfile in\n\t    *.exe|*.EXE) ;;\n\t    *)\n\t      lt_outputfile=\"$lt_outputfile.exe\"\n\t      lt_tool_outputfile=\"$lt_tool_outputfile.exe\"\n\t      ;;\n\t  esac~\n\t  if test \"$MANIFEST_TOOL\" != \":\" && test -f \"$lt_outputfile.manifest\"; then\n\t    $MANIFEST_TOOL -manifest \"$lt_tool_outputfile.manifest\" -outputresource:\"$lt_tool_outputfile\" || exit 1;\n\t    $RM \"$lt_outputfile.manifest\";\n\t  fi'\n\t;;\n      *)\n\t# Assume MSVC wrapper\n\thardcode_libdir_flag_spec=' '\n\tallow_undefined_flag=unsupported\n\t# Tell ltmain to make .lib files, not .a files.\n\tlibext=lib\n\t# Tell ltmain to make .dll files, not .so files.\n\tshrext_cmds=\".dll\"\n\t# FIXME: Setting linknames here is a bad hack.\n\tarchive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all \"$deplibs\" | $SED '\\''s/ -lc$//'\\''` -link -dll~linknames='\n\t# The linker will automatically build a .lib file if we build a DLL.\n\told_archive_from_new_cmds='true'\n\t# FIXME: Should let the user specify the lib program.\n\told_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'\n\tenable_shared_with_static_runtimes=yes\n\t;;\n      esac\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  if test \"$lt_cv_ld_force_load\" = \"yes\"; then\n    whole_archive_flag_spec='`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience ${wl}-force_load,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"`'\n\n  else\n    whole_archive_flag_spec=''\n  fi\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=func_echo_all\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    # 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 $pic_flag -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 $pic_flag ${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 && test \"$with_gnu_ld\" = no; then\n\tarchive_cmds='$CC -shared $pic_flag ${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_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 && test \"$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 $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\t*)\n\t  archive_cmds='$CC -shared $pic_flag ${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\n\t  # Older versions of the 11.00 compiler do not understand -b yet\n\t  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)\n\t  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $CC understands -b\" >&5\n$as_echo_n \"checking if $CC understands -b... \" >&6; }\nif ${lt_cv_prog_compiler__b+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler__b=no\n   save_LDFLAGS=\"$LDFLAGS\"\n   LDFLAGS=\"$LDFLAGS -b\"\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 \"$_lt_linker_boilerplate\" | $SED '/^$/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__b=yes\n       fi\n     else\n       lt_cv_prog_compiler__b=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__b\" >&5\n$as_echo \"$lt_cv_prog_compiler__b\" >&6; }\n\nif test x\"$lt_cv_prog_compiler__b\" = xyes; then\n    archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'\nelse\n    archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'\nfi\n\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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${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\t# This should be the same for all languages, so no per-tag cache variable.\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol\" >&5\n$as_echo_n \"checking whether the $host_os linker accepts -exported_symbol... \" >&6; }\nif ${lt_cv_irix_exported_symbol+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  save_LDFLAGS=\"$LDFLAGS\"\n\t   LDFLAGS=\"$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null\"\n\t   cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\nint foo (void) { return 0; }\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  lt_cv_irix_exported_symbol=yes\nelse\n  lt_cv_irix_exported_symbol=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n           LDFLAGS=\"$save_LDFLAGS\"\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol\" >&5\n$as_echo \"$lt_cv_irix_exported_symbol\" >&6; }\n\tif test \"$lt_cv_irix_exported_symbol\" = yes; then\n          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'\n\tfi\n      else\n\tarchive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib'\n\tarchive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -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\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${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\" && func_echo_all \"-set_version $verstring\"` -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} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${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\" && func_echo_all \"-set_version $verstring\"` -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 \"-set_version $verstring\"` -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 $pic_flag ${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 $pic_flag ${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; }\nif ${lt_cv_archive_cmds_need_lc+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  $RM conftest*\n\techo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n\tif { { 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\t  soname=conftest\n\t  lib=conftest\n\t  libobjs=conftest.$ac_objext\n\t  deplibs=\n\t  wl=$lt_prog_compiler_wl\n\t  pic_flag=$lt_prog_compiler_pic\n\t  compiler_flags=-v\n\t  linker_flags=-v\n\t  verstring=\n\t  output_objdir=.\n\t  libname=conftest\n\t  lt_save_allow_undefined_flag=$allow_undefined_flag\n\t  allow_undefined_flag=\n\t  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\t  then\n\t    lt_cv_archive_cmds_need_lc=no\n\t  else\n\t    lt_cv_archive_cmds_need_lc=yes\n\t  fi\n\t  allow_undefined_flag=$lt_save_allow_undefined_flag\n\telse\n\t  cat conftest.err 1>&5\n\tfi\n\t$RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc\" >&5\n$as_echo \"$lt_cv_archive_cmds_need_lc\" >&6; }\n      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc\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  { $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  case $host_os in\n    mingw* | cegcc*) lt_sed_strip_eq=\"s,=\\([A-Za-z]:\\),\\1,g\" ;;\n    *) lt_sed_strip_eq=\"s,=/,/,g\" ;;\n  esac\n  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e \"s/^libraries://\" -e $lt_sed_strip_eq`\n  case $lt_search_path_spec in\n  *\\;*)\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 's/;/ /g'`\n    ;;\n  *)\n    lt_search_path_spec=`$ECHO \"$lt_search_path_spec\" | $SED \"s/$PATH_SEPARATOR/ /g\"`\n    ;;\n  esac\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  # AWK program above erroneously prepends '/' to C:/dos/paths\n  # for these hosts.\n  case $host_os in\n    mingw* | cegcc*) lt_search_path_spec=`$ECHO \"$lt_search_path_spec\" |\\\n      $SED 's,/\\([A-Za-z]:\\),\\1,g'` ;;\n  esac\n  sys_lib_search_path_spec=`$ECHO \"$lt_search_path_spec\" | $lt_NL2SP`\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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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=`func_echo_all \"$lib\" | $SED '\\''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 # correct to gnu/linux during the next big refactor\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,$cc_basename in\n  yes,*)\n    # gcc\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\n      sys_lib_search_path_spec=\"$sys_lib_search_path_spec /usr/lib/w32api\"\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      ;;\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    dynamic_linker='Win32 ld.exe'\n    ;;\n\n  *,cl*)\n    # Native MSVC\n    libname_spec='$name'\n    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'\n    library_names_spec='${libname}.dll.lib'\n\n    case $build_os in\n    mingw*)\n      sys_lib_search_path_spec=\n      lt_save_ifs=$IFS\n      IFS=';'\n      for lt_path in $LIB\n      do\n        IFS=$lt_save_ifs\n        # Let DOS variable expansion print the short 8.3 style file name.\n        lt_path=`cd \"$lt_path\" 2>/dev/null && cmd //C \"for %i in (\".\") do @echo %~si\"`\n        sys_lib_search_path_spec=\"$sys_lib_search_path_spec $lt_path\"\n      done\n      IFS=$lt_save_ifs\n      # Convert to MSYS style.\n      sys_lib_search_path_spec=`$ECHO \"$sys_lib_search_path_spec\" | sed -e 's|\\\\\\\\|/|g' -e 's| \\\\([a-zA-Z]\\\\):| /\\\\1|g' -e 's|^ ||'`\n      ;;\n    cygwin*)\n      # Convert to unix form, then to dos form, then back to unix form\n      # but this time dos style (no spaces!) so that the unix form looks\n      # like /cygdrive/c/PROGRA~1:/cygdr...\n      sys_lib_search_path_spec=`cygpath --path --unix \"$LIB\"`\n      sys_lib_search_path_spec=`cygpath --path --dos \"$sys_lib_search_path_spec\" 2>/dev/null`\n      sys_lib_search_path_spec=`cygpath --path --unix \"$sys_lib_search_path_spec\" | $SED -e \"s/$PATH_SEPARATOR/ /g\"`\n      ;;\n    *)\n      sys_lib_search_path_spec=\"$LIB\"\n      if $ECHO \"$sys_lib_search_path_spec\" | $GREP ';[c-zC-Z]:/' >/dev/null; then\n        # It is most probably a Windows format PATH.\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      # FIXME: find the short name or the path components, as spaces are\n      # common. (e.g. \"Program Files\" -> \"PROGRA~1\")\n      ;;\n    esac\n\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    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\\''. $file; echo \\$dlname'\\''`~\n      dlpath=$dir/\\$dldll~\n       $RM \\$dlpath'\n    shlibpath_overrides_runpath=yes\n    dynamic_linker='Win32 link.exe'\n    ;;\n\n  *)\n    # Assume MSVC wrapper\n    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'\n    dynamic_linker='Win32 ld.exe'\n    ;;\n  esac\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 # correct to gnu/linux during the next big refactor\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\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[23].*) 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 # correct to gnu/linux during the next big refactor\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  ;;\n\nhaiku*)\n  version_type=linux # correct to gnu/linux during the next big refactor\n  need_lib_prefix=no\n  need_version=no\n  dynamic_linker=\"$host_os runtime_loader\"\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=LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'\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  # or fails outright, so override atomically:\n  install_override_mode=555\n  ;;\n\ninterix[3-9]*)\n  version_type=linux # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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 glibc/ELF.\nlinux* | k*bsd*-gnu | kopensolaris*-gnu)\n  version_type=linux # correct to gnu/linux during the next big refactor\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\n  # Some binutils ld are patched to set DT_RUNPATH\n  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_shlibpath_overrides_runpath=no\n    save_LDFLAGS=$LDFLAGS\n    save_libdir=$libdir\n    eval \"libdir=/foo; wl=\\\"$lt_prog_compiler_wl\\\"; \\\n\t 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  lt_cv_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\nfi\n\n  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath\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;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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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\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 ${ac_cv_lib_dl_dlopen+:} false; 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\" = xyes; 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\" = xyes; 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 ${ac_cv_lib_dld_shl_load+:} false; 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\" = xyes; 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\" = xyes; 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 ${ac_cv_lib_dl_dlopen+:} false; 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\" = xyes; 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 ${ac_cv_lib_svld_dlopen+:} false; 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\" = xyes; 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 ${ac_cv_lib_dld_dld_link+:} false; 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\" = xyes; 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 ${lt_cv_dlopen_self+:} false; 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 $LINENO \"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\n/* When -fvisbility=hidden is used, assume the code has been annotated\n   correspondingly for the symbols needed.  */\n#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))\nint fnord () __attribute__((visibility(\"default\")));\n#endif\n\nint fnord () { return 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\n        {\n\t  if (dlsym( self,\"_fnord\"))  status = $lt_dlneed_uscore;\n          else puts (dlerror ());\n\t}\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 ${lt_cv_dlopen_self_static+:} false; 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 $LINENO \"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\n/* When -fvisbility=hidden is used, assume the code has been annotated\n   correspondingly for the symbols needed.  */\n#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))\nint fnord () __attribute__((visibility(\"default\")));\n#endif\n\nint fnord () { return 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\n        {\n\t  if (dlsym( self,\"_fnord\"))  status = $lt_dlneed_uscore;\n          else puts (dlerror ());\n\t}\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\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\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 ${ac_cv_prog_CXX+:} false; 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 ${ac_cv_prog_ac_ct_CXX+:} false; 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 ${ac_cv_cxx_compiler_gnu+:} false; 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 ${ac_cv_prog_cxx_g+:} false; 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 ${am_cv_CXX_dependencies_compiler_type+:} false; 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  rm -rf conftest.dir\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  am__universal=false\n  case \" $depcc \" in #(\n     *\\ -arch\\ *\\ -arch\\ *) am__universal=true ;;\n     esac\n\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    # 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.  Also, some Intel\n    # versions had trouble with output in subdirs\n    am__obj=sub/conftest.${OBJEXT-o}\n    am__minus_obj=\"-o $am__obj\"\n    case $depmode in\n    gcc)\n      # This depmode causes a compiler race in universal mode.\n      test \"$am__universal\" = false || continue\n      ;;\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    msvc7 | msvc7msys | msvisualcpp | msvcmsys)\n      # This compiler won't grok `-c -o', but also, the minuso test has\n      # not run yet.  These depmodes are late enough in the game, and\n      # so weak that their functioning should not be impacted.\n      am__obj=conftest.${OBJEXT-o}\n      am__minus_obj=\n      ;;\n    none) break ;;\n    esac\n    if depmode=$depmode \\\n       source=sub/conftest.c object=$am__obj \\\n       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \\\n       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \\\n         >/dev/null 2>conftest.err &&\n       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&\n       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&\n       grep $am__obj 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 if\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\nfunc_stripname_cnf ()\n{\n  case ${2} in\n  .*) func_stripname_result=`$ECHO \"${3}\" | $SED \"s%^${1}%%; s%\\\\\\\\${2}\\$%%\"`;;\n  *)  func_stripname_result=`$ECHO \"${3}\" | $SED \"s%^${1}%%; s%${2}\\$%%\"`;;\n  esac\n} # func_stripname_cnf\n\n      if 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 ${ac_cv_prog_CXXCPP+:} false; 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.i 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.i conftest.$ac_ext\n\ndone\n# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.\nrm -f conftest.i 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.i 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.i conftest.$ac_ext\n\ndone\n# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.\nrm -f conftest.i 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 \\\"$CXXCPP\\\" 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\nelse\n  _lt_caught_CXX_error=yes\nfi\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_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\nreload_flag_CXX=$reload_flag\nreload_cmds_CXX=$reload_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_CFLAGS=$CFLAGS\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  CFLAGS=$CXXFLAGS\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 \"$cc_temp\" | $SED \"s%.*/%%; 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 ${lt_cv_path_LD+:} false; 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 ${lt_cv_prog_gnu_ld+:} false; 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 $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'\n        archive_expsym_cmds_CXX='$CC $pic_flag -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 -v \"^Configured with:\" | $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          if test \"${lt_cv_aix_libpath+set}\" = set; then\n  aix_libpath=$lt_cv_aix_libpath\nelse\n  if ${lt_cv_aix_libpath__CXX+:} false; 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\nif ac_fn_cxx_try_link \"$LINENO\"; then :\n\n  lt_aix_libpath_sed='\n      /Import File Strings/,/^$/ {\n\t  /^0/ {\n\t      s/^0  *\\([^ ]*\\) *$/\\1/\n\t      p\n\t  }\n      }'\n  lt_cv_aix_libpath__CXX=`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.\n  if test -z \"$lt_cv_aix_libpath__CXX\"; then\n    lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\n  fi\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n  if test -z \"$lt_cv_aix_libpath__CXX\"; then\n    lt_cv_aix_libpath__CXX=\"/usr/lib:/lib\"\n  fi\n\nfi\n\n  aix_libpath=$lt_cv_aix_libpath__CXX\nfi\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 func_echo_all \"${wl}${allow_undefined_flag}\"; 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    if test \"${lt_cv_aix_libpath+set}\" = set; then\n  aix_libpath=$lt_cv_aix_libpath\nelse\n  if ${lt_cv_aix_libpath__CXX+:} false; 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\nif ac_fn_cxx_try_link \"$LINENO\"; then :\n\n  lt_aix_libpath_sed='\n      /Import File Strings/,/^$/ {\n\t  /^0/ {\n\t      s/^0  *\\([^ ]*\\) *$/\\1/\n\t      p\n\t  }\n      }'\n  lt_cv_aix_libpath__CXX=`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.\n  if test -z \"$lt_cv_aix_libpath__CXX\"; then\n    lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\n  fi\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n  if test -z \"$lt_cv_aix_libpath__CXX\"; then\n    lt_cv_aix_libpath__CXX=\"/usr/lib:/lib\"\n  fi\n\nfi\n\n  aix_libpath=$lt_cv_aix_libpath__CXX\nfi\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    if test \"$with_gnu_ld\" = yes; then\n\t      # We only use this code for GNU lds that support --whole-archive.\n\t      whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'\n\t    else\n\t      # Exported symbols can be pulled into shared objects from archives\n\t      whole_archive_flag_spec_CXX='$convenience'\n\t    fi\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\tcase $GXX,$cc_basename in\n\t,cl* | no,cl*)\n\t  # Native MSVC\n\t  # hardcode_libdir_flag_spec is actually meaningless, as there is\n\t  # no search path for DLLs.\n\t  hardcode_libdir_flag_spec_CXX=' '\n\t  allow_undefined_flag_CXX=unsupported\n\t  always_export_symbols_CXX=yes\n\t  file_list_spec_CXX='@'\n\t  # Tell ltmain to make .lib files, not .a files.\n\t  libext=lib\n\t  # Tell ltmain to make .dll files, not .so files.\n\t  shrext_cmds=\".dll\"\n\t  # FIXME: Setting linknames here is a bad hack.\n\t  archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='\n\t  archive_expsym_cmds_CXX='if test \"x`$SED 1q $export_symbols`\" = xEXPORTS; then\n\t      $SED -n -e 's/\\\\\\\\\\\\\\(.*\\\\\\\\\\\\\\)/-link\\\\\\ -EXPORT:\\\\\\\\\\\\\\1/' -e '1\\\\\\!p' < $export_symbols > $output_objdir/$soname.exp;\n\t    else\n\t      $SED -e 's/\\\\\\\\\\\\\\(.*\\\\\\\\\\\\\\)/-link\\\\\\ -EXPORT:\\\\\\\\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;\n\t    fi~\n\t    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs \"@$tool_output_objdir$soname.exp\" -Wl,-DLL,-IMPLIB:\"$tool_output_objdir$libname.dll.lib\"~\n\t    linknames='\n\t  # The linker will not automatically build a static lib if we build a DLL.\n\t  # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'\n\t  enable_shared_with_static_runtimes_CXX=yes\n\t  # Don't use ranlib\n\t  old_postinstall_cmds_CXX='chmod 644 $oldlib'\n\t  postlink_cmds_CXX='lt_outputfile=\"@OUTPUT@\"~\n\t    lt_tool_outputfile=\"@TOOL_OUTPUT@\"~\n\t    case $lt_outputfile in\n\t      *.exe|*.EXE) ;;\n\t      *)\n\t\tlt_outputfile=\"$lt_outputfile.exe\"\n\t\tlt_tool_outputfile=\"$lt_tool_outputfile.exe\"\n\t\t;;\n\t    esac~\n\t    func_to_tool_file \"$lt_outputfile\"~\n\t    if test \"$MANIFEST_TOOL\" != \":\" && test -f \"$lt_outputfile.manifest\"; then\n\t      $MANIFEST_TOOL -manifest \"$lt_tool_outputfile.manifest\" -outputresource:\"$lt_tool_outputfile\" || exit 1;\n\t      $RM \"$lt_outputfile.manifest\";\n\t    fi'\n\t  ;;\n\t*)\n\t  # g++\n\t  # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,\n\t  # as there is no search path for DLLs.\n\t  hardcode_libdir_flag_spec_CXX='-L$libdir'\n\t  export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'\n\t  allow_undefined_flag_CXX=unsupported\n\t  always_export_symbols_CXX=no\n\t  enable_shared_with_static_runtimes_CXX=yes\n\n\t  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then\n\t    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\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    archive_expsym_cmds_CXX='if test \"x`$SED 1q $export_symbols`\" = xEXPORTS; then\n\t      cp $export_symbols $output_objdir/$soname.def;\n\t    else\n\t      echo EXPORTS > $output_objdir/$soname.def;\n\t      cat $export_symbols >> $output_objdir/$soname.def;\n\t    fi~\n\t    $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\t  else\n\t    ld_shlibs_CXX=no\n\t  fi\n\t  ;;\n\tesac\n\t;;\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  if test \"$lt_cv_ld_force_load\" = \"yes\"; then\n    whole_archive_flag_spec_CXX='`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience ${wl}-force_load,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"`'\n\n  else\n    whole_archive_flag_spec_CXX=''\n  fi\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=func_echo_all\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      freebsd2.*)\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      haiku*)\n        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n        link_all_deplibs_CXX=yes\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; func_echo_all \"$list\"'\n            ;;\n          *)\n            if test \"$GXX\" = yes; then\n              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${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; func_echo_all \"$list\"'\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 $pic_flag ${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 $pic_flag ${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\" && func_echo_all \"-set_version $verstring\"` -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 $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t      else\n\t        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` -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; func_echo_all \"$list\"'\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 | sort | $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 | sort | $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 | sort | $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 | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'\n\t      ;;\n\t    *) # Version 6 and above 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; func_echo_all \\\"$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=`func_echo_all \"$templist\" | $SED \"s/\\(^.*ld.*\\)\\( .*ld .*$\\)/\\1/\"`; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; func_echo_all \"X$list\" | $Xsed'\n\t    ;;\n\t  xl* | mpixl* | bgxl*)\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; func_echo_all \\\"$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='func_echo_all'\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=func_echo_all\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\" && func_echo_all \"${wl}-set_version $verstring\"` -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\" && func_echo_all \"-set_version $verstring\"` -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 \"-set_version $verstring\"` -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=`func_echo_all \"$templist\" | $SED \"s/\\(^.*ld.*\\)\\( .*ld.*$\\)/\\1/\"`; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; func_echo_all \"$list\"'\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\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t\t  ;;\n\t        *)\n\t          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${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 -v \"^Configured with:\" | $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* | sunCC*)\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='func_echo_all'\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 $pic_flag -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 $pic_flag -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 -v \"^Configured with:\" | $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 -v \"^Configured with:\" | $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    old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~\n\t      '\"$old_archive_cmds_CXX\"\n\t    reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~\n\t      '\"$reload_cmds_CXX\"\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\n\n_lt_libdeps_save_CFLAGS=$CFLAGS\ncase \"$CC $CFLAGS \" in #(\n*\\ -flto*\\ *) CFLAGS=\"$CFLAGS -fno-lto\" ;;\n*\\ -fwhopr*\\ *) CFLAGS=\"$CFLAGS -fno-whopr\" ;;\n*\\ -fuse-linker-plugin*\\ *) CFLAGS=\"$CFLAGS -fno-use-linker-plugin\" ;;\nesac\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 ${prev}${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       fi\n\n       # Expand the sysroot to ease extracting the directories later.\n       if test -z \"$prev\"; then\n         case $p in\n         -L*) func_stripname_cnf '-L' '' \"$p\"; prev=-L; p=$func_stripname_result ;;\n         -R*) func_stripname_cnf '-R' '' \"$p\"; prev=-R; p=$func_stripname_result ;;\n         -l*) func_stripname_cnf '-l' '' \"$p\"; prev=-l; p=$func_stripname_result ;;\n         esac\n       fi\n       case $p in\n       =*) func_stripname_cnf '=' '' \"$p\"; p=$lt_sysroot$func_stripname_result ;;\n       esac\n       if test \"$pre_test_object_deps_done\" = no; then\n\t case ${prev} 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       prev=\n       ;;\n\n    *.lto.$objext) ;; # Ignore GCC LTO objects\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\nCFLAGS=$_lt_libdeps_save_CFLAGS\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* | sunCC*)\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\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    haiku*)\n      # PIC is the default for Haiku.\n      # The \"-static\" flag exists, but is broken.\n      lt_prog_compiler_static_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      mingw* | cygwin* | os2* | pw32* | cegcc*)\n\t# This hack is so that the source file can tell whether it is being\n\t# built for inclusion in a dll (and should export symbols for example).\n\tlt_prog_compiler_pic_CXX='-DDLL_EXPORT'\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* | bgxl[cC]* | mpixl[cC]*)\n\t    # IBM XL 8.0, 9.0 on PPC and BlueGene\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* | sunCC*)\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\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; }\nif ${lt_cv_prog_compiler_pic_CXX+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX\" >&5\n$as_echo \"$lt_cv_prog_compiler_pic_CXX\" >&6; }\nlt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX\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 ${lt_cv_prog_compiler_pic_works_CXX+:} false; 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:$LINENO: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>conftest.err)\n   ac_status=$?\n   cat conftest.err >&5\n   echo \"$as_me:$LINENO: \\$? = $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 \"$_lt_compiler_boilerplate\" | $SED '/^$/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\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 ${lt_cv_prog_compiler_static_works_CXX+:} false; 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 \"$_lt_linker_boilerplate\" | $SED '/^$/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 ${lt_cv_prog_compiler_c_o_CXX+:} false; 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:$LINENO: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>out/conftest.err)\n   ac_status=$?\n   cat out/conftest.err >&5\n   echo \"$as_me:$LINENO: \\$? = $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 \"$_lt_compiler_boilerplate\" | $SED '/^$/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 ${lt_cv_prog_compiler_c_o_CXX+:} false; 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:$LINENO: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>out/conftest.err)\n   ac_status=$?\n   cat out/conftest.err >&5\n   echo \"$as_me:$LINENO: \\$? = $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 \"$_lt_compiler_boilerplate\" | $SED '/^$/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  exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'\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    # Also, AIX nm treats weak defined symbols like other global defined\n    # symbols, whereas GNU nm marks them as \"W\".\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\") || (\\$ 2 == \"W\")) && (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    case $cc_basename in\n    cl*)\n      exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'\n      ;;\n    *)\n      export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\\''/^[BCDGRS][ ]/s/.*[ ]\\([^ ]*\\)/\\1 DATA/;s/^.*[ ]__nm__\\([^ ]*\\)[ ][^ ]*/\\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\\'' | sort | uniq > $export_symbols'\n      exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'\n      ;;\n    esac\n    ;;\n  linux* | k*bsd*-gnu | 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\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; }\nif ${lt_cv_archive_cmds_need_lc_CXX+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  $RM conftest*\n\techo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n\tif { { 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\t  soname=conftest\n\t  lib=conftest\n\t  libobjs=conftest.$ac_objext\n\t  deplibs=\n\t  wl=$lt_prog_compiler_wl_CXX\n\t  pic_flag=$lt_prog_compiler_pic_CXX\n\t  compiler_flags=-v\n\t  linker_flags=-v\n\t  verstring=\n\t  output_objdir=.\n\t  libname=conftest\n\t  lt_save_allow_undefined_flag=$allow_undefined_flag_CXX\n\t  allow_undefined_flag_CXX=\n\t  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\t  then\n\t    lt_cv_archive_cmds_need_lc_CXX=no\n\t  else\n\t    lt_cv_archive_cmds_need_lc_CXX=yes\n\t  fi\n\t  allow_undefined_flag_CXX=$lt_save_allow_undefined_flag\n\telse\n\t  cat conftest.err 1>&5\n\tfi\n\t$RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX\" >&5\n$as_echo \"$lt_cv_archive_cmds_need_lc_CXX\" >&6; }\n      archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX\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    { $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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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=`func_echo_all \"$lib\" | $SED '\\''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 # correct to gnu/linux during the next big refactor\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,$cc_basename in\n  yes,*)\n    # gcc\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\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      ;;\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    dynamic_linker='Win32 ld.exe'\n    ;;\n\n  *,cl*)\n    # Native MSVC\n    libname_spec='$name'\n    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'\n    library_names_spec='${libname}.dll.lib'\n\n    case $build_os in\n    mingw*)\n      sys_lib_search_path_spec=\n      lt_save_ifs=$IFS\n      IFS=';'\n      for lt_path in $LIB\n      do\n        IFS=$lt_save_ifs\n        # Let DOS variable expansion print the short 8.3 style file name.\n        lt_path=`cd \"$lt_path\" 2>/dev/null && cmd //C \"for %i in (\".\") do @echo %~si\"`\n        sys_lib_search_path_spec=\"$sys_lib_search_path_spec $lt_path\"\n      done\n      IFS=$lt_save_ifs\n      # Convert to MSYS style.\n      sys_lib_search_path_spec=`$ECHO \"$sys_lib_search_path_spec\" | sed -e 's|\\\\\\\\|/|g' -e 's| \\\\([a-zA-Z]\\\\):| /\\\\1|g' -e 's|^ ||'`\n      ;;\n    cygwin*)\n      # Convert to unix form, then to dos form, then back to unix form\n      # but this time dos style (no spaces!) so that the unix form looks\n      # like /cygdrive/c/PROGRA~1:/cygdr...\n      sys_lib_search_path_spec=`cygpath --path --unix \"$LIB\"`\n      sys_lib_search_path_spec=`cygpath --path --dos \"$sys_lib_search_path_spec\" 2>/dev/null`\n      sys_lib_search_path_spec=`cygpath --path --unix \"$sys_lib_search_path_spec\" | $SED -e \"s/$PATH_SEPARATOR/ /g\"`\n      ;;\n    *)\n      sys_lib_search_path_spec=\"$LIB\"\n      if $ECHO \"$sys_lib_search_path_spec\" | $GREP ';[c-zC-Z]:/' >/dev/null; then\n        # It is most probably a Windows format PATH.\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      # FIXME: find the short name or the path components, as spaces are\n      # common. (e.g. \"Program Files\" -> \"PROGRA~1\")\n      ;;\n    esac\n\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    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\\''. $file; echo \\$dlname'\\''`~\n      dlpath=$dir/\\$dldll~\n       $RM \\$dlpath'\n    shlibpath_overrides_runpath=yes\n    dynamic_linker='Win32 link.exe'\n    ;;\n\n  *)\n    # Assume MSVC wrapper\n    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'\n    dynamic_linker='Win32 ld.exe'\n    ;;\n  esac\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 # correct to gnu/linux during the next big refactor\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\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[23].*) 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 # correct to gnu/linux during the next big refactor\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  ;;\n\nhaiku*)\n  version_type=linux # correct to gnu/linux during the next big refactor\n  need_lib_prefix=no\n  need_version=no\n  dynamic_linker=\"$host_os runtime_loader\"\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=LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'\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  # or fails outright, so override atomically:\n  install_override_mode=555\n  ;;\n\ninterix[3-9]*)\n  version_type=linux # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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 glibc/ELF.\nlinux* | k*bsd*-gnu | kopensolaris*-gnu)\n  version_type=linux # correct to gnu/linux during the next big refactor\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\n  # Some binutils ld are patched to set DT_RUNPATH\n  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_shlibpath_overrides_runpath=no\n    save_LDFLAGS=$LDFLAGS\n    save_libdir=$libdir\n    eval \"libdir=/foo; wl=\\\"$lt_prog_compiler_wl_CXX\\\"; \\\n\t 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  lt_cv_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\nfi\n\n  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath\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;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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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 # correct to gnu/linux during the next big refactor\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    { $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  CFLAGS=$lt_save_CFLAGS\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\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\n { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian\" >&5\n$as_echo_n \"checking whether byte ordering is bigendian... \" >&6; }\nif ${ac_cv_c_bigendian+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_cv_c_bigendian=unknown\n    # See if we're dealing with a universal compiler.\n    cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#ifndef __APPLE_CC__\n\t       not a universal capable compiler\n\t     #endif\n\t     typedef int dummy;\n\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n\n\t# Check for potential -arch flags.  It is not universal unless\n\t# there are at least two -arch flags with different values.\n\tac_arch=\n\tac_prev=\n\tfor ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do\n\t if test -n \"$ac_prev\"; then\n\t   case $ac_word in\n\t     i?86 | x86_64 | ppc | ppc64)\n\t       if test -z \"$ac_arch\" || test \"$ac_arch\" = \"$ac_word\"; then\n\t\t ac_arch=$ac_word\n\t       else\n\t\t ac_cv_c_bigendian=universal\n\t\t break\n\t       fi\n\t       ;;\n\t   esac\n\t   ac_prev=\n\t elif test \"x$ac_word\" = \"x-arch\"; then\n\t   ac_prev=arch\n\t fi\n       done\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n    if test $ac_cv_c_bigendian = unknown; then\n      # See if sys/param.h defines the BYTE_ORDER macro.\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <sys/types.h>\n\t     #include <sys/param.h>\n\nint\nmain ()\n{\n#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \\\n\t\t     && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \\\n\t\t     && LITTLE_ENDIAN)\n\t      bogus endian macros\n\t     #endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  # It does; now see whether it defined to BIG_ENDIAN or not.\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <sys/types.h>\n\t\t#include <sys/param.h>\n\nint\nmain ()\n{\n#if BYTE_ORDER != BIG_ENDIAN\n\t\t not big endian\n\t\t#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_cv_c_bigendian=yes\nelse\n  ac_cv_c_bigendian=no\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    fi\n    if test $ac_cv_c_bigendian = unknown; then\n      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <limits.h>\n\nint\nmain ()\n{\n#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)\n\t      bogus endian macros\n\t     #endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  # It does; now see whether it defined to _BIG_ENDIAN or not.\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <limits.h>\n\nint\nmain ()\n{\n#ifndef _BIG_ENDIAN\n\t\t not big endian\n\t\t#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_cv_c_bigendian=yes\nelse\n  ac_cv_c_bigendian=no\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    fi\n    if test $ac_cv_c_bigendian = unknown; then\n      # Compile a test program.\n      if test \"$cross_compiling\" = yes; then :\n  # Try to guess by grepping values from an object file.\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\nshort int ascii_mm[] =\n\t\t  { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };\n\t\tshort int ascii_ii[] =\n\t\t  { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };\n\t\tint use_ascii (int i) {\n\t\t  return ascii_mm[i] + ascii_ii[i];\n\t\t}\n\t\tshort int ebcdic_ii[] =\n\t\t  { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };\n\t\tshort int ebcdic_mm[] =\n\t\t  { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };\n\t\tint use_ebcdic (int i) {\n\t\t  return ebcdic_mm[i] + ebcdic_ii[i];\n\t\t}\n\t\textern int foo;\n\nint\nmain ()\n{\nreturn use_ascii (foo) == use_ebcdic (foo);\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then\n\t      ac_cv_c_bigendian=yes\n\t    fi\n\t    if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then\n\t      if test \"$ac_cv_c_bigendian\" = unknown; then\n\t\tac_cv_c_bigendian=no\n\t      else\n\t\t# finding both strings is unlikely to happen, but who knows?\n\t\tac_cv_c_bigendian=unknown\n\t      fi\n\t    fi\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n$ac_includes_default\nint\nmain ()\n{\n\n\t     /* Are we little or big endian?  From Harbison&Steele.  */\n\t     union\n\t     {\n\t       long int l;\n\t       char c[sizeof (long int)];\n\t     } u;\n\t     u.l = 1;\n\t     return u.c[sizeof (long int) - 1] == 1;\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_run \"$LINENO\"; then :\n  ac_cv_c_bigendian=no\nelse\n  ac_cv_c_bigendian=yes\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\n    fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian\" >&5\n$as_echo \"$ac_cv_c_bigendian\" >&6; }\n case $ac_cv_c_bigendian in #(\n   yes)\n     $as_echo \"#define WORDS_BIGENDIAN 1\" >>confdefs.h\n;; #(\n   no)\n      ;; #(\n   universal)\n\n$as_echo \"#define AC_APPLE_UNIVERSAL_BUILD 1\" >>confdefs.h\n\n     ;; #(\n   *)\n     as_fn_error $? \"unknown endianness\n presetting ac_cv_c_bigendian=no (or yes) will help\" \"$LINENO\" 5 ;;\n esac\n\n\nfor ac_header in stdint.h stddef.h sys/mman.h sys/resource.h windows.h byteswap.h sys/byteswap.h sys/endian.h sys/time.h\ndo :\n  as_ac_Header=`$as_echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nac_fn_cxx_check_header_mongrel \"$LINENO\" \"$ac_header\" \"$as_ac_Header\" \"$ac_includes_default\"\nif eval test \\\"x\\$\"$as_ac_Header\"\\\" = 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# Don't use AC_FUNC_MMAP, as it checks for mappings of already-mapped memory,\n# which we don't need (and does not exist on Windows).\nac_fn_cxx_check_func \"$LINENO\" \"mmap\" \"ac_cv_func_mmap\"\nif test \"x$ac_cv_func_mmap\" = xyes; then :\n\nfi\n\n\n\n# Check whether --enable-gtest was given.\nif test \"${enable_gtest+set}\" = set; then :\n  enableval=$enable_gtest;\nelse\n  enable_gtest=\nfi\n\n\n\n\n\n\n\nHAVE_GTEST=\"no\"\nif test \"x${enable_gtest}\" != \"xno\"; then :\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for 'gtest-config'\" >&5\n$as_echo_n \"checking for 'gtest-config'... \" >&6; }\n   if test \"x${enable_gtest}\" = \"xyes\"; then :\n  if test -x \"${enable_gtest}/scripts/gtest-config\"; then :\n  GTEST_CONFIG=\"${enable_gtest}/scripts/gtest-config\"\nelse\n  GTEST_CONFIG=\"${enable_gtest}/bin/gtest-config\"\nfi\n      if test -x \"${GTEST_CONFIG}\"; then :\n\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n         as_fn_error $? \"Unable to locate either a built or installed Google Test.\nThe specific location '${enable_gtest}' was provided for a built or installed\nGoogle Test, but no 'gtest-config' script could be found at this location.\" \"$LINENO\" 5\n\nfi\nelse\n  # Extract the first word of \"gtest-config\", so it can be a program name with args.\nset dummy gtest-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 ${ac_cv_path_GTEST_CONFIG+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  case $GTEST_CONFIG in\n  [\\\\/]* | ?:[\\\\/]*)\n  ac_cv_path_GTEST_CONFIG=\"$GTEST_CONFIG\" # Let the user override the test with a path.\n  ;;\n  *)\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_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_path_GTEST_CONFIG=\"$as_dir/$ac_word$ac_exec_ext\"\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  ;;\nesac\nfi\nGTEST_CONFIG=$ac_cv_path_GTEST_CONFIG\nif test -n \"$GTEST_CONFIG\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $GTEST_CONFIG\" >&5\n$as_echo \"$GTEST_CONFIG\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\n   if test -x \"${GTEST_CONFIG}\"; then :\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: ${GTEST_CONFIG}\" >&5\n$as_echo \"${GTEST_CONFIG}\" >&6; }\n      _gtest_min_version=\"--min-version=0\"\n         { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for Google Test\" >&5\n$as_echo_n \"checking for Google Test... \" >&6; }\n      if ${GTEST_CONFIG} ${_gtest_min_version}; then :\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n         HAVE_GTEST='yes'\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n   if test \"x${HAVE_GTEST}\" = \"xyes\"; then :\n  GTEST_CPPFLAGS=`${GTEST_CONFIG} --cppflags`\n      GTEST_CXXFLAGS=`${GTEST_CONFIG} --cxxflags`\n      GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags`\n      GTEST_LIBS=`${GTEST_CONFIG} --libs`\n      GTEST_VERSION=`${GTEST_CONFIG} --version`\n\n$as_echo \"#define HAVE_GTEST 1\" >>confdefs.h\n\nelse\n  if test \"x${enable_gtest}\" = \"xyes\"; then :\n  as_fn_error $? \"Google Test was enabled, but no viable version could be found.\" \"$LINENO\" 5\n\nfi\nfi\nfi\n\n if test \"x$HAVE_GTEST\" = \"xyes\"; then\n  HAVE_GTEST_TRUE=\n  HAVE_GTEST_FALSE='#'\nelse\n  HAVE_GTEST_TRUE='#'\n  HAVE_GTEST_FALSE=\nfi\n\nif test \"x$HAVE_GTEST\" = \"xyes\"; then :\n  true\nelse\n  true # Ignore; we can live without it.\nfi\n\n\n\n# Check whether --with-gflags was given.\nif test \"${with_gflags+set}\" = set; then :\n  withval=$with_gflags;\nelse\n  with_gflags=check\nfi\n\n\nif test \"x$with_gflags\" != \"xno\"; then\n\n\n\n\n\n\n\nif test \"x$ac_cv_env_PKG_CONFIG_set\" != \"xset\"; then\n\tif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}pkg-config\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}pkg-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 ${ac_cv_path_PKG_CONFIG+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  case $PKG_CONFIG in\n  [\\\\/]* | ?:[\\\\/]*)\n  ac_cv_path_PKG_CONFIG=\"$PKG_CONFIG\" # Let the user override the test with a path.\n  ;;\n  *)\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_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_path_PKG_CONFIG=\"$as_dir/$ac_word$ac_exec_ext\"\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  ;;\nesac\nfi\nPKG_CONFIG=$ac_cv_path_PKG_CONFIG\nif test -n \"$PKG_CONFIG\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG\" >&5\n$as_echo \"$PKG_CONFIG\" >&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_path_PKG_CONFIG\"; then\n  ac_pt_PKG_CONFIG=$PKG_CONFIG\n  # Extract the first word of \"pkg-config\", so it can be a program name with args.\nset dummy pkg-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 ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  case $ac_pt_PKG_CONFIG in\n  [\\\\/]* | ?:[\\\\/]*)\n  ac_cv_path_ac_pt_PKG_CONFIG=\"$ac_pt_PKG_CONFIG\" # Let the user override the test with a path.\n  ;;\n  *)\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_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_path_ac_pt_PKG_CONFIG=\"$as_dir/$ac_word$ac_exec_ext\"\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  ;;\nesac\nfi\nac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG\nif test -n \"$ac_pt_PKG_CONFIG\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG\" >&5\n$as_echo \"$ac_pt_PKG_CONFIG\" >&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_pt_PKG_CONFIG\" = x; then\n    PKG_CONFIG=\"\"\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    PKG_CONFIG=$ac_pt_PKG_CONFIG\n  fi\nelse\n  PKG_CONFIG=\"$ac_cv_path_PKG_CONFIG\"\nfi\n\nfi\nif test -n \"$PKG_CONFIG\"; then\n\t_pkg_min_version=0.9.0\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version\" >&5\n$as_echo_n \"checking pkg-config is at least version $_pkg_min_version... \" >&6; }\n\tif $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then\n\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n\telse\n\t\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n\t\tPKG_CONFIG=\"\"\n\tfi\nfi\n\npkg_failed=no\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for gflags\" >&5\n$as_echo_n \"checking for gflags... \" >&6; }\n\nif test -n \"$gflags_CFLAGS\"; then\n    pkg_cv_gflags_CFLAGS=\"$gflags_CFLAGS\"\n elif test -n \"$PKG_CONFIG\"; then\n    if test -n \"$PKG_CONFIG\" && \\\n    { { $as_echo \"$as_me:${as_lineno-$LINENO}: \\$PKG_CONFIG --exists --print-errors \\\"libgflags\\\"\"; } >&5\n  ($PKG_CONFIG --exists --print-errors \"libgflags\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then\n  pkg_cv_gflags_CFLAGS=`$PKG_CONFIG --cflags \"libgflags\" 2>/dev/null`\n\t\t      test \"x$?\" != \"x0\" && pkg_failed=yes\nelse\n  pkg_failed=yes\nfi\n else\n    pkg_failed=untried\nfi\nif test -n \"$gflags_LIBS\"; then\n    pkg_cv_gflags_LIBS=\"$gflags_LIBS\"\n elif test -n \"$PKG_CONFIG\"; then\n    if test -n \"$PKG_CONFIG\" && \\\n    { { $as_echo \"$as_me:${as_lineno-$LINENO}: \\$PKG_CONFIG --exists --print-errors \\\"libgflags\\\"\"; } >&5\n  ($PKG_CONFIG --exists --print-errors \"libgflags\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then\n  pkg_cv_gflags_LIBS=`$PKG_CONFIG --libs \"libgflags\" 2>/dev/null`\n\t\t      test \"x$?\" != \"x0\" && pkg_failed=yes\nelse\n  pkg_failed=yes\nfi\n else\n    pkg_failed=untried\nfi\n\n\n\nif test $pkg_failed = yes; then\n   \t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n\nif $PKG_CONFIG --atleast-pkgconfig-version 0.20; then\n        _pkg_short_errors_supported=yes\nelse\n        _pkg_short_errors_supported=no\nfi\n        if test $_pkg_short_errors_supported = yes; then\n\t        gflags_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs \"libgflags\" 2>&1`\n        else\n\t        gflags_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs \"libgflags\" 2>&1`\n        fi\n\t# Put the nasty error message in config.log where it belongs\n\techo \"$gflags_PKG_ERRORS\" >&5\n\n\tif test \"x$with_gflags\" != \"xcheck\"; then\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 $? \"--with-gflags was given, but test for gflags failed\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\n    fi\nelif test $pkg_failed = untried; then\n     \t{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n\tif test \"x$with_gflags\" != \"xcheck\"; then\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 $? \"--with-gflags was given, but test for gflags failed\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\n    fi\nelse\n\tgflags_CFLAGS=$pkg_cv_gflags_CFLAGS\n\tgflags_LIBS=$pkg_cv_gflags_LIBS\n        { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n\n$as_echo \"#define HAVE_GFLAGS 1\" >>confdefs.h\n\nfi\nfi\n\n# See if we have __builtin_expect.\n# TODO: Use AC_CACHE.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if the compiler supports __builtin_expect\" >&5\n$as_echo_n \"checking if the compiler supports __builtin_expect... \" >&6; }\n\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n    return __builtin_expect(1, 1) ? 1 : 0\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n\n    snappy_have_builtin_expect=yes\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n\nelse\n\n    snappy_have_builtin_expect=no\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nif test x$snappy_have_builtin_expect = xyes ; then\n\n$as_echo \"#define HAVE_BUILTIN_EXPECT 1\" >>confdefs.h\n\nfi\n\n# See if we have working count-trailing-zeros intrinsics.\n# TODO: Use AC_CACHE.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if the compiler supports __builtin_ctzll\" >&5\n$as_echo_n \"checking if the compiler supports __builtin_ctzll... \" >&6; }\n\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n    return (__builtin_ctzll(0x100000000LL) == 32) ? 1 : 0\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n\n    snappy_have_builtin_ctz=yes\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n\nelse\n\n    snappy_have_builtin_ctz=no\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nif test x$snappy_have_builtin_ctz = xyes ; then\n\n$as_echo \"#define HAVE_BUILTIN_CTZ 1\" >>confdefs.h\n\nfi\n\n# Other compression libraries; the unit test can use these for comparison\n# if they are available. If they are not found, just ignore.\nUNITTEST_LIBS=\"\"\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for zlibVersion in -lz\" >&5\n$as_echo_n \"checking for zlibVersion in -lz... \" >&6; }\nif ${ac_cv_lib_z_zlibVersion+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lz  $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 zlibVersion ();\nint\nmain ()\n{\nreturn zlibVersion ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_link \"$LINENO\"; then :\n  ac_cv_lib_z_zlibVersion=yes\nelse\n  ac_cv_lib_z_zlibVersion=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_z_zlibVersion\" >&5\n$as_echo \"$ac_cv_lib_z_zlibVersion\" >&6; }\nif test \"x$ac_cv_lib_z_zlibVersion\" = xyes; then :\n\n      cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBZ 1\n_ACEOF\n\n      UNITTEST_LIBS=\"-lz $UNITTEST_LIBS\"\n\nelse\n  true\n\nfi\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for lzo1x_1_15_compress in -llzo2\" >&5\n$as_echo_n \"checking for lzo1x_1_15_compress in -llzo2... \" >&6; }\nif ${ac_cv_lib_lzo2_lzo1x_1_15_compress+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-llzo2  $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 lzo1x_1_15_compress ();\nint\nmain ()\n{\nreturn lzo1x_1_15_compress ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_link \"$LINENO\"; then :\n  ac_cv_lib_lzo2_lzo1x_1_15_compress=yes\nelse\n  ac_cv_lib_lzo2_lzo1x_1_15_compress=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_lzo2_lzo1x_1_15_compress\" >&5\n$as_echo \"$ac_cv_lib_lzo2_lzo1x_1_15_compress\" >&6; }\nif test \"x$ac_cv_lib_lzo2_lzo1x_1_15_compress\" = xyes; then :\n\n      cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBLZO2 1\n_ACEOF\n\n      UNITTEST_LIBS=\"-llzo2 $UNITTEST_LIBS\"\n\nelse\n  true\n\nfi\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for lzf_compress in -llzf\" >&5\n$as_echo_n \"checking for lzf_compress in -llzf... \" >&6; }\nif ${ac_cv_lib_lzf_lzf_compress+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-llzf  $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 lzf_compress ();\nint\nmain ()\n{\nreturn lzf_compress ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_link \"$LINENO\"; then :\n  ac_cv_lib_lzf_lzf_compress=yes\nelse\n  ac_cv_lib_lzf_lzf_compress=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_lzf_lzf_compress\" >&5\n$as_echo \"$ac_cv_lib_lzf_lzf_compress\" >&6; }\nif test \"x$ac_cv_lib_lzf_lzf_compress\" = xyes; then :\n\n      cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBLZF 1\n_ACEOF\n\n      UNITTEST_LIBS=\"-llzf $UNITTEST_LIBS\"\n\nelse\n  true\n\nfi\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for fastlz_compress in -lfastlz\" >&5\n$as_echo_n \"checking for fastlz_compress in -lfastlz... \" >&6; }\nif ${ac_cv_lib_fastlz_fastlz_compress+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lfastlz  $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 fastlz_compress ();\nint\nmain ()\n{\nreturn fastlz_compress ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_link \"$LINENO\"; then :\n  ac_cv_lib_fastlz_fastlz_compress=yes\nelse\n  ac_cv_lib_fastlz_fastlz_compress=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_fastlz_fastlz_compress\" >&5\n$as_echo \"$ac_cv_lib_fastlz_fastlz_compress\" >&6; }\nif test \"x$ac_cv_lib_fastlz_fastlz_compress\" = xyes; then :\n\n      cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBFASTLZ 1\n_ACEOF\n\n      UNITTEST_LIBS=\"-lfastlz $UNITTEST_LIBS\"\n\nelse\n  true\n\nfi\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for qlz_compress in -lquicklz\" >&5\n$as_echo_n \"checking for qlz_compress in -lquicklz... \" >&6; }\nif ${ac_cv_lib_quicklz_qlz_compress+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lquicklz  $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 qlz_compress ();\nint\nmain ()\n{\nreturn qlz_compress ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_link \"$LINENO\"; then :\n  ac_cv_lib_quicklz_qlz_compress=yes\nelse\n  ac_cv_lib_quicklz_qlz_compress=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_quicklz_qlz_compress\" >&5\n$as_echo \"$ac_cv_lib_quicklz_qlz_compress\" >&6; }\nif test \"x$ac_cv_lib_quicklz_qlz_compress\" = xyes; then :\n\n      cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBQUICKLZ 1\n_ACEOF\n\n      UNITTEST_LIBS=\"-lquicklz $UNITTEST_LIBS\"\n\nelse\n  true\n\nfi\n\n\n\n\n# These are used by snappy-stubs-public.h.in.\nif test \"$ac_cv_header_stdint_h\" = \"yes\"; then\n    ac_cv_have_stdint_h=1\n\nelse\n    ac_cv_have_stdint_h=0\n\nfi\nif test \"$ac_cv_header_stddef_h\" = \"yes\"; then\n    ac_cv_have_stddef_h=1\n\nelse\n    ac_cv_have_stddef_h=0\n\nfi\n\n# Export the version to snappy-stubs-public.h.\nSNAPPY_MAJOR=\"1\"\nSNAPPY_MINOR=\"1\"\nSNAPPY_PATCHLEVEL=\"0\"\n\n\n\n\nSNAPPY_LTVERSION=2:4:1\n\n\nac_config_headers=\"$ac_config_headers config.h\"\n\nac_config_files=\"$ac_config_files Makefile snappy-stubs-public.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    if test \"x$cache_file\" != \"x/dev/null\"; then\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: updating cache $cache_file\" >&5\n$as_echo \"$as_me: updating cache $cache_file\" >&6;}\n      if test ! -f \"$cache_file\" || test -h \"$cache_file\"; then\n\tcat confcache >\"$cache_file\"\n      else\n        case $cache_file in #(\n        */* | ?:*)\n\t  mv -f confcache \"$cache_file\"$$ &&\n\t  mv -f \"$cache_file\"$$ \"$cache_file\" ;; #(\n        *)\n\t  mv -f confcache \"$cache_file\" ;;\n\tesac\n      fi\n    fi\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=\nU=\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\n if test -n \"$EXEEXT\"; then\n  am__EXEEXT_TRUE=\n  am__EXEEXT_FALSE='#'\nelse\n  am__EXEEXT_TRUE='#'\n  am__EXEEXT_FALSE=\nfi\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\n\nif test -z \"${HAVE_GTEST_TRUE}\" && test -z \"${HAVE_GTEST_FALSE}\"; then\n  as_fn_error $? \"conditional \\\"HAVE_GTEST\\\" 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.\nas_myself=\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 STATUS 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=$1; test $as_status -eq 0 && as_status=1\n  if test \"$4\"; then\n    as_lineno=${as_lineno-\"$3\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n    $as_echo \"$as_me:${as_lineno-$LINENO}: error: $2\" >&$4\n  fi\n  $as_echo \"$as_me: error: $2\" >&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 snappy $as_me 1.1.0, which was\ngenerated by GNU Autoconf 2.68.  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 the package provider.\"\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=\"\\\\\nsnappy config.status 1.1.0\nconfigured by $0, generated by GNU Autoconf 2.68,\n  with options \\\\\"\\$ac_cs_config\\\\\"\n\nCopyright (C) 2010 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'\nMKDIR_P='$MKDIR_P'\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=`expr \"X$1\" : 'X\\([^=]*\\)='`\n    ac_optarg=\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    '') as_fn_error $? \"missing file argument\" ;;\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'\nmacro_version='`$ECHO \"$macro_version\" | $SED \"$delay_single_quote_subst\"`'\nmacro_revision='`$ECHO \"$macro_revision\" | $SED \"$delay_single_quote_subst\"`'\nenable_shared='`$ECHO \"$enable_shared\" | $SED \"$delay_single_quote_subst\"`'\nenable_static='`$ECHO \"$enable_static\" | $SED \"$delay_single_quote_subst\"`'\npic_mode='`$ECHO \"$pic_mode\" | $SED \"$delay_single_quote_subst\"`'\nenable_fast_install='`$ECHO \"$enable_fast_install\" | $SED \"$delay_single_quote_subst\"`'\nSHELL='`$ECHO \"$SHELL\" | $SED \"$delay_single_quote_subst\"`'\nECHO='`$ECHO \"$ECHO\" | $SED \"$delay_single_quote_subst\"`'\nPATH_SEPARATOR='`$ECHO \"$PATH_SEPARATOR\" | $SED \"$delay_single_quote_subst\"`'\nhost_alias='`$ECHO \"$host_alias\" | $SED \"$delay_single_quote_subst\"`'\nhost='`$ECHO \"$host\" | $SED \"$delay_single_quote_subst\"`'\nhost_os='`$ECHO \"$host_os\" | $SED \"$delay_single_quote_subst\"`'\nbuild_alias='`$ECHO \"$build_alias\" | $SED \"$delay_single_quote_subst\"`'\nbuild='`$ECHO \"$build\" | $SED \"$delay_single_quote_subst\"`'\nbuild_os='`$ECHO \"$build_os\" | $SED \"$delay_single_quote_subst\"`'\nSED='`$ECHO \"$SED\" | $SED \"$delay_single_quote_subst\"`'\nXsed='`$ECHO \"$Xsed\" | $SED \"$delay_single_quote_subst\"`'\nGREP='`$ECHO \"$GREP\" | $SED \"$delay_single_quote_subst\"`'\nEGREP='`$ECHO \"$EGREP\" | $SED \"$delay_single_quote_subst\"`'\nFGREP='`$ECHO \"$FGREP\" | $SED \"$delay_single_quote_subst\"`'\nLD='`$ECHO \"$LD\" | $SED \"$delay_single_quote_subst\"`'\nNM='`$ECHO \"$NM\" | $SED \"$delay_single_quote_subst\"`'\nLN_S='`$ECHO \"$LN_S\" | $SED \"$delay_single_quote_subst\"`'\nmax_cmd_len='`$ECHO \"$max_cmd_len\" | $SED \"$delay_single_quote_subst\"`'\nac_objext='`$ECHO \"$ac_objext\" | $SED \"$delay_single_quote_subst\"`'\nexeext='`$ECHO \"$exeext\" | $SED \"$delay_single_quote_subst\"`'\nlt_unset='`$ECHO \"$lt_unset\" | $SED \"$delay_single_quote_subst\"`'\nlt_SP2NL='`$ECHO \"$lt_SP2NL\" | $SED \"$delay_single_quote_subst\"`'\nlt_NL2SP='`$ECHO \"$lt_NL2SP\" | $SED \"$delay_single_quote_subst\"`'\nlt_cv_to_host_file_cmd='`$ECHO \"$lt_cv_to_host_file_cmd\" | $SED \"$delay_single_quote_subst\"`'\nlt_cv_to_tool_file_cmd='`$ECHO \"$lt_cv_to_tool_file_cmd\" | $SED \"$delay_single_quote_subst\"`'\nreload_flag='`$ECHO \"$reload_flag\" | $SED \"$delay_single_quote_subst\"`'\nreload_cmds='`$ECHO \"$reload_cmds\" | $SED \"$delay_single_quote_subst\"`'\nOBJDUMP='`$ECHO \"$OBJDUMP\" | $SED \"$delay_single_quote_subst\"`'\ndeplibs_check_method='`$ECHO \"$deplibs_check_method\" | $SED \"$delay_single_quote_subst\"`'\nfile_magic_cmd='`$ECHO \"$file_magic_cmd\" | $SED \"$delay_single_quote_subst\"`'\nfile_magic_glob='`$ECHO \"$file_magic_glob\" | $SED \"$delay_single_quote_subst\"`'\nwant_nocaseglob='`$ECHO \"$want_nocaseglob\" | $SED \"$delay_single_quote_subst\"`'\nDLLTOOL='`$ECHO \"$DLLTOOL\" | $SED \"$delay_single_quote_subst\"`'\nsharedlib_from_linklib_cmd='`$ECHO \"$sharedlib_from_linklib_cmd\" | $SED \"$delay_single_quote_subst\"`'\nAR='`$ECHO \"$AR\" | $SED \"$delay_single_quote_subst\"`'\nAR_FLAGS='`$ECHO \"$AR_FLAGS\" | $SED \"$delay_single_quote_subst\"`'\narchiver_list_spec='`$ECHO \"$archiver_list_spec\" | $SED \"$delay_single_quote_subst\"`'\nSTRIP='`$ECHO \"$STRIP\" | $SED \"$delay_single_quote_subst\"`'\nRANLIB='`$ECHO \"$RANLIB\" | $SED \"$delay_single_quote_subst\"`'\nold_postinstall_cmds='`$ECHO \"$old_postinstall_cmds\" | $SED \"$delay_single_quote_subst\"`'\nold_postuninstall_cmds='`$ECHO \"$old_postuninstall_cmds\" | $SED \"$delay_single_quote_subst\"`'\nold_archive_cmds='`$ECHO \"$old_archive_cmds\" | $SED \"$delay_single_quote_subst\"`'\nlock_old_archive_extraction='`$ECHO \"$lock_old_archive_extraction\" | $SED \"$delay_single_quote_subst\"`'\nCC='`$ECHO \"$CC\" | $SED \"$delay_single_quote_subst\"`'\nCFLAGS='`$ECHO \"$CFLAGS\" | $SED \"$delay_single_quote_subst\"`'\ncompiler='`$ECHO \"$compiler\" | $SED \"$delay_single_quote_subst\"`'\nGCC='`$ECHO \"$GCC\" | $SED \"$delay_single_quote_subst\"`'\nlt_cv_sys_global_symbol_pipe='`$ECHO \"$lt_cv_sys_global_symbol_pipe\" | $SED \"$delay_single_quote_subst\"`'\nlt_cv_sys_global_symbol_to_cdecl='`$ECHO \"$lt_cv_sys_global_symbol_to_cdecl\" | $SED \"$delay_single_quote_subst\"`'\nlt_cv_sys_global_symbol_to_c_name_address='`$ECHO \"$lt_cv_sys_global_symbol_to_c_name_address\" | $SED \"$delay_single_quote_subst\"`'\nlt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO \"$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix\" | $SED \"$delay_single_quote_subst\"`'\nnm_file_list_spec='`$ECHO \"$nm_file_list_spec\" | $SED \"$delay_single_quote_subst\"`'\nlt_sysroot='`$ECHO \"$lt_sysroot\" | $SED \"$delay_single_quote_subst\"`'\nobjdir='`$ECHO \"$objdir\" | $SED \"$delay_single_quote_subst\"`'\nMAGIC_CMD='`$ECHO \"$MAGIC_CMD\" | $SED \"$delay_single_quote_subst\"`'\nlt_prog_compiler_no_builtin_flag='`$ECHO \"$lt_prog_compiler_no_builtin_flag\" | $SED \"$delay_single_quote_subst\"`'\nlt_prog_compiler_pic='`$ECHO \"$lt_prog_compiler_pic\" | $SED \"$delay_single_quote_subst\"`'\nlt_prog_compiler_wl='`$ECHO \"$lt_prog_compiler_wl\" | $SED \"$delay_single_quote_subst\"`'\nlt_prog_compiler_static='`$ECHO \"$lt_prog_compiler_static\" | $SED \"$delay_single_quote_subst\"`'\nlt_cv_prog_compiler_c_o='`$ECHO \"$lt_cv_prog_compiler_c_o\" | $SED \"$delay_single_quote_subst\"`'\nneed_locks='`$ECHO \"$need_locks\" | $SED \"$delay_single_quote_subst\"`'\nMANIFEST_TOOL='`$ECHO \"$MANIFEST_TOOL\" | $SED \"$delay_single_quote_subst\"`'\nDSYMUTIL='`$ECHO \"$DSYMUTIL\" | $SED \"$delay_single_quote_subst\"`'\nNMEDIT='`$ECHO \"$NMEDIT\" | $SED \"$delay_single_quote_subst\"`'\nLIPO='`$ECHO \"$LIPO\" | $SED \"$delay_single_quote_subst\"`'\nOTOOL='`$ECHO \"$OTOOL\" | $SED \"$delay_single_quote_subst\"`'\nOTOOL64='`$ECHO \"$OTOOL64\" | $SED \"$delay_single_quote_subst\"`'\nlibext='`$ECHO \"$libext\" | $SED \"$delay_single_quote_subst\"`'\nshrext_cmds='`$ECHO \"$shrext_cmds\" | $SED \"$delay_single_quote_subst\"`'\nextract_expsyms_cmds='`$ECHO \"$extract_expsyms_cmds\" | $SED \"$delay_single_quote_subst\"`'\narchive_cmds_need_lc='`$ECHO \"$archive_cmds_need_lc\" | $SED \"$delay_single_quote_subst\"`'\nenable_shared_with_static_runtimes='`$ECHO \"$enable_shared_with_static_runtimes\" | $SED \"$delay_single_quote_subst\"`'\nexport_dynamic_flag_spec='`$ECHO \"$export_dynamic_flag_spec\" | $SED \"$delay_single_quote_subst\"`'\nwhole_archive_flag_spec='`$ECHO \"$whole_archive_flag_spec\" | $SED \"$delay_single_quote_subst\"`'\ncompiler_needs_object='`$ECHO \"$compiler_needs_object\" | $SED \"$delay_single_quote_subst\"`'\nold_archive_from_new_cmds='`$ECHO \"$old_archive_from_new_cmds\" | $SED \"$delay_single_quote_subst\"`'\nold_archive_from_expsyms_cmds='`$ECHO \"$old_archive_from_expsyms_cmds\" | $SED \"$delay_single_quote_subst\"`'\narchive_cmds='`$ECHO \"$archive_cmds\" | $SED \"$delay_single_quote_subst\"`'\narchive_expsym_cmds='`$ECHO \"$archive_expsym_cmds\" | $SED \"$delay_single_quote_subst\"`'\nmodule_cmds='`$ECHO \"$module_cmds\" | $SED \"$delay_single_quote_subst\"`'\nmodule_expsym_cmds='`$ECHO \"$module_expsym_cmds\" | $SED \"$delay_single_quote_subst\"`'\nwith_gnu_ld='`$ECHO \"$with_gnu_ld\" | $SED \"$delay_single_quote_subst\"`'\nallow_undefined_flag='`$ECHO \"$allow_undefined_flag\" | $SED \"$delay_single_quote_subst\"`'\nno_undefined_flag='`$ECHO \"$no_undefined_flag\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_libdir_flag_spec='`$ECHO \"$hardcode_libdir_flag_spec\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_libdir_separator='`$ECHO \"$hardcode_libdir_separator\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_direct='`$ECHO \"$hardcode_direct\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_direct_absolute='`$ECHO \"$hardcode_direct_absolute\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_minus_L='`$ECHO \"$hardcode_minus_L\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_shlibpath_var='`$ECHO \"$hardcode_shlibpath_var\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_automatic='`$ECHO \"$hardcode_automatic\" | $SED \"$delay_single_quote_subst\"`'\ninherit_rpath='`$ECHO \"$inherit_rpath\" | $SED \"$delay_single_quote_subst\"`'\nlink_all_deplibs='`$ECHO \"$link_all_deplibs\" | $SED \"$delay_single_quote_subst\"`'\nalways_export_symbols='`$ECHO \"$always_export_symbols\" | $SED \"$delay_single_quote_subst\"`'\nexport_symbols_cmds='`$ECHO \"$export_symbols_cmds\" | $SED \"$delay_single_quote_subst\"`'\nexclude_expsyms='`$ECHO \"$exclude_expsyms\" | $SED \"$delay_single_quote_subst\"`'\ninclude_expsyms='`$ECHO \"$include_expsyms\" | $SED \"$delay_single_quote_subst\"`'\nprelink_cmds='`$ECHO \"$prelink_cmds\" | $SED \"$delay_single_quote_subst\"`'\npostlink_cmds='`$ECHO \"$postlink_cmds\" | $SED \"$delay_single_quote_subst\"`'\nfile_list_spec='`$ECHO \"$file_list_spec\" | $SED \"$delay_single_quote_subst\"`'\nvariables_saved_for_relink='`$ECHO \"$variables_saved_for_relink\" | $SED \"$delay_single_quote_subst\"`'\nneed_lib_prefix='`$ECHO \"$need_lib_prefix\" | $SED \"$delay_single_quote_subst\"`'\nneed_version='`$ECHO \"$need_version\" | $SED \"$delay_single_quote_subst\"`'\nversion_type='`$ECHO \"$version_type\" | $SED \"$delay_single_quote_subst\"`'\nrunpath_var='`$ECHO \"$runpath_var\" | $SED \"$delay_single_quote_subst\"`'\nshlibpath_var='`$ECHO \"$shlibpath_var\" | $SED \"$delay_single_quote_subst\"`'\nshlibpath_overrides_runpath='`$ECHO \"$shlibpath_overrides_runpath\" | $SED \"$delay_single_quote_subst\"`'\nlibname_spec='`$ECHO \"$libname_spec\" | $SED \"$delay_single_quote_subst\"`'\nlibrary_names_spec='`$ECHO \"$library_names_spec\" | $SED \"$delay_single_quote_subst\"`'\nsoname_spec='`$ECHO \"$soname_spec\" | $SED \"$delay_single_quote_subst\"`'\ninstall_override_mode='`$ECHO \"$install_override_mode\" | $SED \"$delay_single_quote_subst\"`'\npostinstall_cmds='`$ECHO \"$postinstall_cmds\" | $SED \"$delay_single_quote_subst\"`'\npostuninstall_cmds='`$ECHO \"$postuninstall_cmds\" | $SED \"$delay_single_quote_subst\"`'\nfinish_cmds='`$ECHO \"$finish_cmds\" | $SED \"$delay_single_quote_subst\"`'\nfinish_eval='`$ECHO \"$finish_eval\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_into_libs='`$ECHO \"$hardcode_into_libs\" | $SED \"$delay_single_quote_subst\"`'\nsys_lib_search_path_spec='`$ECHO \"$sys_lib_search_path_spec\" | $SED \"$delay_single_quote_subst\"`'\nsys_lib_dlsearch_path_spec='`$ECHO \"$sys_lib_dlsearch_path_spec\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_action='`$ECHO \"$hardcode_action\" | $SED \"$delay_single_quote_subst\"`'\nenable_dlopen='`$ECHO \"$enable_dlopen\" | $SED \"$delay_single_quote_subst\"`'\nenable_dlopen_self='`$ECHO \"$enable_dlopen_self\" | $SED \"$delay_single_quote_subst\"`'\nenable_dlopen_self_static='`$ECHO \"$enable_dlopen_self_static\" | $SED \"$delay_single_quote_subst\"`'\nold_striplib='`$ECHO \"$old_striplib\" | $SED \"$delay_single_quote_subst\"`'\nstriplib='`$ECHO \"$striplib\" | $SED \"$delay_single_quote_subst\"`'\ncompiler_lib_search_dirs='`$ECHO \"$compiler_lib_search_dirs\" | $SED \"$delay_single_quote_subst\"`'\npredep_objects='`$ECHO \"$predep_objects\" | $SED \"$delay_single_quote_subst\"`'\npostdep_objects='`$ECHO \"$postdep_objects\" | $SED \"$delay_single_quote_subst\"`'\npredeps='`$ECHO \"$predeps\" | $SED \"$delay_single_quote_subst\"`'\npostdeps='`$ECHO \"$postdeps\" | $SED \"$delay_single_quote_subst\"`'\ncompiler_lib_search_path='`$ECHO \"$compiler_lib_search_path\" | $SED \"$delay_single_quote_subst\"`'\nLD_CXX='`$ECHO \"$LD_CXX\" | $SED \"$delay_single_quote_subst\"`'\nreload_flag_CXX='`$ECHO \"$reload_flag_CXX\" | $SED \"$delay_single_quote_subst\"`'\nreload_cmds_CXX='`$ECHO \"$reload_cmds_CXX\" | $SED \"$delay_single_quote_subst\"`'\nold_archive_cmds_CXX='`$ECHO \"$old_archive_cmds_CXX\" | $SED \"$delay_single_quote_subst\"`'\ncompiler_CXX='`$ECHO \"$compiler_CXX\" | $SED \"$delay_single_quote_subst\"`'\nGCC_CXX='`$ECHO \"$GCC_CXX\" | $SED \"$delay_single_quote_subst\"`'\nlt_prog_compiler_no_builtin_flag_CXX='`$ECHO \"$lt_prog_compiler_no_builtin_flag_CXX\" | $SED \"$delay_single_quote_subst\"`'\nlt_prog_compiler_pic_CXX='`$ECHO \"$lt_prog_compiler_pic_CXX\" | $SED \"$delay_single_quote_subst\"`'\nlt_prog_compiler_wl_CXX='`$ECHO \"$lt_prog_compiler_wl_CXX\" | $SED \"$delay_single_quote_subst\"`'\nlt_prog_compiler_static_CXX='`$ECHO \"$lt_prog_compiler_static_CXX\" | $SED \"$delay_single_quote_subst\"`'\nlt_cv_prog_compiler_c_o_CXX='`$ECHO \"$lt_cv_prog_compiler_c_o_CXX\" | $SED \"$delay_single_quote_subst\"`'\narchive_cmds_need_lc_CXX='`$ECHO \"$archive_cmds_need_lc_CXX\" | $SED \"$delay_single_quote_subst\"`'\nenable_shared_with_static_runtimes_CXX='`$ECHO \"$enable_shared_with_static_runtimes_CXX\" | $SED \"$delay_single_quote_subst\"`'\nexport_dynamic_flag_spec_CXX='`$ECHO \"$export_dynamic_flag_spec_CXX\" | $SED \"$delay_single_quote_subst\"`'\nwhole_archive_flag_spec_CXX='`$ECHO \"$whole_archive_flag_spec_CXX\" | $SED \"$delay_single_quote_subst\"`'\ncompiler_needs_object_CXX='`$ECHO \"$compiler_needs_object_CXX\" | $SED \"$delay_single_quote_subst\"`'\nold_archive_from_new_cmds_CXX='`$ECHO \"$old_archive_from_new_cmds_CXX\" | $SED \"$delay_single_quote_subst\"`'\nold_archive_from_expsyms_cmds_CXX='`$ECHO \"$old_archive_from_expsyms_cmds_CXX\" | $SED \"$delay_single_quote_subst\"`'\narchive_cmds_CXX='`$ECHO \"$archive_cmds_CXX\" | $SED \"$delay_single_quote_subst\"`'\narchive_expsym_cmds_CXX='`$ECHO \"$archive_expsym_cmds_CXX\" | $SED \"$delay_single_quote_subst\"`'\nmodule_cmds_CXX='`$ECHO \"$module_cmds_CXX\" | $SED \"$delay_single_quote_subst\"`'\nmodule_expsym_cmds_CXX='`$ECHO \"$module_expsym_cmds_CXX\" | $SED \"$delay_single_quote_subst\"`'\nwith_gnu_ld_CXX='`$ECHO \"$with_gnu_ld_CXX\" | $SED \"$delay_single_quote_subst\"`'\nallow_undefined_flag_CXX='`$ECHO \"$allow_undefined_flag_CXX\" | $SED \"$delay_single_quote_subst\"`'\nno_undefined_flag_CXX='`$ECHO \"$no_undefined_flag_CXX\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_libdir_flag_spec_CXX='`$ECHO \"$hardcode_libdir_flag_spec_CXX\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_libdir_separator_CXX='`$ECHO \"$hardcode_libdir_separator_CXX\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_direct_CXX='`$ECHO \"$hardcode_direct_CXX\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_direct_absolute_CXX='`$ECHO \"$hardcode_direct_absolute_CXX\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_minus_L_CXX='`$ECHO \"$hardcode_minus_L_CXX\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_shlibpath_var_CXX='`$ECHO \"$hardcode_shlibpath_var_CXX\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_automatic_CXX='`$ECHO \"$hardcode_automatic_CXX\" | $SED \"$delay_single_quote_subst\"`'\ninherit_rpath_CXX='`$ECHO \"$inherit_rpath_CXX\" | $SED \"$delay_single_quote_subst\"`'\nlink_all_deplibs_CXX='`$ECHO \"$link_all_deplibs_CXX\" | $SED \"$delay_single_quote_subst\"`'\nalways_export_symbols_CXX='`$ECHO \"$always_export_symbols_CXX\" | $SED \"$delay_single_quote_subst\"`'\nexport_symbols_cmds_CXX='`$ECHO \"$export_symbols_cmds_CXX\" | $SED \"$delay_single_quote_subst\"`'\nexclude_expsyms_CXX='`$ECHO \"$exclude_expsyms_CXX\" | $SED \"$delay_single_quote_subst\"`'\ninclude_expsyms_CXX='`$ECHO \"$include_expsyms_CXX\" | $SED \"$delay_single_quote_subst\"`'\nprelink_cmds_CXX='`$ECHO \"$prelink_cmds_CXX\" | $SED \"$delay_single_quote_subst\"`'\npostlink_cmds_CXX='`$ECHO \"$postlink_cmds_CXX\" | $SED \"$delay_single_quote_subst\"`'\nfile_list_spec_CXX='`$ECHO \"$file_list_spec_CXX\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_action_CXX='`$ECHO \"$hardcode_action_CXX\" | $SED \"$delay_single_quote_subst\"`'\ncompiler_lib_search_dirs_CXX='`$ECHO \"$compiler_lib_search_dirs_CXX\" | $SED \"$delay_single_quote_subst\"`'\npredep_objects_CXX='`$ECHO \"$predep_objects_CXX\" | $SED \"$delay_single_quote_subst\"`'\npostdep_objects_CXX='`$ECHO \"$postdep_objects_CXX\" | $SED \"$delay_single_quote_subst\"`'\npredeps_CXX='`$ECHO \"$predeps_CXX\" | $SED \"$delay_single_quote_subst\"`'\npostdeps_CXX='`$ECHO \"$postdeps_CXX\" | $SED \"$delay_single_quote_subst\"`'\ncompiler_lib_search_path_CXX='`$ECHO \"$compiler_lib_search_path_CXX\" | $SED \"$delay_single_quote_subst\"`'\n\nLTCC='$LTCC'\nLTCFLAGS='$LTCFLAGS'\ncompiler='$compiler_DEFAULT'\n\n# A function that is used when there is no print builtin or printf.\nfunc_fallback_echo ()\n{\n  eval 'cat <<_LTECHO_EOF\n\\$1\n_LTECHO_EOF'\n}\n\n# Quote evaled strings.\nfor var in SHELL \\\nECHO \\\nPATH_SEPARATOR \\\nSED \\\nGREP \\\nEGREP \\\nFGREP \\\nLD \\\nNM \\\nLN_S \\\nlt_SP2NL \\\nlt_NL2SP \\\nreload_flag \\\nOBJDUMP \\\ndeplibs_check_method \\\nfile_magic_cmd \\\nfile_magic_glob \\\nwant_nocaseglob \\\nDLLTOOL \\\nsharedlib_from_linklib_cmd \\\nAR \\\nAR_FLAGS \\\narchiver_list_spec \\\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 \\\nnm_file_list_spec \\\nlt_prog_compiler_no_builtin_flag \\\nlt_prog_compiler_pic \\\nlt_prog_compiler_wl \\\nlt_prog_compiler_static \\\nlt_cv_prog_compiler_c_o \\\nneed_locks \\\nMANIFEST_TOOL \\\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_separator \\\nexclude_expsyms \\\ninclude_expsyms \\\nfile_list_spec \\\nvariables_saved_for_relink \\\nlibname_spec \\\nlibrary_names_spec \\\nsoname_spec \\\ninstall_override_mode \\\nfinish_eval \\\nold_striplib \\\nstriplib \\\ncompiler_lib_search_dirs \\\npredep_objects \\\npostdep_objects \\\npredeps \\\npostdeps \\\ncompiler_lib_search_path \\\nLD_CXX \\\nreload_flag_CXX \\\ncompiler_CXX \\\nlt_prog_compiler_no_builtin_flag_CXX \\\nlt_prog_compiler_pic_CXX \\\nlt_prog_compiler_wl_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_separator_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 \\\\\\\\\"\"\\\\\\\\\\$\\$var\"\\\\\\\\\"\\` in\n    *[\\\\\\\\\\\\\\`\\\\\"\\\\\\$]*)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\`\\\\\\$ECHO \\\\\"\\\\\\$\\$var\\\\\" | \\\\\\$SED \\\\\"\\\\\\$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 \\\npostlink_cmds \\\npostinstall_cmds \\\npostuninstall_cmds \\\nfinish_cmds \\\nsys_lib_search_path_spec \\\nsys_lib_dlsearch_path_spec \\\nreload_cmds_CXX \\\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 \\\npostlink_cmds_CXX; do\n    case \\`eval \\\\\\\\\\$ECHO \\\\\\\\\"\"\\\\\\\\\\$\\$var\"\\\\\\\\\"\\` in\n    *[\\\\\\\\\\\\\\`\\\\\"\\\\\\$]*)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\`\\\\\\$ECHO \\\\\"\\\\\\$\\$var\\\\\" | \\\\\\$SED -e \\\\\"\\\\\\$double_quote_subst\\\\\" -e \\\\\"\\\\\\$sed_quote_subst\\\\\" -e \\\\\"\\\\\\$delay_variable_subst\\\\\"\\\\\\`\\\\\\\\\\\\\"\"\n      ;;\n    *)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\$\\$var\\\\\\\\\\\\\"\"\n      ;;\n    esac\ndone\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    \"depfiles\") CONFIG_COMMANDS=\"$CONFIG_COMMANDS depfiles\" ;;\n    \"libtool\") CONFIG_COMMANDS=\"$CONFIG_COMMANDS libtool\" ;;\n    \"config.h\") CONFIG_HEADERS=\"$CONFIG_HEADERS config.h\" ;;\n    \"Makefile\") CONFIG_FILES=\"$CONFIG_FILES Makefile\" ;;\n    \"snappy-stubs-public.h\") CONFIG_FILES=\"$CONFIG_FILES snappy-stubs-public.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= ac_tmp=\n  trap 'exit_status=$?\n  : \"${ac_tmp:=$tmp}\"\n  { test ! -d \"$ac_tmp\" || rm -fr \"$ac_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 -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\nac_tmp=$tmp\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 {' >\"$ac_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 >>\"\\$ac_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 >>\"\\$ac_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 < \"$ac_tmp/subs1.awk\" > \"$ac_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 sole $(srcdir),\n# ${srcdir} and @srcdir@ entries 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 ]*=[\t ]*/{\nh\ns///\ns/^/:/\ns/[\t ]*$/:/\ns/:\\$(srcdir):/:/g\ns/:\\${srcdir}:/:/g\ns/:@srcdir@:/:/g\ns/^:*//\ns/:*$//\nx\ns/\\(=[\t ]*\\).*/\\1/\nG\ns/\\n//\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 >\"$ac_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_tt=`sed -n \"/$ac_delim/p\" confdefs.h`\n  if test -z \"$ac_tt\"; 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=\"$ac_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 1 \"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 >\"$ac_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  ac_MKDIR_P=$MKDIR_P\n  case $MKDIR_P in\n  [\\\\/$]* | ?:[\\\\/]* ) ;;\n  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;\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\ns&@MKDIR_P@&$ac_MKDIR_P&;t t\n$ac_datarootdir_hack\n\"\neval sed \\\"\\$ac_sed_extra\\\" \"$ac_file_inputs\" | $AWK -f \"$ac_tmp/subs.awk\" \\\n  >$ac_tmp/out || 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' \"$ac_tmp/out\"`; test -n \"$ac_out\"; } &&\n  { ac_out=`sed -n '/^[\t ]*datarootdir[\t ]*:*=/p' \\\n      \"$ac_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 \"$ac_tmp/stdin\"\n  case $ac_file in\n  -) cat \"$ac_tmp/out\" && rm -f \"$ac_tmp/out\";;\n  *) rm -f \"$ac_file\" && mv \"$ac_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 \"$ac_tmp/defines.awk\"' \"$ac_file_inputs\"\n    } >\"$ac_tmp/config.h\" \\\n      || as_fn_error $? \"could not create $ac_file\" \"$LINENO\" 5\n    if diff \"$ac_file\" \"$ac_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 \"$ac_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 \"$ac_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_arg=\"$ac_file\"\n_am_stamp_count=1\nfor _am_header in $config_headers :; do\n  case $_am_header in\n    $_am_arg | $_am_arg:* )\n      break ;;\n    * )\n      _am_stamp_count=`expr $_am_stamp_count + 1` ;;\n  esac\ndone\necho \"timestamp for $_am_arg\" >`$as_dirname -- \"$_am_arg\" ||\n$as_expr X\"$_am_arg\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$_am_arg\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$_am_arg\" : 'X\\(//\\)$' \\| \\\n\t X\"$_am_arg\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$_am_arg\" |\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\"\" || {\n  # Autoconf 2.62 quotes --file arguments for eval, but not when files\n  # are listed without --file.  Let's play safe and only enable the eval\n  # if we detect the quoting.\n  case $CONFIG_FILES in\n  *\\'*) eval set x \"$CONFIG_FILES\" ;;\n  *)   set x $CONFIG_FILES ;;\n  esac\n  shift\n  for mf\n  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    # Grep'ing the whole file is not good either: AIX grep has a line\n    # limit of 2048, but all sed's we know have understand at least 4000.\n    if sed -n 's,^#.*generated by automake.*,X,p' \"$mf\" | grep X >/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\t 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\n  done\n}\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, 2009, 2010, 2011 Free Software\n#                 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# 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# Whether or not to optimize for fast installation.\nfast_install=$enable_fast_install\n\n# Shell to use when invoking shell scripts.\nSHELL=$lt_SHELL\n\n# An echo program that protects backslashes.\nECHO=$lt_ECHO\n\n# The PATH separator for the build system.\nPATH_SEPARATOR=$lt_PATH_SEPARATOR\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# convert \\$build file names to \\$host format.\nto_host_file_cmd=$lt_cv_to_host_file_cmd\n\n# convert \\$build files to toolchain format.\nto_tool_file_cmd=$lt_cv_to_tool_file_cmd\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# How to find potential files when deplibs_check_method = \"file_magic\".\nfile_magic_glob=$lt_file_magic_glob\n\n# Find potential files using nocaseglob when deplibs_check_method = \"file_magic\".\nwant_nocaseglob=$lt_want_nocaseglob\n\n# DLL creation program.\nDLLTOOL=$lt_DLLTOOL\n\n# Command to associate shared and link libraries.\nsharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd\n\n# The archiver.\nAR=$lt_AR\n\n# Flags to create an archive.\nAR_FLAGS=$lt_AR_FLAGS\n\n# How to feed a file listing to the archiver.\narchiver_list_spec=$lt_archiver_list_spec\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# Whether to use a lock for old archive extraction.\nlock_old_archive_extraction=$lock_old_archive_extraction\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# Specify filename containing input files for \\$NM.\nnm_file_list_spec=$lt_nm_file_list_spec\n\n# The root where to search for dependent libraries,and in which our libraries should be installed.\nlt_sysroot=$lt_sysroot\n\n# The name of the directory that contains temporary libtool files.\nobjdir=$objdir\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# Manifest tool.\nMANIFEST_TOOL=$lt_MANIFEST_TOOL\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# Permission mode override for installation of shared libraries.\ninstall_override_mode=$lt_install_override_mode\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# How to create reloadable object files.\nreload_flag=$lt_reload_flag\nreload_cmds=$lt_reload_cmds\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# Additional compiler flags for building library objects.\npic_flag=$lt_lt_prog_compiler_pic\n\n# How to pass a linker flag through the compiler.\nwl=$lt_lt_prog_compiler_wl\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# 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# 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# Commands necessary for finishing linking programs.\npostlink_cmds=$lt_postlink_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 '$q' \"$ltmain\" >> \"$cfgfile\" \\\n     || (rm -f \"$cfgfile\"; exit 1)\n\n  if test x\"$xsi_shell\" = xyes; then\n  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\\\nfunc_dirname ()\\\n{\\\n\\    case ${1} in\\\n\\      */*) func_dirname_result=\"${1%/*}${2}\" ;;\\\n\\      *  ) func_dirname_result=\"${3}\" ;;\\\n\\    esac\\\n} # Extended-shell func_dirname implementation' \"$cfgfile\" > $cfgfile.tmp \\\n  && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\ntest 0 -eq $? || _lt_function_replace_fail=:\n\n\n  sed -e '/^func_basename ()$/,/^} # func_basename /c\\\nfunc_basename ()\\\n{\\\n\\    func_basename_result=\"${1##*/}\"\\\n} # Extended-shell func_basename implementation' \"$cfgfile\" > $cfgfile.tmp \\\n  && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\ntest 0 -eq $? || _lt_function_replace_fail=:\n\n\n  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\\\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} # Extended-shell func_dirname_and_basename implementation' \"$cfgfile\" > $cfgfile.tmp \\\n  && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\ntest 0 -eq $? || _lt_function_replace_fail=:\n\n\n  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\\\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} # Extended-shell func_stripname implementation' \"$cfgfile\" > $cfgfile.tmp \\\n  && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\ntest 0 -eq $? || _lt_function_replace_fail=:\n\n\n  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\\\nfunc_split_long_opt ()\\\n{\\\n\\    func_split_long_opt_name=${1%%=*}\\\n\\    func_split_long_opt_arg=${1#*=}\\\n} # Extended-shell func_split_long_opt implementation' \"$cfgfile\" > $cfgfile.tmp \\\n  && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\ntest 0 -eq $? || _lt_function_replace_fail=:\n\n\n  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\\\nfunc_split_short_opt ()\\\n{\\\n\\    func_split_short_opt_arg=${1#??}\\\n\\    func_split_short_opt_name=${1%\"$func_split_short_opt_arg\"}\\\n} # Extended-shell func_split_short_opt implementation' \"$cfgfile\" > $cfgfile.tmp \\\n  && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\ntest 0 -eq $? || _lt_function_replace_fail=:\n\n\n  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\\\nfunc_lo2o ()\\\n{\\\n\\    case ${1} in\\\n\\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\\\n\\      *)    func_lo2o_result=${1} ;;\\\n\\    esac\\\n} # Extended-shell func_lo2o implementation' \"$cfgfile\" > $cfgfile.tmp \\\n  && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\ntest 0 -eq $? || _lt_function_replace_fail=:\n\n\n  sed -e '/^func_xform ()$/,/^} # func_xform /c\\\nfunc_xform ()\\\n{\\\n    func_xform_result=${1%.*}.lo\\\n} # Extended-shell func_xform implementation' \"$cfgfile\" > $cfgfile.tmp \\\n  && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\ntest 0 -eq $? || _lt_function_replace_fail=:\n\n\n  sed -e '/^func_arith ()$/,/^} # func_arith /c\\\nfunc_arith ()\\\n{\\\n    func_arith_result=$(( $* ))\\\n} # Extended-shell func_arith implementation' \"$cfgfile\" > $cfgfile.tmp \\\n  && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\ntest 0 -eq $? || _lt_function_replace_fail=:\n\n\n  sed -e '/^func_len ()$/,/^} # func_len /c\\\nfunc_len ()\\\n{\\\n    func_len_result=${#1}\\\n} # Extended-shell func_len implementation' \"$cfgfile\" > $cfgfile.tmp \\\n  && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\ntest 0 -eq $? || _lt_function_replace_fail=:\n\nfi\n\nif test x\"$lt_shell_append\" = xyes; then\n  sed -e '/^func_append ()$/,/^} # func_append /c\\\nfunc_append ()\\\n{\\\n    eval \"${1}+=\\\\${2}\"\\\n} # Extended-shell func_append implementation' \"$cfgfile\" > $cfgfile.tmp \\\n  && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\ntest 0 -eq $? || _lt_function_replace_fail=:\n\n\n  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\\\nfunc_append_quoted ()\\\n{\\\n\\    func_quote_for_eval \"${2}\"\\\n\\    eval \"${1}+=\\\\\\\\ \\\\$func_quote_for_eval_result\"\\\n} # Extended-shell func_append_quoted implementation' \"$cfgfile\" > $cfgfile.tmp \\\n  && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\ntest 0 -eq $? || _lt_function_replace_fail=:\n\n\n  # Save a `func_append' function call where possible by direct use of '+='\n  sed -e 's%func_append \\([a-zA-Z_]\\{1,\\}\\) \"%\\1+=\"%g' $cfgfile > $cfgfile.tmp \\\n    && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n      || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\n  test 0 -eq $? || _lt_function_replace_fail=:\nelse\n  # Save a `func_append' function call even when '+=' is not available\n  sed -e 's%func_append \\([a-zA-Z_]\\{1,\\}\\) \"%\\1=\"$\\1%g' $cfgfile > $cfgfile.tmp \\\n    && mv -f \"$cfgfile.tmp\" \"$cfgfile\" \\\n      || (rm -f \"$cfgfile\" && cp \"$cfgfile.tmp\" \"$cfgfile\" && rm -f \"$cfgfile.tmp\")\n  test 0 -eq $? || _lt_function_replace_fail=:\nfi\n\nif test x\"$_lt_function_replace_fail\" = x\":\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile\" >&5\n$as_echo \"$as_me: WARNING: Unable to substitute extended shell functions in $ofile\" >&2;}\nfi\n\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# How to create reloadable object files.\nreload_flag=$lt_reload_flag_CXX\nreload_cmds=$lt_reload_cmds_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# Additional compiler flags for building library objects.\npic_flag=$lt_lt_prog_compiler_pic_CXX\n\n# How to pass a linker flag through the compiler.\nwl=$lt_lt_prog_compiler_wl_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# 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# 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# Commands necessary for finishing linking programs.\npostlink_cmds=$lt_postlink_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 1\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": "deps/snappy-1.1.0/configure.ac",
    "content": "m4_define([snappy_major], [1])\nm4_define([snappy_minor], [1])\nm4_define([snappy_patchlevel], [0])\n\n# Libtool shared library interface versions (current:revision:age)\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\nm4_define([snappy_ltversion], [2:4:1])\n\nAC_INIT([snappy], [snappy_major.snappy_minor.snappy_patchlevel])\nAC_CONFIG_MACRO_DIR([m4])\n\n# These are flags passed to automake (though they look like gcc flags!)\nAM_INIT_AUTOMAKE([-Wall])\n\nLT_INIT\nAC_SUBST([LIBTOOL_DEPS])\nAC_PROG_CXX\nAC_LANG([C++])\nAC_C_BIGENDIAN\nAC_CHECK_HEADERS([stdint.h stddef.h sys/mman.h sys/resource.h windows.h byteswap.h sys/byteswap.h sys/endian.h sys/time.h])\n\n# Don't use AC_FUNC_MMAP, as it checks for mappings of already-mapped memory,\n# which we don't need (and does not exist on Windows).\nAC_CHECK_FUNC([mmap])\n\nGTEST_LIB_CHECK([], [true], [true # Ignore; we can live without it.])\n\nAC_ARG_WITH([gflags],\n  [AS_HELP_STRING(\n    [--with-gflags],\n    [use Google Flags package to enhance the unit test @<:@default=check@:>@])],\n    [],\n    [with_gflags=check])\n\nif test \"x$with_gflags\" != \"xno\"; then\n  PKG_CHECK_MODULES(\n    [gflags],\n    [libgflags],\n    [AC_DEFINE([HAVE_GFLAGS], [1], [Use the gflags package for command-line parsing.])],\n    [if test \"x$with_gflags\" != \"xcheck\"; then\n      AC_MSG_FAILURE([--with-gflags was given, but test for gflags failed])\n    fi])\nfi\n\n# See if we have __builtin_expect.\n# TODO: Use AC_CACHE.\nAC_MSG_CHECKING([if the compiler supports __builtin_expect])\n \nAC_TRY_COMPILE(, [\n    return __builtin_expect(1, 1) ? 1 : 0\n], [\n    snappy_have_builtin_expect=yes\n    AC_MSG_RESULT([yes])\n], [\n    snappy_have_builtin_expect=no\n    AC_MSG_RESULT([no])\n])\nif test x$snappy_have_builtin_expect = xyes ; then\n    AC_DEFINE([HAVE_BUILTIN_EXPECT], [1], [Define to 1 if the compiler supports __builtin_expect.])\nfi\n\n# See if we have working count-trailing-zeros intrinsics.\n# TODO: Use AC_CACHE.\nAC_MSG_CHECKING([if the compiler supports __builtin_ctzll])\n\nAC_TRY_COMPILE(, [\n    return (__builtin_ctzll(0x100000000LL) == 32) ? 1 : 0\n], [\n    snappy_have_builtin_ctz=yes\n    AC_MSG_RESULT([yes])\n], [\n    snappy_have_builtin_ctz=no\n    AC_MSG_RESULT([no])\n])\nif test x$snappy_have_builtin_ctz = xyes ; then\n    AC_DEFINE([HAVE_BUILTIN_CTZ], [1], [Define to 1 if the compiler supports __builtin_ctz and friends.])\nfi\n\n# Other compression libraries; the unit test can use these for comparison\n# if they are available. If they are not found, just ignore.\nUNITTEST_LIBS=\"\"\nAC_DEFUN([CHECK_EXT_COMPRESSION_LIB], [\n  AH_CHECK_LIB([$1])\n  AC_CHECK_LIB(\n    [$1],\n    [$2],\n    [\n      AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_LIB$1))\n      UNITTEST_LIBS=\"-l$1 $UNITTEST_LIBS\"\n    ],\n    [true]\n  )\n])\nCHECK_EXT_COMPRESSION_LIB([z], [zlibVersion])\nCHECK_EXT_COMPRESSION_LIB([lzo2], [lzo1x_1_15_compress])\nCHECK_EXT_COMPRESSION_LIB([lzf], [lzf_compress])\nCHECK_EXT_COMPRESSION_LIB([fastlz], [fastlz_compress])\nCHECK_EXT_COMPRESSION_LIB([quicklz], [qlz_compress])\nAC_SUBST([UNITTEST_LIBS])\n\n# These are used by snappy-stubs-public.h.in.\nif test \"$ac_cv_header_stdint_h\" = \"yes\"; then\n    AC_SUBST([ac_cv_have_stdint_h], [1])\nelse\n    AC_SUBST([ac_cv_have_stdint_h], [0])\nfi\nif test \"$ac_cv_header_stddef_h\" = \"yes\"; then\n    AC_SUBST([ac_cv_have_stddef_h], [1])\nelse\n    AC_SUBST([ac_cv_have_stddef_h], [0])\nfi\n\n# Export the version to snappy-stubs-public.h.\nSNAPPY_MAJOR=\"snappy_major\"\nSNAPPY_MINOR=\"snappy_minor\"\nSNAPPY_PATCHLEVEL=\"snappy_patchlevel\"\n\nAC_SUBST([SNAPPY_MAJOR])\nAC_SUBST([SNAPPY_MINOR])\nAC_SUBST([SNAPPY_PATCHLEVEL])\nAC_SUBST([SNAPPY_LTVERSION], snappy_ltversion)\n\nAC_CONFIG_HEADERS([config.h])\nAC_CONFIG_FILES([Makefile snappy-stubs-public.h])\nAC_OUTPUT\n"
  },
  {
    "path": "deps/snappy-1.1.0/depcomp",
    "content": "#! /bin/sh\n# depcomp - compile a program generating dependencies as side-effects\n\nscriptversion=2011-12-04.11; # UTC\n\n# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,\n# 2011 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, see <http://www.gnu.org/licenses/>.\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 outputting 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\ncygpath_u=\"cygpath -u -f -\"\nif test \"$depmode\" = msvcmsys; then\n   # This is just like msvisualcpp but w/o cygpath translation.\n   # Just convert the backslash-escaped backslashes to single forward\n   # slashes to satisfy depend.m4\n   cygpath_u='sed s,\\\\\\\\,/,g'\n   depmode=msvisualcpp\nfi\n\nif test \"$depmode\" = msvc7msys; then\n   # This is just like msvc7 but w/o cygpath translation.\n   # Just convert the backslash-escaped backslashes to single forward\n   # slashes to satisfy depend.m4\n   cygpath_u='sed s,\\\\\\\\,/,g'\n   depmode=msvc7\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## Unfortunately, FreeBSD c89 acceptance of flags depends upon\n## the command line argument order; so add the flags where they\n## appear in depend2.am.  Note that the slowdown incurred here\n## affects only configure: in makefiles, %FASTDEP% shortcuts this.\n  for arg\n  do\n    case $arg in\n    -c) set fnord \"$@\" -MT \"$object\" -MD -MP -MF \"$tmpdepfile\" \"$arg\" ;;\n    *)  set fnord \"$@\" \"$arg\" ;;\n    esac\n    shift # fnord\n    shift # $arg\n  done\n  \"$@\"\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.  hp depmode also adds that space, but also prefixes the VPATH\n## to the object.  Take care to not repeat it in the output.\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 \"s|.*$object$||\" -e '/:$/d' \\\n      | 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  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  if test \"$libtool\" = yes; then\n    tmpdepfile1=$dir$base.u\n    tmpdepfile2=$base.u\n    tmpdepfile3=$dir.libs/$base.u\n    \"$@\" -Wc,-M\n  else\n    tmpdepfile1=$dir$base.u\n    tmpdepfile2=$dir$base.u\n    tmpdepfile3=$dir$base.u\n    \"$@\" -M\n  fi\n  stat=$?\n\n  if test $stat -eq 0; then :\n  else\n    rm -f \"$tmpdepfile1\" \"$tmpdepfile2\" \"$tmpdepfile3\"\n    exit $stat\n  fi\n\n  for tmpdepfile in \"$tmpdepfile1\" \"$tmpdepfile2\" \"$tmpdepfile3\"\n  do\n    test -f \"$tmpdepfile\" && break\n  done\n  if test -f \"$tmpdepfile\"; then\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,^.*\\.[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    # 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\nhp2)\n  # The \"hp\" stanza above does not work with aCC (C++) and HP's ia64\n  # compilers, which have integrated preprocessors.  The correct option\n  # to use with these is +Maked; it writes dependencies to a file named\n  # 'foo.d', which lands next to the object file, wherever that\n  # happens to be.\n  # Much of this is similar to the tru64 case; see comments there.\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  if test \"$libtool\" = yes; then\n    tmpdepfile1=$dir$base.d\n    tmpdepfile2=$dir.libs/$base.d\n    \"$@\" -Wc,+Maked\n  else\n    tmpdepfile1=$dir$base.d\n    tmpdepfile2=$dir$base.d\n    \"$@\" +Maked\n  fi\n  stat=$?\n  if test $stat -eq 0; then :\n  else\n     rm -f \"$tmpdepfile1\" \"$tmpdepfile2\"\n     exit $stat\n  fi\n\n  for tmpdepfile in \"$tmpdepfile1\" \"$tmpdepfile2\"\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    # Add `dependent.h:' lines.\n    sed -ne '2,${\n\t       s/^ *//\n\t       s/ \\\\*$//\n\t       s/$/:/\n\t       p\n\t     }' \"$tmpdepfile\" >> \"$depfile\"\n  else\n    echo \"#dummy\" > \"$depfile\"\n  fi\n  rm -f \"$tmpdepfile\" \"$tmpdepfile2\"\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 mechanism 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 $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\nmsvc7)\n  if test \"$libtool\" = yes; then\n    showIncludes=-Wc,-showIncludes\n  else\n    showIncludes=-showIncludes\n  fi\n  \"$@\" $showIncludes > \"$tmpdepfile\"\n  stat=$?\n  grep -v '^Note: including file: ' \"$tmpdepfile\"\n  if test \"$stat\" = 0; then :\n  else\n    rm -f \"$tmpdepfile\"\n    exit $stat\n  fi\n  rm -f \"$depfile\"\n  echo \"$object : \\\\\" > \"$depfile\"\n  # The first sed program below extracts the file names and escapes\n  # backslashes for cygpath.  The second sed program outputs the file\n  # name when reading, but also accumulates all include files in the\n  # hold buffer in order to output them again at the end.  This only\n  # works with sed implementations that can handle large buffers.\n  sed < \"$tmpdepfile\" -n '\n/^Note: including file:  *\\(.*\\)/ {\n  s//\\1/\n  s/\\\\/\\\\\\\\/g\n  p\n}' | $cygpath_u | sort -u | sed -n '\ns/ /\\\\ /g\ns/\\(.*\\)/\t\\1 \\\\/p\ns/.\\(.*\\) \\\\/\\1:/\nH\n$ {\n  s/.*/\t/\n  G\n  p\n}' >> \"$depfile\"\n  rm -f \"$tmpdepfile\"\n  ;;\n\nmsvc7msys)\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\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 \"X$1\" != 'X--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 \"X$1\" != 'X--mode=compile'; do\n      shift\n    done\n    shift\n  fi\n  # X makedepend\n  shift\n  cleared=no eat=no\n  for arg\n  do\n    case $cleared in\n    no)\n      set \"\"; shift\n      cleared=yes ;;\n    esac\n    if test $eat = yes; then\n      eat=no\n      continue\n    fi\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    -arch)\n      eat=yes ;;\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  # makedepend may prepend the VPATH from the source file name to the object.\n  # No need to regex-escape $object, excess matching of '.' is harmless.\n  sed \"s|^.*\\($object *:\\)|\\1|\" \"$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 \"X$1\" != 'X--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.\n  \"$@\" || exit $?\n\n  # Remove the call to Libtool.\n  if test \"$libtool\" = yes; then\n    while test \"X$1\" != 'X--mode=compile'; do\n      shift\n    done\n    shift\n  fi\n\n  IFS=\" \"\n  for arg\n  do\n    case \"$arg\" in\n    -o)\n      shift\n      ;;\n    $object)\n      shift\n      ;;\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 2>/dev/null |\n  sed -n '/^#line [0-9][0-9]* \"\\([^\"]*\\)\"/ s::\\1:p' | $cygpath_u | sort -u > \"$tmpdepfile\"\n  rm -f \"$depfile\"\n  echo \"$object : \\\\\" > \"$depfile\"\n  sed < \"$tmpdepfile\" -n -e 's% %\\\\ %g' -e '/^\\(.*\\)$/ s::\t\\1 \\\\:p' >> \"$depfile\"\n  echo \"\t\" >> \"$depfile\"\n  sed < \"$tmpdepfile\" -n -e 's% %\\\\ %g' -e '/^\\(.*\\)$/ s::\\1\\::p' >> \"$depfile\"\n  rm -f \"$tmpdepfile\"\n  ;;\n\nmsvcmsys)\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\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-time-zone: \"UTC\"\n# time-stamp-end: \"; # UTC\"\n# End:\n"
  },
  {
    "path": "deps/snappy-1.1.0/format_description.txt",
    "content": "Snappy compressed format description\nLast revised: 2011-10-05\n\n\nThis is not a formal specification, but should suffice to explain most\nrelevant parts of how the Snappy format works. It is originally based on\ntext by Zeev Tarantov.\n\nSnappy is a LZ77-type compressor with a fixed, byte-oriented encoding.\nThere is no entropy encoder backend nor framing layer -- the latter is\nassumed to be handled by other parts of the system.\n\nThis document only describes the format, not how the Snappy compressor nor\ndecompressor actually works. The correctness of the decompressor should not\ndepend on implementation details of the compressor, and vice versa.\n\n\n1. Preamble\n\nThe stream starts with the uncompressed length (up to a maximum of 2^32 - 1),\nstored as a little-endian varint. Varints consist of a series of bytes,\nwhere the lower 7 bits are data and the upper bit is set iff there are\nmore bytes to be read. In other words, an uncompressed length of 64 would\nbe stored as 0x40, and an uncompressed length of 2097150 (0x1FFFFE)\nwould be stored as 0xFE 0xFF 0x7F.\n\n\n2. The compressed stream itself\n\nThere are two types of elements in a Snappy stream: Literals and\ncopies (backreferences). There is no restriction on the order of elements,\nexcept that the stream naturally cannot start with a copy. (Having\ntwo literals in a row is never optimal from a compression point of\nview, but nevertheless fully permitted.) Each element starts with a tag byte,\nand the lower two bits of this tag byte signal what type of element will\nfollow:\n\n  00: Literal\n  01: Copy with 1-byte offset\n  10: Copy with 2-byte offset\n  11: Copy with 4-byte offset\n\nThe interpretation of the upper six bits are element-dependent.\n\n\n2.1. Literals (00)\n\nLiterals are uncompressed data stored directly in the byte stream.\nThe literal length is stored differently depending on the length\nof the literal:\n\n - For literals up to and including 60 bytes in length, the upper\n   six bits of the tag byte contain (len-1). The literal follows\n   immediately thereafter in the bytestream.\n - For longer literals, the (len-1) value is stored after the tag byte,\n   little-endian. The upper six bits of the tag byte describe how\n   many bytes are used for the length; 60, 61, 62 or 63 for\n   1-4 bytes, respectively. The literal itself follows after the\n   length.\n\n\n2.2. Copies\n\nCopies are references back into previous decompressed data, telling\nthe decompressor to reuse data it has previously decoded.\nThey encode two values: The _offset_, saying how many bytes back\nfrom the current position to read, and the _length_, how many bytes\nto copy. Offsets of zero can be encoded, but are not legal;\nsimilarly, it is possible to encode backreferences that would\ngo past the end of the block (offset > current decompressed position),\nwhich is also nonsensical and thus not allowed.\n\nAs in most LZ77-based compressors, the length can be larger than the offset,\nyielding a form of run-length encoding (RLE). For instance,\n\"xababab\" could be encoded as\n\n  <literal: \"xab\"> <copy: offset=2 length=4>\n\nNote that since the current Snappy compressor works in 32 kB\nblocks and does not do matching across blocks, it will never produce\na bitstream with offsets larger than about 32768. However, the\ndecompressor should not rely on this, as it may change in the future.\n\nThere are several different kinds of copy elements, depending on\nthe amount of bytes to be copied (length), and how far back the\ndata to be copied is (offset).\n\n\n2.2.1. Copy with 1-byte offset (01)\n\nThese elements can encode lengths between [4..11] bytes and offsets\nbetween [0..2047] bytes. (len-4) occupies three bits and is stored\nin bits [2..4] of the tag byte. The offset occupies 11 bits, of which the\nupper three are stored in the upper three bits ([5..7]) of the tag byte,\nand the lower eight are stored in a byte following the tag byte.\n\n\n2.2.2. Copy with 2-byte offset (10)\n\nThese elements can encode lengths between [1..64] and offsets from\n[0..65535]. (len-1) occupies six bits and is stored in the upper\nsix bits ([2..7]) of the tag byte. The offset is stored as a\nlittle-endian 16-bit integer in the two bytes following the tag byte.\n\n\n2.2.3. Copy with 4-byte offset (11)\n\nThese are like the copies with 2-byte offsets (see previous subsection),\nexcept that the offset is stored as a 32-bit integer instead of a\n16-bit integer (and thus will occupy four bytes).\n"
  },
  {
    "path": "deps/snappy-1.1.0/framing_format.txt",
    "content": "Snappy framing format description\nLast revised: 2013-01-05\n\nThis format decribes a framing format for Snappy, allowing compressing to\nfiles or streams that can then more easily be decompressed without having\nto hold the entire stream in memory. It also provides data checksums to\nhelp verify integrity. It does not provide metadata checksums, so it does\nnot protect against e.g. all forms of truncations.\n\nImplementation of the framing format is optional for Snappy compressors and\ndecompressor; it is not part of the Snappy core specification.\n\n\n1. General structure\n\nThe file consists solely of chunks, lying back-to-back with no padding\nin between. Each chunk consists first a single byte of chunk identifier,\nthen a three-byte little-endian length of the chunk in bytes (from 0 to\n16777215, inclusive), and then the data if any. The four bytes of chunk\nheader is not counted in the data length.\n\nThe different chunk types are listed below. The first chunk must always\nbe the stream identifier chunk (see section 4.1, below). The stream\nends when the file ends -- there is no explicit end-of-file marker.\n\n\n2. File type identification\n\nThe following identifiers for this format are recommended where appropriate.\nHowever, note that none have been registered officially, so this is only to\nbe taken as a guideline. We use \"Snappy framed\" to distinguish between this\nformat and raw Snappy data.\n\n  File extension:         .sz\n  MIME type:              application/x-snappy-framed\n  HTTP Content-Encoding:  x-snappy-framed\n\n\n3. Checksum format\n\nSome chunks have data protected by a checksum (the ones that do will say so\nexplicitly). The checksums are always masked CRC-32Cs.\n\nA description of CRC-32C can be found in RFC 3720, section 12.1, with\nexamples in section B.4.\n\nChecksums are not stored directly, but masked, as checksumming data and\nthen its own checksum can be problematic. The masking is the same as used\nin Apache Hadoop: Rotate the checksum by 15 bits, then add the constant\n0xa282ead8 (using wraparound as normal for unsigned integers). This is\nequivalent to the following C code:\n\n  uint32_t mask_checksum(uint32_t x) {\n    return ((x >> 15) | (x << 17)) + 0xa282ead8;\n  }\n\nNote that the masking is reversible.\n\nThe checksum is always stored as a four bytes long integer, in little-endian.\n\n\n4. Chunk types\n\nThe currently supported chunk types are described below. The list may\nbe extended in the future.\n\n\n4.1. Stream identifier (chunk type 0xff)\n\nThe stream identifier is always the first element in the stream.\nIt is exactly six bytes long and contains \"sNaPpY\" in ASCII. This means that\na valid Snappy framed stream always starts with the bytes\n\n  0xff 0x06 0x00 0x00 0x73 0x4e 0x61 0x50 0x70 0x59\n\nThe stream identifier chunk can come multiple times in the stream besides\nthe first; if such a chunk shows up, it should simply be ignored, assuming\nit has the right length and contents. This allows for easy concatenation of\ncompressed files without the need for re-framing.\n\n\n4.2. Compressed data (chunk type 0x00)\n\nCompressed data chunks contain a normal Snappy compressed bitstream;\nsee the compressed format specification. The compressed data is preceded by\nthe CRC-32C (see section 3) of the _uncompressed_ data.\n\nNote that the data portion of the chunk, i.e., the compressed contents,\ncan be at most 16777211 bytes (2^24 - 1, minus the checksum).\nHowever, we place an additional restriction that the uncompressed data\nin a chunk must be no longer than 65536 bytes. This allows consumers to\neasily use small fixed-size buffers.\n\n\n4.3. Uncompressed data (chunk type 0x01)\n\nUncompressed data chunks allow a compressor to send uncompressed,\nraw data; this is useful if, for instance, uncompressible or\nnear-incompressible data is detected, and faster decompression is desired.\n\nAs in the compressed chunks, the data is preceded by its own masked\nCRC-32C (see section 3).\n\nAn uncompressed data chunk, like compressed data chunks, should contain\nno more than 65536 data bytes, so the maximum legal chunk length with the\nchecksum is 65540.\n\n\n4.4. Reserved unskippable chunks (chunk types 0x02-0x7f)\n\nThese are reserved for future expansion. A decoder that sees such a chunk\nshould immediately return an error, as it must assume it cannot decode the\nstream correctly.\n\nFuture versions of this specification may define meanings for these chunks.\n\n\n4.5. Reserved skippable chunks (chunk types 0x80-0xfe)\n\nThese are also reserved for future expansion, but unlike the chunks\ndescribed in 4.4, a decoder seeing these must skip them and continue\ndecoding.\n\nFuture versions of this specification may define meanings for these chunks.\n"
  },
  {
    "path": "deps/snappy-1.1.0/install-sh",
    "content": "#!/bin/sh\n# install - install a program, script, or datafile\n\nscriptversion=2011-01-19.21; # UTC\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.\n\nnl='\n'\nIFS=\" \"\"\t$nl\"\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-}\nif test -z \"$doit\"; then\n  doit_exec=exec\nelse\n  doit_exec=$doit\nfi\n\n# Put in absolute file names if you don't have them in your path;\n# or use environment vars.\n\nchgrpprog=${CHGRPPROG-chgrp}\nchmodprog=${CHMODPROG-chmod}\nchownprog=${CHOWNPROG-chown}\ncmpprog=${CMPPROG-cmp}\ncpprog=${CPPROG-cp}\nmkdirprog=${MKDIRPROG-mkdir}\nmvprog=${MVPROG-mv}\nrmprog=${RMPROG-rm}\nstripprog=${STRIPPROG-strip}\n\nposix_glob='?'\ninitialize_posix_glob='\n  test \"$posix_glob\" != \"?\" || {\n    if (set -f) 2>/dev/null; then\n      posix_glob=\n    else\n      posix_glob=:\n    fi\n  }\n'\n\nposix_mkdir=\n\n# Desired mode of installed file.\nmode=0755\n\nchgrpcmd=\nchmodcmd=$chmodprog\nchowncmd=\nmvcmd=$mvprog\nrmcmd=\"$rmprog -f\"\nstripcmd=\n\nsrc=\ndst=\ndir_arg=\ndst_arg=\n\ncopy_on_change=false\nno_target_directory=\n\nusage=\"\\\nUsage: $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     --help     display this help and exit.\n     --version  display version info and exit.\n\n  -c            (ignored)\n  -C            install only if different (preserve the last data modification time)\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\nEnvironment variables override the default commands:\n  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG\n  RMPROG STRIPPROG\n\"\n\nwhile test $# -ne 0; do\n  case $1 in\n    -c) ;;\n\n    -C) copy_on_change=true;;\n\n    -d) dir_arg=true;;\n\n    -g) chgrpcmd=\"$chgrpprog $2\"\n\tshift;;\n\n    --help) echo \"$usage\"; exit $?;;\n\n    -m) mode=$2\n\tcase $mode in\n\t  *' '* | *'\t'* | *'\n'*\t  | *'*'* | *'?'* | *'['*)\n\t    echo \"$0: invalid mode: $mode\" >&2\n\t    exit 1;;\n\tesac\n\tshift;;\n\n    -o) chowncmd=\"$chownprog $2\"\n\tshift;;\n\n    -s) stripcmd=$stripprog;;\n\n    -t) dst_arg=$2\n\t# Protect names problematic for `test' and other utilities.\n\tcase $dst_arg in\n\t  -* | [=\\(\\)!]) dst_arg=./$dst_arg;;\n\tesac\n\tshift;;\n\n    -T) no_target_directory=true;;\n\n    --version) echo \"$0 $scriptversion\"; exit $?;;\n\n    --)\tshift\n\tbreak;;\n\n    -*)\techo \"$0: invalid option: $1\" >&2\n\texit 1;;\n\n    *)  break;;\n  esac\n  shift\ndone\n\nif test $# -ne 0 && test -z \"$dir_arg$dst_arg\"; then\n  # When -d is used, all remaining arguments are directories to create.\n  # When -t is used, the destination is already specified.\n  # Otherwise, the last argument is the destination.  Remove it from $@.\n  for arg\n  do\n    if test -n \"$dst_arg\"; then\n      # $@ is not empty: it contains at least $arg.\n      set fnord \"$@\" \"$dst_arg\"\n      shift # fnord\n    fi\n    shift # arg\n    dst_arg=$arg\n    # Protect names problematic for `test' and other utilities.\n    case $dst_arg in\n      -* | [=\\(\\)!]) dst_arg=./$dst_arg;;\n    esac\n  done\nfi\n\nif test $# -eq 0; 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\nif test -z \"$dir_arg\"; then\n  do_exit='(exit $ret); exit $ret'\n  trap \"ret=129; $do_exit\" 1\n  trap \"ret=130; $do_exit\" 2\n  trap \"ret=141; $do_exit\" 13\n  trap \"ret=143; $do_exit\" 15\n\n  # Set umask so as not to create temps with too-generous modes.\n  # However, 'strip' requires both read and write access to temps.\n  case $mode in\n    # Optimize common cases.\n    *644) cp_umask=133;;\n    *755) cp_umask=22;;\n\n    *[0-7])\n      if test -z \"$stripcmd\"; then\n\tu_plus_rw=\n      else\n\tu_plus_rw='% 200'\n      fi\n      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;\n    *)\n      if test -z \"$stripcmd\"; then\n\tu_plus_rw=\n      else\n\tu_plus_rw=,u+rw\n      fi\n      cp_umask=$mode$u_plus_rw;;\n  esac\nfi\n\nfor src\ndo\n  # Protect names problematic for `test' and other utilities.\n  case $src in\n    -* | [=\\(\\)!]) src=./$src;;\n  esac\n\n  if test -n \"$dir_arg\"; then\n    dst=$src\n    dstdir=$dst\n    test -d \"$dstdir\"\n    dstdir_status=$?\n  else\n\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 \"$dst_arg\"; then\n      echo \"$0: no destination specified.\" >&2\n      exit 1\n    fi\n    dst=$dst_arg\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: $dst_arg: Is a directory\" >&2\n\texit 1\n      fi\n      dstdir=$dst\n      dst=$dstdir/`basename \"$src\"`\n      dstdir_status=0\n    else\n      # Prefer dirname, but fall back on a substitute if dirname fails.\n      dstdir=`\n\t(dirname \"$dst\") 2>/dev/null ||\n\texpr X\"$dst\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t     X\"$dst\" : 'X\\(//\\)[^/]' \\| \\\n\t     X\"$dst\" : 'X\\(//\\)$' \\| \\\n\t     X\"$dst\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n\techo X\"$dst\" |\n\t    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t\t   s//\\1/\n\t\t   q\n\t\t }\n\t\t /^X\\(\\/\\/\\)[^/].*/{\n\t\t   s//\\1/\n\t\t   q\n\t\t }\n\t\t /^X\\(\\/\\/\\)$/{\n\t\t   s//\\1/\n\t\t   q\n\t\t }\n\t\t /^X\\(\\/\\).*/{\n\t\t   s//\\1/\n\t\t   q\n\t\t }\n\t\t s/.*/./; q'\n      `\n\n      test -d \"$dstdir\"\n      dstdir_status=$?\n    fi\n  fi\n\n  obsolete_mkdir_used=false\n\n  if test $dstdir_status != 0; then\n    case $posix_mkdir in\n      '')\n\t# Create intermediate dirs using mode 755 as modified by the umask.\n\t# This is like FreeBSD 'install' as of 1997-10-28.\n\tumask=`umask`\n\tcase $stripcmd.$umask in\n\t  # Optimize common cases.\n\t  *[2367][2367]) mkdir_umask=$umask;;\n\t  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;\n\n\t  *[0-7])\n\t    mkdir_umask=`expr $umask + 22 \\\n\t      - $umask % 100 % 40 + $umask % 20 \\\n\t      - $umask % 10 % 4 + $umask % 2\n\t    `;;\n\t  *) mkdir_umask=$umask,go-w;;\n\tesac\n\n\t# With -d, create the new directory with the user-specified mode.\n\t# Otherwise, rely on $mkdir_umask.\n\tif test -n \"$dir_arg\"; then\n\t  mkdir_mode=-m$mode\n\telse\n\t  mkdir_mode=\n\tfi\n\n\tposix_mkdir=false\n\tcase $umask in\n\t  *[123567][0-7][0-7])\n\t    # POSIX mkdir -p sets u+wx bits regardless of umask, which\n\t    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.\n\t    ;;\n\t  *)\n\t    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$\n\t    trap 'ret=$?; rmdir \"$tmpdir/d\" \"$tmpdir\" 2>/dev/null; exit $ret' 0\n\n\t    if (umask $mkdir_umask &&\n\t\texec $mkdirprog $mkdir_mode -p -- \"$tmpdir/d\") >/dev/null 2>&1\n\t    then\n\t      if test -z \"$dir_arg\" || {\n\t\t   # Check for POSIX incompatibilities with -m.\n\t\t   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or\n\t\t   # other-writeable bit of parent directory when it shouldn't.\n\t\t   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.\n\t\t   ls_ld_tmpdir=`ls -ld \"$tmpdir\"`\n\t\t   case $ls_ld_tmpdir in\n\t\t     d????-?r-*) different_mode=700;;\n\t\t     d????-?--*) different_mode=755;;\n\t\t     *) false;;\n\t\t   esac &&\n\t\t   $mkdirprog -m$different_mode -p -- \"$tmpdir\" && {\n\t\t     ls_ld_tmpdir_1=`ls -ld \"$tmpdir\"`\n\t\t     test \"$ls_ld_tmpdir\" = \"$ls_ld_tmpdir_1\"\n\t\t   }\n\t\t }\n\t      then posix_mkdir=:\n\t      fi\n\t      rmdir \"$tmpdir/d\" \"$tmpdir\"\n\t    else\n\t      # Remove any dirs left behind by ancient mkdir implementations.\n\t      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null\n\t    fi\n\t    trap '' 0;;\n\tesac;;\n    esac\n\n    if\n      $posix_mkdir && (\n\tumask $mkdir_umask &&\n\t$doit_exec $mkdirprog $mkdir_mode -p -- \"$dstdir\"\n      )\n    then :\n    else\n\n      # The umask is ridiculous, or mkdir does not conform to POSIX,\n      # or it failed possibly due to a race condition.  Create the\n      # directory the slow way, step by step, checking for races as we go.\n\n      case $dstdir in\n\t/*) prefix='/';;\n\t[-=\\(\\)!]*) prefix='./';;\n\t*)  prefix='';;\n      esac\n\n      eval \"$initialize_posix_glob\"\n\n      oIFS=$IFS\n      IFS=/\n      $posix_glob set -f\n      set fnord $dstdir\n      shift\n      $posix_glob set +f\n      IFS=$oIFS\n\n      prefixes=\n\n      for d\n      do\n\ttest X\"$d\" = X && continue\n\n\tprefix=$prefix$d\n\tif test -d \"$prefix\"; then\n\t  prefixes=\n\telse\n\t  if $posix_mkdir; then\n\t    (umask=$mkdir_umask &&\n\t     $doit_exec $mkdirprog $mkdir_mode -p -- \"$dstdir\") && break\n\t    # Don't fail if two instances are running concurrently.\n\t    test -d \"$prefix\" || exit 1\n\t  else\n\t    case $prefix in\n\t      *\\'*) qprefix=`echo \"$prefix\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"`;;\n\t      *) qprefix=$prefix;;\n\t    esac\n\t    prefixes=\"$prefixes '$qprefix'\"\n\t  fi\n\tfi\n\tprefix=$prefix/\n      done\n\n      if test -n \"$prefixes\"; then\n\t# Don't fail if two instances are running concurrently.\n\t(umask $mkdir_umask &&\n\t eval \"\\$doit_exec \\$mkdirprog $prefixes\") ||\n\t  test -d \"$dstdir\" || exit 1\n\tobsolete_mkdir_used=true\n      fi\n    fi\n  fi\n\n  if test -n \"$dir_arg\"; then\n    { test -z \"$chowncmd\" || $doit $chowncmd \"$dst\"; } &&\n    { test -z \"$chgrpcmd\" || $doit $chgrpcmd \"$dst\"; } &&\n    { test \"$obsolete_mkdir_used$chowncmd$chgrpcmd\" = false ||\n      test -z \"$chmodcmd\" || $doit $chmodcmd $mode \"$dst\"; } || exit 1\n  else\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\n    # Copy the file name to the temp name.\n    (umask $cp_umask && $doit_exec $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 $mode \"$dsttmp\"; } &&\n\n    # If -C, don't bother to copy if it wouldn't change the file.\n    if $copy_on_change &&\n       old=`LC_ALL=C ls -dlL \"$dst\"\t2>/dev/null` &&\n       new=`LC_ALL=C ls -dlL \"$dsttmp\"\t2>/dev/null` &&\n\n       eval \"$initialize_posix_glob\" &&\n       $posix_glob set -f &&\n       set X $old && old=:$2:$4:$5:$6 &&\n       set X $new && new=:$2:$4:$5:$6 &&\n       $posix_glob set +f &&\n\n       test \"$old\" = \"$new\" &&\n       $cmpprog \"$dst\" \"$dsttmp\" >/dev/null 2>&1\n    then\n      rm -f \"$dsttmp\"\n    else\n      # Rename the file to the real destination.\n      $doit $mvcmd -f \"$dsttmp\" \"$dst\" 2>/dev/null ||\n\n      # The rename failed, perhaps because mv can't rename something else\n      # to itself, or perhaps because mv is so ancient that it does not\n      # 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  test ! -f \"$dst\" ||\n\t  $doit $rmcmd -f \"$dst\" 2>/dev/null ||\n\t  { $doit $mvcmd -f \"$dst\" \"$rmtmp\" 2>/dev/null &&\n\t    { $doit $rmcmd -f \"$rmtmp\" 2>/dev/null; :; }\n\t  } ||\n\t  { echo \"$0: cannot unlink or rename $dst\" >&2\n\t    (exit 1); exit 1\n\t  }\n\t} &&\n\n\t# Now rename the file to the real destination.\n\t$doit $mvcmd \"$dsttmp\" \"$dst\"\n      }\n    fi || exit 1\n\n    trap '' 0\n  fi\ndone\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-time-zone: \"UTC\"\n# time-stamp-end: \"; # UTC\"\n# End:\n"
  },
  {
    "path": "deps/snappy-1.1.0/ltmain.sh",
    "content": "\n# libtool (GNU libtool) 2.4.2\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,\n# 2007, 2008, 2009, 2010, 2011 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#       --no-quiet, --no-silent\n#                            print informational messages (default)\n#       --no-warn            don't display warning messages\n#       --tag=TAG            use configuration variables from tag TAG\n#   -v, --verbose            print more informational messages than default\n#       --no-verbose         don't print the extra informational messages\n#       --version            print version information\n#   -h, --help, --help-all   print short, long, or detailed 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.  When passed as first option,\n# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.\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(GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1\n#         automake:\t$automake_version\n#         autoconf:\t$autoconf_version\n#\n# Report bugs to <bug-libtool@gnu.org>.\n# GNU libtool home page: <http://www.gnu.org/software/libtool/>.\n# General help using GNU software: <http://www.gnu.org/gethelp/>.\n\nPROGRAM=libtool\nPACKAGE=libtool\nVERSION=\"2.4.2 Debian-2.4.2-1ubuntu1\"\nTIMESTAMP=\"\"\npackage_revision=1.3337\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# A function that is used when there is no print builtin or printf.\nfunc_fallback_echo ()\n{\n  eval 'cat <<_LTECHO_EOF\n$1\n_LTECHO_EOF'\n}\n\n# NLS nuisances: We save the old values to restore during execute mode.\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\nLC_ALL=C\nLANGUAGE=C\nexport LANGUAGE LC_ALL\n\n$lt_unset CDPATH\n\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\n\n: ${CP=\"cp -f\"}\ntest \"${ECHO+set}\" = set || ECHO=${as_echo-'printf %s\\n'}\n: ${MAKE=\"make\"}\n: ${MKDIR=\"mkdir\"}\n: ${MV=\"mv -f\"}\n: ${RM=\"rm -f\"}\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 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    func_dirname_result=`$ECHO \"${1}\" | $SED \"$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_dirname may be replaced by extended shell implementation\n\n\n# func_basename file\nfunc_basename ()\n{\n    func_basename_result=`$ECHO \"${1}\" | $SED \"$basename\"`\n} # func_basename may be replaced by extended shell implementation\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    # Extract subdirectory from the argument.\n    func_dirname_result=`$ECHO \"${1}\" | $SED -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 \"${1}\" | $SED -e \"$basename\"`\n} # func_dirname_and_basename may be replaced by extended shell implementation\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 \"${3}\" | $SED \"s%^${1}%%; s%\\\\\\\\${2}\\$%%\"`;;\n      *)  func_stripname_result=`$ECHO \"${3}\" | $SED \"s%^${1}%%; s%${2}\\$%%\"`;;\n    esac\n} # func_stripname may be replaced by extended shell implementation\n\n\n# These SED scripts presuppose an absolute path with a trailing slash.\npathcar='s,^/\\([^/]*\\).*$,\\1,'\npathcdr='s,^/[^/]*,,'\nremovedotparts=':dotsl\n\t\ts@/\\./@/@g\n\t\tt dotsl\n\t\ts,/\\.$,/,'\ncollapseslashes='s@/\\{1,\\}@/@g'\nfinalslash='s,/*$,/,'\n\n# func_normal_abspath PATH\n# Remove doubled-up and trailing slashes, \".\" path components,\n# and cancel out any \"..\" path components in PATH after making\n# it an absolute path.\n#             value returned in \"$func_normal_abspath_result\"\nfunc_normal_abspath ()\n{\n  # Start from root dir and reassemble the path.\n  func_normal_abspath_result=\n  func_normal_abspath_tpath=$1\n  func_normal_abspath_altnamespace=\n  case $func_normal_abspath_tpath in\n    \"\")\n      # Empty path, that just means $cwd.\n      func_stripname '' '/' \"`pwd`\"\n      func_normal_abspath_result=$func_stripname_result\n      return\n    ;;\n    # The next three entries are used to spot a run of precisely\n    # two leading slashes without using negated character classes;\n    # we take advantage of case's first-match behaviour.\n    ///*)\n      # Unusual form of absolute path, do nothing.\n    ;;\n    //*)\n      # Not necessarily an ordinary path; POSIX reserves leading '//'\n      # and for example Cygwin uses it to access remote file shares\n      # over CIFS/SMB, so we conserve a leading double slash if found.\n      func_normal_abspath_altnamespace=/\n    ;;\n    /*)\n      # Absolute path, do nothing.\n    ;;\n    *)\n      # Relative path, prepend $cwd.\n      func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath\n    ;;\n  esac\n  # Cancel out all the simple stuff to save iterations.  We also want\n  # the path to end with a slash for ease of parsing, so make sure\n  # there is one (and only one) here.\n  func_normal_abspath_tpath=`$ECHO \"$func_normal_abspath_tpath\" | $SED \\\n        -e \"$removedotparts\" -e \"$collapseslashes\" -e \"$finalslash\"`\n  while :; do\n    # Processed it all yet?\n    if test \"$func_normal_abspath_tpath\" = / ; then\n      # If we ascended to the root using \"..\" the result may be empty now.\n      if test -z \"$func_normal_abspath_result\" ; then\n        func_normal_abspath_result=/\n      fi\n      break\n    fi\n    func_normal_abspath_tcomponent=`$ECHO \"$func_normal_abspath_tpath\" | $SED \\\n        -e \"$pathcar\"`\n    func_normal_abspath_tpath=`$ECHO \"$func_normal_abspath_tpath\" | $SED \\\n        -e \"$pathcdr\"`\n    # Figure out what to do with it\n    case $func_normal_abspath_tcomponent in\n      \"\")\n        # Trailing empty path component, ignore it.\n      ;;\n      ..)\n        # Parent dir; strip last assembled component from result.\n        func_dirname \"$func_normal_abspath_result\"\n        func_normal_abspath_result=$func_dirname_result\n      ;;\n      *)\n        # Actual path component, append it.\n        func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent\n      ;;\n    esac\n  done\n  # Restore leading double-slash if one was found on entry.\n  func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result\n}\n\n# func_relative_path SRCDIR DSTDIR\n# generates a relative path from SRCDIR to DSTDIR, with a trailing\n# slash if non-empty, suitable for immediately appending a filename\n# without needing to append a separator.\n#             value returned in \"$func_relative_path_result\"\nfunc_relative_path ()\n{\n  func_relative_path_result=\n  func_normal_abspath \"$1\"\n  func_relative_path_tlibdir=$func_normal_abspath_result\n  func_normal_abspath \"$2\"\n  func_relative_path_tbindir=$func_normal_abspath_result\n\n  # Ascend the tree starting from libdir\n  while :; do\n    # check if we have found a prefix of bindir\n    case $func_relative_path_tbindir in\n      $func_relative_path_tlibdir)\n        # found an exact match\n        func_relative_path_tcancelled=\n        break\n        ;;\n      $func_relative_path_tlibdir*)\n        # found a matching prefix\n        func_stripname \"$func_relative_path_tlibdir\" '' \"$func_relative_path_tbindir\"\n        func_relative_path_tcancelled=$func_stripname_result\n        if test -z \"$func_relative_path_result\"; then\n          func_relative_path_result=.\n        fi\n        break\n        ;;\n      *)\n        func_dirname $func_relative_path_tlibdir\n        func_relative_path_tlibdir=${func_dirname_result}\n        if test \"x$func_relative_path_tlibdir\" = x ; then\n          # Have to descend all the way to the root!\n          func_relative_path_result=../$func_relative_path_result\n          func_relative_path_tcancelled=$func_relative_path_tbindir\n          break\n        fi\n        func_relative_path_result=../$func_relative_path_result\n        ;;\n    esac\n  done\n\n  # Now calculate path; take care to avoid doubling-up slashes.\n  func_stripname '' '/' \"$func_relative_path_result\"\n  func_relative_path_result=$func_stripname_result\n  func_stripname '/' '/' \"$func_relative_path_tcancelled\"\n  if test \"x$func_stripname_result\" != x ; then\n    func_relative_path_result=${func_relative_path_result}/${func_stripname_result}\n  fi\n\n  # Normalisation. If bindir is libdir, return empty string,\n  # else relative path ending with a slash; either way, target\n  # file name can be directly appended.\n  if test ! -z \"$func_relative_path_result\"; then\n    func_stripname './' '' \"$func_relative_path_result/\"\n    func_relative_path_result=$func_stripname_result\n  fi\n}\n\n# The name of this program:\nfunc_dirname_and_basename \"$progpath\"\nprogname=$func_basename_result\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=${PATH_SEPARATOR-:}\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# Sed substitution that turns a string into a regex matching for the\n# string literally.\nsed_make_literal_regex='s,[].[^$\\\\*\\/],\\\\&,g'\n\n# Sed substitution that converts a w32 file name or path\n# which contains forward slashes, into one that contains\n# (escaped) backslashes.  A very naive implementation.\nlt_sed_naive_backslashify='s|\\\\\\\\*|\\\\|g;s|/|\\\\|g;s|\\\\|\\\\\\\\|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: ${opt_mode+$opt_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_echo_all arg...\n# Invoke $ECHO with all args, space-separated.\nfunc_echo_all ()\n{\n    $ECHO \"$*\"\n}\n\n# func_error arg...\n# Echo program name prefixed message to standard error.\nfunc_error ()\n{\n    $ECHO \"$progname: ${opt_mode+$opt_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: ${opt_mode+$opt_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 \"$my_directory_path\" | $SED -e \"$dirname\"`\n      done\n      my_dir_list=`$ECHO \"$my_dir_list\" | $SED '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 \"$my_tmpdir\"\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 \"$1\" | $SED \"$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 \"$1\" | $SED \\\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# func_tr_sh\n# Turn $1 into a string suitable for a shell variable name.\n# Result is stored in $func_tr_sh_result.  All characters\n# not in the set a-zA-Z0-9_ are replaced with '_'. Further,\n# if $1 begins with a digit, a '_' is prepended as well.\nfunc_tr_sh ()\n{\n  case $1 in\n  [0-9]* | *[!a-zA-Z0-9_]*)\n    func_tr_sh_result=`$ECHO \"$1\" | $SED 's/^\\([0-9]\\)/_\\1/; s/[^a-zA-Z0-9_]/_/g'`\n    ;;\n  * )\n    func_tr_sh_result=$1\n    ;;\n  esac\n}\n\n\n# func_version\n# Echo version message to standard output and exit.\nfunc_version ()\n{\n    $opt_debug\n\n    $SED -n '/(C)/!b go\n\t:more\n\t/\\./!{\n\t  N\n\t  s/\\n# / /\n\t  b more\n\t}\n\t:go\n\t/^# '$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    $opt_debug\n\n    $SED -n '/^# Usage:/,/^#  *.*--help/ {\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 [NOEXIT]\n# Echo long help message to standard output and exit,\n# unless 'noexit' is passed as argument.\nfunc_help ()\n{\n    $opt_debug\n\n    $SED -n '/^# Usage:/,/# Report bugs to/ {\n\t:print\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-automake} --version) 2>/dev/null |$SED 1q`\"'/\n\ts/\\$autoconf_version/'\"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`\"'/\n\tp\n\td\n     }\n     /^# .* home page:/b print\n     /^# General help using/b print\n     ' < \"$progpath\"\n    ret=$?\n    if test -z \"$1\"; then\n      exit $ret\n    fi\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    $opt_debug\n\n    func_error \"missing argument for $1.\"\n    exit_cmd=exit\n}\n\n\n# func_split_short_opt shortopt\n# Set func_split_short_opt_name and func_split_short_opt_arg shell\n# variables after splitting SHORTOPT after the 2nd character.\nfunc_split_short_opt ()\n{\n    my_sed_short_opt='1s/^\\(..\\).*$/\\1/;q'\n    my_sed_short_rest='1s/^..\\(.*\\)$/\\1/;q'\n\n    func_split_short_opt_name=`$ECHO \"$1\" | $SED \"$my_sed_short_opt\"`\n    func_split_short_opt_arg=`$ECHO \"$1\" | $SED \"$my_sed_short_rest\"`\n} # func_split_short_opt may be replaced by extended shell implementation\n\n\n# func_split_long_opt longopt\n# Set func_split_long_opt_name and func_split_long_opt_arg shell\n# variables after splitting LONGOPT at the `=' sign.\nfunc_split_long_opt ()\n{\n    my_sed_long_opt='1s/^\\(--[^=]*\\)=.*/\\1/;q'\n    my_sed_long_arg='1s/^--[^=]*=//'\n\n    func_split_long_opt_name=`$ECHO \"$1\" | $SED \"$my_sed_long_opt\"`\n    func_split_long_opt_arg=`$ECHO \"$1\" | $SED \"$my_sed_long_arg\"`\n} # func_split_long_opt may be replaced by extended shell implementation\n\nexit_cmd=:\n\n\n\n\n\nmagic=\"%%%MAGIC variable%%%\"\nmagic_exe=\"%%%MAGIC EXE variable%%%\"\n\n# Global variables.\nnonopt=\npreserve_args=\nlo2o=\"s/\\\\.lo\\$/.${objext}/\"\no2lo=\"s/\\\\.${objext}\\$/.lo/\"\nextracted_archives=\nextracted_serial=0\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_append var value\n# Append VALUE to the end of shell variable VAR.\nfunc_append ()\n{\n    eval \"${1}=\\$${1}\\${2}\"\n} # func_append may be replaced by extended shell implementation\n\n# func_append_quoted var value\n# Quote VALUE and append to the end of shell variable VAR, separated\n# by a space.\nfunc_append_quoted ()\n{\n    func_quote_for_eval \"${2}\"\n    eval \"${1}=\\$${1}\\\\ \\$func_quote_for_eval_result\"\n} # func_append_quoted may be replaced by extended shell implementation\n\n\n# func_arith arithmetic-term...\nfunc_arith ()\n{\n    func_arith_result=`expr \"${@}\"`\n} # func_arith may be replaced by extended shell implementation\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} # func_len may be replaced by extended shell implementation\n\n\n# func_lo2o object\nfunc_lo2o ()\n{\n    func_lo2o_result=`$ECHO \"${1}\" | $SED \"$lo2o\"`\n} # func_lo2o may be replaced by extended shell implementation\n\n\n# func_xform libobj-or-source\nfunc_xform ()\n{\n    func_xform_result=`$ECHO \"${1}\" | $SED 's/\\.[^.]*$/.lo/'`\n} # func_xform may be replaced by extended shell implementation\n\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# 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# Shorthand for --mode=foo, only valid as the first argument\ncase $1 in\nclean|clea|cle|cl)\n  shift; set dummy --mode clean ${1+\"$@\"}; shift\n  ;;\ncompile|compil|compi|comp|com|co|c)\n  shift; set dummy --mode compile ${1+\"$@\"}; shift\n  ;;\nexecute|execut|execu|exec|exe|ex|e)\n  shift; set dummy --mode execute ${1+\"$@\"}; shift\n  ;;\nfinish|finis|fini|fin|fi|f)\n  shift; set dummy --mode finish ${1+\"$@\"}; shift\n  ;;\ninstall|instal|insta|inst|ins|in|i)\n  shift; set dummy --mode install ${1+\"$@\"}; shift\n  ;;\nlink|lin|li|l)\n  shift; set dummy --mode link ${1+\"$@\"}; shift\n  ;;\nuninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)\n  shift; set dummy --mode uninstall ${1+\"$@\"}; shift\n  ;;\nesac\n\n\n\n# Option defaults:\nopt_debug=:\nopt_dry_run=false\nopt_config=false\nopt_preserve_dup_deps=false\nopt_features=false\nopt_finish=false\nopt_help=false\nopt_help_all=false\nopt_silent=:\nopt_warning=:\nopt_verbose=:\nopt_silent=false\nopt_verbose=false\n\n\n# Parse options once, thoroughly.  This comes as soon as possible in the\n# script to make things like `--version' happen as quickly as we can.\n{\n  # this just eases exit handling\n  while test $# -gt 0; do\n    opt=\"$1\"\n    shift\n    case $opt in\n      --debug|-x)\topt_debug='set -x'\n\t\t\tfunc_echo \"enabling shell trace mode\"\n\t\t\t$opt_debug\n\t\t\t;;\n      --dry-run|--dryrun|-n)\n\t\t\topt_dry_run=:\n\t\t\t;;\n      --config)\n\t\t\topt_config=:\nfunc_config\n\t\t\t;;\n      --dlopen|-dlopen)\n\t\t\toptarg=\"$1\"\n\t\t\topt_dlopen=\"${opt_dlopen+$opt_dlopen\n}$optarg\"\n\t\t\tshift\n\t\t\t;;\n      --preserve-dup-deps)\n\t\t\topt_preserve_dup_deps=:\n\t\t\t;;\n      --features)\n\t\t\topt_features=:\nfunc_features\n\t\t\t;;\n      --finish)\n\t\t\topt_finish=:\nset dummy --mode finish ${1+\"$@\"}; shift\n\t\t\t;;\n      --help)\n\t\t\topt_help=:\n\t\t\t;;\n      --help-all)\n\t\t\topt_help_all=:\nopt_help=': help-all'\n\t\t\t;;\n      --mode)\n\t\t\ttest $# = 0 && func_missing_arg $opt && break\n\t\t\toptarg=\"$1\"\n\t\t\topt_mode=\"$optarg\"\ncase $optarg in\n  # Valid mode arguments:\n  clean|compile|execute|finish|install|link|relink|uninstall) ;;\n\n  # Catch anything else as an error\n  *) func_error \"invalid argument for $opt\"\n     exit_cmd=exit\n     break\n     ;;\nesac\n\t\t\tshift\n\t\t\t;;\n      --no-silent|--no-quiet)\n\t\t\topt_silent=false\nfunc_append preserve_args \" $opt\"\n\t\t\t;;\n      --no-warning|--no-warn)\n\t\t\topt_warning=false\nfunc_append preserve_args \" $opt\"\n\t\t\t;;\n      --no-verbose)\n\t\t\topt_verbose=false\nfunc_append preserve_args \" $opt\"\n\t\t\t;;\n      --silent|--quiet)\n\t\t\topt_silent=:\nfunc_append preserve_args \" $opt\"\n        opt_verbose=false\n\t\t\t;;\n      --verbose|-v)\n\t\t\topt_verbose=:\nfunc_append preserve_args \" $opt\"\nopt_silent=false\n\t\t\t;;\n      --tag)\n\t\t\ttest $# = 0 && func_missing_arg $opt && break\n\t\t\toptarg=\"$1\"\n\t\t\topt_tag=\"$optarg\"\nfunc_append preserve_args \" $opt $optarg\"\nfunc_enable_tag \"$optarg\"\n\t\t\tshift\n\t\t\t;;\n\n      -\\?|-h)\t\tfunc_usage\t\t\t\t;;\n      --help)\t\tfunc_help\t\t\t\t;;\n      --version)\tfunc_version\t\t\t\t;;\n\n      # Separate optargs to long options:\n      --*=*)\n\t\t\tfunc_split_long_opt \"$opt\"\n\t\t\tset dummy \"$func_split_long_opt_name\" \"$func_split_long_opt_arg\" ${1+\"$@\"}\n\t\t\tshift\n\t\t\t;;\n\n      # Separate non-argument short options:\n      -\\?*|-h*|-n*|-v*)\n\t\t\tfunc_split_short_opt \"$opt\"\n\t\t\tset dummy \"$func_split_short_opt_name\" \"-$func_split_short_opt_arg\" ${1+\"$@\"}\n\t\t\tshift\n\t\t\t;;\n\n      --)\t\tbreak\t\t\t\t\t;;\n      -*)\t\tfunc_fatal_help \"unrecognized option \\`$opt'\" ;;\n      *)\t\tset dummy \"$opt\" ${1+\"$@\"};\tshift; break  ;;\n    esac\n  done\n\n  # Validate options:\n\n  # save first non-option argument\n  if test \"$#\" -gt 0; then\n    nonopt=\"$opt\"\n    shift\n  fi\n\n  # preserve --debug\n  test \"$opt_debug\" = : || func_append preserve_args \" --debug\"\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_preserve_dup_deps\n      ;;\n  esac\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    # Darwin sucks\n    eval std_shrext=\\\"$shrext_cmds\\\"\n\n    # Only execute mode is allowed to have -dlopen flags.\n    if test -n \"$opt_dlopen\" && test \"$opt_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=$opt_mode' for more information.\"\n  }\n\n\n  # Bail if the options were screwed\n  $exit_cmd $EXIT_FAILURE\n}\n\n\n\n\n## ----------- ##\n##    Main.    ##\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_dirname_and_basename \"$1\" \"\" \".\"\n    func_stripname '' '.exe' \"$func_basename_result\"\n    func_ltwrapper_scriptname_result=\"$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper\"\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_resolve_sysroot PATH\n# Replace a leading = in PATH with a sysroot.  Store the result into\n# func_resolve_sysroot_result\nfunc_resolve_sysroot ()\n{\n  func_resolve_sysroot_result=$1\n  case $func_resolve_sysroot_result in\n  =*)\n    func_stripname '=' '' \"$func_resolve_sysroot_result\"\n    func_resolve_sysroot_result=$lt_sysroot$func_stripname_result\n    ;;\n  esac\n}\n\n# func_replace_sysroot PATH\n# If PATH begins with the sysroot, replace it with = and\n# store the result into func_replace_sysroot_result.\nfunc_replace_sysroot ()\n{\n  case \"$lt_sysroot:$1\" in\n  ?*:\"$lt_sysroot\"*)\n    func_stripname \"$lt_sysroot\" '' \"$1\"\n    func_replace_sysroot_result=\"=$func_stripname_result\"\n    ;;\n  *)\n    # Including no sysroot.\n    func_replace_sysroot_result=$1\n    ;;\n  esac\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\tfunc_append_quoted CC_quoted \"$arg\"\n      done\n      CC_expanded=`func_echo_all $CC`\n      CC_quoted_expanded=`func_echo_all $CC_quoted`\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 \"* | \" $CC_expanded \"* | \"$CC_expanded \"* | \\\n      \" $CC_quoted\"* | \"$CC_quoted \"* | \" $CC_quoted_expanded \"* | \"$CC_quoted_expanded \"*) ;;\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_append_quoted CC_quoted \"$arg\"\n\t    done\n\t    CC_expanded=`func_echo_all $CC`\n\t    CC_quoted_expanded=`func_echo_all $CC_quoted`\n\t    case \"$@ \" in\n\t    \" $CC \"* | \"$CC \"* | \" $CC_expanded \"* | \"$CC_expanded \"* | \\\n\t    \" $CC_quoted\"* | \"$CC_quoted \"* | \" $CC_quoted_expanded \"* | \"$CC_quoted_expanded \"*)\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\n##################################################\n# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #\n##################################################\n\n# func_convert_core_file_wine_to_w32 ARG\n# Helper function used by file name conversion functions when $build is *nix,\n# and $host is mingw, cygwin, or some other w32 environment. Relies on a\n# correctly configured wine environment available, with the winepath program\n# in $build's $PATH.\n#\n# ARG is the $build file name to be converted to w32 format.\n# Result is available in $func_convert_core_file_wine_to_w32_result, and will\n# be empty on error (or when ARG is empty)\nfunc_convert_core_file_wine_to_w32 ()\n{\n  $opt_debug\n  func_convert_core_file_wine_to_w32_result=\"$1\"\n  if test -n \"$1\"; then\n    # Unfortunately, winepath does not exit with a non-zero error code, so we\n    # are forced to check the contents of stdout. On the other hand, if the\n    # command is not found, the shell will set an exit code of 127 and print\n    # *an error message* to stdout. So we must check for both error code of\n    # zero AND non-empty stdout, which explains the odd construction:\n    func_convert_core_file_wine_to_w32_tmp=`winepath -w \"$1\" 2>/dev/null`\n    if test \"$?\" -eq 0 && test -n \"${func_convert_core_file_wine_to_w32_tmp}\"; then\n      func_convert_core_file_wine_to_w32_result=`$ECHO \"$func_convert_core_file_wine_to_w32_tmp\" |\n        $SED -e \"$lt_sed_naive_backslashify\"`\n    else\n      func_convert_core_file_wine_to_w32_result=\n    fi\n  fi\n}\n# end: func_convert_core_file_wine_to_w32\n\n\n# func_convert_core_path_wine_to_w32 ARG\n# Helper function used by path conversion functions when $build is *nix, and\n# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly\n# configured wine environment available, with the winepath program in $build's\n# $PATH. Assumes ARG has no leading or trailing path separator characters.\n#\n# ARG is path to be converted from $build format to win32.\n# Result is available in $func_convert_core_path_wine_to_w32_result.\n# Unconvertible file (directory) names in ARG are skipped; if no directory names\n# are convertible, then the result may be empty.\nfunc_convert_core_path_wine_to_w32 ()\n{\n  $opt_debug\n  # unfortunately, winepath doesn't convert paths, only file names\n  func_convert_core_path_wine_to_w32_result=\"\"\n  if test -n \"$1\"; then\n    oldIFS=$IFS\n    IFS=:\n    for func_convert_core_path_wine_to_w32_f in $1; do\n      IFS=$oldIFS\n      func_convert_core_file_wine_to_w32 \"$func_convert_core_path_wine_to_w32_f\"\n      if test -n \"$func_convert_core_file_wine_to_w32_result\" ; then\n        if test -z \"$func_convert_core_path_wine_to_w32_result\"; then\n          func_convert_core_path_wine_to_w32_result=\"$func_convert_core_file_wine_to_w32_result\"\n        else\n          func_append func_convert_core_path_wine_to_w32_result \";$func_convert_core_file_wine_to_w32_result\"\n        fi\n      fi\n    done\n    IFS=$oldIFS\n  fi\n}\n# end: func_convert_core_path_wine_to_w32\n\n\n# func_cygpath ARGS...\n# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when\n# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)\n# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or\n# (2), returns the Cygwin file name or path in func_cygpath_result (input\n# file name or path is assumed to be in w32 format, as previously converted\n# from $build's *nix or MSYS format). In case (3), returns the w32 file name\n# or path in func_cygpath_result (input file name or path is assumed to be in\n# Cygwin format). Returns an empty string on error.\n#\n# ARGS are passed to cygpath, with the last one being the file name or path to\n# be converted.\n#\n# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH\n# environment variable; do not put it in $PATH.\nfunc_cygpath ()\n{\n  $opt_debug\n  if test -n \"$LT_CYGPATH\" && test -f \"$LT_CYGPATH\"; then\n    func_cygpath_result=`$LT_CYGPATH \"$@\" 2>/dev/null`\n    if test \"$?\" -ne 0; then\n      # on failure, ensure result is empty\n      func_cygpath_result=\n    fi\n  else\n    func_cygpath_result=\n    func_error \"LT_CYGPATH is empty or specifies non-existent file: \\`$LT_CYGPATH'\"\n  fi\n}\n#end: func_cygpath\n\n\n# func_convert_core_msys_to_w32 ARG\n# Convert file name or path ARG from MSYS format to w32 format.  Return\n# result in func_convert_core_msys_to_w32_result.\nfunc_convert_core_msys_to_w32 ()\n{\n  $opt_debug\n  # awkward: cmd appends spaces to result\n  func_convert_core_msys_to_w32_result=`( cmd //c echo \"$1\" ) 2>/dev/null |\n    $SED -e 's/[ ]*$//' -e \"$lt_sed_naive_backslashify\"`\n}\n#end: func_convert_core_msys_to_w32\n\n\n# func_convert_file_check ARG1 ARG2\n# Verify that ARG1 (a file name in $build format) was converted to $host\n# format in ARG2. Otherwise, emit an error message, but continue (resetting\n# func_to_host_file_result to ARG1).\nfunc_convert_file_check ()\n{\n  $opt_debug\n  if test -z \"$2\" && test -n \"$1\" ; then\n    func_error \"Could not determine host file name corresponding to\"\n    func_error \"  \\`$1'\"\n    func_error \"Continuing, but uninstalled executables may not work.\"\n    # Fallback:\n    func_to_host_file_result=\"$1\"\n  fi\n}\n# end func_convert_file_check\n\n\n# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH\n# Verify that FROM_PATH (a path in $build format) was converted to $host\n# format in TO_PATH. Otherwise, emit an error message, but continue, resetting\n# func_to_host_file_result to a simplistic fallback value (see below).\nfunc_convert_path_check ()\n{\n  $opt_debug\n  if test -z \"$4\" && test -n \"$3\"; then\n    func_error \"Could not determine the host path corresponding to\"\n    func_error \"  \\`$3'\"\n    func_error \"Continuing, but uninstalled executables may not work.\"\n    # Fallback.  This is a deliberately simplistic \"conversion\" and\n    # should not be \"improved\".  See libtool.info.\n    if test \"x$1\" != \"x$2\"; then\n      lt_replace_pathsep_chars=\"s|$1|$2|g\"\n      func_to_host_path_result=`echo \"$3\" |\n        $SED -e \"$lt_replace_pathsep_chars\"`\n    else\n      func_to_host_path_result=\"$3\"\n    fi\n  fi\n}\n# end func_convert_path_check\n\n\n# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG\n# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT\n# and appending REPL if ORIG matches BACKPAT.\nfunc_convert_path_front_back_pathsep ()\n{\n  $opt_debug\n  case $4 in\n  $1 ) func_to_host_path_result=\"$3$func_to_host_path_result\"\n    ;;\n  esac\n  case $4 in\n  $2 ) func_append func_to_host_path_result \"$3\"\n    ;;\n  esac\n}\n# end func_convert_path_front_back_pathsep\n\n\n##################################################\n# $build to $host FILE NAME CONVERSION FUNCTIONS #\n##################################################\n# invoked via `$to_host_file_cmd ARG'\n#\n# In each case, ARG is the path to be converted from $build to $host format.\n# Result will be available in $func_to_host_file_result.\n\n\n# func_to_host_file ARG\n# Converts the file name ARG from $build format to $host format. Return result\n# in func_to_host_file_result.\nfunc_to_host_file ()\n{\n  $opt_debug\n  $to_host_file_cmd \"$1\"\n}\n# end func_to_host_file\n\n\n# func_to_tool_file ARG LAZY\n# converts the file name ARG from $build format to toolchain format. Return\n# result in func_to_tool_file_result.  If the conversion in use is listed\n# in (the comma separated) LAZY, no conversion takes place.\nfunc_to_tool_file ()\n{\n  $opt_debug\n  case ,$2, in\n    *,\"$to_tool_file_cmd\",*)\n      func_to_tool_file_result=$1\n      ;;\n    *)\n      $to_tool_file_cmd \"$1\"\n      func_to_tool_file_result=$func_to_host_file_result\n      ;;\n  esac\n}\n# end func_to_tool_file\n\n\n# func_convert_file_noop ARG\n# Copy ARG to func_to_host_file_result.\nfunc_convert_file_noop ()\n{\n  func_to_host_file_result=\"$1\"\n}\n# end func_convert_file_noop\n\n\n# func_convert_file_msys_to_w32 ARG\n# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic\n# conversion to w32 is not available inside the cwrapper.  Returns result in\n# func_to_host_file_result.\nfunc_convert_file_msys_to_w32 ()\n{\n  $opt_debug\n  func_to_host_file_result=\"$1\"\n  if test -n \"$1\"; then\n    func_convert_core_msys_to_w32 \"$1\"\n    func_to_host_file_result=\"$func_convert_core_msys_to_w32_result\"\n  fi\n  func_convert_file_check \"$1\" \"$func_to_host_file_result\"\n}\n# end func_convert_file_msys_to_w32\n\n\n# func_convert_file_cygwin_to_w32 ARG\n# Convert file name ARG from Cygwin to w32 format.  Returns result in\n# func_to_host_file_result.\nfunc_convert_file_cygwin_to_w32 ()\n{\n  $opt_debug\n  func_to_host_file_result=\"$1\"\n  if test -n \"$1\"; then\n    # because $build is cygwin, we call \"the\" cygpath in $PATH; no need to use\n    # LT_CYGPATH in this case.\n    func_to_host_file_result=`cygpath -m \"$1\"`\n  fi\n  func_convert_file_check \"$1\" \"$func_to_host_file_result\"\n}\n# end func_convert_file_cygwin_to_w32\n\n\n# func_convert_file_nix_to_w32 ARG\n# Convert file name ARG from *nix to w32 format.  Requires a wine environment\n# and a working winepath. Returns result in func_to_host_file_result.\nfunc_convert_file_nix_to_w32 ()\n{\n  $opt_debug\n  func_to_host_file_result=\"$1\"\n  if test -n \"$1\"; then\n    func_convert_core_file_wine_to_w32 \"$1\"\n    func_to_host_file_result=\"$func_convert_core_file_wine_to_w32_result\"\n  fi\n  func_convert_file_check \"$1\" \"$func_to_host_file_result\"\n}\n# end func_convert_file_nix_to_w32\n\n\n# func_convert_file_msys_to_cygwin ARG\n# Convert file name ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.\n# Returns result in func_to_host_file_result.\nfunc_convert_file_msys_to_cygwin ()\n{\n  $opt_debug\n  func_to_host_file_result=\"$1\"\n  if test -n \"$1\"; then\n    func_convert_core_msys_to_w32 \"$1\"\n    func_cygpath -u \"$func_convert_core_msys_to_w32_result\"\n    func_to_host_file_result=\"$func_cygpath_result\"\n  fi\n  func_convert_file_check \"$1\" \"$func_to_host_file_result\"\n}\n# end func_convert_file_msys_to_cygwin\n\n\n# func_convert_file_nix_to_cygwin ARG\n# Convert file name ARG from *nix to Cygwin format.  Requires Cygwin installed\n# in a wine environment, working winepath, and LT_CYGPATH set.  Returns result\n# in func_to_host_file_result.\nfunc_convert_file_nix_to_cygwin ()\n{\n  $opt_debug\n  func_to_host_file_result=\"$1\"\n  if test -n \"$1\"; then\n    # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.\n    func_convert_core_file_wine_to_w32 \"$1\"\n    func_cygpath -u \"$func_convert_core_file_wine_to_w32_result\"\n    func_to_host_file_result=\"$func_cygpath_result\"\n  fi\n  func_convert_file_check \"$1\" \"$func_to_host_file_result\"\n}\n# end func_convert_file_nix_to_cygwin\n\n\n#############################################\n# $build to $host PATH CONVERSION FUNCTIONS #\n#############################################\n# invoked via `$to_host_path_cmd ARG'\n#\n# In each case, ARG is the path to be converted from $build to $host format.\n# The result will be available in $func_to_host_path_result.\n#\n# Path separators are also converted from $build format to $host format.  If\n# ARG begins or ends with a path separator character, it is preserved (but\n# converted to $host format) on output.\n#\n# All path conversion functions are named using the following convention:\n#   file name conversion function    : func_convert_file_X_to_Y ()\n#   path conversion function         : func_convert_path_X_to_Y ()\n# where, for any given $build/$host combination the 'X_to_Y' value is the\n# same.  If conversion functions are added for new $build/$host combinations,\n# the two new functions must follow this pattern, or func_init_to_host_path_cmd\n# will break.\n\n\n# func_init_to_host_path_cmd\n# Ensures that function \"pointer\" variable $to_host_path_cmd is set to the\n# appropriate value, based on the value of $to_host_file_cmd.\nto_host_path_cmd=\nfunc_init_to_host_path_cmd ()\n{\n  $opt_debug\n  if test -z \"$to_host_path_cmd\"; then\n    func_stripname 'func_convert_file_' '' \"$to_host_file_cmd\"\n    to_host_path_cmd=\"func_convert_path_${func_stripname_result}\"\n  fi\n}\n\n\n# func_to_host_path ARG\n# Converts the path ARG from $build format to $host format. Return result\n# in func_to_host_path_result.\nfunc_to_host_path ()\n{\n  $opt_debug\n  func_init_to_host_path_cmd\n  $to_host_path_cmd \"$1\"\n}\n# end func_to_host_path\n\n\n# func_convert_path_noop ARG\n# Copy ARG to func_to_host_path_result.\nfunc_convert_path_noop ()\n{\n  func_to_host_path_result=\"$1\"\n}\n# end func_convert_path_noop\n\n\n# func_convert_path_msys_to_w32 ARG\n# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic\n# conversion to w32 is not available inside the cwrapper.  Returns result in\n# func_to_host_path_result.\nfunc_convert_path_msys_to_w32 ()\n{\n  $opt_debug\n  func_to_host_path_result=\"$1\"\n  if test -n \"$1\"; then\n    # Remove leading and trailing path separator characters from ARG.  MSYS\n    # behavior is inconsistent here; cygpath turns them into '.;' and ';.';\n    # and winepath ignores them completely.\n    func_stripname : : \"$1\"\n    func_to_host_path_tmp1=$func_stripname_result\n    func_convert_core_msys_to_w32 \"$func_to_host_path_tmp1\"\n    func_to_host_path_result=\"$func_convert_core_msys_to_w32_result\"\n    func_convert_path_check : \";\" \\\n      \"$func_to_host_path_tmp1\" \"$func_to_host_path_result\"\n    func_convert_path_front_back_pathsep \":*\" \"*:\" \";\" \"$1\"\n  fi\n}\n# end func_convert_path_msys_to_w32\n\n\n# func_convert_path_cygwin_to_w32 ARG\n# Convert path ARG from Cygwin to w32 format.  Returns result in\n# func_to_host_file_result.\nfunc_convert_path_cygwin_to_w32 ()\n{\n  $opt_debug\n  func_to_host_path_result=\"$1\"\n  if test -n \"$1\"; then\n    # See func_convert_path_msys_to_w32:\n    func_stripname : : \"$1\"\n    func_to_host_path_tmp1=$func_stripname_result\n    func_to_host_path_result=`cygpath -m -p \"$func_to_host_path_tmp1\"`\n    func_convert_path_check : \";\" \\\n      \"$func_to_host_path_tmp1\" \"$func_to_host_path_result\"\n    func_convert_path_front_back_pathsep \":*\" \"*:\" \";\" \"$1\"\n  fi\n}\n# end func_convert_path_cygwin_to_w32\n\n\n# func_convert_path_nix_to_w32 ARG\n# Convert path ARG from *nix to w32 format.  Requires a wine environment and\n# a working winepath.  Returns result in func_to_host_file_result.\nfunc_convert_path_nix_to_w32 ()\n{\n  $opt_debug\n  func_to_host_path_result=\"$1\"\n  if test -n \"$1\"; then\n    # See func_convert_path_msys_to_w32:\n    func_stripname : : \"$1\"\n    func_to_host_path_tmp1=$func_stripname_result\n    func_convert_core_path_wine_to_w32 \"$func_to_host_path_tmp1\"\n    func_to_host_path_result=\"$func_convert_core_path_wine_to_w32_result\"\n    func_convert_path_check : \";\" \\\n      \"$func_to_host_path_tmp1\" \"$func_to_host_path_result\"\n    func_convert_path_front_back_pathsep \":*\" \"*:\" \";\" \"$1\"\n  fi\n}\n# end func_convert_path_nix_to_w32\n\n\n# func_convert_path_msys_to_cygwin ARG\n# Convert path ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.\n# Returns result in func_to_host_file_result.\nfunc_convert_path_msys_to_cygwin ()\n{\n  $opt_debug\n  func_to_host_path_result=\"$1\"\n  if test -n \"$1\"; then\n    # See func_convert_path_msys_to_w32:\n    func_stripname : : \"$1\"\n    func_to_host_path_tmp1=$func_stripname_result\n    func_convert_core_msys_to_w32 \"$func_to_host_path_tmp1\"\n    func_cygpath -u -p \"$func_convert_core_msys_to_w32_result\"\n    func_to_host_path_result=\"$func_cygpath_result\"\n    func_convert_path_check : : \\\n      \"$func_to_host_path_tmp1\" \"$func_to_host_path_result\"\n    func_convert_path_front_back_pathsep \":*\" \"*:\" : \"$1\"\n  fi\n}\n# end func_convert_path_msys_to_cygwin\n\n\n# func_convert_path_nix_to_cygwin ARG\n# Convert path ARG from *nix to Cygwin format.  Requires Cygwin installed in a\n# a wine environment, working winepath, and LT_CYGPATH set.  Returns result in\n# func_to_host_file_result.\nfunc_convert_path_nix_to_cygwin ()\n{\n  $opt_debug\n  func_to_host_path_result=\"$1\"\n  if test -n \"$1\"; then\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_stripname : : \"$1\"\n    func_to_host_path_tmp1=$func_stripname_result\n    func_convert_core_path_wine_to_w32 \"$func_to_host_path_tmp1\"\n    func_cygpath -u -p \"$func_convert_core_path_wine_to_w32_result\"\n    func_to_host_path_result=\"$func_cygpath_result\"\n    func_convert_path_check : : \\\n      \"$func_to_host_path_tmp1\" \"$func_to_host_path_result\"\n    func_convert_path_front_back_pathsep \":*\" \"*:\" : \"$1\"\n  fi\n}\n# end func_convert_path_nix_to_cygwin\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          func_append pie_flag \" $arg\"\n\t  continue\n\t  ;;\n\n\t-shared | -static | -prefer-pic | -prefer-non-pic)\n\t  func_append 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_append_quoted lastarg \"$arg\"\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  func_append 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_append_quoted base_compile \"$lastarg\"\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 | *.go | *.obj | *.sx | *.cu | *.cup)\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 \"$srcfile\" | $SED 's%^.*/%%; 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      func_append removelist \" $output_obj\"\n      $ECHO \"$srcfile\" > \"$lockfile\"\n    fi\n\n    $opt_dry_run || $RM $removelist\n    func_append removelist \" $lockfile\"\n    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15\n\n    func_to_tool_file \"$srcfile\" func_convert_file_msys_to_w32\n    srcfile=$func_to_tool_file_result\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\tfunc_append 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\tfunc_append command \" -o $obj\"\n      fi\n\n      # Suppress compiler output if we already did a PIC compilation.\n      func_append 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 || {\n  test \"$opt_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 $opt_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 build PIC objects only\n  -prefer-non-pic   try to build 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  -Wc,FLAG          pass FLAG directly to the compiler\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-dir 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  -bindir BINDIR    specify path to binaries directory (for systems where\n                    libraries must be found in the PATH setting at runtime)\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  -Wc,FLAG\n  -Xcompiler FLAG   pass linker-specific FLAG directly to the compiler\n  -Wl,FLAG\n  -Xlinker FLAG     pass linker-specific FLAG directly to the linker\n  -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)\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 \\`$opt_mode'\"\n        ;;\n    esac\n\n    echo\n    $ECHO \"Try \\`$progname --help' for more information about other modes.\"\n}\n\n# Now that we've collected a possible --mode arg, show help if necessary\nif $opt_help; then\n  if test \"$opt_help\" = :; then\n    func_mode_help\n  else\n    {\n      func_help noexit\n      for opt_mode in compile link execute install finish uninstall clean; do\n\tfunc_mode_help\n      done\n    } | sed -n '1p; 2,$s/^Usage:/  or: /p'\n    {\n      func_help noexit\n      for opt_mode in compile link execute install finish uninstall clean; do\n\techo\n\tfunc_mode_help\n      done\n    } |\n    sed '1d\n      /^When reporting/,/^Report/{\n\tH\n\td\n      }\n      $x\n      /information about other modes/d\n      /more detailed .*MODE/d\n      s/^Usage:.*--mode=\\([^ ]*\\) .*/Description of \\1 mode:/'\n  fi\n  exit $?\nfi\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 $opt_dlopen; 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\tfunc_resolve_sysroot \"$file\"\n\tfile=$func_resolve_sysroot_result\n\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  func_append 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      -* | *.la | *.lo ) ;;\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_append_quoted args \"$file\"\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\techo \"export $shlibpath_var\"\n      fi\n      $ECHO \"$cmd$args\"\n      exit $EXIT_SUCCESS\n    fi\n}\n\ntest \"$opt_mode\" = execute && func_mode_execute ${1+\"$@\"}\n\n\n# func_mode_finish arg...\nfunc_mode_finish ()\n{\n    $opt_debug\n    libs=\n    libdirs=\n    admincmds=\n\n    for opt in \"$nonopt\" ${1+\"$@\"}\n    do\n      if test -d \"$opt\"; then\n\tfunc_append libdirs \" $opt\"\n\n      elif test -f \"$opt\"; then\n\tif func_lalib_unsafe_p \"$opt\"; then\n\t  func_append libs \" $opt\"\n\telse\n\t  func_warning \"\\`$opt' is not a valid libtool archive\"\n\tfi\n\n      else\n\tfunc_fatal_error \"invalid argument \\`$opt'\"\n      fi\n    done\n\n    if test -n \"$libs\"; then\n      if test -n \"$lt_sysroot\"; then\n        sysroot_regex=`$ECHO \"$lt_sysroot\" | $SED \"$sed_make_literal_regex\"`\n        sysroot_cmd=\"s/\\([ ']\\)$sysroot_regex/\\1/g;\"\n      else\n        sysroot_cmd=\n      fi\n\n      # Remove sysroot references\n      if $opt_dry_run; then\n        for lib in $libs; do\n          echo \"removing references to $lt_sysroot and \\`=' prefixes from $lib\"\n        done\n      else\n        tmpdir=`func_mktempdir`\n        for lib in $libs; do\n\t  sed -e \"${sysroot_cmd} s/\\([ ']-[LR]\\)=/\\1/g; s/\\([ ']\\)=/\\1/g\" $lib \\\n\t    > $tmpdir/tmp-la\n\t  mv -f $tmpdir/tmp-la $lib\n\tdone\n        ${RM}r \"$tmpdir\"\n      fi\n    fi\n\n    if test -n \"$finish_cmds$finish_eval\" && test -n \"$libdirs\"; then\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\" || func_append 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    if test -n \"$finish_cmds$finish_eval\" && test -n \"$libdirs\"; then\n      echo \"----------------------------------------------------------------------\"\n      echo \"Libraries have been installed in:\"\n      for libdir in $libdirs; do\n\t$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\techo \"   - add LIBDIR to the \\`$shlibpath_var' environment variable\"\n\techo \"     during execution\"\n      fi\n      if test -n \"$runpath_var\"; then\n\techo \"   - add LIBDIR to the \\`$runpath_var' environment variable\"\n\techo \"     during linking\"\n      fi\n      if test -n \"$hardcode_libdir_flag_spec\"; then\n\tlibdir=LIBDIR\n\teval flag=\\\"$hardcode_libdir_flag_spec\\\"\n\n\t$ECHO \"   - use the \\`$flag' linker flag\"\n      fi\n      if test -n \"$admincmds\"; then\n\t$ECHO \"   - have your system administrator run these commands:$admincmds\"\n      fi\n      if test -f /etc/ld.so.conf; then\n\techo \"   - 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\tsolaris2.[6789]|solaris2.1[0-9])\n\t  echo \"more information, such as the ld(1), crle(1) and ld.so(8) manual\"\n\t  echo \"pages.\"\n\t  ;;\n\t*)\n\t  echo \"more information, such as the ld(1) and ld.so(8) manual pages.\"\n\t  ;;\n      esac\n      echo \"----------------------------------------------------------------------\"\n    fi\n    exit $EXIT_SUCCESS\n}\n\ntest \"$opt_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       case $nonopt in *shtool*) :;; *) false;; esac; 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    func_append install_prog \"$func_quote_for_eval_result\"\n    install_shared_prog=$install_prog\n    case \" $install_prog \" in\n      *[\\\\\\ /]cp\\ *) install_cp=: ;;\n      *) install_cp=false ;;\n    esac\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    no_mode=:\n    for arg\n    do\n      arg2=\n      if test -n \"$dest\"; then\n\tfunc_append files \" $dest\"\n\tdest=$arg\n\tcontinue\n      fi\n\n      case $arg in\n      -d) isdir=yes ;;\n      -f)\n\tif $install_cp; then :; else\n\t  prev=$arg\n\tfi\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  if test \"x$prev\" = x-m && test -n \"$install_override_mode\"; then\n\t    arg2=$install_override_mode\n\t    no_mode=false\n\t  fi\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      func_append install_prog \" $func_quote_for_eval_result\"\n      if test -n \"$arg2\"; then\n\tfunc_quote_for_eval \"$arg2\"\n      fi\n      func_append install_shared_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 -n \"$install_override_mode\" && $no_mode; then\n      if $install_cp; then :; else\n\tfunc_quote_for_eval \"$install_override_mode\"\n\tfunc_append install_shared_prog \" -m $func_quote_for_eval_result\"\n      fi\n    fi\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\tfunc_append staticlibs \" $file\"\n\t;;\n\n      *.la)\n\tfunc_resolve_sysroot \"$file\"\n\tfile=$func_resolve_sysroot_result\n\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  *) func_append 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  *) func_append future_libdirs \" $libdir\" ;;\n\t  esac\n\tfi\n\n\tfunc_dirname \"$file\" \"/\" \"\"\n\tdir=\"$func_dirname_result\"\n\tfunc_append 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 \"$destdir\" | $SED -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 \"$relink_command\" | $SED \"s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%\"`\n\t  else\n\t    relink_command=`$ECHO \"$relink_command\" | $SED \"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_shared_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\" && func_append 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 \"$lib\" | $SED '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 \"$relink_command\" | $SED '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 \"$file$stripped_ext\" | $SED \"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      func_to_tool_file \"$oldlib\" func_convert_file_msys_to_w32\n      tool_oldlib=$func_to_tool_file_result\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 $tool_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 \"$opt_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#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))\n#pragma GCC diagnostic ignored \\\"-Wstrict-prototypes\\\"\n#endif\n\n/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */\n#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)\n/* DATA imports from DLLs on WIN32 con't be const, because runtime\n   relocations are performed -- see ld's documentation on pseudo-relocs.  */\n# define LT_DLSYM_CONST\n#elif defined(__osf__)\n/* This system does not cope well with relocations in const data.  */\n# define LT_DLSYM_CONST\n#else\n# define LT_DLSYM_CONST const\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 \"$objs$old_deplibs\" | $SP2NL | $SED \"$lo2o\" | $NL2SP`\n\t  for progfile in $progfiles; do\n\t    func_to_tool_file \"$progfile\" func_convert_file_msys_to_w32\n\t    func_verbose \"extracting global C symbols from \\`$func_to_tool_file_result'\"\n\t    $opt_dry_run || eval \"$NM $func_to_tool_file_result | $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          case $host in\n\t    *cygwin* | *mingw* | *cegcc* )\n\t      # if an import library, we need to obtain dlname\n\t      if func_win32_import_lib_p \"$dlprefile\"; then\n\t        func_tr_sh \"$dlprefile\"\n\t        eval \"curr_lafile=\\$libfile_$func_tr_sh_result\"\n\t        dlprefile_dlbasename=\"\"\n\t        if test -n \"$curr_lafile\" && func_lalib_p \"$curr_lafile\"; then\n\t          # Use subshell, to avoid clobbering current variable values\n\t          dlprefile_dlname=`source \"$curr_lafile\" && echo \"$dlname\"`\n\t          if test -n \"$dlprefile_dlname\" ; then\n\t            func_basename \"$dlprefile_dlname\"\n\t            dlprefile_dlbasename=\"$func_basename_result\"\n\t          else\n\t            # no lafile. user explicitly requested -dlpreopen <import library>.\n\t            $sharedlib_from_linklib_cmd \"$dlprefile\"\n\t            dlprefile_dlbasename=$sharedlib_from_linklib_result\n\t          fi\n\t        fi\n\t        $opt_dry_run || {\n\t          if test -n \"$dlprefile_dlbasename\" ; then\n\t            eval '$ECHO \": $dlprefile_dlbasename\" >> \"$nlist\"'\n\t          else\n\t            func_warning \"Could not compute DLL name from $name\"\n\t            eval '$ECHO \": $name \" >> \"$nlist\"'\n\t          fi\n\t          func_to_tool_file \"$dlprefile\" func_convert_file_msys_to_w32\n\t          eval \"$NM \\\"$func_to_tool_file_result\\\" 2>/dev/null | $global_symbol_pipe |\n\t            $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'\"\n\t        }\n\t      else # not an import lib\n\t        $opt_dry_run || {\n\t          eval '$ECHO \": $name \" >> \"$nlist\"'\n\t          func_to_tool_file \"$dlprefile\" func_convert_file_msys_to_w32\n\t          eval \"$NM \\\"$func_to_tool_file_result\\\" 2>/dev/null | $global_symbol_pipe >> '$nlist'\"\n\t        }\n\t      fi\n\t    ;;\n\t    *)\n\t      $opt_dry_run || {\n\t        eval '$ECHO \": $name \" >> \"$nlist\"'\n\t        func_to_tool_file \"$dlprefile\" func_convert_file_msys_to_w32\n\t        eval \"$NM \\\"$func_to_tool_file_result\\\" 2>/dev/null | $global_symbol_pipe >> '$nlist'\"\n\t      }\n\t    ;;\n          esac\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;\nextern LT_DLSYM_CONST lt_dlsymlist\nlt_${my_prefix}_LTX_preloaded_symbols[];\nLT_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  *) func_append 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 \"$compile_command\" | $SED \"s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%\"`\n\t    finalize_command=`$ECHO \"$finalize_command\" | $SED \"s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%\"`\n\t  else\n\t    compile_command=`$ECHO \"$compile_command\" | $SED \"s%@SYMFILE@%$symfileobj%\"`\n\t    finalize_command=`$ECHO \"$finalize_command\" | $SED \"s%@SYMFILE@%$symfileobj%\"`\n\t  fi\n\t  ;;\n\t*)\n\t  compile_command=`$ECHO \"$compile_command\" | $SED \"s%@SYMFILE@%$symfileobj%\"`\n\t  finalize_command=`$ECHO \"$finalize_command\" | $SED \"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 \"$compile_command\" | $SED \"s% @SYMFILE@%%\"`\n      finalize_command=`$ECHO \"$finalize_command\" | $SED \"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.\n# Despite the name, also deal with 64 bit binaries.\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    # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.\n    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |\n       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then\n      func_to_tool_file \"$1\" func_convert_file_msys_to_w32\n      win32_nmres=`eval $NM -f posix -A \\\"$func_to_tool_file_result\\\" |\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# func_cygming_dll_for_implib ARG\n#\n# Platform-specific function to extract the\n# name of the DLL associated with the specified\n# import library ARG.\n# Invoked by eval'ing the libtool variable\n#    $sharedlib_from_linklib_cmd\n# Result is available in the variable\n#    $sharedlib_from_linklib_result\nfunc_cygming_dll_for_implib ()\n{\n  $opt_debug\n  sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify \"$1\"`\n}\n\n# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs\n#\n# The is the core of a fallback implementation of a\n# platform-specific function to extract the name of the\n# DLL associated with the specified import library LIBNAME.\n#\n# SECTION_NAME is either .idata$6 or .idata$7, depending\n# on the platform and compiler that created the implib.\n#\n# Echos the name of the DLL associated with the\n# specified import library.\nfunc_cygming_dll_for_implib_fallback_core ()\n{\n  $opt_debug\n  match_literal=`$ECHO \"$1\" | $SED \"$sed_make_literal_regex\"`\n  $OBJDUMP -s --section \"$1\" \"$2\" 2>/dev/null |\n    $SED '/^Contents of section '\"$match_literal\"':/{\n      # Place marker at beginning of archive member dllname section\n      s/.*/====MARK====/\n      p\n      d\n    }\n    # These lines can sometimes be longer than 43 characters, but\n    # are always uninteresting\n    /:[\t ]*file format pe[i]\\{,1\\}-/d\n    /^In archive [^:]*:/d\n    # Ensure marker is printed\n    /^====MARK====/p\n    # Remove all lines with less than 43 characters\n    /^.\\{43\\}/!d\n    # From remaining lines, remove first 43 characters\n    s/^.\\{43\\}//' |\n    $SED -n '\n      # Join marker and all lines until next marker into a single line\n      /^====MARK====/ b para\n      H\n      $ b para\n      b\n      :para\n      x\n      s/\\n//g\n      # Remove the marker\n      s/^====MARK====//\n      # Remove trailing dots and whitespace\n      s/[\\. \\t]*$//\n      # Print\n      /./p' |\n    # we now have a list, one entry per line, of the stringified\n    # contents of the appropriate section of all members of the\n    # archive which possess that section. Heuristic: eliminate\n    # all those which have a first or second character that is\n    # a '.' (that is, objdump's representation of an unprintable\n    # character.) This should work for all archives with less than\n    # 0x302f exports -- but will fail for DLLs whose name actually\n    # begins with a literal '.' or a single character followed by\n    # a '.'.\n    #\n    # Of those that remain, print the first one.\n    $SED -e '/^\\./d;/^.\\./d;q'\n}\n\n# func_cygming_gnu_implib_p ARG\n# This predicate returns with zero status (TRUE) if\n# ARG is a GNU/binutils-style import library. Returns\n# with nonzero status (FALSE) otherwise.\nfunc_cygming_gnu_implib_p ()\n{\n  $opt_debug\n  func_to_tool_file \"$1\" func_convert_file_msys_to_w32\n  func_cygming_gnu_implib_tmp=`$NM \"$func_to_tool_file_result\" | eval \"$global_symbol_pipe\" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`\n  test -n \"$func_cygming_gnu_implib_tmp\"\n}\n\n# func_cygming_ms_implib_p ARG\n# This predicate returns with zero status (TRUE) if\n# ARG is an MS-style import library. Returns\n# with nonzero status (FALSE) otherwise.\nfunc_cygming_ms_implib_p ()\n{\n  $opt_debug\n  func_to_tool_file \"$1\" func_convert_file_msys_to_w32\n  func_cygming_ms_implib_tmp=`$NM \"$func_to_tool_file_result\" | eval \"$global_symbol_pipe\" | $GREP '_NULL_IMPORT_DESCRIPTOR'`\n  test -n \"$func_cygming_ms_implib_tmp\"\n}\n\n# func_cygming_dll_for_implib_fallback ARG\n# Platform-specific function to extract the\n# name of the DLL associated with the specified\n# import library ARG.\n#\n# This fallback implementation is for use when $DLLTOOL\n# does not support the --identify-strict option.\n# Invoked by eval'ing the libtool variable\n#    $sharedlib_from_linklib_cmd\n# Result is available in the variable\n#    $sharedlib_from_linklib_result\nfunc_cygming_dll_for_implib_fallback ()\n{\n  $opt_debug\n  if func_cygming_gnu_implib_p \"$1\" ; then\n    # binutils import library\n    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' \"$1\"`\n  elif func_cygming_ms_implib_p \"$1\" ; then\n    # ms-generated import library\n    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' \"$1\"`\n  else\n    # unknown\n    sharedlib_from_linklib_result=\"\"\n  fi\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    if test \"$lock_old_archive_extraction\" = yes; then\n      lockfile=$f_ex_an_ar_oldlib.lock\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    fi\n    func_show_eval \"(cd \\$f_ex_an_ar_dir && $AR x \\\"\\$f_ex_an_ar_oldlib\\\")\" \\\n\t\t   'stat=$?; rm -f \"$lockfile\"; exit $stat'\n    if test \"$lock_old_archive_extraction\" = yes; then\n      $opt_dry_run || rm -f \"$lockfile\"\n    fi\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 | sort | $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 | sort | $NL2SP`\n    done\n\n    func_extract_archives_result=\"$my_oldobjs\"\n}\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=${1-no}\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.\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    file=\\\"\\$0\\\"\"\n\n    qECHO=`$ECHO \"$ECHO\" | $SED \"$sed_quote_subst\"`\n    $ECHO \"\\\n\n# A function that is used when there is no print builtin or printf.\nfunc_fallback_echo ()\n{\n  eval 'cat <<_LTECHO_EOF\n\\$1\n_LTECHO_EOF'\n}\n    ECHO=\\\"$qECHO\\\"\n  fi\n\n# Very basic option parsing. These options are (a) specific to\n# the libtool wrapper, (b) are identical between the wrapper\n# /script/ and the wrapper /executable/ which is used only on\n# windows platforms, and (c) all begin with the string \"--lt-\"\n# (application programs are unlikely to have options which match\n# this pattern).\n#\n# There are only two supported options: --lt-debug and\n# --lt-dump-script. There is, deliberately, no --lt-help.\n#\n# The first argument to this parsing function should be the\n# script's $0 value, followed by \"$@\".\nlt_option_debug=\nfunc_parse_lt_options ()\n{\n  lt_script_arg0=\\$0\n  shift\n  for lt_opt\n  do\n    case \\\"\\$lt_opt\\\" in\n    --lt-debug) lt_option_debug=1 ;;\n    --lt-dump-script)\n        lt_dump_D=\\`\\$ECHO \\\"X\\$lt_script_arg0\\\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\\`\n        test \\\"X\\$lt_dump_D\\\" = \\\"X\\$lt_script_arg0\\\" && lt_dump_D=.\n        lt_dump_F=\\`\\$ECHO \\\"X\\$lt_script_arg0\\\" | $SED -e 's/^X//' -e 's%^.*/%%'\\`\n        cat \\\"\\$lt_dump_D/\\$lt_dump_F\\\"\n        exit 0\n      ;;\n    --lt-*)\n        \\$ECHO \\\"Unrecognized --lt- option: '\\$lt_opt'\\\" 1>&2\n        exit 1\n      ;;\n    esac\n  done\n\n  # Print the debug banner immediately:\n  if test -n \\\"\\$lt_option_debug\\\"; then\n    echo \\\"${outputname}:${output}:\\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\\\" 1>&2\n  fi\n}\n\n# Used when --lt-debug. Prints its arguments to stdout\n# (redirection is the responsibility of the caller)\nfunc_lt_dump_args ()\n{\n  lt_dump_args_N=1;\n  for lt_arg\n  do\n    \\$ECHO \\\"${outputname}:${output}:\\${LINENO}: newargv[\\$lt_dump_args_N]: \\$lt_arg\\\"\n    lt_dump_args_N=\\`expr \\$lt_dump_args_N + 1\\`\n  done\n}\n\n# Core function for launching the target application\nfunc_exec_program_core ()\n{\n\"\n  case $host in\n  # Backslashes separate directories on plain windows\n  *-*-mingw | *-*-os2* | *-cegcc*)\n    $ECHO \"\\\n      if test -n \\\"\\$lt_option_debug\\\"; then\n        \\$ECHO \\\"${outputname}:${output}:\\${LINENO}: newargv[0]: \\$progdir\\\\\\\\\\$program\\\" 1>&2\n        func_lt_dump_args \\${1+\\\"\\$@\\\"} 1>&2\n      fi\n      exec \\\"\\$progdir\\\\\\\\\\$program\\\" \\${1+\\\"\\$@\\\"}\n\"\n    ;;\n\n  *)\n    $ECHO \"\\\n      if test -n \\\"\\$lt_option_debug\\\"; then\n        \\$ECHO \\\"${outputname}:${output}:\\${LINENO}: newargv[0]: \\$progdir/\\$program\\\" 1>&2\n        func_lt_dump_args \\${1+\\\"\\$@\\\"} 1>&2\n      fi\n      exec \\\"\\$progdir/\\$program\\\" \\${1+\\\"\\$@\\\"}\n\"\n    ;;\n  esac\n  $ECHO \"\\\n      \\$ECHO \\\"\\$0: cannot exec \\$program \\$*\\\" 1>&2\n      exit 1\n}\n\n# A function to encapsulate launching the target application\n# Strips options in the --lt-* namespace from \\$@ and\n# launches target application with the remaining arguments.\nfunc_exec_program ()\n{\n  case \\\" \\$* \\\" in\n  *\\\\ --lt-*)\n    for lt_wr_arg\n    do\n      case \\$lt_wr_arg in\n      --lt-*) ;;\n      *) set x \\\"\\$@\\\" \\\"\\$lt_wr_arg\\\"; shift;;\n      esac\n      shift\n    done ;;\n  esac\n  func_exec_program_core \\${1+\\\"\\$@\\\"}\n}\n\n  # Parse options\n  func_parse_lt_options \\\"\\$0\\\" \\${1+\\\"\\$@\\\"}\n\n  # Find the directory that this script lives in.\n  thisdir=\\`\\$ECHO \\\"\\$file\\\" | $SED '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 \\\"\\$file\\\" | $SED '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 \\\"\\$file\\\" | $SED 's%^.*/%%'\\`\n    file=\\`ls -ld \\\"\\$thisdir/\\$file\\\" | $SED -n 's/.*-> //p'\\`\n  done\n\n  # Usually 'no', except on cygwin/mingw when embedded into\n  # the cwrapper.\n  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_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 \\\"\\$thisdir\\\" | $SED '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# fixup the dll searchpath if we need to.\n\t#\n\t# Fix the DLL searchpath if we need to.  Do this before prepending\n\t# to shlibpath, because on Windows, both are PATH and uninstalled\n\t# libraries must come first.\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# 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 \\\"\\$$shlibpath_var\\\" | $SED 's/::*\\$//'\\`\n\n    export $shlibpath_var\n\"\n\tfi\n\n\t$ECHO \"\\\n    if test \\\"\\$libtool_execute_magic\\\" != \\\"$magic\\\"; then\n      # Run the actual program with our arguments.\n      func_exec_program \\${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\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*/\nEOF\n\t    cat <<\"EOF\"\n#ifdef _MSC_VER\n# define _CRT_SECURE_NO_DEPRECATE 1\n#endif\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#else\n# include <unistd.h>\n# include <stdint.h>\n# ifdef __CYGWIN__\n#  include <io.h>\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/* declarations of non-ANSI functions */\n#if defined(__MINGW32__)\n# ifdef __STRICT_ANSI__\nint _putenv (const char *);\n# endif\n#elif defined(__CYGWIN__)\n# ifdef __STRICT_ANSI__\nchar *realpath (const char *, char *);\nint putenv (char *);\nint setenv (const char *, const char *, int);\n# endif\n/* #elif defined (other platforms) ... */\n#endif\n\n/* portability defines, excluding path handling macros */\n#if defined(_MSC_VER)\n# define setmode _setmode\n# define stat    _stat\n# define chmod   _chmod\n# define getcwd  _getcwd\n# define putenv  _putenv\n# define S_IXUSR _S_IEXEC\n# ifndef _INTPTR_T_DEFINED\n#  define _INTPTR_T_DEFINED\n#  define intptr_t int\n# endif\n#elif defined(__MINGW32__)\n# define setmode _setmode\n# define stat    _stat\n# define chmod   _chmod\n# define getcwd  _getcwd\n# define putenv  _putenv\n#elif defined(__CYGWIN__)\n# define HAVE_SETENV\n# define FOPEN_WB \"wb\"\n/* #elif defined (other platforms) ... */\n#endif\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/* path handling portability macros */\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#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#if defined(LT_DEBUGWRAPPER)\nstatic int lt_debug = 1;\n#else\nstatic int lt_debug = 0;\n#endif\n\nconst char *program_name = \"libtool-wrapper\"; /* in case xstrdup fails */\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_debugprintf (const char *file, int line, const char *fmt, ...);\nvoid lt_fatal (const char *file, int line, const char *message, ...);\nstatic const char *nonnull (const char *s);\nstatic const char *nonempty (const char *s);\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_update_exe_path (const char *name, const char *value);\nvoid lt_update_lib_path (const char *name, const char *value);\nchar **prepare_spawn (char **argv);\nvoid lt_dump_script (FILE *f);\nEOF\n\n\t    cat <<EOF\nvolatile const 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_path \"$temp_rpath\"\n\t      cat <<EOF\nconst char * LIB_PATH_VALUE   = \"$func_to_host_path_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_path \"$dllsearchpath:\"\n\t      cat <<EOF\nconst char * EXE_PATH_VARNAME = \"PATH\";\nconst char * EXE_PATH_VALUE   = \"$func_to_host_path_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\nstatic const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;\nstatic const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX \"dump-script\";\nstatic const char *debug_opt            = LTWRAPPER_OPTION_PREFIX \"debug\";\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  newargz = XMALLOC (char *, argc + 1);\n\n  /* very simple arg parsing; don't want to rely on getopt\n   * also, copy all non cwrapper options to newargz, except\n   * argz[0], which is handled differently\n   */\n  newargc=0;\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  lt_dump_script (stdout);\n\t  return 0;\n\t}\n      if (strcmp (argv[i], debug_opt) == 0)\n\t{\n          lt_debug = 1;\n          continue;\n\t}\n      if (strcmp (argv[i], ltwrapper_option_prefix) == 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 (__FILE__, __LINE__,\n\t\t    \"unrecognized %s option: '%s'\",\n                    ltwrapper_option_prefix, argv[i]);\n        }\n      /* otherwise ... */\n      newargz[++newargc] = xstrdup (argv[i]);\n    }\n  newargz[++newargc] = NULL;\n\nEOF\n\t    cat <<EOF\n  /* The GNU banner must be the first non-error debug message */\n  lt_debugprintf (__FILE__, __LINE__, \"libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\\n\");\nEOF\n\t    cat <<\"EOF\"\n  lt_debugprintf (__FILE__, __LINE__, \"(main) argv[0]: %s\\n\", argv[0]);\n  lt_debugprintf (__FILE__, __LINE__, \"(main) program_name: %s\\n\", program_name);\n\n  tmp_pathspec = find_executable (argv[0]);\n  if (tmp_pathspec == NULL)\n    lt_fatal (__FILE__, __LINE__, \"couldn't find %s\", argv[0]);\n  lt_debugprintf (__FILE__, __LINE__,\n                  \"(main) found exe (before symlink chase) at: %s\\n\",\n\t\t  tmp_pathspec);\n\n  actual_cwrapper_path = chase_symlinks (tmp_pathspec);\n  lt_debugprintf (__FILE__, __LINE__,\n                  \"(main) found exe (after symlink chase) at: %s\\n\",\n\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  lt_debugprintf (__FILE__, __LINE__,\n\t\t  \"(main) libtool target name: %s\\n\",\n\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  /* Update the DLL searchpath.  EXE_PATH_VALUE ($dllsearchpath) must\n     be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)\n     because on Windows, both *_VARNAMEs are PATH but uninstalled\n     libraries must come first. */\n  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);\n  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);\n\n  lt_debugprintf (__FILE__, __LINE__, \"(main) lt_argv_zero: %s\\n\",\n\t\t  nonnull (lt_argv_zero));\n  for (i = 0; i < newargc; i++)\n    {\n      lt_debugprintf (__FILE__, __LINE__, \"(main) newargz[%d]: %s\\n\",\n\t\t      i, nonnull (newargz[i]));\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  newargz = prepare_spawn (newargz);\n  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);\n  if (rval == -1)\n    {\n      /* failed to start process */\n      lt_debugprintf (__FILE__, __LINE__,\n\t\t      \"(main) failed to launch target \\\"%s\\\": %s\\n\",\n\t\t      lt_argv_zero, nonnull (strerror (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 (__FILE__, __LINE__, \"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  lt_debugprintf (__FILE__, __LINE__, \"(check_executable): %s\\n\",\n                  nonempty (path));\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  lt_debugprintf (__FILE__, __LINE__, \"(make_executable): %s\\n\",\n                  nonempty (path));\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  lt_debugprintf (__FILE__, __LINE__, \"(find_executable): %s\\n\",\n                  nonempty (wrapper));\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 (__FILE__, __LINE__, \"getcwd failed: %s\",\n                              nonnull (strerror (errno)));\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 (__FILE__, __LINE__, \"getcwd failed: %s\",\n              nonnull (strerror (errno)));\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      lt_debugprintf (__FILE__, __LINE__,\n\t\t      \"checking path component for symlinks: %s\\n\",\n\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  lt_fatal (__FILE__, __LINE__,\n\t\t    \"error accessing file \\\"%s\\\": %s\",\n\t\t    tmp_pathspec, nonnull (strerror (errno)));\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 (__FILE__, __LINE__,\n\t\t\"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\nvoid\nlt_debugprintf (const char *file, int line, const char *fmt, ...)\n{\n  va_list args;\n  if (lt_debug)\n    {\n      (void) fprintf (stderr, \"%s:%s:%d: \", program_name, file, line);\n      va_start (args, fmt);\n      (void) vfprintf (stderr, fmt, args);\n      va_end (args);\n    }\n}\n\nstatic void\nlt_error_core (int exit_status, const char *file,\n\t       int line, const char *mode,\n\t       const char *message, va_list ap)\n{\n  fprintf (stderr, \"%s:%s:%d: %s: \", program_name, file, line, 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 *file, int line, const char *message, ...)\n{\n  va_list ap;\n  va_start (ap, message);\n  lt_error_core (EXIT_FAILURE, file, line, \"FATAL\", message, ap);\n  va_end (ap);\n}\n\nstatic const char *\nnonnull (const char *s)\n{\n  return s ? s : \"(null)\";\n}\n\nstatic const char *\nnonempty (const char *s)\n{\n  return (s && !*s) ? \"(empty)\" : nonnull (s);\n}\n\nvoid\nlt_setenv (const char *name, const char *value)\n{\n  lt_debugprintf (__FILE__, __LINE__,\n\t\t  \"(lt_setenv) setting '%s' to '%s'\\n\",\n                  nonnull (name), nonnull (value));\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\nvoid\nlt_update_exe_path (const char *name, const char *value)\n{\n  lt_debugprintf (__FILE__, __LINE__,\n\t\t  \"(lt_update_exe_path) modifying '%s' by prepending '%s'\\n\",\n                  nonnull (name), nonnull (value));\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  lt_debugprintf (__FILE__, __LINE__,\n\t\t  \"(lt_update_lib_path) modifying '%s' by prepending '%s'\\n\",\n                  nonnull (name), nonnull (value));\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\nEOF\n\t    case $host_os in\n\t      mingw*)\n\t\tcat <<\"EOF\"\n\n/* Prepares an argument vector before calling spawn().\n   Note that spawn() does not by itself call the command interpreter\n     (getenv (\"COMSPEC\") != NULL ? getenv (\"COMSPEC\") :\n      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\n         GetVersionEx(&v);\n         v.dwPlatformId == VER_PLATFORM_WIN32_NT;\n      }) ? \"cmd.exe\" : \"command.com\").\n   Instead it simply concatenates the arguments, separated by ' ', and calls\n   CreateProcess().  We must quote the arguments since Win32 CreateProcess()\n   interprets characters like ' ', '\\t', '\\\\', '\"' (but not '<' and '>') in a\n   special way:\n   - Space and tab are interpreted as delimiters. They are not treated as\n     delimiters if they are surrounded by double quotes: \"...\".\n   - Unescaped double quotes are removed from the input. Their only effect is\n     that within double quotes, space and tab are treated like normal\n     characters.\n   - Backslashes not followed by double quotes are not special.\n   - But 2*n+1 backslashes followed by a double quote become\n     n backslashes followed by a double quote (n >= 0):\n       \\\" -> \"\n       \\\\\\\" -> \\\"\n       \\\\\\\\\\\" -> \\\\\"\n */\n#define SHELL_SPECIAL_CHARS \"\\\"\\\\ \\001\\002\\003\\004\\005\\006\\007\\010\\011\\012\\013\\014\\015\\016\\017\\020\\021\\022\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037\"\n#define SHELL_SPACE_CHARS \" \\001\\002\\003\\004\\005\\006\\007\\010\\011\\012\\013\\014\\015\\016\\017\\020\\021\\022\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037\"\nchar **\nprepare_spawn (char **argv)\n{\n  size_t argc;\n  char **new_argv;\n  size_t i;\n\n  /* Count number of arguments.  */\n  for (argc = 0; argv[argc] != NULL; argc++)\n    ;\n\n  /* Allocate new argument vector.  */\n  new_argv = XMALLOC (char *, argc + 1);\n\n  /* Put quoted arguments into the new argument vector.  */\n  for (i = 0; i < argc; i++)\n    {\n      const char *string = argv[i];\n\n      if (string[0] == '\\0')\n\tnew_argv[i] = xstrdup (\"\\\"\\\"\");\n      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)\n\t{\n\t  int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);\n\t  size_t length;\n\t  unsigned int backslashes;\n\t  const char *s;\n\t  char *quoted_string;\n\t  char *p;\n\n\t  length = 0;\n\t  backslashes = 0;\n\t  if (quote_around)\n\t    length++;\n\t  for (s = string; *s != '\\0'; s++)\n\t    {\n\t      char c = *s;\n\t      if (c == '\"')\n\t\tlength += backslashes + 1;\n\t      length++;\n\t      if (c == '\\\\')\n\t\tbackslashes++;\n\t      else\n\t\tbackslashes = 0;\n\t    }\n\t  if (quote_around)\n\t    length += backslashes + 1;\n\n\t  quoted_string = XMALLOC (char, length + 1);\n\n\t  p = quoted_string;\n\t  backslashes = 0;\n\t  if (quote_around)\n\t    *p++ = '\"';\n\t  for (s = string; *s != '\\0'; s++)\n\t    {\n\t      char c = *s;\n\t      if (c == '\"')\n\t\t{\n\t\t  unsigned int j;\n\t\t  for (j = backslashes + 1; j > 0; j--)\n\t\t    *p++ = '\\\\';\n\t\t}\n\t      *p++ = c;\n\t      if (c == '\\\\')\n\t\tbackslashes++;\n\t      else\n\t\tbackslashes = 0;\n\t    }\n\t  if (quote_around)\n\t    {\n\t      unsigned int j;\n\t      for (j = backslashes; j > 0; j--)\n\t\t*p++ = '\\\\';\n\t      *p++ = '\"';\n\t    }\n\t  *p = '\\0';\n\n\t  new_argv[i] = quoted_string;\n\t}\n      else\n\tnew_argv[i] = (char *) string;\n    }\n  new_argv[argc] = NULL;\n\n  return new_argv;\n}\nEOF\n\t\t;;\n\t    esac\n\n            cat <<\"EOF\"\nvoid lt_dump_script (FILE* f)\n{\nEOF\n\t    func_emit_wrapper yes |\n\t      $SED -n -e '\ns/^\\(.\\{79\\}\\)\\(..*\\)/\\1\\\n\\2/\nh\ns/\\([\\\\\"]\\)/\\\\\\1/g\ns/$/\\\\n/\ns/\\([^\\n]*\\).*/  fputs (\"\\1\", f);/p\ng\nD'\n            cat <<\"EOF\"\n}\nEOF\n}\n# end: func_emit_cwrapperexe_src\n\n# func_win32_import_lib_p ARG\n# True if ARG is an import lib, as indicated by $file_magic_cmd\nfunc_win32_import_lib_p ()\n{\n    $opt_debug\n    case `eval $file_magic_cmd \\\"\\$1\\\" 2>/dev/null | $SED -e 10q` in\n    *import*) : ;;\n    *) false ;;\n    esac\n}\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    bindir=\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\tbindir)\n\t  bindir=\"$arg\"\n\t  prev=\n\t  continue\n\t  ;;\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      func_append dlfiles \" $arg\"\n\t    else\n\t      func_append 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*) func_append 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      func_append 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      func_append 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    func_append 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    *) func_append rpath \" $arg\" ;;\n\t    esac\n\t  else\n\t    case \"$xrpath \" in\n\t    *\" $arg \"*) ;;\n\t    *) func_append 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  func_append weak_libs \" $arg\"\n\t  prev=\n\t  continue\n\t  ;;\n\txcclinker)\n\t  func_append linker_flags \" $qarg\"\n\t  func_append 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  func_append 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  func_append linker_flags \" $qarg\"\n\t  func_append 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      -bindir)\n\tprev=bindir\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\tif test -z \"$func_stripname_result\"; 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\tfunc_resolve_sysroot \"$func_stripname_result\"\n\tdir=$func_resolve_sysroot_result\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 \"* | *\" $arg \"*)\n\t  # Will only happen for absolute or sysroot arguments\n\t  ;;\n\t*)\n\t  # Preserve sysroot, but never include relative directories\n\t  case $dir in\n\t    [\\\\/]* | [A-Za-z]:[\\\\/]* | =*) func_append deplibs \" $arg\" ;;\n\t    *) func_append deplibs \" -L$dir\" ;;\n\t  esac\n\t  func_append lib_search_path \" $dir\"\n\t  ;;\n\tesac\n\tcase $host in\n\t*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)\n\t  testbindir=`$ECHO \"$dir\" | $SED 's*/lib$*/bin*'`\n\t  case :$dllsearchpath: in\n\t  *\":$dir:\"*) ;;\n\t  ::) dllsearchpath=$dir;;\n\t  *) func_append dllsearchpath \":$dir\";;\n\t  esac\n\t  case :$dllsearchpath: in\n\t  *\":$testbindir:\"*) ;;\n\t  ::) dllsearchpath=$testbindir;;\n\t  *) func_append 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* | *-*-haiku*)\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    func_append 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\tfunc_append 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|--sysroot)\n\tfunc_append 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 \\\n      |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)\n\tfunc_append 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    * ) func_append 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_stripname '=' '' \"$dir\"\n\t  dir=$lt_sysroot$func_stripname_result\n\t  ;;\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*) func_append 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  func_append arg \" $func_quote_for_eval_result\"\n\t  func_append 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  func_append arg \" $wl$func_quote_for_eval_result\"\n\t  func_append compiler_flags \" $wl$func_quote_for_eval_result\"\n\t  func_append 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      # Flags to be passed through unchanged, with rationale:\n      # -64, -mips[0-9]      enable 64-bit mode for the SGI compiler\n      # -r[0-9][0-9]*        specify processor for the SGI compiler\n      # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler\n      # +DA*, +DD*           enable 64-bit mode for the HP compiler\n      # -q*                  compiler args for the IBM compiler\n      # -m*, -t[45]*, -txscale* architecture-specific flags for GCC\n      # -F/path              path to uninstalled frameworks, gcc on darwin\n      # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC\n      # @file                GCC response files\n      # -tp=*                Portland pgcc target processor selection\n      # --sysroot=*          for sysroot support\n      # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization\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*|@*|-tp=*|--sysroot=*| \\\n      -O*|-flto*|-fwhopr*|-fuse-linker-plugin)\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        func_append 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\tfunc_append 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\tfunc_append 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      func_append 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\tfunc_append deplibs \" $arg\"\n\tfunc_append old_deplibs \" $arg\"\n\tcontinue\n\t;;\n\n      *.la)\n\t# A libtool-controlled library.\n\n\tfunc_resolve_sysroot \"$arg\"\n\tif test \"$prev\" = dlfiles; then\n\t  # This library was specified with -dlopen.\n\t  func_append dlfiles \" $func_resolve_sysroot_result\"\n\t  prev=\n\telif test \"$prev\" = dlprefiles; then\n\t  # The library was specified with -dlpreopen.\n\t  func_append dlprefiles \" $func_resolve_sysroot_result\"\n\t  prev=\n\telse\n\t  func_append deplibs \" $func_resolve_sysroot_result\"\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 \\\"\\${$shlibpath_var}\\\" \\| \\$SED \\'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    func_to_tool_file \"$output_objdir/\"\n    tool_output_objdir=$func_to_tool_file_result\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_preserve_dup_deps ; then\n\tcase \"$libs \" in\n\t*\" $deplib \"*) func_append specialdeplibs \" $deplib\" ;;\n\tesac\n      fi\n      func_append 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 \"*) func_append specialdeplibs \" $pre_post_deps\" ;;\n\t  esac\n\t  func_append 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  func_resolve_sysroot \"$lib\"\n\t  case $lib in\n\t  *.la)\tfunc_source \"$func_resolve_sysroot_result\" ;;\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\t    func_basename \"$deplib\"\n            deplib_base=$func_basename_result\n\t    case \" $weak_libs \" in\n\t    *\" $deplib_base \"*) ;;\n\t    *) func_append 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 \\\n        |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)\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    func_append 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    * ) func_append 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    * ) func_append 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    func_resolve_sysroot \"$func_stripname_result\"\n\t    func_append newlib_search_path \" $func_resolve_sysroot_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    func_resolve_sysroot \"$func_stripname_result\"\n\t    func_append newlib_search_path \" $func_resolve_sysroot_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    func_resolve_sysroot \"$func_stripname_result\"\n\t    dir=$func_resolve_sysroot_result\n\t    # Make sure the xrpath contains only unique directories.\n\t    case \"$xrpath \" in\n\t    *\" $dir \"*) ;;\n\t    *) func_append xrpath \" $dir\" ;;\n\t    esac\n\t  fi\n\t  deplibs=\"$deplib $deplibs\"\n\t  continue\n\t  ;;\n\t*.la)\n\t  func_resolve_sysroot \"$deplib\"\n\t  lib=$func_resolve_sysroot_result\n\t  ;;\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 \\\"$deplib\\\"\" 2>/dev/null | $SED 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\techo\n\t\t$ECHO \"*** Warning: Trying to link with static lib archive $deplib.\"\n\t\techo \"*** I have the capability to make that library automatically link in when\"\n\t\techo \"*** you link to this library.  But I can only do this if you have a\"\n\t\techo \"*** shared version of the library, which you do not appear to have\"\n\t\techo \"*** because the file extensions .$libext of this argument makes me believe\"\n\t\techo \"*** that it is just a static archive that I should not use here.\"\n\t      else\n\t\techo\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      func_append newdlprefiles \" $deplib\"\n\t      compile_deplibs=\"$deplib $compile_deplibs\"\n\t      finalize_deplibs=\"$deplib $finalize_deplibs\"\n\t    else\n\t      func_append 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 \"$inherited_linker_flags\" | $SED '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      *) func_append new_inherited_linker_flags \" $tmp_inherited_linker_flag\";;\n\t    esac\n\t  done\n\tfi\n\tdependency_libs=`$ECHO \" $dependency_libs\" | $SED '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\" && func_append dlfiles \" $dlopen\"\n\t  test -n \"$dlpreopen\" && func_append 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    func_append convenience \" $ladir/$objdir/$old_library\"\n\t    func_append 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_preserve_dup_deps ; then\n\t\tcase \"$tmp_libs \" in\n\t\t*\" $deplib \"*) func_append specialdeplibs \" $deplib\" ;;\n\t\tesac\n\t      fi\n\t      func_append 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\tif test -n \"$old_library\" &&\n\t   { test \"$prefer_static_libs\" = yes ||\n\t     test \"$prefer_static_libs,$installed\" = \"built,no\"; }; then\n\t  linklib=$old_library\n\telse\n\t  for l in $old_library $library_names; do\n\t    linklib=\"$l\"\n\t  done\n\tfi\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    func_append dlprefiles \" $lib $dependency_libs\"\n\t  else\n\t    func_append 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 \"$lt_sysroot$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=\"$lt_sysroot$libdir\"\n\t    absdir=\"$lt_sysroot$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    func_append 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    func_append 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  case \"$host\" in\n\t    # special handling for platforms with PE-DLLs.\n\t    *cygwin* | *mingw* | *cegcc* )\n\t      # Linker will automatically link against shared library if both\n\t      # static and shared are present.  Therefore, ensure we extract\n\t      # symbols from the import library if a shared library is present\n\t      # (otherwise, the dlopen module name will be incorrect).  We do\n\t      # this by putting the import library name into $newdlprefiles.\n\t      # We recover the dlopen module name by 'saving' the la file\n\t      # name in a special purpose variable, and (later) extracting the\n\t      # dlname from the la file.\n\t      if test -n \"$dlname\"; then\n\t        func_tr_sh \"$dir/$linklib\"\n\t        eval \"libfile_$func_tr_sh_result=\\$abs_ladir/\\$laname\"\n\t        func_append newdlprefiles \" $dir/$linklib\"\n\t      else\n\t        func_append 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          func_append dlpreconveniencelibs \" $dir/$old_library\"\n\t      fi\n\t    ;;\n\t    * )\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        func_append 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          func_append 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        func_append newdlprefiles \" $dir/$dlname\"\n\t      else\n\t        func_append newdlprefiles \" $dir/$linklib\"\n\t      fi\n\t    ;;\n\t  esac\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  func_append 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         func_resolve_sysroot \"$func_stripname_result\"\n\t         func_append newlib_search_path \" $func_resolve_sysroot_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_preserve_dup_deps ; then\n\t      case \"$tmp_libs \" in\n\t      *\" $deplib \"*) func_append specialdeplibs \" $deplib\" ;;\n\t      esac\n\t    fi\n\t    func_append 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      *) func_append 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      *) func_append 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      *) func_append 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      func_append notinst_deplibs \" $lib\"\n\t      need_relink=no\n\t    ;;\n\t  *)\n\t    if test \"$installed\" = no; then\n\t      func_append 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      *) func_append 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      *) func_append 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 \"$opt_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$absdir\"\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      func_append 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      *) func_append 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*) func_append finalize_shlibpath \"$libdir:\" ;;\n\t\tesac\n\t      fi\n\t    fi\n\t  fi\n\n\t  if test \"$linkmode\" = prog || test \"$opt_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      *) func_append 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    func_append 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\techo\n\t\techo \"*** However, this would only work if libtool was able to extract symbol\"\n\t\techo \"*** lists from a program, using \\`nm' or equivalent, but libtool could\"\n\t\techo \"*** not find such a program.  So, this module is probably useless.\"\n\t\techo \"*** \\`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   *) func_append xrpath \" $temp_xrpath\";;\n\t\t   esac;;\n\t      *) func_append temp_deplibs \" $libdir\";;\n\t      esac\n\t    done\n\t    dependency_libs=\"$temp_deplibs\"\n\t  fi\n\n\t  func_append 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    case $deplib in\n              -L*) func_stripname '-L' '' \"$deplib\"\n                   func_resolve_sysroot \"$func_stripname_result\";;\n              *) func_resolve_sysroot \"$deplib\" ;;\n            esac\n\t    if $opt_preserve_dup_deps ; then\n\t      case \"$tmp_libs \" in\n\t      *\" $func_resolve_sysroot_result \"*)\n                func_append specialdeplibs \" $func_resolve_sysroot_result\" ;;\n\t      esac\n\t    fi\n\t    func_append tmp_libs \" $func_resolve_sysroot_result\"\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_resolve_sysroot \"$deplib\"\n\t        deplib=$func_resolve_sysroot_result\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      func_append compiler_flags \" ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}\"\n\t\t      func_append 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 \" $new_inherited_linker_flags\" | $SED '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    *) func_append 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      *) func_append tmp_libs \" $deplib\" ;;\n\t      esac\n\t      ;;\n\t    *) func_append 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  func_append 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      func_append 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  func_append 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  # correct linux to gnu/linux during the next big refactor\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|qnx|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) # correct to gnu/linux during the next big refactor\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  func_append 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      func_append libobjs \" $symfileobj\"\n      test \"X$libobjs\" = \"X \" && libobjs=\n\n      if test \"$opt_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       func_append 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\tfunc_append oldlibs \" $output_objdir/$libname.$libext\"\n\n\t# Transform .lo files to .o files.\n\toldobjs=\"$objs \"`$ECHO \"$libobjs\" | $SP2NL | $SED \"/\\.${libext}$/d; $lo2o\" | $NL2SP`\n      fi\n\n      # Eliminate all temporary directories.\n      #for path in $notinst_path; do\n      #\tlib_search_path=`$ECHO \"$lib_search_path \" | $SED \"s% $path % %g\"`\n      #\tdeplibs=`$ECHO \"$deplibs \" | $SED \"s% -L$path % %g\"`\n      #\tdependency_libs=`$ECHO \"$dependency_libs \" | $SED \"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  func_replace_sysroot \"$libdir\"\n\t  func_append temp_xrpath \" -R$func_replace_sysroot_result\"\n\t  case \"$finalize_rpath \" in\n\t  *\" $libdir \"*) ;;\n\t  *) func_append 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*) func_append 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*) func_append 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* | *-*-haiku*)\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    func_append 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      func_append 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    func_append 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    func_append 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\tfunc_append 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      func_append 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      func_append 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\tfunc_append 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  func_append 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\tif test -n \"$file_magic_glob\"; then\n\t\t  libnameglob=`func_echo_all \"$libname\" | $SED -e $file_magic_glob`\n\t\telse\n\t\t  libnameglob=$libname\n\t\tfi\n\t\ttest \"$want_nocaseglob\" = yes && nocaseglob=`shopt -p nocaseglob`\n\t\tfor i in $lib_search_path $sys_lib_search_path $shlib_search_path; do\n\t\t  if test \"$want_nocaseglob\" = yes; then\n\t\t    shopt -s nocaseglob\n\t\t    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`\n\t\t    $nocaseglob\n\t\t  else\n\t\t    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`\n\t\t  fi\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 \"$potlib\" | $SED '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\tfunc_append 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\techo\n\t\t$ECHO \"*** Warning: linker path does not have real file for library $a_deplib.\"\n\t\techo \"*** I have the capability to make that library automatically link in when\"\n\t\techo \"*** you link to this library.  But I can only do this if you have a\"\n\t\techo \"*** shared version of the library, which you do not appear to have\"\n\t\techo \"*** 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      func_append 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  func_append 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 \\\"$potent_lib\\\"\" 2>/dev/null | $SED 10q | \\\n\t\t       $EGREP \"$match_pattern_regex\" > /dev/null; then\n\t\t      func_append 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\techo\n\t\t$ECHO \"*** Warning: linker path does not have real file for library $a_deplib.\"\n\t\techo \"*** I have the capability to make that library automatically link in when\"\n\t\techo \"*** you link to this library.  But I can only do this if you have a\"\n\t\techo \"*** shared version of the library, which you do not appear to have\"\n\t\techo \"*** 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      func_append 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 \" $deplibs\" | $SED 's/ -lc$//; 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 \" $tmp_deplibs\" | $SED \"s,$i,,\"`\n\t    done\n\t  fi\n\t  case $tmp_deplibs in\n\t  *[!\\\t\\ ]*)\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    ;;\n\t  esac\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 \" $newdeplibs\" | $SED '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 \" $newdeplibs\" | $SED 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\t  new_inherited_linker_flags=`$ECHO \" $new_inherited_linker_flags\" | $SED 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\t  deplibs=`$ECHO \" $deplibs\" | $SED '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    func_append 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  *) func_append new_libs \" $deplib\" ;;\n\t  esac\n\t  ;;\n\t*) func_append 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\t# Remove ${wl} instances when linking with ld.\n\t# FIXME: should test the right _cmds variable.\n\tcase $archive_cmds in\n\t  *\\$LD\\ *) wl= ;;\n        esac\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 \"$opt_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\tfunc_replace_sysroot \"$libdir\"\n\t\tlibdir=$func_replace_sysroot_result\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    func_append 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\tfunc_append 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      *) func_append 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    eval \"dep_rpath=\\\"$hardcode_libdir_flag_spec\\\"\"\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      func_append 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 \"$opt_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  func_append linknames \" $link\"\n\tdone\n\n\t# Use standard objects if they are pic\n\ttest -z \"$pic_flag\" && libobjs=`$ECHO \"$libobjs\" | $SP2NL | $SED \"$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  func_append 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 cmd1 in $cmds; do\n\t      IFS=\"$save_ifs\"\n\t      # Take the normal branch if the nm_file_list_spec branch\n\t      # doesn't work or if tool conversion is not needed.\n\t      case $nm_file_list_spec~$to_tool_file_cmd in\n\t\t*~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)\n\t\t  try_normal_branch=yes\n\t\t  eval cmd=\\\"$cmd1\\\"\n\t\t  func_len \" $cmd\"\n\t\t  len=$func_len_result\n\t\t  ;;\n\t\t*)\n\t\t  try_normal_branch=no\n\t\t  ;;\n\t      esac\n\t      if test \"$try_normal_branch\" = yes \\\n\t\t && { test \"$len\" -lt \"$max_cmd_len\" \\\n\t\t      || test \"$max_cmd_len\" -le -1; }\n\t      then\n\t\tfunc_show_eval \"$cmd\" 'exit $?'\n\t\tskipped_export=false\n\t      elif test -n \"$nm_file_list_spec\"; then\n\t\tfunc_basename \"$output\"\n\t\toutput_la=$func_basename_result\n\t\tsave_libobjs=$libobjs\n\t\tsave_output=$output\n\t\toutput=${output_objdir}/${output_la}.nm\n\t\tfunc_to_tool_file \"$output\"\n\t\tlibobjs=$nm_file_list_spec$func_to_tool_file_result\n\t\tfunc_append delfiles \" $output\"\n\t\tfunc_verbose \"creating $NM input file list: $output\"\n\t\tfor obj in $save_libobjs; do\n\t\t  func_to_tool_file \"$obj\"\n\t\t  $ECHO \"$func_to_tool_file_result\"\n\t\tdone > \"$output\"\n\t\teval cmd=\\\"$cmd1\\\"\n\t\tfunc_show_eval \"$cmd\" 'exit $?'\n\t\toutput=$save_output\n\t\tlibobjs=$save_libobjs\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 \"$include_expsyms\" | $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  func_append 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    func_append 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    func_append generated \" $gentop\"\n\n\t    func_extract_archives $gentop $convenience\n\t    func_append 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  func_append linker_flags \" $flag\"\n\tfi\n\n\t# Make a backup of the uninstalled library when relinking\n\tif test \"$opt_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  func_basename \"$output\"\n\t  output_la=$func_basename_result\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      func_to_tool_file \"$obj\"\n\t      $ECHO \"$func_to_tool_file_result\" >> $output\n\t    done\n\t    echo ')' >> $output\n\t    func_append delfiles \" $output\"\n\t    func_to_tool_file \"$output\"\n\t    output=$func_to_tool_file_result\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      func_to_tool_file \"$obj\"\n\t      $ECHO \"$func_to_tool_file_result\" >> $output\n\t    done\n\t    func_append delfiles \" $output\"\n\t    func_to_tool_file \"$output\"\n\t    output=$firstobj\\\"$file_list_spec$func_to_tool_file_result\\\"\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    reload_objs=$objlist\n\t\t    eval concat_cmds=\\\"$reload_cmds\\\"\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    reload_objs=\"$objlist $last_robj\"\n\t\t    eval concat_cmds=\\\"\\$concat_cmds~$reload_cmds~\\$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      reload_objs=\"$objlist $last_robj\"\n\t      eval concat_cmds=\\\"\\${concat_cmds}$reload_cmds\\\"\n\t      if test -n \"$last_robj\"; then\n\t        eval concat_cmds=\\\"\\${concat_cmds}~\\$RM $last_robj\\\"\n\t      fi\n\t      func_append 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 \"$opt_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 \"$include_expsyms\" | $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      func_append 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  func_append generated \" $gentop\"\n\n\t  func_extract_archives $gentop $dlprefiles\n\t  func_append 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 \"$opt_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 \"$opt_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 \"$tmp_whole_archive_flags\" | $SED 's|,| |g'`\n\telse\n\t  gentop=\"$output_objdir/${obj}x\"\n\t  func_append 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      # If we're not building shared, we need to use non_pic_objs\n      test \"$build_libtool_libs\" != yes && libobjs=\"$non_pic_objects\"\n\n      # Create the old-style object.\n      reload_objs=\"$objs$old_deplibs \"`$ECHO \"$libobjs\" | $SP2NL | $SED \"/\\.${libext}$/d; /\\.lib$/d; $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 \" $compile_deplibs\" | $SED 's/ -lc / System.ltframework /'`\n\tfinalize_deplibs=`$ECHO \" $finalize_deplibs\" | $SED '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      func_append compile_command \" ${wl}-bind_at_load\"\n\t      func_append 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 \" $compile_deplibs\" | $SED 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\tfinalize_deplibs=`$ECHO \" $finalize_deplibs\" | $SED '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    func_append 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  *) func_append new_libs \" $deplib\" ;;\n\t  esac\n\t  ;;\n\t*) func_append new_libs \" $deplib\" ;;\n\tesac\n      done\n      compile_deplibs=\"$new_libs\"\n\n\n      func_append compile_command \" $compile_deplibs\"\n      func_append 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  *) func_append 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\tfunc_append 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    func_append rpath \" $flag\"\n\t  fi\n\telif test -n \"$runpath_var\"; then\n\t  case \"$perm_rpath \" in\n\t  *\" $libdir \"*) ;;\n\t  *) func_append 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  *) func_append dllsearchpath \":$libdir\";;\n\t  esac\n\t  case :$dllsearchpath: in\n\t  *\":$testbindir:\"*) ;;\n\t  ::) dllsearchpath=$testbindir;;\n\t  *) func_append 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\tfunc_append 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    func_append rpath \" $flag\"\n\t  fi\n\telif test -n \"$runpath_var\"; then\n\t  case \"$finalize_perm_rpath \" in\n\t  *\" $libdir \"*) ;;\n\t  *) func_append 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 \"$compile_command\" | $SP2NL | $SED \"$lo2o\" | $NL2SP`\n\tfinalize_command=`$ECHO \"$finalize_command\" | $SP2NL | $SED \"$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      *cegcc* | *mingw32ce*)\n        # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.\n        wrappers_required=no\n        ;;\n      *cygwin* | *mingw* )\n        if test \"$build_libtool_libs\" != yes; then\n          wrappers_required=no\n        fi\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 \"$compile_command\" | $SED '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\tif test -n \"$postlink_cmds\"; then\n\t  func_to_tool_file \"$output\"\n\t  postlink_cmds=`func_echo_all \"$postlink_cmds\" | $SED -e 's%@OUTPUT@%'\"$output\"'%g' -e 's%@TOOL_OUTPUT@%'\"$func_to_tool_file_result\"'%g'`\n\t  func_execute_cmds \"$postlink_cmds\" 'exit $?'\n\tfi\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    func_append 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    func_append 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 \"$link_command\" | $SED '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\n\tif test -n \"$postlink_cmds\"; then\n\t  func_to_tool_file \"$output\"\n\t  postlink_cmds=`func_echo_all \"$postlink_cmds\" | $SED -e 's%@OUTPUT@%'\"$output\"'%g' -e 's%@TOOL_OUTPUT@%'\"$func_to_tool_file_result\"'%g'`\n\t  func_execute_cmds \"$postlink_cmds\" 'exit $?'\n\tfi\n\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 \"$compile_var$compile_command$compile_rpath\" | $SED '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 \"$link_command\" | $SED '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      if test -n \"$postlink_cmds\"; then\n\tfunc_to_tool_file \"$output_objdir/$outputname\"\n\tpostlink_cmds=`func_echo_all \"$postlink_cmds\" | $SED -e 's%@OUTPUT@%'\"$output_objdir/$outputname\"'%g' -e 's%@TOOL_OUTPUT@%'\"$func_to_tool_file_result\"'%g'`\n\tfunc_execute_cmds \"$postlink_cmds\" 'exit $?'\n      fi\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 \"$relink_command\" | $SED \"$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    func_append 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\tfunc_append generated \" $gentop\"\n\n\tfunc_extract_archives $gentop $addlibs\n\tfunc_append 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  func_append generated \" $gentop\"\n\n\t  func_extract_archives $gentop $dlprefiles\n\t  func_append 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  func_append 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      func_append oldobjs \" $gentop/$newobj\"\n\t      ;;\n\t    *) func_append oldobjs \" $obj\" ;;\n\t    esac\n\t  done\n\tfi\n\tfunc_to_tool_file \"$oldlib\" func_convert_file_msys_to_w32\n\ttool_oldlib=$func_to_tool_file_result\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\telif test -n \"$archiver_list_spec\"; then\n\t  func_verbose \"using command file archive linking...\"\n\t  for obj in $oldobjs\n\t  do\n\t    func_to_tool_file \"$obj\"\n\t    $ECHO \"$func_to_tool_file_result\"\n\t  done > $output_objdir/$libname.libcmd\n\t  func_to_tool_file \"$output_objdir/$libname.libcmd\"\n\t  oldobjs=\" $archiver_list_spec$func_to_tool_file_result\"\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 \"$relink_command\" | $SED \"$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\tfunc_resolve_sysroot \"$deplib\"\n\t\teval libdir=`${SED} -n -e 's/^libdir=\\(.*\\)$/\\1/p' $func_resolve_sysroot_result`\n\t\ttest -z \"$libdir\" && \\\n\t\t  func_fatal_error \"\\`$deplib' is not a valid libtool archive\"\n\t\tfunc_append newdependency_libs \" ${lt_sysroot:+=}$libdir/$name\"\n\t\t;;\n\t      -L*)\n\t\tfunc_stripname -L '' \"$deplib\"\n\t\tfunc_replace_sysroot \"$func_stripname_result\"\n\t\tfunc_append newdependency_libs \" -L$func_replace_sysroot_result\"\n\t\t;;\n\t      -R*)\n\t\tfunc_stripname -R '' \"$deplib\"\n\t\tfunc_replace_sysroot \"$func_stripname_result\"\n\t\tfunc_append newdependency_libs \" -R$func_replace_sysroot_result\"\n\t\t;;\n\t      *) func_append 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\tfunc_append newdlfiles \" ${lt_sysroot:+=}$libdir/$name\"\n\t\t;;\n\t      *) func_append 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\tfunc_append newdlprefiles \" ${lt_sysroot:+=}$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      func_append 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      func_append 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  # In fact, it would be nice if we could use this code for all target\n\t  # systems that can't hard-code library paths into their executables\n\t  # and that have no shared library path variable independent of PATH,\n\t  # but it turns out we can't easily determine that from inspecting\n\t  # libtool variables, so we have to hard-code the OSs to which it\n\t  # applies here; at the moment, that means platforms that use the PE\n\t  # object format with DLL files.  See the long comment at the top of\n\t  # tests/bindir.at for full details.\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)\n\t      # If a -bindir argument was supplied, place the dll there.\n\t      if test \"x$bindir\" != x ;\n\t      then\n\t\tfunc_relative_path \"$install_libdir\" \"$bindir\"\n\t\ttdlname=$func_relative_path_result$dlname\n\t      else\n\t\t# Otherwise fall back on heuristic.\n\t\ttdlname=../bin/$dlname\n\t      fi\n\t      ;;\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 \"$opt_mode\" = link || test \"$opt_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) func_append RM \" $arg\"; rmforce=yes ;;\n      -*) func_append RM \" $arg\" ;;\n      *) func_append 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    for file in $files; do\n      func_dirname \"$file\" \"\" \".\"\n      dir=\"$func_dirname_result\"\n      if test \"X$dir\" = X.; then\n\todir=\"$objdir\"\n      else\n\todir=\"$dir/$objdir\"\n      fi\n      func_basename \"$file\"\n      name=\"$func_basename_result\"\n      test \"$opt_mode\" = uninstall && odir=\"$dir\"\n\n      # Remember odir for removal later, being careful to avoid duplicates\n      if test \"$opt_mode\" = clean; then\n\tcase \" $rmdirs \" in\n\t  *\" $odir \"*) ;;\n\t  *) func_append rmdirs \" $odir\" ;;\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    func_append rmfiles \" $odir/$n\"\n\t  done\n\t  test -n \"$old_library\" && func_append rmfiles \" $odir/$old_library\"\n\n\t  case \"$opt_mode\" in\n\t  clean)\n\t    case \" $library_names \" in\n\t    *\" $dlname \"*) ;;\n\t    *) test -n \"$dlname\" && func_append rmfiles \" $odir/$dlname\" ;;\n\t    esac\n\t    test -n \"$libdir\" && func_append rmfiles \" $odir/$name $odir/${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    func_append 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    func_append rmfiles \" $dir/$non_pic_object\"\n\t  fi\n\tfi\n\t;;\n\n      *)\n\tif test \"$opt_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    func_append 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      func_append 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    func_append rmfiles \" $odir/$name $odir/${name}S.${objext}\"\n\t    if test \"$fast_install\" = yes && test -n \"$relink_command\"; then\n\t      func_append rmfiles \" $odir/lt-$name\"\n\t    fi\n\t    if test \"X$noexename\" != \"X$name\" ; then\n\t      func_append rmfiles \" $odir/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\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 \"$opt_mode\" = uninstall || test \"$opt_mode\" = clean; } &&\n    func_mode_uninstall ${1+\"$@\"}\n\ntest -z \"$opt_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 \\`$opt_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": "deps/snappy-1.1.0/m4/gtest.m4",
    "content": "dnl GTEST_LIB_CHECK([minimum version [,\ndnl                  action if found [,action if not found]]])\ndnl\ndnl Check for the presence of the Google Test library, optionally at a minimum\ndnl version, and indicate a viable version with the HAVE_GTEST flag. It defines\ndnl standard variables for substitution including GTEST_CPPFLAGS,\ndnl GTEST_CXXFLAGS, GTEST_LDFLAGS, and GTEST_LIBS. It also defines\ndnl GTEST_VERSION as the version of Google Test found. Finally, it provides\ndnl optional custom action slots in the event GTEST is found or not.\nAC_DEFUN([GTEST_LIB_CHECK],\n[\ndnl Provide a flag to enable or disable Google Test usage.\nAC_ARG_ENABLE([gtest],\n  [AS_HELP_STRING([--enable-gtest],\n                  [Enable tests using the Google C++ Testing Framework.\n                  (Default is enabled.)])],\n  [],\n  [enable_gtest=])\nAC_ARG_VAR([GTEST_CONFIG],\n           [The exact path of Google Test's 'gtest-config' script.])\nAC_ARG_VAR([GTEST_CPPFLAGS],\n           [C-like preprocessor flags for Google Test.])\nAC_ARG_VAR([GTEST_CXXFLAGS],\n           [C++ compile flags for Google Test.])\nAC_ARG_VAR([GTEST_LDFLAGS],\n           [Linker path and option flags for Google Test.])\nAC_ARG_VAR([GTEST_LIBS],\n           [Library linking flags for Google Test.])\nAC_ARG_VAR([GTEST_VERSION],\n           [The version of Google Test available.])\nHAVE_GTEST=\"no\"\nAS_IF([test \"x${enable_gtest}\" != \"xno\"],\n  [AC_MSG_CHECKING([for 'gtest-config'])\n   AS_IF([test \"x${enable_gtest}\" = \"xyes\"],\n     [AS_IF([test -x \"${enable_gtest}/scripts/gtest-config\"],\n        [GTEST_CONFIG=\"${enable_gtest}/scripts/gtest-config\"],\n        [GTEST_CONFIG=\"${enable_gtest}/bin/gtest-config\"])\n      AS_IF([test -x \"${GTEST_CONFIG}\"], [],\n        [AC_MSG_RESULT([no])\n         AC_MSG_ERROR([dnl\nUnable to locate either a built or installed Google Test.\nThe specific location '${enable_gtest}' was provided for a built or installed\nGoogle Test, but no 'gtest-config' script could be found at this location.])\n         ])],\n     [AC_PATH_PROG([GTEST_CONFIG], [gtest-config])])\n   AS_IF([test -x \"${GTEST_CONFIG}\"],\n     [AC_MSG_RESULT([${GTEST_CONFIG}])\n      m4_ifval([$1],\n        [_gtest_min_version=\"--min-version=$1\"\n         AC_MSG_CHECKING([for Google Test at least version >= $1])],\n        [_gtest_min_version=\"--min-version=0\"\n         AC_MSG_CHECKING([for Google Test])])\n      AS_IF([${GTEST_CONFIG} ${_gtest_min_version}],\n        [AC_MSG_RESULT([yes])\n         HAVE_GTEST='yes'],\n        [AC_MSG_RESULT([no])])],\n     [AC_MSG_RESULT([no])])\n   AS_IF([test \"x${HAVE_GTEST}\" = \"xyes\"],\n     [GTEST_CPPFLAGS=`${GTEST_CONFIG} --cppflags`\n      GTEST_CXXFLAGS=`${GTEST_CONFIG} --cxxflags`\n      GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags`\n      GTEST_LIBS=`${GTEST_CONFIG} --libs`\n      GTEST_VERSION=`${GTEST_CONFIG} --version`\n      AC_DEFINE([HAVE_GTEST],[1],[Defined when Google Test is available.])],\n     [AS_IF([test \"x${enable_gtest}\" = \"xyes\"],\n        [AC_MSG_ERROR([dnl\nGoogle Test was enabled, but no viable version could be found.])\n         ])])])\nAC_SUBST([HAVE_GTEST])\nAM_CONDITIONAL([HAVE_GTEST],[test \"x$HAVE_GTEST\" = \"xyes\"])\nAS_IF([test \"x$HAVE_GTEST\" = \"xyes\"],\n  [m4_ifval([$2], [$2])],\n  [m4_ifval([$3], [$3])])\n])\n"
  },
  {
    "path": "deps/snappy-1.1.0/missing",
    "content": "#! /bin/sh\n# Common stub for a few missing GNU programs while installing.\n\nscriptversion=2012-01-06.13; # UTC\n\n# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,\n# 2008, 2009, 2010, 2011, 2012 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, see <http://www.gnu.org/licenses/>.\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=:\nsed_output='s/.* --output[ =]\\([^ ]*\\).*/\\1/p'\nsed_minuso='s/.* -o \\([^ ]*\\).*/\\1/p'\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  autom4te     touch the output file, or create a stub one\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  yacc         create \\`y.tab.[ch]', if possible, from existing .[ch]\n\nVersion suffixes to PROGRAM as well as the prefixes \\`gnu-', \\`gnu', and\n\\`g' are ignored when checking the name.\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# normalize program name to check for.\nprogram=`echo \"$1\" | sed '\n  s/^gnu-//; t\n  s/^gnu//; t\n  s/^g//; t'`\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).  This is about non-GNU programs, so use $1 not\n# $program.\ncase $1 in\n  lex*|yacc*)\n    # Not GNU programs, they don't have --version.\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 $program 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 \"$sed_output\"`\n    test -z \"$file\" && file=`echo \"$*\" | sed -n \"$sed_minuso\"`\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 test $# -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 test -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 test -f \"$SRCFILE\"; then\n\t         cp \"$SRCFILE\" y.tab.h\n\t    fi\n\t  ;;\n\tesac\n    fi\n    if test ! -f y.tab.h; then\n\techo >y.tab.h\n    fi\n    if test ! -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 test $# -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 test -f \"$SRCFILE\"; then\n\t         cp \"$SRCFILE\" lex.yy.c\n\t    fi\n\t  ;;\n\tesac\n    fi\n    if test ! -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 \"$sed_output\"`\n    test -z \"$file\" && file=`echo \"$*\" | sed -n \"$sed_minuso\"`\n    if test -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 $?\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 \"$sed_output\"`\n    test -z \"$file\" && file=`echo \"$*\" | sed -n \"$sed_minuso\"`\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 '\n\t/^@setfilename/{\n\t  s/.* \\([^ ]*\\) *$/\\1/\n\t  p\n\t  q\n\t}' $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  *)\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-time-zone: \"UTC\"\n# time-stamp-end: \"; # UTC\"\n# End:\n"
  },
  {
    "path": "deps/snappy-1.1.0/snappy-c.cc",
    "content": "// Copyright 2011 Martin Gieseking <martin.gieseking@uos.de>.\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 \"snappy.h\"\n#include \"snappy-c.h\"\n\nextern \"C\" {\n\nsnappy_status snappy_compress(const char* input,\n                              size_t input_length,\n                              char* compressed,\n                              size_t *compressed_length) {\n  if (*compressed_length < snappy_max_compressed_length(input_length)) {\n    return SNAPPY_BUFFER_TOO_SMALL;\n  }\n  snappy::RawCompress(input, input_length, compressed, compressed_length);\n  return SNAPPY_OK;\n}\n\nsnappy_status snappy_uncompress(const char* compressed,\n                                size_t compressed_length,\n                                char* uncompressed,\n                                size_t* uncompressed_length) {\n  size_t real_uncompressed_length;\n  if (!snappy::GetUncompressedLength(compressed,\n                                     compressed_length,\n                                     &real_uncompressed_length)) {\n    return SNAPPY_INVALID_INPUT;\n  }\n  if (*uncompressed_length < real_uncompressed_length) {\n    return SNAPPY_BUFFER_TOO_SMALL;\n  }\n  if (!snappy::RawUncompress(compressed, compressed_length, uncompressed)) {\n    return SNAPPY_INVALID_INPUT;\n  }\n  *uncompressed_length = real_uncompressed_length;\n  return SNAPPY_OK;\n}\n\nsize_t snappy_max_compressed_length(size_t source_length) {\n  return snappy::MaxCompressedLength(source_length);\n}\n\nsnappy_status snappy_uncompressed_length(const char *compressed,\n                                         size_t compressed_length,\n                                         size_t *result) {\n  if (snappy::GetUncompressedLength(compressed,\n                                    compressed_length,\n                                    result)) {\n    return SNAPPY_OK;\n  } else {\n    return SNAPPY_INVALID_INPUT;\n  }\n}\n\nsnappy_status snappy_validate_compressed_buffer(const char *compressed,\n                                                size_t compressed_length) {\n  if (snappy::IsValidCompressedBuffer(compressed, compressed_length)) {\n    return SNAPPY_OK;\n  } else {\n    return SNAPPY_INVALID_INPUT;\n  }\n}\n\n}  // extern \"C\"\n"
  },
  {
    "path": "deps/snappy-1.1.0/snappy-c.h",
    "content": "/*\n * Copyright 2011 Martin Gieseking <martin.gieseking@uos.de>.\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 * Plain C interface (a wrapper around the C++ implementation).\n */\n\n#ifndef UTIL_SNAPPY_OPENSOURCE_SNAPPY_C_H_\n#define UTIL_SNAPPY_OPENSOURCE_SNAPPY_C_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stddef.h>\n\n/*\n * Return values; see the documentation for each function to know\n * what each can return.\n */\ntypedef enum {\n  SNAPPY_OK = 0,\n  SNAPPY_INVALID_INPUT = 1,\n  SNAPPY_BUFFER_TOO_SMALL = 2\n} snappy_status;\n\n/*\n * Takes the data stored in \"input[0..input_length-1]\" and stores\n * it in the array pointed to by \"compressed\".\n *\n * <compressed_length> signals the space available in \"compressed\".\n * If it is not at least equal to \"snappy_max_compressed_length(input_length)\",\n * SNAPPY_BUFFER_TOO_SMALL is returned. After successful compression,\n * <compressed_length> contains the true length of the compressed output,\n * and SNAPPY_OK is returned.\n *\n * Example:\n *   size_t output_length = snappy_max_compressed_length(input_length);\n *   char* output = (char*)malloc(output_length);\n *   if (snappy_compress(input, input_length, output, &output_length)\n *       == SNAPPY_OK) {\n *     ... Process(output, output_length) ...\n *   }\n *   free(output);\n */\nsnappy_status snappy_compress(const char* input,\n                              size_t input_length,\n                              char* compressed,\n                              size_t* compressed_length);\n\n/*\n * Given data in \"compressed[0..compressed_length-1]\" generated by\n * calling the snappy_compress routine, this routine stores\n * the uncompressed data to\n *   uncompressed[0..uncompressed_length-1].\n * Returns failure (a value not equal to SNAPPY_OK) if the message\n * is corrupted and could not be decrypted.\n *\n * <uncompressed_length> signals the space available in \"uncompressed\".\n * If it is not at least equal to the value returned by\n * snappy_uncompressed_length for this stream, SNAPPY_BUFFER_TOO_SMALL\n * is returned. After successful decompression, <uncompressed_length>\n * contains the true length of the decompressed output.\n *\n * Example:\n *   size_t output_length;\n *   if (snappy_uncompressed_length(input, input_length, &output_length)\n *       != SNAPPY_OK) {\n *     ... fail ...\n *   }\n *   char* output = (char*)malloc(output_length);\n *   if (snappy_uncompress(input, input_length, output, &output_length)\n *       == SNAPPY_OK) {\n *     ... Process(output, output_length) ...\n *   }\n *   free(output);\n */\nsnappy_status snappy_uncompress(const char* compressed,\n                                size_t compressed_length,\n                                char* uncompressed,\n                                size_t* uncompressed_length);\n\n/*\n * Returns the maximal size of the compressed representation of\n * input data that is \"source_length\" bytes in length.\n */\nsize_t snappy_max_compressed_length(size_t source_length);\n\n/*\n * REQUIRES: \"compressed[]\" was produced by snappy_compress()\n * Returns SNAPPY_OK and stores the length of the uncompressed data in\n * *result normally. Returns SNAPPY_INVALID_INPUT on parsing error.\n * This operation takes O(1) time.\n */\nsnappy_status snappy_uncompressed_length(const char* compressed,\n                                         size_t compressed_length,\n                                         size_t* result);\n\n/*\n * Check if the contents of \"compressed[]\" can be uncompressed successfully.\n * Does not return the uncompressed data; if so, returns SNAPPY_OK,\n * or if not, returns SNAPPY_INVALID_INPUT.\n * Takes time proportional to compressed_length, but is usually at least a\n * factor of four faster than actual decompression.\n */\nsnappy_status snappy_validate_compressed_buffer(const char* compressed,\n                                                size_t compressed_length);\n\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif\n\n#endif  /* UTIL_SNAPPY_OPENSOURCE_SNAPPY_C_H_ */\n"
  },
  {
    "path": "deps/snappy-1.1.0/snappy-internal.h",
    "content": "// Copyright 2008 Google Inc. 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// Internals shared between the Snappy implementation and its unittest.\n\n#ifndef UTIL_SNAPPY_SNAPPY_INTERNAL_H_\n#define UTIL_SNAPPY_SNAPPY_INTERNAL_H_\n\n#include \"snappy-stubs-internal.h\"\n\nnamespace snappy {\nnamespace internal {\n\nclass WorkingMemory {\n public:\n  WorkingMemory() : large_table_(NULL) { }\n  ~WorkingMemory() { delete[] large_table_; }\n\n  // Allocates and clears a hash table using memory in \"*this\",\n  // stores the number of buckets in \"*table_size\" and returns a pointer to\n  // the base of the hash table.\n  uint16* GetHashTable(size_t input_size, int* table_size);\n\n private:\n  uint16 small_table_[1<<10];    // 2KB\n  uint16* large_table_;          // Allocated only when needed\n\n  DISALLOW_COPY_AND_ASSIGN(WorkingMemory);\n};\n\n// Flat array compression that does not emit the \"uncompressed length\"\n// prefix. Compresses \"input\" string to the \"*op\" buffer.\n//\n// REQUIRES: \"input_length <= kBlockSize\"\n// REQUIRES: \"op\" points to an array of memory that is at least\n// \"MaxCompressedLength(input_length)\" in size.\n// REQUIRES: All elements in \"table[0..table_size-1]\" are initialized to zero.\n// REQUIRES: \"table_size\" is a power of two\n//\n// Returns an \"end\" pointer into \"op\" buffer.\n// \"end - op\" is the compressed size of \"input\".\nchar* CompressFragment(const char* input,\n                       size_t input_length,\n                       char* op,\n                       uint16* table,\n                       const int table_size);\n\n// Return the largest n such that\n//\n//   s1[0,n-1] == s2[0,n-1]\n//   and n <= (s2_limit - s2).\n//\n// Does not read *s2_limit or beyond.\n// Does not read *(s1 + (s2_limit - s2)) or beyond.\n// Requires that s2_limit >= s2.\n//\n// Separate implementation for x86_64, for speed.  Uses the fact that\n// x86_64 is little endian.\n#if defined(ARCH_K8)\nstatic inline int FindMatchLength(const char* s1,\n                                  const char* s2,\n                                  const char* s2_limit) {\n  assert(s2_limit >= s2);\n  int matched = 0;\n\n  // Find out how long the match is. We loop over the data 64 bits at a\n  // time until we find a 64-bit block that doesn't match; then we find\n  // the first non-matching bit and use that to calculate the total\n  // length of the match.\n  while (PREDICT_TRUE(s2 <= s2_limit - 8)) {\n    if (PREDICT_FALSE(UNALIGNED_LOAD64(s2) == UNALIGNED_LOAD64(s1 + matched))) {\n      s2 += 8;\n      matched += 8;\n    } else {\n      // On current (mid-2008) Opteron models there is a 3% more\n      // efficient code sequence to find the first non-matching byte.\n      // However, what follows is ~10% better on Intel Core 2 and newer,\n      // and we expect AMD's bsf instruction to improve.\n      uint64 x = UNALIGNED_LOAD64(s2) ^ UNALIGNED_LOAD64(s1 + matched);\n      int matching_bits = Bits::FindLSBSetNonZero64(x);\n      matched += matching_bits >> 3;\n      return matched;\n    }\n  }\n  while (PREDICT_TRUE(s2 < s2_limit)) {\n    if (PREDICT_TRUE(s1[matched] == *s2)) {\n      ++s2;\n      ++matched;\n    } else {\n      return matched;\n    }\n  }\n  return matched;\n}\n#else\nstatic inline int FindMatchLength(const char* s1,\n                                  const char* s2,\n                                  const char* s2_limit) {\n  // Implementation based on the x86-64 version, above.\n  assert(s2_limit >= s2);\n  int matched = 0;\n\n  while (s2 <= s2_limit - 4 &&\n         UNALIGNED_LOAD32(s2) == UNALIGNED_LOAD32(s1 + matched)) {\n    s2 += 4;\n    matched += 4;\n  }\n  if (LittleEndian::IsLittleEndian() && s2 <= s2_limit - 4) {\n    uint32 x = UNALIGNED_LOAD32(s2) ^ UNALIGNED_LOAD32(s1 + matched);\n    int matching_bits = Bits::FindLSBSetNonZero(x);\n    matched += matching_bits >> 3;\n  } else {\n    while ((s2 < s2_limit) && (s1[matched] == *s2)) {\n      ++s2;\n      ++matched;\n    }\n  }\n  return matched;\n}\n#endif\n\n}  // end namespace internal\n}  // end namespace snappy\n\n#endif  // UTIL_SNAPPY_SNAPPY_INTERNAL_H_\n"
  },
  {
    "path": "deps/snappy-1.1.0/snappy-sinksource.cc",
    "content": "// Copyright 2011 Google Inc. 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 <string.h>\n\n#include \"snappy-sinksource.h\"\n\nnamespace snappy {\n\nSource::~Source() { }\n\nSink::~Sink() { }\n\nchar* Sink::GetAppendBuffer(size_t length, char* scratch) {\n  return scratch;\n}\n\nByteArraySource::~ByteArraySource() { }\n\nsize_t ByteArraySource::Available() const { return left_; }\n\nconst char* ByteArraySource::Peek(size_t* len) {\n  *len = left_;\n  return ptr_;\n}\n\nvoid ByteArraySource::Skip(size_t n) {\n  left_ -= n;\n  ptr_ += n;\n}\n\nUncheckedByteArraySink::~UncheckedByteArraySink() { }\n\nvoid UncheckedByteArraySink::Append(const char* data, size_t n) {\n  // Do no copying if the caller filled in the result of GetAppendBuffer()\n  if (data != dest_) {\n    memcpy(dest_, data, n);\n  }\n  dest_ += n;\n}\n\nchar* UncheckedByteArraySink::GetAppendBuffer(size_t len, char* scratch) {\n  return dest_;\n}\n\n}\n"
  },
  {
    "path": "deps/snappy-1.1.0/snappy-sinksource.h",
    "content": "// Copyright 2011 Google Inc. 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 UTIL_SNAPPY_SNAPPY_SINKSOURCE_H_\n#define UTIL_SNAPPY_SNAPPY_SINKSOURCE_H_\n\n#include <stddef.h>\n\n\nnamespace snappy {\n\n// A Sink is an interface that consumes a sequence of bytes.\nclass Sink {\n public:\n  Sink() { }\n  virtual ~Sink();\n\n  // Append \"bytes[0,n-1]\" to this.\n  virtual void Append(const char* bytes, size_t n) = 0;\n\n  // Returns a writable buffer of the specified length for appending.\n  // May return a pointer to the caller-owned scratch buffer which\n  // must have at least the indicated length.  The returned buffer is\n  // only valid until the next operation on this Sink.\n  //\n  // After writing at most \"length\" bytes, call Append() with the\n  // pointer returned from this function and the number of bytes\n  // written.  Many Append() implementations will avoid copying\n  // bytes if this function returned an internal buffer.\n  //\n  // If a non-scratch buffer is returned, the caller may only pass a\n  // prefix of it to Append().  That is, it is not correct to pass an\n  // interior pointer of the returned array to Append().\n  //\n  // The default implementation always returns the scratch buffer.\n  virtual char* GetAppendBuffer(size_t length, char* scratch);\n\n\n private:\n  // No copying\n  Sink(const Sink&);\n  void operator=(const Sink&);\n};\n\n// A Source is an interface that yields a sequence of bytes\nclass Source {\n public:\n  Source() { }\n  virtual ~Source();\n\n  // Return the number of bytes left to read from the source\n  virtual size_t Available() const = 0;\n\n  // Peek at the next flat region of the source.  Does not reposition\n  // the source.  The returned region is empty iff Available()==0.\n  //\n  // Returns a pointer to the beginning of the region and store its\n  // length in *len.\n  //\n  // The returned region is valid until the next call to Skip() or\n  // until this object is destroyed, whichever occurs first.\n  //\n  // The returned region may be larger than Available() (for example\n  // if this ByteSource is a view on a substring of a larger source).\n  // The caller is responsible for ensuring that it only reads the\n  // Available() bytes.\n  virtual const char* Peek(size_t* len) = 0;\n\n  // Skip the next n bytes.  Invalidates any buffer returned by\n  // a previous call to Peek().\n  // REQUIRES: Available() >= n\n  virtual void Skip(size_t n) = 0;\n\n private:\n  // No copying\n  Source(const Source&);\n  void operator=(const Source&);\n};\n\n// A Source implementation that yields the contents of a flat array\nclass ByteArraySource : public Source {\n public:\n  ByteArraySource(const char* p, size_t n) : ptr_(p), left_(n) { }\n  virtual ~ByteArraySource();\n  virtual size_t Available() const;\n  virtual const char* Peek(size_t* len);\n  virtual void Skip(size_t n);\n private:\n  const char* ptr_;\n  size_t left_;\n};\n\n// A Sink implementation that writes to a flat array without any bound checks.\nclass UncheckedByteArraySink : public Sink {\n public:\n  explicit UncheckedByteArraySink(char* dest) : dest_(dest) { }\n  virtual ~UncheckedByteArraySink();\n  virtual void Append(const char* data, size_t n);\n  virtual char* GetAppendBuffer(size_t len, char* scratch);\n\n  // Return the current output pointer so that a caller can see how\n  // many bytes were produced.\n  // Note: this is not a Sink method.\n  char* CurrentDestination() const { return dest_; }\n private:\n  char* dest_;\n};\n\n\n}\n\n#endif  // UTIL_SNAPPY_SNAPPY_SINKSOURCE_H_\n"
  },
  {
    "path": "deps/snappy-1.1.0/snappy-stubs-internal.cc",
    "content": "// Copyright 2011 Google Inc. 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 <algorithm>\n#include <string>\n\n#include \"snappy-stubs-internal.h\"\n\nnamespace snappy {\n\nvoid Varint::Append32(string* s, uint32 value) {\n  char buf[Varint::kMax32];\n  const char* p = Varint::Encode32(buf, value);\n  s->append(buf, p - buf);\n}\n\n}  // namespace snappy\n"
  },
  {
    "path": "deps/snappy-1.1.0/snappy-stubs-internal.h",
    "content": "// Copyright 2011 Google Inc. 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// Various stubs for the open-source version of Snappy.\n\n#ifndef UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_\n#define UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <string>\n\n#include <assert.h>\n#include <stdlib.h>\n#include <string.h>\n\n#ifdef HAVE_SYS_MMAN_H\n#include <sys/mman.h>\n#endif\n\n#include \"snappy-stubs-public.h\"\n\n#if defined(__x86_64__)\n\n// Enable 64-bit optimized versions of some routines.\n#define ARCH_K8 1\n\n#endif\n\n// Needed by OS X, among others.\n#ifndef MAP_ANONYMOUS\n#define MAP_ANONYMOUS MAP_ANON\n#endif\n\n// Pull in std::min, std::ostream, and the likes. This is safe because this\n// header file is never used from any public header files.\nusing namespace std;\n\n// The size of an array, if known at compile-time.\n// Will give unexpected results if used on a pointer.\n// We undefine it first, since some compilers already have a definition.\n#ifdef ARRAYSIZE\n#undef ARRAYSIZE\n#endif\n#define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a)))\n\n// Static prediction hints.\n#ifdef HAVE_BUILTIN_EXPECT\n#define PREDICT_FALSE(x) (__builtin_expect(x, 0))\n#define PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))\n#else\n#define PREDICT_FALSE(x) x\n#define PREDICT_TRUE(x) x\n#endif\n\n// This is only used for recomputing the tag byte table used during\n// decompression; for simplicity we just remove it from the open-source\n// version (anyone who wants to regenerate it can just do the call\n// themselves within main()).\n#define DEFINE_bool(flag_name, default_value, description) \\\n  bool FLAGS_ ## flag_name = default_value\n#define DECLARE_bool(flag_name) \\\n  extern bool FLAGS_ ## flag_name\n\nnamespace snappy {\n\nstatic const uint32 kuint32max = static_cast<uint32>(0xFFFFFFFF);\nstatic const int64 kint64max = static_cast<int64>(0x7FFFFFFFFFFFFFFFLL);\n\n// Potentially unaligned loads and stores.\n\n// x86 and PowerPC can simply do these loads and stores native.\n\n#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__)\n\n#define UNALIGNED_LOAD16(_p) (*reinterpret_cast<const uint16 *>(_p))\n#define UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32 *>(_p))\n#define UNALIGNED_LOAD64(_p) (*reinterpret_cast<const uint64 *>(_p))\n\n#define UNALIGNED_STORE16(_p, _val) (*reinterpret_cast<uint16 *>(_p) = (_val))\n#define UNALIGNED_STORE32(_p, _val) (*reinterpret_cast<uint32 *>(_p) = (_val))\n#define UNALIGNED_STORE64(_p, _val) (*reinterpret_cast<uint64 *>(_p) = (_val))\n\n// ARMv7 and newer support native unaligned accesses, but only of 16-bit\n// and 32-bit values (not 64-bit); older versions either raise a fatal signal,\n// do an unaligned read and rotate the words around a bit, or do the reads very\n// slowly (trip through kernel mode). There's no simple #define that says just\n// “ARMv7 or higher”, so we have to filter away all ARMv5 and ARMv6\n// sub-architectures.\n//\n// This is a mess, but there's not much we can do about it.\n\n#elif defined(__arm__) && \\\n      !defined(__ARM_ARCH_4__) && \\\n      !defined(__ARM_ARCH_4T__) && \\\n      !defined(__ARM_ARCH_5__) && \\\n      !defined(__ARM_ARCH_5T__) && \\\n      !defined(__ARM_ARCH_5TE__) && \\\n      !defined(__ARM_ARCH_5TEJ__) && \\\n      !defined(__ARM_ARCH_6__) && \\\n      !defined(__ARM_ARCH_6J__) && \\\n      !defined(__ARM_ARCH_6K__) && \\\n      !defined(__ARM_ARCH_6Z__) && \\\n      !defined(__ARM_ARCH_6ZK__) && \\\n      !defined(__ARM_ARCH_6T2__)\n\n#define UNALIGNED_LOAD16(_p) (*reinterpret_cast<const uint16 *>(_p))\n#define UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32 *>(_p))\n\n#define UNALIGNED_STORE16(_p, _val) (*reinterpret_cast<uint16 *>(_p) = (_val))\n#define UNALIGNED_STORE32(_p, _val) (*reinterpret_cast<uint32 *>(_p) = (_val))\n\n// TODO(user): NEON supports unaligned 64-bit loads and stores.\n// See if that would be more efficient on platforms supporting it,\n// at least for copies.\n\ninline uint64 UNALIGNED_LOAD64(const void *p) {\n  uint64 t;\n  memcpy(&t, p, sizeof t);\n  return t;\n}\n\ninline void UNALIGNED_STORE64(void *p, uint64 v) {\n  memcpy(p, &v, sizeof v);\n}\n\n#else\n\n// These functions are provided for architectures that don't support\n// unaligned loads and stores.\n\ninline uint16 UNALIGNED_LOAD16(const void *p) {\n  uint16 t;\n  memcpy(&t, p, sizeof t);\n  return t;\n}\n\ninline uint32 UNALIGNED_LOAD32(const void *p) {\n  uint32 t;\n  memcpy(&t, p, sizeof t);\n  return t;\n}\n\ninline uint64 UNALIGNED_LOAD64(const void *p) {\n  uint64 t;\n  memcpy(&t, p, sizeof t);\n  return t;\n}\n\ninline void UNALIGNED_STORE16(void *p, uint16 v) {\n  memcpy(p, &v, sizeof v);\n}\n\ninline void UNALIGNED_STORE32(void *p, uint32 v) {\n  memcpy(p, &v, sizeof v);\n}\n\ninline void UNALIGNED_STORE64(void *p, uint64 v) {\n  memcpy(p, &v, sizeof v);\n}\n\n#endif\n\n// This can be more efficient than UNALIGNED_LOAD64 + UNALIGNED_STORE64\n// on some platforms, in particular ARM.\ninline void UnalignedCopy64(const void *src, void *dst) {\n  if (sizeof(void *) == 8) {\n    UNALIGNED_STORE64(dst, UNALIGNED_LOAD64(src));\n  } else {\n    const char *src_char = reinterpret_cast<const char *>(src);\n    char *dst_char = reinterpret_cast<char *>(dst);\n\n    UNALIGNED_STORE32(dst_char, UNALIGNED_LOAD32(src_char));\n    UNALIGNED_STORE32(dst_char + 4, UNALIGNED_LOAD32(src_char + 4));\n  }\n}\n\n// The following guarantees declaration of the byte swap functions.\n#ifdef WORDS_BIGENDIAN\n\n#ifdef HAVE_SYS_BYTEORDER_H\n#include <sys/byteorder.h>\n#endif\n\n#ifdef HAVE_SYS_ENDIAN_H\n#include <sys/endian.h>\n#endif\n\n#ifdef _MSC_VER\n#include <stdlib.h>\n#define bswap_16(x) _byteswap_ushort(x)\n#define bswap_32(x) _byteswap_ulong(x)\n#define bswap_64(x) _byteswap_uint64(x)\n\n#elif defined(__APPLE__)\n// Mac OS X / Darwin features\n#include <libkern/OSByteOrder.h>\n#define bswap_16(x) OSSwapInt16(x)\n#define bswap_32(x) OSSwapInt32(x)\n#define bswap_64(x) OSSwapInt64(x)\n\n#elif defined(HAVE_BYTESWAP_H)\n#include <byteswap.h>\n\n#elif defined(bswap32)\n// FreeBSD defines bswap{16,32,64} in <sys/endian.h> (already #included).\n#define bswap_16(x) bswap16(x)\n#define bswap_32(x) bswap32(x)\n#define bswap_64(x) bswap64(x)\n\n#elif defined(BSWAP_64)\n// Solaris 10 defines BSWAP_{16,32,64} in <sys/byteorder.h> (already #included).\n#define bswap_16(x) BSWAP_16(x)\n#define bswap_32(x) BSWAP_32(x)\n#define bswap_64(x) BSWAP_64(x)\n\n#else\n\ninline uint16 bswap_16(uint16 x) {\n  return (x << 8) | (x >> 8);\n}\n\ninline uint32 bswap_32(uint32 x) {\n  x = ((x & 0xff00ff00UL) >> 8) | ((x & 0x00ff00ffUL) << 8);\n  return (x >> 16) | (x << 16);\n}\n\ninline uint64 bswap_64(uint64 x) {\n  x = ((x & 0xff00ff00ff00ff00ULL) >> 8) | ((x & 0x00ff00ff00ff00ffULL) << 8);\n  x = ((x & 0xffff0000ffff0000ULL) >> 16) | ((x & 0x0000ffff0000ffffULL) << 16);\n  return (x >> 32) | (x << 32);\n}\n\n#endif\n\n#endif  // WORDS_BIGENDIAN\n\n// Convert to little-endian storage, opposite of network format.\n// Convert x from host to little endian: x = LittleEndian.FromHost(x);\n// convert x from little endian to host: x = LittleEndian.ToHost(x);\n//\n//  Store values into unaligned memory converting to little endian order:\n//    LittleEndian.Store16(p, x);\n//\n//  Load unaligned values stored in little endian converting to host order:\n//    x = LittleEndian.Load16(p);\nclass LittleEndian {\n public:\n  // Conversion functions.\n#ifdef WORDS_BIGENDIAN\n\n  static uint16 FromHost16(uint16 x) { return bswap_16(x); }\n  static uint16 ToHost16(uint16 x) { return bswap_16(x); }\n\n  static uint32 FromHost32(uint32 x) { return bswap_32(x); }\n  static uint32 ToHost32(uint32 x) { return bswap_32(x); }\n\n  static bool IsLittleEndian() { return false; }\n\n#else  // !defined(WORDS_BIGENDIAN)\n\n  static uint16 FromHost16(uint16 x) { return x; }\n  static uint16 ToHost16(uint16 x) { return x; }\n\n  static uint32 FromHost32(uint32 x) { return x; }\n  static uint32 ToHost32(uint32 x) { return x; }\n\n  static bool IsLittleEndian() { return true; }\n\n#endif  // !defined(WORDS_BIGENDIAN)\n\n  // Functions to do unaligned loads and stores in little-endian order.\n  static uint16 Load16(const void *p) {\n    return ToHost16(UNALIGNED_LOAD16(p));\n  }\n\n  static void Store16(void *p, uint16 v) {\n    UNALIGNED_STORE16(p, FromHost16(v));\n  }\n\n  static uint32 Load32(const void *p) {\n    return ToHost32(UNALIGNED_LOAD32(p));\n  }\n\n  static void Store32(void *p, uint32 v) {\n    UNALIGNED_STORE32(p, FromHost32(v));\n  }\n};\n\n// Some bit-manipulation functions.\nclass Bits {\n public:\n  // Return floor(log2(n)) for positive integer n.  Returns -1 iff n == 0.\n  static int Log2Floor(uint32 n);\n\n  // Return the first set least / most significant bit, 0-indexed.  Returns an\n  // undefined value if n == 0.  FindLSBSetNonZero() is similar to ffs() except\n  // that it's 0-indexed.\n  static int FindLSBSetNonZero(uint32 n);\n  static int FindLSBSetNonZero64(uint64 n);\n\n private:\n  DISALLOW_COPY_AND_ASSIGN(Bits);\n};\n\n#ifdef HAVE_BUILTIN_CTZ\n\ninline int Bits::Log2Floor(uint32 n) {\n  return n == 0 ? -1 : 31 ^ __builtin_clz(n);\n}\n\ninline int Bits::FindLSBSetNonZero(uint32 n) {\n  return __builtin_ctz(n);\n}\n\ninline int Bits::FindLSBSetNonZero64(uint64 n) {\n  return __builtin_ctzll(n);\n}\n\n#else  // Portable versions.\n\ninline int Bits::Log2Floor(uint32 n) {\n  if (n == 0)\n    return -1;\n  int log = 0;\n  uint32 value = n;\n  for (int i = 4; i >= 0; --i) {\n    int shift = (1 << i);\n    uint32 x = value >> shift;\n    if (x != 0) {\n      value = x;\n      log += shift;\n    }\n  }\n  assert(value == 1);\n  return log;\n}\n\ninline int Bits::FindLSBSetNonZero(uint32 n) {\n  int rc = 31;\n  for (int i = 4, shift = 1 << 4; i >= 0; --i) {\n    const uint32 x = n << shift;\n    if (x != 0) {\n      n = x;\n      rc -= shift;\n    }\n    shift >>= 1;\n  }\n  return rc;\n}\n\n// FindLSBSetNonZero64() is defined in terms of FindLSBSetNonZero().\ninline int Bits::FindLSBSetNonZero64(uint64 n) {\n  const uint32 bottombits = static_cast<uint32>(n);\n  if (bottombits == 0) {\n    // Bottom bits are zero, so scan in top bits\n    return 32 + FindLSBSetNonZero(static_cast<uint32>(n >> 32));\n  } else {\n    return FindLSBSetNonZero(bottombits);\n  }\n}\n\n#endif  // End portable versions.\n\n// Variable-length integer encoding.\nclass Varint {\n public:\n  // Maximum lengths of varint encoding of uint32.\n  static const int kMax32 = 5;\n\n  // Attempts to parse a varint32 from a prefix of the bytes in [ptr,limit-1].\n  // Never reads a character at or beyond limit.  If a valid/terminated varint32\n  // was found in the range, stores it in *OUTPUT and returns a pointer just\n  // past the last byte of the varint32. Else returns NULL.  On success,\n  // \"result <= limit\".\n  static const char* Parse32WithLimit(const char* ptr, const char* limit,\n                                      uint32* OUTPUT);\n\n  // REQUIRES   \"ptr\" points to a buffer of length sufficient to hold \"v\".\n  // EFFECTS    Encodes \"v\" into \"ptr\" and returns a pointer to the\n  //            byte just past the last encoded byte.\n  static char* Encode32(char* ptr, uint32 v);\n\n  // EFFECTS    Appends the varint representation of \"value\" to \"*s\".\n  static void Append32(string* s, uint32 value);\n};\n\ninline const char* Varint::Parse32WithLimit(const char* p,\n                                            const char* l,\n                                            uint32* OUTPUT) {\n  const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);\n  const unsigned char* limit = reinterpret_cast<const unsigned char*>(l);\n  uint32 b, result;\n  if (ptr >= limit) return NULL;\n  b = *(ptr++); result = b & 127;          if (b < 128) goto done;\n  if (ptr >= limit) return NULL;\n  b = *(ptr++); result |= (b & 127) <<  7; if (b < 128) goto done;\n  if (ptr >= limit) return NULL;\n  b = *(ptr++); result |= (b & 127) << 14; if (b < 128) goto done;\n  if (ptr >= limit) return NULL;\n  b = *(ptr++); result |= (b & 127) << 21; if (b < 128) goto done;\n  if (ptr >= limit) return NULL;\n  b = *(ptr++); result |= (b & 127) << 28; if (b < 16) goto done;\n  return NULL;       // Value is too long to be a varint32\n done:\n  *OUTPUT = result;\n  return reinterpret_cast<const char*>(ptr);\n}\n\ninline char* Varint::Encode32(char* sptr, uint32 v) {\n  // Operate on characters as unsigneds\n  unsigned char* ptr = reinterpret_cast<unsigned char*>(sptr);\n  static const int B = 128;\n  if (v < (1<<7)) {\n    *(ptr++) = v;\n  } else if (v < (1<<14)) {\n    *(ptr++) = v | B;\n    *(ptr++) = v>>7;\n  } else if (v < (1<<21)) {\n    *(ptr++) = v | B;\n    *(ptr++) = (v>>7) | B;\n    *(ptr++) = v>>14;\n  } else if (v < (1<<28)) {\n    *(ptr++) = v | B;\n    *(ptr++) = (v>>7) | B;\n    *(ptr++) = (v>>14) | B;\n    *(ptr++) = v>>21;\n  } else {\n    *(ptr++) = v | B;\n    *(ptr++) = (v>>7) | B;\n    *(ptr++) = (v>>14) | B;\n    *(ptr++) = (v>>21) | B;\n    *(ptr++) = v>>28;\n  }\n  return reinterpret_cast<char*>(ptr);\n}\n\n// If you know the internal layout of the std::string in use, you can\n// replace this function with one that resizes the string without\n// filling the new space with zeros (if applicable) --\n// it will be non-portable but faster.\ninline void STLStringResizeUninitialized(string* s, size_t new_size) {\n  s->resize(new_size);\n}\n\n// Return a mutable char* pointing to a string's internal buffer,\n// which may not be null-terminated. Writing through this pointer will\n// modify the string.\n//\n// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the\n// next call to a string method that invalidates iterators.\n//\n// As of 2006-04, there is no standard-blessed way of getting a\n// mutable reference to a string's internal buffer. However, issue 530\n// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-defects.html#530)\n// proposes this as the method. It will officially be part of the standard\n// for C++0x. This should already work on all current implementations.\ninline char* string_as_array(string* str) {\n  return str->empty() ? NULL : &*str->begin();\n}\n\n}  // namespace snappy\n\n#endif  // UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_\n"
  },
  {
    "path": "deps/snappy-1.1.0/snappy-stubs-public.h",
    "content": "// Copyright 2011 Google Inc. All Rights Reserved.\n// Author: sesse@google.com (Steinar H. Gunderson)\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// Various type stubs for the open-source version of Snappy.\n//\n// This file cannot include config.h, as it is included from snappy.h,\n// which is a public header. Instead, snappy-stubs-public.h is generated by\n// from snappy-stubs-public.h.in at configure time.\n\n#ifndef UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_\n#define UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_\n\n#if 1\n#include <stdint.h>\n#endif\n\n#if 1\n#include <stddef.h>\n#endif\n\n#define SNAPPY_MAJOR 1\n#define SNAPPY_MINOR 1\n#define SNAPPY_PATCHLEVEL 0\n#define SNAPPY_VERSION \\\n    ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL)\n\n#include <string>\n\nnamespace snappy {\n\n#if 1\ntypedef int8_t int8;\ntypedef uint8_t uint8;\ntypedef int16_t int16;\ntypedef uint16_t uint16;\ntypedef int32_t int32;\ntypedef uint32_t uint32;\ntypedef int64_t int64;\ntypedef uint64_t uint64;\n#else\ntypedef signed char int8;\ntypedef unsigned char uint8;\ntypedef short int16;\ntypedef unsigned short uint16;\ntypedef int int32;\ntypedef unsigned int uint32;\ntypedef long long int64;\ntypedef unsigned long long uint64;\n#endif\n\ntypedef std::string string;\n\n#define DISALLOW_COPY_AND_ASSIGN(TypeName) \\\n  TypeName(const TypeName&);               \\\n  void operator=(const TypeName&)\n\n}  // namespace snappy\n\n#endif  // UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_\n"
  },
  {
    "path": "deps/snappy-1.1.0/snappy-stubs-public.h.in",
    "content": "// Copyright 2011 Google Inc. All Rights Reserved.\n// Author: sesse@google.com (Steinar H. Gunderson)\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// Various type stubs for the open-source version of Snappy.\n//\n// This file cannot include config.h, as it is included from snappy.h,\n// which is a public header. Instead, snappy-stubs-public.h is generated by\n// from snappy-stubs-public.h.in at configure time.\n\n#ifndef UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_\n#define UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_\n\n#if @ac_cv_have_stdint_h@\n#include <stdint.h>\n#endif\n\n#if @ac_cv_have_stddef_h@\n#include <stddef.h>\n#endif\n\n#define SNAPPY_MAJOR @SNAPPY_MAJOR@\n#define SNAPPY_MINOR @SNAPPY_MINOR@\n#define SNAPPY_PATCHLEVEL @SNAPPY_PATCHLEVEL@\n#define SNAPPY_VERSION \\\n    ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL)\n\n#include <string>\n\nnamespace snappy {\n\n#if @ac_cv_have_stdint_h@\ntypedef int8_t int8;\ntypedef uint8_t uint8;\ntypedef int16_t int16;\ntypedef uint16_t uint16;\ntypedef int32_t int32;\ntypedef uint32_t uint32;\ntypedef int64_t int64;\ntypedef uint64_t uint64;\n#else\ntypedef signed char int8;\ntypedef unsigned char uint8;\ntypedef short int16;\ntypedef unsigned short uint16;\ntypedef int int32;\ntypedef unsigned int uint32;\ntypedef long long int64;\ntypedef unsigned long long uint64;\n#endif\n\ntypedef std::string string;\n\n#define DISALLOW_COPY_AND_ASSIGN(TypeName) \\\n  TypeName(const TypeName&);               \\\n  void operator=(const TypeName&)\n\n}  // namespace snappy\n\n#endif  // UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_\n"
  },
  {
    "path": "deps/snappy-1.1.0/snappy-test.cc",
    "content": "// Copyright 2011 Google Inc. 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// Various stubs for the unit tests for the open-source version of Snappy.\n\n#include \"snappy-test.h\"\n\n#ifdef HAVE_WINDOWS_H\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n#endif\n\n#include <algorithm>\n\nDEFINE_bool(run_microbenchmarks, true,\n            \"Run microbenchmarks before doing anything else.\");\n\nnamespace snappy {\n\nstring ReadTestDataFile(const string& base) {\n  string contents;\n  const char* srcdir = getenv(\"srcdir\");  // This is set by Automake.\n  if (srcdir) {\n    file::ReadFileToString(string(srcdir) + \"/testdata/\" + base,\n                           &contents,\n                           file::Defaults()).CheckSuccess();\n  } else {\n    file::ReadFileToString(\"testdata/\" + base,\n                           &contents,\n                           file::Defaults()).CheckSuccess();\n  }\n  return contents;\n}\n\nstring StringPrintf(const char* format, ...) {\n  char buf[4096];\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\nbool benchmark_running = false;\nint64 benchmark_real_time_us = 0;\nint64 benchmark_cpu_time_us = 0;\nstring *benchmark_label = NULL;\nint64 benchmark_bytes_processed = 0;\n\nvoid ResetBenchmarkTiming() {\n  benchmark_real_time_us = 0;\n  benchmark_cpu_time_us = 0;\n}\n\n#ifdef WIN32\nLARGE_INTEGER benchmark_start_real;\nFILETIME benchmark_start_cpu;\n#else  // WIN32\nstruct timeval benchmark_start_real;\nstruct rusage benchmark_start_cpu;\n#endif  // WIN32\n\nvoid StartBenchmarkTiming() {\n#ifdef WIN32\n  QueryPerformanceCounter(&benchmark_start_real);\n  FILETIME dummy;\n  CHECK(GetProcessTimes(\n      GetCurrentProcess(), &dummy, &dummy, &dummy, &benchmark_start_cpu));\n#else\n  gettimeofday(&benchmark_start_real, NULL);\n  if (getrusage(RUSAGE_SELF, &benchmark_start_cpu) == -1) {\n    perror(\"getrusage(RUSAGE_SELF)\");\n    exit(1);\n  }\n#endif\n  benchmark_running = true;\n}\n\nvoid StopBenchmarkTiming() {\n  if (!benchmark_running) {\n    return;\n  }\n\n#ifdef WIN32\n  LARGE_INTEGER benchmark_stop_real;\n  LARGE_INTEGER benchmark_frequency;\n  QueryPerformanceCounter(&benchmark_stop_real);\n  QueryPerformanceFrequency(&benchmark_frequency);\n\n  double elapsed_real = static_cast<double>(\n      benchmark_stop_real.QuadPart - benchmark_start_real.QuadPart) /\n      benchmark_frequency.QuadPart;\n  benchmark_real_time_us += elapsed_real * 1e6 + 0.5;\n\n  FILETIME benchmark_stop_cpu, dummy;\n  CHECK(GetProcessTimes(\n      GetCurrentProcess(), &dummy, &dummy, &dummy, &benchmark_stop_cpu));\n\n  ULARGE_INTEGER start_ulargeint;\n  start_ulargeint.LowPart = benchmark_start_cpu.dwLowDateTime;\n  start_ulargeint.HighPart = benchmark_start_cpu.dwHighDateTime;\n\n  ULARGE_INTEGER stop_ulargeint;\n  stop_ulargeint.LowPart = benchmark_stop_cpu.dwLowDateTime;\n  stop_ulargeint.HighPart = benchmark_stop_cpu.dwHighDateTime;\n\n  benchmark_cpu_time_us +=\n      (stop_ulargeint.QuadPart - start_ulargeint.QuadPart + 5) / 10;\n#else  // WIN32\n  struct timeval benchmark_stop_real;\n  gettimeofday(&benchmark_stop_real, NULL);\n  benchmark_real_time_us +=\n      1000000 * (benchmark_stop_real.tv_sec - benchmark_start_real.tv_sec);\n  benchmark_real_time_us +=\n      (benchmark_stop_real.tv_usec - benchmark_start_real.tv_usec);\n\n  struct rusage benchmark_stop_cpu;\n  if (getrusage(RUSAGE_SELF, &benchmark_stop_cpu) == -1) {\n    perror(\"getrusage(RUSAGE_SELF)\");\n    exit(1);\n  }\n  benchmark_cpu_time_us += 1000000 * (benchmark_stop_cpu.ru_utime.tv_sec -\n                                      benchmark_start_cpu.ru_utime.tv_sec);\n  benchmark_cpu_time_us += (benchmark_stop_cpu.ru_utime.tv_usec -\n                            benchmark_start_cpu.ru_utime.tv_usec);\n#endif  // WIN32\n\n  benchmark_running = false;\n}\n\nvoid SetBenchmarkLabel(const string& str) {\n  if (benchmark_label) {\n    delete benchmark_label;\n  }\n  benchmark_label = new string(str);\n}\n\nvoid SetBenchmarkBytesProcessed(int64 bytes) {\n  benchmark_bytes_processed = bytes;\n}\n\nstruct BenchmarkRun {\n  int64 real_time_us;\n  int64 cpu_time_us;\n};\n\nstruct BenchmarkCompareCPUTime {\n  bool operator() (const BenchmarkRun& a, const BenchmarkRun& b) const {\n    return a.cpu_time_us < b.cpu_time_us;\n  }\n};\n\nvoid Benchmark::Run() {\n  for (int test_case_num = start_; test_case_num <= stop_; ++test_case_num) {\n    // Run a few iterations first to find out approximately how fast\n    // the benchmark is.\n    const int kCalibrateIterations = 100;\n    ResetBenchmarkTiming();\n    StartBenchmarkTiming();\n    (*function_)(kCalibrateIterations, test_case_num);\n    StopBenchmarkTiming();\n\n    // Let each test case run for about 200ms, but at least as many\n    // as we used to calibrate.\n    // Run five times and pick the median.\n    const int kNumRuns = 5;\n    const int kMedianPos = kNumRuns / 2;\n    int num_iterations = 0;\n    if (benchmark_real_time_us > 0) {\n      num_iterations = 200000 * kCalibrateIterations / benchmark_real_time_us;\n    }\n    num_iterations = max(num_iterations, kCalibrateIterations);\n    BenchmarkRun benchmark_runs[kNumRuns];\n\n    for (int run = 0; run < kNumRuns; ++run) {\n      ResetBenchmarkTiming();\n      StartBenchmarkTiming();\n      (*function_)(num_iterations, test_case_num);\n      StopBenchmarkTiming();\n\n      benchmark_runs[run].real_time_us = benchmark_real_time_us;\n      benchmark_runs[run].cpu_time_us = benchmark_cpu_time_us;\n    }\n\n    string heading = StringPrintf(\"%s/%d\", name_.c_str(), test_case_num);\n    string human_readable_speed;\n\n    nth_element(benchmark_runs,\n                benchmark_runs + kMedianPos,\n                benchmark_runs + kNumRuns,\n                BenchmarkCompareCPUTime());\n    int64 real_time_us = benchmark_runs[kMedianPos].real_time_us;\n    int64 cpu_time_us = benchmark_runs[kMedianPos].cpu_time_us;\n    if (cpu_time_us <= 0) {\n      human_readable_speed = \"?\";\n    } else {\n      int64 bytes_per_second =\n          benchmark_bytes_processed * 1000000 / cpu_time_us;\n      if (bytes_per_second < 1024) {\n        human_readable_speed = StringPrintf(\"%dB/s\", bytes_per_second);\n      } else if (bytes_per_second < 1024 * 1024) {\n        human_readable_speed = StringPrintf(\n            \"%.1fkB/s\", bytes_per_second / 1024.0f);\n      } else if (bytes_per_second < 1024 * 1024 * 1024) {\n        human_readable_speed = StringPrintf(\n            \"%.1fMB/s\", bytes_per_second / (1024.0f * 1024.0f));\n      } else {\n        human_readable_speed = StringPrintf(\n            \"%.1fGB/s\", bytes_per_second / (1024.0f * 1024.0f * 1024.0f));\n      }\n    }\n\n    fprintf(stderr,\n#ifdef WIN32\n            \"%-18s %10I64d %10I64d %10d %s  %s\\n\",\n#else\n            \"%-18s %10lld %10lld %10d %s  %s\\n\",\n#endif\n            heading.c_str(),\n            static_cast<long long>(real_time_us * 1000 / num_iterations),\n            static_cast<long long>(cpu_time_us * 1000 / num_iterations),\n            num_iterations,\n            human_readable_speed.c_str(),\n            benchmark_label->c_str());\n  }\n}\n\n#ifdef HAVE_LIBZ\n\nZLib::ZLib()\n    : comp_init_(false),\n      uncomp_init_(false) {\n  Reinit();\n}\n\nZLib::~ZLib() {\n  if (comp_init_)   { deflateEnd(&comp_stream_); }\n  if (uncomp_init_) { inflateEnd(&uncomp_stream_); }\n}\n\nvoid ZLib::Reinit() {\n  compression_level_ = Z_DEFAULT_COMPRESSION;\n  window_bits_ = MAX_WBITS;\n  mem_level_ =  8;  // DEF_MEM_LEVEL\n  if (comp_init_) {\n    deflateEnd(&comp_stream_);\n    comp_init_ = false;\n  }\n  if (uncomp_init_) {\n    inflateEnd(&uncomp_stream_);\n    uncomp_init_ = false;\n  }\n  first_chunk_ = true;\n}\n\nvoid ZLib::Reset() {\n  first_chunk_ = true;\n}\n\n// --------- COMPRESS MODE\n\n// Initialization method to be called if we hit an error while\n// compressing. On hitting an error, call this method before returning\n// the error.\nvoid ZLib::CompressErrorInit() {\n  deflateEnd(&comp_stream_);\n  comp_init_ = false;\n  Reset();\n}\n\nint ZLib::DeflateInit() {\n  return deflateInit2(&comp_stream_,\n                      compression_level_,\n                      Z_DEFLATED,\n                      window_bits_,\n                      mem_level_,\n                      Z_DEFAULT_STRATEGY);\n}\n\nint ZLib::CompressInit(Bytef *dest, uLongf *destLen,\n                       const Bytef *source, uLong *sourceLen) {\n  int err;\n\n  comp_stream_.next_in = (Bytef*)source;\n  comp_stream_.avail_in = (uInt)*sourceLen;\n  if ((uLong)comp_stream_.avail_in != *sourceLen) return Z_BUF_ERROR;\n  comp_stream_.next_out = dest;\n  comp_stream_.avail_out = (uInt)*destLen;\n  if ((uLong)comp_stream_.avail_out != *destLen) return Z_BUF_ERROR;\n\n  if ( !first_chunk_ )   // only need to set up stream the first time through\n    return Z_OK;\n\n  if (comp_init_) {      // we've already initted it\n    err = deflateReset(&comp_stream_);\n    if (err != Z_OK) {\n      LOG(WARNING) << \"ERROR: Can't reset compress object; creating a new one\";\n      deflateEnd(&comp_stream_);\n      comp_init_ = false;\n    }\n  }\n  if (!comp_init_) {     // first use\n    comp_stream_.zalloc = (alloc_func)0;\n    comp_stream_.zfree = (free_func)0;\n    comp_stream_.opaque = (voidpf)0;\n    err = DeflateInit();\n    if (err != Z_OK) return err;\n    comp_init_ = true;\n  }\n  return Z_OK;\n}\n\n// In a perfect world we'd always have the full buffer to compress\n// when the time came, and we could just call Compress().  Alas, we\n// want to do chunked compression on our webserver.  In this\n// application, we compress the header, send it off, then compress the\n// results, send them off, then compress the footer.  Thus we need to\n// use the chunked compression features of zlib.\nint ZLib::CompressAtMostOrAll(Bytef *dest, uLongf *destLen,\n                              const Bytef *source, uLong *sourceLen,\n                              int flush_mode) {   // Z_FULL_FLUSH or Z_FINISH\n  int err;\n\n  if ( (err=CompressInit(dest, destLen, source, sourceLen)) != Z_OK )\n    return err;\n\n  // This is used to figure out how many bytes we wrote *this chunk*\n  int compressed_size = comp_stream_.total_out;\n\n  // Some setup happens only for the first chunk we compress in a run\n  if ( first_chunk_ ) {\n    first_chunk_ = false;\n  }\n\n  // flush_mode is Z_FINISH for all mode, Z_SYNC_FLUSH for incremental\n  // compression.\n  err = deflate(&comp_stream_, flush_mode);\n\n  *sourceLen = comp_stream_.avail_in;\n\n  if ((err == Z_STREAM_END || err == Z_OK)\n      && comp_stream_.avail_in == 0\n      && comp_stream_.avail_out != 0 ) {\n    // we processed everything ok and the output buffer was large enough.\n    ;\n  } else if (err == Z_STREAM_END && comp_stream_.avail_in > 0) {\n    return Z_BUF_ERROR;                            // should never happen\n  } else if (err != Z_OK && err != Z_STREAM_END && err != Z_BUF_ERROR) {\n    // an error happened\n    CompressErrorInit();\n    return err;\n  } else if (comp_stream_.avail_out == 0) {     // not enough space\n    err = Z_BUF_ERROR;\n  }\n\n  assert(err == Z_OK || err == Z_STREAM_END || err == Z_BUF_ERROR);\n  if (err == Z_STREAM_END)\n    err = Z_OK;\n\n  // update the crc and other metadata\n  compressed_size = comp_stream_.total_out - compressed_size;  // delta\n  *destLen = compressed_size;\n\n  return err;\n}\n\nint ZLib::CompressChunkOrAll(Bytef *dest, uLongf *destLen,\n                             const Bytef *source, uLong sourceLen,\n                             int flush_mode) {   // Z_FULL_FLUSH or Z_FINISH\n  const int ret =\n    CompressAtMostOrAll(dest, destLen, source, &sourceLen, flush_mode);\n  if (ret == Z_BUF_ERROR)\n    CompressErrorInit();\n  return ret;\n}\n\n// This routine only initializes the compression stream once.  Thereafter, it\n// just does a deflateReset on the stream, which should be faster.\nint ZLib::Compress(Bytef *dest, uLongf *destLen,\n                   const Bytef *source, uLong sourceLen) {\n  int err;\n  if ( (err=CompressChunkOrAll(dest, destLen, source, sourceLen,\n                               Z_FINISH)) != Z_OK )\n    return err;\n  Reset();         // reset for next call to Compress\n\n  return Z_OK;\n}\n\n\n// --------- UNCOMPRESS MODE\n\nint ZLib::InflateInit() {\n  return inflateInit2(&uncomp_stream_, MAX_WBITS);\n}\n\n// Initialization method to be called if we hit an error while\n// uncompressing. On hitting an error, call this method before\n// returning the error.\nvoid ZLib::UncompressErrorInit() {\n  inflateEnd(&uncomp_stream_);\n  uncomp_init_ = false;\n  Reset();\n}\n\nint ZLib::UncompressInit(Bytef *dest, uLongf *destLen,\n                         const Bytef *source, uLong *sourceLen) {\n  int err;\n\n  uncomp_stream_.next_in = (Bytef*)source;\n  uncomp_stream_.avail_in = (uInt)*sourceLen;\n  // Check for source > 64K on 16-bit machine:\n  if ((uLong)uncomp_stream_.avail_in != *sourceLen) return Z_BUF_ERROR;\n\n  uncomp_stream_.next_out = dest;\n  uncomp_stream_.avail_out = (uInt)*destLen;\n  if ((uLong)uncomp_stream_.avail_out != *destLen) return Z_BUF_ERROR;\n\n  if ( !first_chunk_ )   // only need to set up stream the first time through\n    return Z_OK;\n\n  if (uncomp_init_) {    // we've already initted it\n    err = inflateReset(&uncomp_stream_);\n    if (err != Z_OK) {\n      LOG(WARNING)\n        << \"ERROR: Can't reset uncompress object; creating a new one\";\n      UncompressErrorInit();\n    }\n  }\n  if (!uncomp_init_) {\n    uncomp_stream_.zalloc = (alloc_func)0;\n    uncomp_stream_.zfree = (free_func)0;\n    uncomp_stream_.opaque = (voidpf)0;\n    err = InflateInit();\n    if (err != Z_OK) return err;\n    uncomp_init_ = true;\n  }\n  return Z_OK;\n}\n\n// If you compressed your data a chunk at a time, with CompressChunk,\n// you can uncompress it a chunk at a time with UncompressChunk.\n// Only difference bewteen chunked and unchunked uncompression\n// is the flush mode we use: Z_SYNC_FLUSH (chunked) or Z_FINISH (unchunked).\nint ZLib::UncompressAtMostOrAll(Bytef *dest, uLongf *destLen,\n                                const Bytef *source, uLong *sourceLen,\n                                int flush_mode) {  // Z_SYNC_FLUSH or Z_FINISH\n  int err = Z_OK;\n\n  if ( (err=UncompressInit(dest, destLen, source, sourceLen)) != Z_OK ) {\n    LOG(WARNING) << \"UncompressInit: Error: \" << err << \" SourceLen: \"\n                 << *sourceLen;\n    return err;\n  }\n\n  // This is used to figure out how many output bytes we wrote *this chunk*:\n  const uLong old_total_out = uncomp_stream_.total_out;\n\n  // This is used to figure out how many input bytes we read *this chunk*:\n  const uLong old_total_in = uncomp_stream_.total_in;\n\n  // Some setup happens only for the first chunk we compress in a run\n  if ( first_chunk_ ) {\n    first_chunk_ = false;                          // so we don't do this again\n\n    // For the first chunk *only* (to avoid infinite troubles), we let\n    // there be no actual data to uncompress.  This sometimes triggers\n    // when the input is only the gzip header, say.\n    if ( *sourceLen == 0 ) {\n      *destLen = 0;\n      return Z_OK;\n    }\n  }\n\n  // We'll uncompress as much as we can.  If we end OK great, otherwise\n  // if we get an error that seems to be the gzip footer, we store the\n  // gzip footer and return OK, otherwise we return the error.\n\n  // flush_mode is Z_SYNC_FLUSH for chunked mode, Z_FINISH for all mode.\n  err = inflate(&uncomp_stream_, flush_mode);\n\n  // Figure out how many bytes of the input zlib slurped up:\n  const uLong bytes_read = uncomp_stream_.total_in - old_total_in;\n  CHECK_LE(source + bytes_read, source + *sourceLen);\n  *sourceLen = uncomp_stream_.avail_in;\n\n  if ((err == Z_STREAM_END || err == Z_OK)  // everything went ok\n             && uncomp_stream_.avail_in == 0) {    // and we read it all\n    ;\n  } else if (err == Z_STREAM_END && uncomp_stream_.avail_in > 0) {\n    LOG(WARNING)\n      << \"UncompressChunkOrAll: Received some extra data, bytes total: \"\n      << uncomp_stream_.avail_in << \" bytes: \"\n      << string(reinterpret_cast<const char *>(uncomp_stream_.next_in),\n                min(int(uncomp_stream_.avail_in), 20));\n    UncompressErrorInit();\n    return Z_DATA_ERROR;       // what's the extra data for?\n  } else if (err != Z_OK && err != Z_STREAM_END && err != Z_BUF_ERROR) {\n    // an error happened\n    LOG(WARNING) << \"UncompressChunkOrAll: Error: \" << err\n                 << \" avail_out: \" << uncomp_stream_.avail_out;\n    UncompressErrorInit();\n    return err;\n  } else if (uncomp_stream_.avail_out == 0) {\n    err = Z_BUF_ERROR;\n  }\n\n  assert(err == Z_OK || err == Z_BUF_ERROR || err == Z_STREAM_END);\n  if (err == Z_STREAM_END)\n    err = Z_OK;\n\n  *destLen = uncomp_stream_.total_out - old_total_out;  // size for this call\n\n  return err;\n}\n\nint ZLib::UncompressChunkOrAll(Bytef *dest, uLongf *destLen,\n                               const Bytef *source, uLong sourceLen,\n                               int flush_mode) {  // Z_SYNC_FLUSH or Z_FINISH\n  const int ret =\n    UncompressAtMostOrAll(dest, destLen, source, &sourceLen, flush_mode);\n  if (ret == Z_BUF_ERROR)\n    UncompressErrorInit();\n  return ret;\n}\n\nint ZLib::UncompressAtMost(Bytef *dest, uLongf *destLen,\n                          const Bytef *source, uLong *sourceLen) {\n  return UncompressAtMostOrAll(dest, destLen, source, sourceLen, Z_SYNC_FLUSH);\n}\n\n// We make sure we've uncompressed everything, that is, the current\n// uncompress stream is at a compressed-buffer-EOF boundary.  In gzip\n// mode, we also check the gzip footer to make sure we pass the gzip\n// consistency checks.  We RETURN true iff both types of checks pass.\nbool ZLib::UncompressChunkDone() {\n  assert(!first_chunk_ && uncomp_init_);\n  // Make sure we're at the end-of-compressed-data point.  This means\n  // if we call inflate with Z_FINISH we won't consume any input or\n  // write any output\n  Bytef dummyin, dummyout;\n  uLongf dummylen = 0;\n  if ( UncompressChunkOrAll(&dummyout, &dummylen, &dummyin, 0, Z_FINISH)\n       != Z_OK ) {\n    return false;\n  }\n\n  // Make sure that when we exit, we can start a new round of chunks later\n  Reset();\n\n  return true;\n}\n\n// Uncompresses the source buffer into the destination buffer.\n// The destination buffer must be long enough to hold the entire\n// decompressed contents.\n//\n// We only initialize the uncomp_stream once.  Thereafter, we use\n// inflateReset, which should be faster.\n//\n// Returns Z_OK on success, otherwise, it returns a zlib error code.\nint ZLib::Uncompress(Bytef *dest, uLongf *destLen,\n                     const Bytef *source, uLong sourceLen) {\n  int err;\n  if ( (err=UncompressChunkOrAll(dest, destLen, source, sourceLen,\n                                 Z_FINISH)) != Z_OK ) {\n    Reset();                           // let us try to compress again\n    return err;\n  }\n  if ( !UncompressChunkDone() )        // calls Reset()\n    return Z_DATA_ERROR;\n  return Z_OK;  // stream_end is ok\n}\n\n#endif  // HAVE_LIBZ\n\n}  // namespace snappy\n"
  },
  {
    "path": "deps/snappy-1.1.0/snappy-test.h",
    "content": "// Copyright 2011 Google Inc. 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// Various stubs for the unit tests for the open-source version of Snappy.\n\n#ifndef UTIL_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_\n#define UTIL_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_\n\n#include <iostream>\n#include <string>\n\n#include \"snappy-stubs-internal.h\"\n\n#include <stdio.h>\n#include <stdarg.h>\n\n#ifdef HAVE_SYS_MMAN_H\n#include <sys/mman.h>\n#endif\n\n#ifdef HAVE_SYS_RESOURCE_H\n#include <sys/resource.h>\n#endif\n\n#ifdef HAVE_SYS_TIME_H\n#include <sys/time.h>\n#endif\n\n#ifdef HAVE_WINDOWS_H\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n#endif\n\n#include <string>\n\n#ifdef HAVE_GTEST\n\n#include <gtest/gtest.h>\n#undef TYPED_TEST\n#define TYPED_TEST TEST\n#define INIT_GTEST(argc, argv) ::testing::InitGoogleTest(argc, *argv)\n\n#else\n\n// Stubs for if the user doesn't have Google Test installed.\n\n#define TEST(test_case, test_subcase) \\\n  void Test_ ## test_case ## _ ## test_subcase()\n#define INIT_GTEST(argc, argv)\n\n#define TYPED_TEST TEST\n#define EXPECT_EQ CHECK_EQ\n#define EXPECT_NE CHECK_NE\n#define EXPECT_FALSE(cond) CHECK(!(cond))\n\n#endif\n\n#ifdef HAVE_GFLAGS\n\n#include <gflags/gflags.h>\n\n// This is tricky; both gflags and Google Test want to look at the command line\n// arguments. Google Test seems to be the most happy with unknown arguments,\n// though, so we call it first and hope for the best.\n#define InitGoogle(argv0, argc, argv, remove_flags) \\\n  INIT_GTEST(argc, argv); \\\n  google::ParseCommandLineFlags(argc, argv, remove_flags);\n\n#else\n\n// If we don't have the gflags package installed, these can only be\n// changed at compile time.\n#define DEFINE_int32(flag_name, default_value, description) \\\n  static int FLAGS_ ## flag_name = default_value;\n\n#define InitGoogle(argv0, argc, argv, remove_flags) \\\n  INIT_GTEST(argc, argv)\n\n#endif\n\n#ifdef HAVE_LIBZ\n#include \"zlib.h\"\n#endif\n\n#ifdef HAVE_LIBLZO2\n#include \"lzo/lzo1x.h\"\n#endif\n\n#ifdef HAVE_LIBLZF\nextern \"C\" {\n#include \"lzf.h\"\n}\n#endif\n\n#ifdef HAVE_LIBFASTLZ\n#include \"fastlz.h\"\n#endif\n\n#ifdef HAVE_LIBQUICKLZ\n#include \"quicklz.h\"\n#endif\n\nnamespace {\n\nnamespace File {\n  void Init() { }\n}  // namespace File\n\nnamespace file {\n  int Defaults() { }\n\n  class DummyStatus {\n   public:\n    void CheckSuccess() { }\n  };\n\n  DummyStatus ReadFileToString(const char* filename, string* data, int unused) {\n    FILE* fp = fopen(filename, \"rb\");\n    if (fp == NULL) {\n      perror(filename);\n      exit(1);\n    }\n\n    data->clear();\n    while (!feof(fp)) {\n      char buf[4096];\n      size_t ret = fread(buf, 1, 4096, fp);\n      if (ret == 0 && ferror(fp)) {\n        perror(\"fread\");\n        exit(1);\n      }\n      data->append(string(buf, ret));\n    }\n\n    fclose(fp);\n  }\n\n  DummyStatus ReadFileToString(const string& filename,\n                               string* data,\n                               int unused) {\n    ReadFileToString(filename.c_str(), data, unused);\n  }\n\n  DummyStatus WriteStringToFile(const string& str,\n                                const string& filename,\n                                int unused) {\n    FILE* fp = fopen(filename.c_str(), \"wb\");\n    if (fp == NULL) {\n      perror(filename.c_str());\n      exit(1);\n    }\n\n    int ret = fwrite(str.data(), str.size(), 1, fp);\n    if (ret != 1) {\n      perror(\"fwrite\");\n      exit(1);\n    }\n\n    fclose(fp);\n  }\n}  // namespace file\n\n}  // namespace\n\nnamespace snappy {\n\n#define FLAGS_test_random_seed 301\ntypedef string TypeParam;\n\nvoid Test_CorruptedTest_VerifyCorrupted();\nvoid Test_Snappy_SimpleTests();\nvoid Test_Snappy_MaxBlowup();\nvoid Test_Snappy_RandomData();\nvoid Test_Snappy_FourByteOffset();\nvoid Test_SnappyCorruption_TruncatedVarint();\nvoid Test_SnappyCorruption_UnterminatedVarint();\nvoid Test_Snappy_ReadPastEndOfBuffer();\nvoid Test_Snappy_FindMatchLength();\nvoid Test_Snappy_FindMatchLengthRandom();\n\nstring ReadTestDataFile(const string& base);\n\n// A sprintf() variant that returns a std::string.\n// Not safe for general use due to truncation issues.\nstring StringPrintf(const char* format, ...);\n\n// A simple, non-cryptographically-secure random generator.\nclass ACMRandom {\n public:\n  explicit ACMRandom(uint32 seed) : seed_(seed) {}\n\n  int32 Next();\n\n  int32 Uniform(int32 n) {\n    return Next() % n;\n  }\n  uint8 Rand8() {\n    return static_cast<uint8>((Next() >> 1) & 0x000000ff);\n  }\n  bool OneIn(int X) { return Uniform(X) == 0; }\n\n  // Skewed: pick \"base\" uniformly from range [0,max_log] and then\n  // return \"base\" random bits.  The effect is to pick a number in the\n  // range [0,2^max_log-1] with bias towards smaller numbers.\n  int32 Skewed(int max_log);\n\n private:\n  static const uint32 M = 2147483647L;   // 2^31-1\n  uint32 seed_;\n};\n\ninline int32 ACMRandom::Next() {\n  static const uint64 A = 16807;  // bits 14, 8, 7, 5, 2, 1, 0\n  // We are computing\n  //       seed_ = (seed_ * A) % M,    where M = 2^31-1\n  //\n  // seed_ must not be zero or M, or else all subsequent computed values\n  // will be zero or M respectively.  For all other values, seed_ will end\n  // up cycling through every number in [1,M-1]\n  uint64 product = seed_ * A;\n\n  // Compute (product % M) using the fact that ((x << 31) % M) == x.\n  seed_ = (product >> 31) + (product & M);\n  // The first reduction may overflow by 1 bit, so we may need to repeat.\n  // mod == M is not possible; using > allows the faster sign-bit-based test.\n  if (seed_ > M) {\n    seed_ -= M;\n  }\n  return seed_;\n}\n\ninline int32 ACMRandom::Skewed(int max_log) {\n  const int32 base = (Next() - 1) % (max_log+1);\n  return (Next() - 1) & ((1u << base)-1);\n}\n\n// A wall-time clock. This stub is not super-accurate, nor resistant to the\n// system time changing.\nclass CycleTimer {\n public:\n  CycleTimer() : real_time_us_(0) {}\n\n  void Start() {\n#ifdef WIN32\n    QueryPerformanceCounter(&start_);\n#else\n    gettimeofday(&start_, NULL);\n#endif\n  }\n\n  void Stop() {\n#ifdef WIN32\n    LARGE_INTEGER stop;\n    LARGE_INTEGER frequency;\n    QueryPerformanceCounter(&stop);\n    QueryPerformanceFrequency(&frequency);\n\n    double elapsed = static_cast<double>(stop.QuadPart - start_.QuadPart) /\n        frequency.QuadPart;\n    real_time_us_ += elapsed * 1e6 + 0.5;\n#else\n    struct timeval stop;\n    gettimeofday(&stop, NULL);\n\n    real_time_us_ += 1000000 * (stop.tv_sec - start_.tv_sec);\n    real_time_us_ += (stop.tv_usec - start_.tv_usec);\n#endif\n  }\n\n  double Get() {\n    return real_time_us_ * 1e-6;\n  }\n\n private:\n  int64 real_time_us_;\n#ifdef WIN32\n  LARGE_INTEGER start_;\n#else\n  struct timeval start_;\n#endif\n};\n\n// Minimalistic microbenchmark framework.\n\ntypedef void (*BenchmarkFunction)(int, int);\n\nclass Benchmark {\n public:\n  Benchmark(const string& name, BenchmarkFunction function) :\n      name_(name), function_(function) {}\n\n  Benchmark* DenseRange(int start, int stop) {\n    start_ = start;\n    stop_ = stop;\n    return this;\n  }\n\n  void Run();\n\n private:\n  const string name_;\n  const BenchmarkFunction function_;\n  int start_, stop_;\n};\n#define BENCHMARK(benchmark_name) \\\n  Benchmark* Benchmark_ ## benchmark_name = \\\n          (new Benchmark(#benchmark_name, benchmark_name))\n\nextern Benchmark* Benchmark_BM_UFlat;\nextern Benchmark* Benchmark_BM_UValidate;\nextern Benchmark* Benchmark_BM_ZFlat;\n\nvoid ResetBenchmarkTiming();\nvoid StartBenchmarkTiming();\nvoid StopBenchmarkTiming();\nvoid SetBenchmarkLabel(const string& str);\nvoid SetBenchmarkBytesProcessed(int64 bytes);\n\n#ifdef HAVE_LIBZ\n\n// Object-oriented wrapper around zlib.\nclass ZLib {\n public:\n  ZLib();\n  ~ZLib();\n\n  // Wipe a ZLib object to a virgin state.  This differs from Reset()\n  // in that it also breaks any state.\n  void Reinit();\n\n  // Call this to make a zlib buffer as good as new.  Here's the only\n  // case where they differ:\n  //    CompressChunk(a); CompressChunk(b); CompressChunkDone();   vs\n  //    CompressChunk(a); Reset(); CompressChunk(b); CompressChunkDone();\n  // You'll want to use Reset(), then, when you interrupt a compress\n  // (or uncompress) in the middle of a chunk and want to start over.\n  void Reset();\n\n  // According to the zlib manual, when you Compress, the destination\n  // buffer must have size at least src + .1%*src + 12.  This function\n  // helps you calculate that.  Augment this to account for a potential\n  // gzip header and footer, plus a few bytes of slack.\n  static int MinCompressbufSize(int uncompress_size) {\n    return uncompress_size + uncompress_size/1000 + 40;\n  }\n\n  // Compresses the source buffer into the destination buffer.\n  // sourceLen is the byte length of the source buffer.\n  // Upon entry, destLen is the total size of the destination buffer,\n  // which must be of size at least MinCompressbufSize(sourceLen).\n  // Upon exit, destLen is the actual size of the compressed buffer.\n  //\n  // This function can be used to compress a whole file at once if the\n  // input file is mmap'ed.\n  //\n  // Returns Z_OK if success, Z_MEM_ERROR if there was not\n  // enough memory, Z_BUF_ERROR if there was not enough room in the\n  // output buffer. Note that if the output buffer is exactly the same\n  // size as the compressed result, we still return Z_BUF_ERROR.\n  // (check CL#1936076)\n  int Compress(Bytef *dest, uLongf *destLen,\n               const Bytef *source, uLong sourceLen);\n\n  // Uncompresses the source buffer into the destination buffer.\n  // The destination buffer must be long enough to hold the entire\n  // decompressed contents.\n  //\n  // Returns Z_OK on success, otherwise, it returns a zlib error code.\n  int Uncompress(Bytef *dest, uLongf *destLen,\n                 const Bytef *source, uLong sourceLen);\n\n  // Uncompress data one chunk at a time -- ie you can call this\n  // more than once.  To get this to work you need to call per-chunk\n  // and \"done\" routines.\n  //\n  // Returns Z_OK if success, Z_MEM_ERROR if there was not\n  // enough memory, Z_BUF_ERROR if there was not enough room in the\n  // output buffer.\n\n  int UncompressAtMost(Bytef *dest, uLongf *destLen,\n                       const Bytef *source, uLong *sourceLen);\n\n  // Checks gzip footer information, as needed.  Mostly this just\n  // makes sure the checksums match.  Whenever you call this, it\n  // will assume the last 8 bytes from the previous UncompressChunk\n  // call are the footer.  Returns true iff everything looks ok.\n  bool UncompressChunkDone();\n\n private:\n  int InflateInit();       // sets up the zlib inflate structure\n  int DeflateInit();       // sets up the zlib deflate structure\n\n  // These init the zlib data structures for compressing/uncompressing\n  int CompressInit(Bytef *dest, uLongf *destLen,\n                   const Bytef *source, uLong *sourceLen);\n  int UncompressInit(Bytef *dest, uLongf *destLen,\n                     const Bytef *source, uLong *sourceLen);\n  // Initialization method to be called if we hit an error while\n  // uncompressing. On hitting an error, call this method before\n  // returning the error.\n  void UncompressErrorInit();\n\n  // Helper function for Compress\n  int CompressChunkOrAll(Bytef *dest, uLongf *destLen,\n                         const Bytef *source, uLong sourceLen,\n                         int flush_mode);\n  int CompressAtMostOrAll(Bytef *dest, uLongf *destLen,\n                          const Bytef *source, uLong *sourceLen,\n                          int flush_mode);\n\n  // Likewise for UncompressAndUncompressChunk\n  int UncompressChunkOrAll(Bytef *dest, uLongf *destLen,\n                           const Bytef *source, uLong sourceLen,\n                           int flush_mode);\n\n  int UncompressAtMostOrAll(Bytef *dest, uLongf *destLen,\n                            const Bytef *source, uLong *sourceLen,\n                            int flush_mode);\n\n  // Initialization method to be called if we hit an error while\n  // compressing. On hitting an error, call this method before\n  // returning the error.\n  void CompressErrorInit();\n\n  int compression_level_;   // compression level\n  int window_bits_;         // log base 2 of the window size used in compression\n  int mem_level_;           // specifies the amount of memory to be used by\n                            // compressor (1-9)\n  z_stream comp_stream_;    // Zlib stream data structure\n  bool comp_init_;          // True if we have initialized comp_stream_\n  z_stream uncomp_stream_;  // Zlib stream data structure\n  bool uncomp_init_;        // True if we have initialized uncomp_stream_\n\n  // These are used only with chunked compression.\n  bool first_chunk_;       // true if we need to emit headers with this chunk\n};\n\n#endif  // HAVE_LIBZ\n\n}  // namespace snappy\n\nDECLARE_bool(run_microbenchmarks);\n\nstatic void RunSpecifiedBenchmarks() {\n  if (!FLAGS_run_microbenchmarks) {\n    return;\n  }\n\n  fprintf(stderr, \"Running microbenchmarks.\\n\");\n#ifndef NDEBUG\n  fprintf(stderr, \"WARNING: Compiled with assertions enabled, will be slow.\\n\");\n#endif\n#ifndef __OPTIMIZE__\n  fprintf(stderr, \"WARNING: Compiled without optimization, will be slow.\\n\");\n#endif\n  fprintf(stderr, \"Benchmark            Time(ns)    CPU(ns) Iterations\\n\");\n  fprintf(stderr, \"---------------------------------------------------\\n\");\n\n  snappy::Benchmark_BM_UFlat->Run();\n  snappy::Benchmark_BM_UValidate->Run();\n  snappy::Benchmark_BM_ZFlat->Run();\n\n  fprintf(stderr, \"\\n\");\n}\n\n#ifndef HAVE_GTEST\n\nstatic inline int RUN_ALL_TESTS() {\n  fprintf(stderr, \"Running correctness tests.\\n\");\n  snappy::Test_CorruptedTest_VerifyCorrupted();\n  snappy::Test_Snappy_SimpleTests();\n  snappy::Test_Snappy_MaxBlowup();\n  snappy::Test_Snappy_RandomData();\n  snappy::Test_Snappy_FourByteOffset();\n  snappy::Test_SnappyCorruption_TruncatedVarint();\n  snappy::Test_SnappyCorruption_UnterminatedVarint();\n  snappy::Test_Snappy_ReadPastEndOfBuffer();\n  snappy::Test_Snappy_FindMatchLength();\n  snappy::Test_Snappy_FindMatchLengthRandom();\n  fprintf(stderr, \"All tests passed.\\n\");\n\n  return 0;\n}\n\n#endif  // HAVE_GTEST\n\n// For main().\nnamespace snappy {\n\nstatic void CompressFile(const char* fname);\nstatic void UncompressFile(const char* fname);\nstatic void MeasureFile(const char* fname);\n\n// Logging.\n\n#define LOG(level) LogMessage()\n#define VLOG(level) true ? (void)0 : \\\n    snappy::LogMessageVoidify() & snappy::LogMessage()\n\nclass LogMessage {\n public:\n  LogMessage() { }\n  ~LogMessage() {\n    cerr << endl;\n  }\n\n  LogMessage& operator<<(const std::string& msg) {\n    cerr << msg;\n    return *this;\n  }\n  LogMessage& operator<<(int x) {\n    cerr << x;\n    return *this;\n  }\n};\n\n// Asserts, both versions activated in debug mode only,\n// and ones that are always active.\n\n#define CRASH_UNLESS(condition) \\\n    PREDICT_TRUE(condition) ? (void)0 : \\\n    snappy::LogMessageVoidify() & snappy::LogMessageCrash()\n\nclass LogMessageCrash : public LogMessage {\n public:\n  LogMessageCrash() { }\n  ~LogMessageCrash() {\n    cerr << endl;\n    abort();\n  }\n};\n\n// This class is used to explicitly ignore values in the conditional\n// logging macros.  This avoids compiler warnings like \"value computed\n// is not used\" and \"statement has no effect\".\n\nclass LogMessageVoidify {\n public:\n  LogMessageVoidify() { }\n  // This has to be an operator with a precedence lower than << but\n  // higher than ?:\n  void operator&(const LogMessage&) { }\n};\n\n#define CHECK(cond) CRASH_UNLESS(cond)\n#define CHECK_LE(a, b) CRASH_UNLESS((a) <= (b))\n#define CHECK_GE(a, b) CRASH_UNLESS((a) >= (b))\n#define CHECK_EQ(a, b) CRASH_UNLESS((a) == (b))\n#define CHECK_NE(a, b) CRASH_UNLESS((a) != (b))\n#define CHECK_LT(a, b) CRASH_UNLESS((a) < (b))\n#define CHECK_GT(a, b) CRASH_UNLESS((a) > (b))\n\n}  // namespace\n\nusing snappy::CompressFile;\nusing snappy::UncompressFile;\nusing snappy::MeasureFile;\n\n#endif  // UTIL_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_\n"
  },
  {
    "path": "deps/snappy-1.1.0/snappy.cc",
    "content": "// Copyright 2005 Google Inc. 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 \"snappy.h\"\n#include \"snappy-internal.h\"\n#include \"snappy-sinksource.h\"\n\n#include <stdio.h>\n\n#include <algorithm>\n#include <string>\n#include <vector>\n\n\nnamespace snappy {\n\n// Any hash function will produce a valid compressed bitstream, but a good\n// hash function reduces the number of collisions and thus yields better\n// compression for compressible input, and more speed for incompressible\n// input. Of course, it doesn't hurt if the hash function is reasonably fast\n// either, as it gets called a lot.\nstatic inline uint32 HashBytes(uint32 bytes, int shift) {\n  uint32 kMul = 0x1e35a7bd;\n  return (bytes * kMul) >> shift;\n}\nstatic inline uint32 Hash(const char* p, int shift) {\n  return HashBytes(UNALIGNED_LOAD32(p), shift);\n}\n\nsize_t MaxCompressedLength(size_t source_len) {\n  // Compressed data can be defined as:\n  //    compressed := item* literal*\n  //    item       := literal* copy\n  //\n  // The trailing literal sequence has a space blowup of at most 62/60\n  // since a literal of length 60 needs one tag byte + one extra byte\n  // for length information.\n  //\n  // Item blowup is trickier to measure.  Suppose the \"copy\" op copies\n  // 4 bytes of data.  Because of a special check in the encoding code,\n  // we produce a 4-byte copy only if the offset is < 65536.  Therefore\n  // the copy op takes 3 bytes to encode, and this type of item leads\n  // to at most the 62/60 blowup for representing literals.\n  //\n  // Suppose the \"copy\" op copies 5 bytes of data.  If the offset is big\n  // enough, it will take 5 bytes to encode the copy op.  Therefore the\n  // worst case here is a one-byte literal followed by a five-byte copy.\n  // I.e., 6 bytes of input turn into 7 bytes of \"compressed\" data.\n  //\n  // This last factor dominates the blowup, so the final estimate is:\n  return 32 + source_len + source_len/6;\n}\n\nenum {\n  LITERAL = 0,\n  COPY_1_BYTE_OFFSET = 1,  // 3 bit length + 3 bits of offset in opcode\n  COPY_2_BYTE_OFFSET = 2,\n  COPY_4_BYTE_OFFSET = 3\n};\n\n// Copy \"len\" bytes from \"src\" to \"op\", one byte at a time.  Used for\n// handling COPY operations where the input and output regions may\n// overlap.  For example, suppose:\n//    src    == \"ab\"\n//    op     == src + 2\n//    len    == 20\n// After IncrementalCopy(src, op, len), the result will have\n// eleven copies of \"ab\"\n//    ababababababababababab\n// Note that this does not match the semantics of either memcpy()\n// or memmove().\nstatic inline void IncrementalCopy(const char* src, char* op, int len) {\n  assert(len > 0);\n  do {\n    *op++ = *src++;\n  } while (--len > 0);\n}\n\n// Equivalent to IncrementalCopy except that it can write up to ten extra\n// bytes after the end of the copy, and that it is faster.\n//\n// The main part of this loop is a simple copy of eight bytes at a time until\n// we've copied (at least) the requested amount of bytes.  However, if op and\n// src are less than eight bytes apart (indicating a repeating pattern of\n// length < 8), we first need to expand the pattern in order to get the correct\n// results. For instance, if the buffer looks like this, with the eight-byte\n// <src> and <op> patterns marked as intervals:\n//\n//    abxxxxxxxxxxxx\n//    [------]           src\n//      [------]         op\n//\n// a single eight-byte copy from <src> to <op> will repeat the pattern once,\n// after which we can move <op> two bytes without moving <src>:\n//\n//    ababxxxxxxxxxx\n//    [------]           src\n//        [------]       op\n//\n// and repeat the exercise until the two no longer overlap.\n//\n// This allows us to do very well in the special case of one single byte\n// repeated many times, without taking a big hit for more general cases.\n//\n// The worst case of extra writing past the end of the match occurs when\n// op - src == 1 and len == 1; the last copy will read from byte positions\n// [0..7] and write to [4..11], whereas it was only supposed to write to\n// position 1. Thus, ten excess bytes.\n\nnamespace {\n\nconst int kMaxIncrementCopyOverflow = 10;\n\n}  // namespace\n\nstatic inline void IncrementalCopyFastPath(const char* src, char* op, int len) {\n  while (op - src < 8) {\n    UnalignedCopy64(src, op);\n    len -= op - src;\n    op += op - src;\n  }\n  while (len > 0) {\n    UnalignedCopy64(src, op);\n    src += 8;\n    op += 8;\n    len -= 8;\n  }\n}\n\nstatic inline char* EmitLiteral(char* op,\n                                const char* literal,\n                                int len,\n                                bool allow_fast_path) {\n  int n = len - 1;      // Zero-length literals are disallowed\n  if (n < 60) {\n    // Fits in tag byte\n    *op++ = LITERAL | (n << 2);\n\n    // The vast majority of copies are below 16 bytes, for which a\n    // call to memcpy is overkill. This fast path can sometimes\n    // copy up to 15 bytes too much, but that is okay in the\n    // main loop, since we have a bit to go on for both sides:\n    //\n    //   - The input will always have kInputMarginBytes = 15 extra\n    //     available bytes, as long as we're in the main loop, and\n    //     if not, allow_fast_path = false.\n    //   - The output will always have 32 spare bytes (see\n    //     MaxCompressedLength).\n    if (allow_fast_path && len <= 16) {\n      UnalignedCopy64(literal, op);\n      UnalignedCopy64(literal + 8, op + 8);\n      return op + len;\n    }\n  } else {\n    // Encode in upcoming bytes\n    char* base = op;\n    int count = 0;\n    op++;\n    while (n > 0) {\n      *op++ = n & 0xff;\n      n >>= 8;\n      count++;\n    }\n    assert(count >= 1);\n    assert(count <= 4);\n    *base = LITERAL | ((59+count) << 2);\n  }\n  memcpy(op, literal, len);\n  return op + len;\n}\n\nstatic inline char* EmitCopyLessThan64(char* op, size_t offset, int len) {\n  assert(len <= 64);\n  assert(len >= 4);\n  assert(offset < 65536);\n\n  if ((len < 12) && (offset < 2048)) {\n    size_t len_minus_4 = len - 4;\n    assert(len_minus_4 < 8);            // Must fit in 3 bits\n    *op++ = COPY_1_BYTE_OFFSET + ((len_minus_4) << 2) + ((offset >> 8) << 5);\n    *op++ = offset & 0xff;\n  } else {\n    *op++ = COPY_2_BYTE_OFFSET + ((len-1) << 2);\n    LittleEndian::Store16(op, offset);\n    op += 2;\n  }\n  return op;\n}\n\nstatic inline char* EmitCopy(char* op, size_t offset, int len) {\n  // Emit 64 byte copies but make sure to keep at least four bytes reserved\n  while (len >= 68) {\n    op = EmitCopyLessThan64(op, offset, 64);\n    len -= 64;\n  }\n\n  // Emit an extra 60 byte copy if have too much data to fit in one copy\n  if (len > 64) {\n    op = EmitCopyLessThan64(op, offset, 60);\n    len -= 60;\n  }\n\n  // Emit remainder\n  op = EmitCopyLessThan64(op, offset, len);\n  return op;\n}\n\n\nbool GetUncompressedLength(const char* start, size_t n, size_t* result) {\n  uint32 v = 0;\n  const char* limit = start + n;\n  if (Varint::Parse32WithLimit(start, limit, &v) != NULL) {\n    *result = v;\n    return true;\n  } else {\n    return false;\n  }\n}\n\nnamespace internal {\nuint16* WorkingMemory::GetHashTable(size_t input_size, int* table_size) {\n  // Use smaller hash table when input.size() is smaller, since we\n  // fill the table, incurring O(hash table size) overhead for\n  // compression, and if the input is short, we won't need that\n  // many hash table entries anyway.\n  assert(kMaxHashTableSize >= 256);\n  size_t htsize = 256;\n  while (htsize < kMaxHashTableSize && htsize < input_size) {\n    htsize <<= 1;\n  }\n\n  uint16* table;\n  if (htsize <= ARRAYSIZE(small_table_)) {\n    table = small_table_;\n  } else {\n    if (large_table_ == NULL) {\n      large_table_ = new uint16[kMaxHashTableSize];\n    }\n    table = large_table_;\n  }\n\n  *table_size = htsize;\n  memset(table, 0, htsize * sizeof(*table));\n  return table;\n}\n}  // end namespace internal\n\n// For 0 <= offset <= 4, GetUint32AtOffset(GetEightBytesAt(p), offset) will\n// equal UNALIGNED_LOAD32(p + offset).  Motivation: On x86-64 hardware we have\n// empirically found that overlapping loads such as\n//  UNALIGNED_LOAD32(p) ... UNALIGNED_LOAD32(p+1) ... UNALIGNED_LOAD32(p+2)\n// are slower than UNALIGNED_LOAD64(p) followed by shifts and casts to uint32.\n//\n// We have different versions for 64- and 32-bit; ideally we would avoid the\n// two functions and just inline the UNALIGNED_LOAD64 call into\n// GetUint32AtOffset, but GCC (at least not as of 4.6) is seemingly not clever\n// enough to avoid loading the value multiple times then. For 64-bit, the load\n// is done when GetEightBytesAt() is called, whereas for 32-bit, the load is\n// done at GetUint32AtOffset() time.\n\n#ifdef ARCH_K8\n\ntypedef uint64 EightBytesReference;\n\nstatic inline EightBytesReference GetEightBytesAt(const char* ptr) {\n  return UNALIGNED_LOAD64(ptr);\n}\n\nstatic inline uint32 GetUint32AtOffset(uint64 v, int offset) {\n  assert(offset >= 0);\n  assert(offset <= 4);\n  return v >> (LittleEndian::IsLittleEndian() ? 8 * offset : 32 - 8 * offset);\n}\n\n#else\n\ntypedef const char* EightBytesReference;\n\nstatic inline EightBytesReference GetEightBytesAt(const char* ptr) {\n  return ptr;\n}\n\nstatic inline uint32 GetUint32AtOffset(const char* v, int offset) {\n  assert(offset >= 0);\n  assert(offset <= 4);\n  return UNALIGNED_LOAD32(v + offset);\n}\n\n#endif\n\n// Flat array compression that does not emit the \"uncompressed length\"\n// prefix. Compresses \"input\" string to the \"*op\" buffer.\n//\n// REQUIRES: \"input\" is at most \"kBlockSize\" bytes long.\n// REQUIRES: \"op\" points to an array of memory that is at least\n// \"MaxCompressedLength(input.size())\" in size.\n// REQUIRES: All elements in \"table[0..table_size-1]\" are initialized to zero.\n// REQUIRES: \"table_size\" is a power of two\n//\n// Returns an \"end\" pointer into \"op\" buffer.\n// \"end - op\" is the compressed size of \"input\".\nnamespace internal {\nchar* CompressFragment(const char* input,\n                       size_t input_size,\n                       char* op,\n                       uint16* table,\n                       const int table_size) {\n  // \"ip\" is the input pointer, and \"op\" is the output pointer.\n  const char* ip = input;\n  assert(input_size <= kBlockSize);\n  assert((table_size & (table_size - 1)) == 0); // table must be power of two\n  const int shift = 32 - Bits::Log2Floor(table_size);\n  assert(static_cast<int>(kuint32max >> shift) == table_size - 1);\n  const char* ip_end = input + input_size;\n  const char* base_ip = ip;\n  // Bytes in [next_emit, ip) will be emitted as literal bytes.  Or\n  // [next_emit, ip_end) after the main loop.\n  const char* next_emit = ip;\n\n  const size_t kInputMarginBytes = 15;\n  if (PREDICT_TRUE(input_size >= kInputMarginBytes)) {\n    const char* ip_limit = input + input_size - kInputMarginBytes;\n\n    for (uint32 next_hash = Hash(++ip, shift); ; ) {\n      assert(next_emit < ip);\n      // The body of this loop calls EmitLiteral once and then EmitCopy one or\n      // more times.  (The exception is that when we're close to exhausting\n      // the input we goto emit_remainder.)\n      //\n      // In the first iteration of this loop we're just starting, so\n      // there's nothing to copy, so calling EmitLiteral once is\n      // necessary.  And we only start a new iteration when the\n      // current iteration has determined that a call to EmitLiteral will\n      // precede the next call to EmitCopy (if any).\n      //\n      // Step 1: Scan forward in the input looking for a 4-byte-long match.\n      // If we get close to exhausting the input then goto emit_remainder.\n      //\n      // Heuristic match skipping: If 32 bytes are scanned with no matches\n      // found, start looking only at every other byte. If 32 more bytes are\n      // scanned, look at every third byte, etc.. When a match is found,\n      // immediately go back to looking at every byte. This is a small loss\n      // (~5% performance, ~0.1% density) for compressible data due to more\n      // bookkeeping, but for non-compressible data (such as JPEG) it's a huge\n      // win since the compressor quickly \"realizes\" the data is incompressible\n      // and doesn't bother looking for matches everywhere.\n      //\n      // The \"skip\" variable keeps track of how many bytes there are since the\n      // last match; dividing it by 32 (ie. right-shifting by five) gives the\n      // number of bytes to move ahead for each iteration.\n      uint32 skip = 32;\n\n      const char* next_ip = ip;\n      const char* candidate;\n      do {\n        ip = next_ip;\n        uint32 hash = next_hash;\n        assert(hash == Hash(ip, shift));\n        uint32 bytes_between_hash_lookups = skip++ >> 5;\n        next_ip = ip + bytes_between_hash_lookups;\n        if (PREDICT_FALSE(next_ip > ip_limit)) {\n          goto emit_remainder;\n        }\n        next_hash = Hash(next_ip, shift);\n        candidate = base_ip + table[hash];\n        assert(candidate >= base_ip);\n        assert(candidate < ip);\n\n        table[hash] = ip - base_ip;\n      } while (PREDICT_TRUE(UNALIGNED_LOAD32(ip) !=\n                            UNALIGNED_LOAD32(candidate)));\n\n      // Step 2: A 4-byte match has been found.  We'll later see if more\n      // than 4 bytes match.  But, prior to the match, input\n      // bytes [next_emit, ip) are unmatched.  Emit them as \"literal bytes.\"\n      assert(next_emit + 16 <= ip_end);\n      op = EmitLiteral(op, next_emit, ip - next_emit, true);\n\n      // Step 3: Call EmitCopy, and then see if another EmitCopy could\n      // be our next move.  Repeat until we find no match for the\n      // input immediately after what was consumed by the last EmitCopy call.\n      //\n      // If we exit this loop normally then we need to call EmitLiteral next,\n      // though we don't yet know how big the literal will be.  We handle that\n      // by proceeding to the next iteration of the main loop.  We also can exit\n      // this loop via goto if we get close to exhausting the input.\n      EightBytesReference input_bytes;\n      uint32 candidate_bytes = 0;\n\n      do {\n        // We have a 4-byte match at ip, and no need to emit any\n        // \"literal bytes\" prior to ip.\n        const char* base = ip;\n        int matched = 4 + FindMatchLength(candidate + 4, ip + 4, ip_end);\n        ip += matched;\n        size_t offset = base - candidate;\n        assert(0 == memcmp(base, candidate, matched));\n        op = EmitCopy(op, offset, matched);\n        // We could immediately start working at ip now, but to improve\n        // compression we first update table[Hash(ip - 1, ...)].\n        const char* insert_tail = ip - 1;\n        next_emit = ip;\n        if (PREDICT_FALSE(ip >= ip_limit)) {\n          goto emit_remainder;\n        }\n        input_bytes = GetEightBytesAt(insert_tail);\n        uint32 prev_hash = HashBytes(GetUint32AtOffset(input_bytes, 0), shift);\n        table[prev_hash] = ip - base_ip - 1;\n        uint32 cur_hash = HashBytes(GetUint32AtOffset(input_bytes, 1), shift);\n        candidate = base_ip + table[cur_hash];\n        candidate_bytes = UNALIGNED_LOAD32(candidate);\n        table[cur_hash] = ip - base_ip;\n      } while (GetUint32AtOffset(input_bytes, 1) == candidate_bytes);\n\n      next_hash = HashBytes(GetUint32AtOffset(input_bytes, 2), shift);\n      ++ip;\n    }\n  }\n\n emit_remainder:\n  // Emit the remaining bytes as a literal\n  if (next_emit < ip_end) {\n    op = EmitLiteral(op, next_emit, ip_end - next_emit, false);\n  }\n\n  return op;\n}\n}  // end namespace internal\n\n// Signature of output types needed by decompression code.\n// The decompression code is templatized on a type that obeys this\n// signature so that we do not pay virtual function call overhead in\n// the middle of a tight decompression loop.\n//\n// class DecompressionWriter {\n//  public:\n//   // Called before decompression\n//   void SetExpectedLength(size_t length);\n//\n//   // Called after decompression\n//   bool CheckLength() const;\n//\n//   // Called repeatedly during decompression\n//   bool Append(const char* ip, size_t length);\n//   bool AppendFromSelf(uint32 offset, size_t length);\n//\n//   // The difference between TryFastAppend and Append is that TryFastAppend\n//   // is allowed to read up to <available> bytes from the input buffer,\n//   // whereas Append is allowed to read <length>.\n//   //\n//   // Also, TryFastAppend is allowed to return false, declining the append,\n//   // without it being a fatal error -- just \"return false\" would be\n//   // a perfectly legal implementation of TryFastAppend. The intention\n//   // is for TryFastAppend to allow a fast path in the common case of\n//   // a small append.\n//   //\n//   // NOTE(user): TryFastAppend must always return decline (return false)\n//   // if <length> is 61 or more, as in this case the literal length is not\n//   // decoded fully. In practice, this should not be a big problem,\n//   // as it is unlikely that one would implement a fast path accepting\n//   // this much data.\n//   bool TryFastAppend(const char* ip, size_t available, size_t length);\n// };\n\n// -----------------------------------------------------------------------\n// Lookup table for decompression code.  Generated by ComputeTable() below.\n// -----------------------------------------------------------------------\n\n// Mapping from i in range [0,4] to a mask to extract the bottom 8*i bits\nstatic const uint32 wordmask[] = {\n  0u, 0xffu, 0xffffu, 0xffffffu, 0xffffffffu\n};\n\n// Data stored per entry in lookup table:\n//      Range   Bits-used       Description\n//      ------------------------------------\n//      1..64   0..7            Literal/copy length encoded in opcode byte\n//      0..7    8..10           Copy offset encoded in opcode byte / 256\n//      0..4    11..13          Extra bytes after opcode\n//\n// We use eight bits for the length even though 7 would have sufficed\n// because of efficiency reasons:\n//      (1) Extracting a byte is faster than a bit-field\n//      (2) It properly aligns copy offset so we do not need a <<8\nstatic const uint16 char_table[256] = {\n  0x0001, 0x0804, 0x1001, 0x2001, 0x0002, 0x0805, 0x1002, 0x2002,\n  0x0003, 0x0806, 0x1003, 0x2003, 0x0004, 0x0807, 0x1004, 0x2004,\n  0x0005, 0x0808, 0x1005, 0x2005, 0x0006, 0x0809, 0x1006, 0x2006,\n  0x0007, 0x080a, 0x1007, 0x2007, 0x0008, 0x080b, 0x1008, 0x2008,\n  0x0009, 0x0904, 0x1009, 0x2009, 0x000a, 0x0905, 0x100a, 0x200a,\n  0x000b, 0x0906, 0x100b, 0x200b, 0x000c, 0x0907, 0x100c, 0x200c,\n  0x000d, 0x0908, 0x100d, 0x200d, 0x000e, 0x0909, 0x100e, 0x200e,\n  0x000f, 0x090a, 0x100f, 0x200f, 0x0010, 0x090b, 0x1010, 0x2010,\n  0x0011, 0x0a04, 0x1011, 0x2011, 0x0012, 0x0a05, 0x1012, 0x2012,\n  0x0013, 0x0a06, 0x1013, 0x2013, 0x0014, 0x0a07, 0x1014, 0x2014,\n  0x0015, 0x0a08, 0x1015, 0x2015, 0x0016, 0x0a09, 0x1016, 0x2016,\n  0x0017, 0x0a0a, 0x1017, 0x2017, 0x0018, 0x0a0b, 0x1018, 0x2018,\n  0x0019, 0x0b04, 0x1019, 0x2019, 0x001a, 0x0b05, 0x101a, 0x201a,\n  0x001b, 0x0b06, 0x101b, 0x201b, 0x001c, 0x0b07, 0x101c, 0x201c,\n  0x001d, 0x0b08, 0x101d, 0x201d, 0x001e, 0x0b09, 0x101e, 0x201e,\n  0x001f, 0x0b0a, 0x101f, 0x201f, 0x0020, 0x0b0b, 0x1020, 0x2020,\n  0x0021, 0x0c04, 0x1021, 0x2021, 0x0022, 0x0c05, 0x1022, 0x2022,\n  0x0023, 0x0c06, 0x1023, 0x2023, 0x0024, 0x0c07, 0x1024, 0x2024,\n  0x0025, 0x0c08, 0x1025, 0x2025, 0x0026, 0x0c09, 0x1026, 0x2026,\n  0x0027, 0x0c0a, 0x1027, 0x2027, 0x0028, 0x0c0b, 0x1028, 0x2028,\n  0x0029, 0x0d04, 0x1029, 0x2029, 0x002a, 0x0d05, 0x102a, 0x202a,\n  0x002b, 0x0d06, 0x102b, 0x202b, 0x002c, 0x0d07, 0x102c, 0x202c,\n  0x002d, 0x0d08, 0x102d, 0x202d, 0x002e, 0x0d09, 0x102e, 0x202e,\n  0x002f, 0x0d0a, 0x102f, 0x202f, 0x0030, 0x0d0b, 0x1030, 0x2030,\n  0x0031, 0x0e04, 0x1031, 0x2031, 0x0032, 0x0e05, 0x1032, 0x2032,\n  0x0033, 0x0e06, 0x1033, 0x2033, 0x0034, 0x0e07, 0x1034, 0x2034,\n  0x0035, 0x0e08, 0x1035, 0x2035, 0x0036, 0x0e09, 0x1036, 0x2036,\n  0x0037, 0x0e0a, 0x1037, 0x2037, 0x0038, 0x0e0b, 0x1038, 0x2038,\n  0x0039, 0x0f04, 0x1039, 0x2039, 0x003a, 0x0f05, 0x103a, 0x203a,\n  0x003b, 0x0f06, 0x103b, 0x203b, 0x003c, 0x0f07, 0x103c, 0x203c,\n  0x0801, 0x0f08, 0x103d, 0x203d, 0x1001, 0x0f09, 0x103e, 0x203e,\n  0x1801, 0x0f0a, 0x103f, 0x203f, 0x2001, 0x0f0b, 0x1040, 0x2040\n};\n\n// In debug mode, allow optional computation of the table at startup.\n// Also, check that the decompression table is correct.\n#ifndef NDEBUG\nDEFINE_bool(snappy_dump_decompression_table, false,\n            \"If true, we print the decompression table at startup.\");\n\nstatic uint16 MakeEntry(unsigned int extra,\n                        unsigned int len,\n                        unsigned int copy_offset) {\n  // Check that all of the fields fit within the allocated space\n  assert(extra       == (extra & 0x7));          // At most 3 bits\n  assert(copy_offset == (copy_offset & 0x7));    // At most 3 bits\n  assert(len         == (len & 0x7f));           // At most 7 bits\n  return len | (copy_offset << 8) | (extra << 11);\n}\n\nstatic void ComputeTable() {\n  uint16 dst[256];\n\n  // Place invalid entries in all places to detect missing initialization\n  int assigned = 0;\n  for (int i = 0; i < 256; i++) {\n    dst[i] = 0xffff;\n  }\n\n  // Small LITERAL entries.  We store (len-1) in the top 6 bits.\n  for (unsigned int len = 1; len <= 60; len++) {\n    dst[LITERAL | ((len-1) << 2)] = MakeEntry(0, len, 0);\n    assigned++;\n  }\n\n  // Large LITERAL entries.  We use 60..63 in the high 6 bits to\n  // encode the number of bytes of length info that follow the opcode.\n  for (unsigned int extra_bytes = 1; extra_bytes <= 4; extra_bytes++) {\n    // We set the length field in the lookup table to 1 because extra\n    // bytes encode len-1.\n    dst[LITERAL | ((extra_bytes+59) << 2)] = MakeEntry(extra_bytes, 1, 0);\n    assigned++;\n  }\n\n  // COPY_1_BYTE_OFFSET.\n  //\n  // The tag byte in the compressed data stores len-4 in 3 bits, and\n  // offset/256 in 5 bits.  offset%256 is stored in the next byte.\n  //\n  // This format is used for length in range [4..11] and offset in\n  // range [0..2047]\n  for (unsigned int len = 4; len < 12; len++) {\n    for (unsigned int offset = 0; offset < 2048; offset += 256) {\n      dst[COPY_1_BYTE_OFFSET | ((len-4)<<2) | ((offset>>8)<<5)] =\n        MakeEntry(1, len, offset>>8);\n      assigned++;\n    }\n  }\n\n  // COPY_2_BYTE_OFFSET.\n  // Tag contains len-1 in top 6 bits, and offset in next two bytes.\n  for (unsigned int len = 1; len <= 64; len++) {\n    dst[COPY_2_BYTE_OFFSET | ((len-1)<<2)] = MakeEntry(2, len, 0);\n    assigned++;\n  }\n\n  // COPY_4_BYTE_OFFSET.\n  // Tag contents len-1 in top 6 bits, and offset in next four bytes.\n  for (unsigned int len = 1; len <= 64; len++) {\n    dst[COPY_4_BYTE_OFFSET | ((len-1)<<2)] = MakeEntry(4, len, 0);\n    assigned++;\n  }\n\n  // Check that each entry was initialized exactly once.\n  if (assigned != 256) {\n    fprintf(stderr, \"ComputeTable: assigned only %d of 256\\n\", assigned);\n    abort();\n  }\n  for (int i = 0; i < 256; i++) {\n    if (dst[i] == 0xffff) {\n      fprintf(stderr, \"ComputeTable: did not assign byte %d\\n\", i);\n      abort();\n    }\n  }\n\n  if (FLAGS_snappy_dump_decompression_table) {\n    printf(\"static const uint16 char_table[256] = {\\n  \");\n    for (int i = 0; i < 256; i++) {\n      printf(\"0x%04x%s\",\n             dst[i],\n             ((i == 255) ? \"\\n\" : (((i%8) == 7) ? \",\\n  \" : \", \")));\n    }\n    printf(\"};\\n\");\n  }\n\n  // Check that computed table matched recorded table\n  for (int i = 0; i < 256; i++) {\n    if (dst[i] != char_table[i]) {\n      fprintf(stderr, \"ComputeTable: byte %d: computed (%x), expect (%x)\\n\",\n              i, static_cast<int>(dst[i]), static_cast<int>(char_table[i]));\n      abort();\n    }\n  }\n}\n#endif /* !NDEBUG */\n\n// Helper class for decompression\nclass SnappyDecompressor {\n private:\n  Source*       reader_;         // Underlying source of bytes to decompress\n  const char*   ip_;             // Points to next buffered byte\n  const char*   ip_limit_;       // Points just past buffered bytes\n  uint32        peeked_;         // Bytes peeked from reader (need to skip)\n  bool          eof_;            // Hit end of input without an error?\n  char          scratch_[5];     // Temporary buffer for PeekFast() boundaries\n\n  // Ensure that all of the tag metadata for the next tag is available\n  // in [ip_..ip_limit_-1].  Also ensures that [ip,ip+4] is readable even\n  // if (ip_limit_ - ip_ < 5).\n  //\n  // Returns true on success, false on error or end of input.\n  bool RefillTag();\n\n public:\n  explicit SnappyDecompressor(Source* reader)\n      : reader_(reader),\n        ip_(NULL),\n        ip_limit_(NULL),\n        peeked_(0),\n        eof_(false) {\n  }\n\n  ~SnappyDecompressor() {\n    // Advance past any bytes we peeked at from the reader\n    reader_->Skip(peeked_);\n  }\n\n  // Returns true iff we have hit the end of the input without an error.\n  bool eof() const {\n    return eof_;\n  }\n\n  // Read the uncompressed length stored at the start of the compressed data.\n  // On succcess, stores the length in *result and returns true.\n  // On failure, returns false.\n  bool ReadUncompressedLength(uint32* result) {\n    assert(ip_ == NULL);       // Must not have read anything yet\n    // Length is encoded in 1..5 bytes\n    *result = 0;\n    uint32 shift = 0;\n    while (true) {\n      if (shift >= 32) return false;\n      size_t n;\n      const char* ip = reader_->Peek(&n);\n      if (n == 0) return false;\n      const unsigned char c = *(reinterpret_cast<const unsigned char*>(ip));\n      reader_->Skip(1);\n      *result |= static_cast<uint32>(c & 0x7f) << shift;\n      if (c < 128) {\n        break;\n      }\n      shift += 7;\n    }\n    return true;\n  }\n\n  // Process the next item found in the input.\n  // Returns true if successful, false on error or end of input.\n  template <class Writer>\n  void DecompressAllTags(Writer* writer) {\n    const char* ip = ip_;\n\n    // We could have put this refill fragment only at the beginning of the loop.\n    // However, duplicating it at the end of each branch gives the compiler more\n    // scope to optimize the <ip_limit_ - ip> expression based on the local\n    // context, which overall increases speed.\n    #define MAYBE_REFILL() \\\n        if (ip_limit_ - ip < 5) { \\\n          ip_ = ip; \\\n          if (!RefillTag()) return; \\\n          ip = ip_; \\\n        }\n\n    MAYBE_REFILL();\n    for ( ;; ) {\n      const unsigned char c = *(reinterpret_cast<const unsigned char*>(ip++));\n\n      if ((c & 0x3) == LITERAL) {\n        size_t literal_length = (c >> 2) + 1u;\n        if (writer->TryFastAppend(ip, ip_limit_ - ip, literal_length)) {\n          assert(literal_length < 61);\n          ip += literal_length;\n          MAYBE_REFILL();\n          continue;\n        }\n        if (PREDICT_FALSE(literal_length >= 61)) {\n          // Long literal.\n          const size_t literal_length_length = literal_length - 60;\n          literal_length =\n              (LittleEndian::Load32(ip) & wordmask[literal_length_length]) + 1;\n          ip += literal_length_length;\n        }\n\n        size_t avail = ip_limit_ - ip;\n        while (avail < literal_length) {\n          if (!writer->Append(ip, avail)) return;\n          literal_length -= avail;\n          reader_->Skip(peeked_);\n          size_t n;\n          ip = reader_->Peek(&n);\n          avail = n;\n          peeked_ = avail;\n          if (avail == 0) return;  // Premature end of input\n          ip_limit_ = ip + avail;\n        }\n        if (!writer->Append(ip, literal_length)) {\n          return;\n        }\n        ip += literal_length;\n        MAYBE_REFILL();\n      } else {\n        const uint32 entry = char_table[c];\n        const uint32 trailer = LittleEndian::Load32(ip) & wordmask[entry >> 11];\n        const uint32 length = entry & 0xff;\n        ip += entry >> 11;\n\n        // copy_offset/256 is encoded in bits 8..10.  By just fetching\n        // those bits, we get copy_offset (since the bit-field starts at\n        // bit 8).\n        const uint32 copy_offset = entry & 0x700;\n        if (!writer->AppendFromSelf(copy_offset + trailer, length)) {\n          return;\n        }\n        MAYBE_REFILL();\n      }\n    }\n\n#undef MAYBE_REFILL\n  }\n};\n\nbool SnappyDecompressor::RefillTag() {\n  const char* ip = ip_;\n  if (ip == ip_limit_) {\n    // Fetch a new fragment from the reader\n    reader_->Skip(peeked_);   // All peeked bytes are used up\n    size_t n;\n    ip = reader_->Peek(&n);\n    peeked_ = n;\n    if (n == 0) {\n      eof_ = true;\n      return false;\n    }\n    ip_limit_ = ip + n;\n  }\n\n  // Read the tag character\n  assert(ip < ip_limit_);\n  const unsigned char c = *(reinterpret_cast<const unsigned char*>(ip));\n  const uint32 entry = char_table[c];\n  const uint32 needed = (entry >> 11) + 1;  // +1 byte for 'c'\n  assert(needed <= sizeof(scratch_));\n\n  // Read more bytes from reader if needed\n  uint32 nbuf = ip_limit_ - ip;\n  if (nbuf < needed) {\n    // Stitch together bytes from ip and reader to form the word\n    // contents.  We store the needed bytes in \"scratch_\".  They\n    // will be consumed immediately by the caller since we do not\n    // read more than we need.\n    memmove(scratch_, ip, nbuf);\n    reader_->Skip(peeked_);  // All peeked bytes are used up\n    peeked_ = 0;\n    while (nbuf < needed) {\n      size_t length;\n      const char* src = reader_->Peek(&length);\n      if (length == 0) return false;\n      uint32 to_add = min<uint32>(needed - nbuf, length);\n      memcpy(scratch_ + nbuf, src, to_add);\n      nbuf += to_add;\n      reader_->Skip(to_add);\n    }\n    assert(nbuf == needed);\n    ip_ = scratch_;\n    ip_limit_ = scratch_ + needed;\n  } else if (nbuf < 5) {\n    // Have enough bytes, but move into scratch_ so that we do not\n    // read past end of input\n    memmove(scratch_, ip, nbuf);\n    reader_->Skip(peeked_);  // All peeked bytes are used up\n    peeked_ = 0;\n    ip_ = scratch_;\n    ip_limit_ = scratch_ + nbuf;\n  } else {\n    // Pass pointer to buffer returned by reader_.\n    ip_ = ip;\n  }\n  return true;\n}\n\ntemplate <typename Writer>\nstatic bool InternalUncompress(Source* r,\n                               Writer* writer,\n                               uint32 max_len) {\n  // Read the uncompressed length from the front of the compressed input\n  SnappyDecompressor decompressor(r);\n  uint32 uncompressed_len = 0;\n  if (!decompressor.ReadUncompressedLength(&uncompressed_len)) return false;\n  return InternalUncompressAllTags(\n      &decompressor, writer, uncompressed_len, max_len);\n}\n\ntemplate <typename Writer>\nstatic bool InternalUncompressAllTags(SnappyDecompressor* decompressor,\n                                      Writer* writer,\n                                      uint32 uncompressed_len,\n                                      uint32 max_len) {\n  // Protect against possible DoS attack\n  if (static_cast<uint64>(uncompressed_len) > max_len) {\n    return false;\n  }\n\n  writer->SetExpectedLength(uncompressed_len);\n\n  // Process the entire input\n  decompressor->DecompressAllTags(writer);\n  return (decompressor->eof() && writer->CheckLength());\n}\n\nbool GetUncompressedLength(Source* source, uint32* result) {\n  SnappyDecompressor decompressor(source);\n  return decompressor.ReadUncompressedLength(result);\n}\n\nsize_t Compress(Source* reader, Sink* writer) {\n  size_t written = 0;\n  size_t N = reader->Available();\n  char ulength[Varint::kMax32];\n  char* p = Varint::Encode32(ulength, N);\n  writer->Append(ulength, p-ulength);\n  written += (p - ulength);\n\n  internal::WorkingMemory wmem;\n  char* scratch = NULL;\n  char* scratch_output = NULL;\n\n  while (N > 0) {\n    // Get next block to compress (without copying if possible)\n    size_t fragment_size;\n    const char* fragment = reader->Peek(&fragment_size);\n    assert(fragment_size != 0);  // premature end of input\n    const size_t num_to_read = min(N, kBlockSize);\n    size_t bytes_read = fragment_size;\n\n    size_t pending_advance = 0;\n    if (bytes_read >= num_to_read) {\n      // Buffer returned by reader is large enough\n      pending_advance = num_to_read;\n      fragment_size = num_to_read;\n    } else {\n      // Read into scratch buffer\n      if (scratch == NULL) {\n        // If this is the last iteration, we want to allocate N bytes\n        // of space, otherwise the max possible kBlockSize space.\n        // num_to_read contains exactly the correct value\n        scratch = new char[num_to_read];\n      }\n      memcpy(scratch, fragment, bytes_read);\n      reader->Skip(bytes_read);\n\n      while (bytes_read < num_to_read) {\n        fragment = reader->Peek(&fragment_size);\n        size_t n = min<size_t>(fragment_size, num_to_read - bytes_read);\n        memcpy(scratch + bytes_read, fragment, n);\n        bytes_read += n;\n        reader->Skip(n);\n      }\n      assert(bytes_read == num_to_read);\n      fragment = scratch;\n      fragment_size = num_to_read;\n    }\n    assert(fragment_size == num_to_read);\n\n    // Get encoding table for compression\n    int table_size;\n    uint16* table = wmem.GetHashTable(num_to_read, &table_size);\n\n    // Compress input_fragment and append to dest\n    const int max_output = MaxCompressedLength(num_to_read);\n\n    // Need a scratch buffer for the output, in case the byte sink doesn't\n    // have room for us directly.\n    if (scratch_output == NULL) {\n      scratch_output = new char[max_output];\n    } else {\n      // Since we encode kBlockSize regions followed by a region\n      // which is <= kBlockSize in length, a previously allocated\n      // scratch_output[] region is big enough for this iteration.\n    }\n    char* dest = writer->GetAppendBuffer(max_output, scratch_output);\n    char* end = internal::CompressFragment(fragment, fragment_size,\n                                           dest, table, table_size);\n    writer->Append(dest, end - dest);\n    written += (end - dest);\n\n    N -= num_to_read;\n    reader->Skip(pending_advance);\n  }\n\n  delete[] scratch;\n  delete[] scratch_output;\n\n  return written;\n}\n\n// -----------------------------------------------------------------------\n// Flat array interfaces\n// -----------------------------------------------------------------------\n\n// A type that writes to a flat array.\n// Note that this is not a \"ByteSink\", but a type that matches the\n// Writer template argument to SnappyDecompressor::DecompressAllTags().\nclass SnappyArrayWriter {\n private:\n  char* base_;\n  char* op_;\n  char* op_limit_;\n\n public:\n  inline explicit SnappyArrayWriter(char* dst)\n      : base_(dst),\n        op_(dst) {\n  }\n\n  inline void SetExpectedLength(size_t len) {\n    op_limit_ = op_ + len;\n  }\n\n  inline bool CheckLength() const {\n    return op_ == op_limit_;\n  }\n\n  inline bool Append(const char* ip, size_t len) {\n    char* op = op_;\n    const size_t space_left = op_limit_ - op;\n    if (space_left < len) {\n      return false;\n    }\n    memcpy(op, ip, len);\n    op_ = op + len;\n    return true;\n  }\n\n  inline bool TryFastAppend(const char* ip, size_t available, size_t len) {\n    char* op = op_;\n    const size_t space_left = op_limit_ - op;\n    if (len <= 16 && available >= 16 && space_left >= 16) {\n      // Fast path, used for the majority (about 95%) of invocations.\n      UnalignedCopy64(ip, op);\n      UnalignedCopy64(ip + 8, op + 8);\n      op_ = op + len;\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  inline bool AppendFromSelf(size_t offset, size_t len) {\n    char* op = op_;\n    const size_t space_left = op_limit_ - op;\n\n    if (op - base_ <= offset - 1u) {  // -1u catches offset==0\n      return false;\n    }\n    if (len <= 16 && offset >= 8 && space_left >= 16) {\n      // Fast path, used for the majority (70-80%) of dynamic invocations.\n      UnalignedCopy64(op - offset, op);\n      UnalignedCopy64(op - offset + 8, op + 8);\n    } else {\n      if (space_left >= len + kMaxIncrementCopyOverflow) {\n        IncrementalCopyFastPath(op - offset, op, len);\n      } else {\n        if (space_left < len) {\n          return false;\n        }\n        IncrementalCopy(op - offset, op, len);\n      }\n    }\n\n    op_ = op + len;\n    return true;\n  }\n};\n\nbool RawUncompress(const char* compressed, size_t n, char* uncompressed) {\n  ByteArraySource reader(compressed, n);\n  return RawUncompress(&reader, uncompressed);\n}\n\nbool RawUncompress(Source* compressed, char* uncompressed) {\n  SnappyArrayWriter output(uncompressed);\n  return InternalUncompress(compressed, &output, kuint32max);\n}\n\nbool Uncompress(const char* compressed, size_t n, string* uncompressed) {\n  size_t ulength;\n  if (!GetUncompressedLength(compressed, n, &ulength)) {\n    return false;\n  }\n  // Protect against possible DoS attack\n  if ((static_cast<uint64>(ulength) + uncompressed->size()) >\n      uncompressed->max_size()) {\n    return false;\n  }\n  STLStringResizeUninitialized(uncompressed, ulength);\n  return RawUncompress(compressed, n, string_as_array(uncompressed));\n}\n\n\n// A Writer that drops everything on the floor and just does validation\nclass SnappyDecompressionValidator {\n private:\n  size_t expected_;\n  size_t produced_;\n\n public:\n  inline SnappyDecompressionValidator() : produced_(0) { }\n  inline void SetExpectedLength(size_t len) {\n    expected_ = len;\n  }\n  inline bool CheckLength() const {\n    return expected_ == produced_;\n  }\n  inline bool Append(const char* ip, size_t len) {\n    produced_ += len;\n    return produced_ <= expected_;\n  }\n  inline bool TryFastAppend(const char* ip, size_t available, size_t length) {\n    return false;\n  }\n  inline bool AppendFromSelf(size_t offset, size_t len) {\n    if (produced_ <= offset - 1u) return false;  // -1u catches offset==0\n    produced_ += len;\n    return produced_ <= expected_;\n  }\n};\n\nbool IsValidCompressedBuffer(const char* compressed, size_t n) {\n  ByteArraySource reader(compressed, n);\n  SnappyDecompressionValidator writer;\n  return InternalUncompress(&reader, &writer, kuint32max);\n}\n\nvoid RawCompress(const char* input,\n                 size_t input_length,\n                 char* compressed,\n                 size_t* compressed_length) {\n  ByteArraySource reader(input, input_length);\n  UncheckedByteArraySink writer(compressed);\n  Compress(&reader, &writer);\n\n  // Compute how many bytes were added\n  *compressed_length = (writer.CurrentDestination() - compressed);\n}\n\nsize_t Compress(const char* input, size_t input_length, string* compressed) {\n  // Pre-grow the buffer to the max length of the compressed output\n  compressed->resize(MaxCompressedLength(input_length));\n\n  size_t compressed_length;\n  RawCompress(input, input_length, string_as_array(compressed),\n              &compressed_length);\n  compressed->resize(compressed_length);\n  return compressed_length;\n}\n\n\n} // end namespace snappy\n\n"
  },
  {
    "path": "deps/snappy-1.1.0/snappy.h",
    "content": "// Copyright 2005 and onwards Google Inc.\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// A light-weight compression algorithm.  It is designed for speed of\n// compression and decompression, rather than for the utmost in space\n// savings.\n//\n// For getting better compression ratios when you are compressing data\n// with long repeated sequences or compressing data that is similar to\n// other data, while still compressing fast, you might look at first\n// using BMDiff and then compressing the output of BMDiff with\n// Snappy.\n\n#ifndef UTIL_SNAPPY_SNAPPY_H__\n#define UTIL_SNAPPY_SNAPPY_H__\n\n#include <stddef.h>\n#include <string>\n\n#include \"snappy-stubs-public.h\"\n\nnamespace snappy {\n  class Source;\n  class Sink;\n\n  // ------------------------------------------------------------------------\n  // Generic compression/decompression routines.\n  // ------------------------------------------------------------------------\n\n  // Compress the bytes read from \"*source\" and append to \"*sink\". Return the\n  // number of bytes written.\n  size_t Compress(Source* source, Sink* sink);\n\n  // Find the uncompressed length of the given stream, as given by the header.\n  // Note that the true length could deviate from this; the stream could e.g.\n  // be truncated.\n  //\n  // Also note that this leaves \"*source\" in a state that is unsuitable for\n  // further operations, such as RawUncompress(). You will need to rewind\n  // or recreate the source yourself before attempting any further calls.\n  bool GetUncompressedLength(Source* source, uint32* result);\n\n  // ------------------------------------------------------------------------\n  // Higher-level string based routines (should be sufficient for most users)\n  // ------------------------------------------------------------------------\n\n  // Sets \"*output\" to the compressed version of \"input[0,input_length-1]\".\n  // Original contents of *output are lost.\n  //\n  // REQUIRES: \"input[]\" is not an alias of \"*output\".\n  size_t Compress(const char* input, size_t input_length, string* output);\n\n  // Decompresses \"compressed[0,compressed_length-1]\" to \"*uncompressed\".\n  // Original contents of \"*uncompressed\" are lost.\n  //\n  // REQUIRES: \"compressed[]\" is not an alias of \"*uncompressed\".\n  //\n  // returns false if the message is corrupted and could not be decompressed\n  bool Uncompress(const char* compressed, size_t compressed_length,\n                  string* uncompressed);\n\n\n  // ------------------------------------------------------------------------\n  // Lower-level character array based routines.  May be useful for\n  // efficiency reasons in certain circumstances.\n  // ------------------------------------------------------------------------\n\n  // REQUIRES: \"compressed\" must point to an area of memory that is at\n  // least \"MaxCompressedLength(input_length)\" bytes in length.\n  //\n  // Takes the data stored in \"input[0..input_length]\" and stores\n  // it in the array pointed to by \"compressed\".\n  //\n  // \"*compressed_length\" is set to the length of the compressed output.\n  //\n  // Example:\n  //    char* output = new char[snappy::MaxCompressedLength(input_length)];\n  //    size_t output_length;\n  //    RawCompress(input, input_length, output, &output_length);\n  //    ... Process(output, output_length) ...\n  //    delete [] output;\n  void RawCompress(const char* input,\n                   size_t input_length,\n                   char* compressed,\n                   size_t* compressed_length);\n\n  // Given data in \"compressed[0..compressed_length-1]\" generated by\n  // calling the Snappy::Compress routine, this routine\n  // stores the uncompressed data to\n  //    uncompressed[0..GetUncompressedLength(compressed)-1]\n  // returns false if the message is corrupted and could not be decrypted\n  bool RawUncompress(const char* compressed, size_t compressed_length,\n                     char* uncompressed);\n\n  // Given data from the byte source 'compressed' generated by calling\n  // the Snappy::Compress routine, this routine stores the uncompressed\n  // data to\n  //    uncompressed[0..GetUncompressedLength(compressed,compressed_length)-1]\n  // returns false if the message is corrupted and could not be decrypted\n  bool RawUncompress(Source* compressed, char* uncompressed);\n\n  // Returns the maximal size of the compressed representation of\n  // input data that is \"source_bytes\" bytes in length;\n  size_t MaxCompressedLength(size_t source_bytes);\n\n  // REQUIRES: \"compressed[]\" was produced by RawCompress() or Compress()\n  // Returns true and stores the length of the uncompressed data in\n  // *result normally.  Returns false on parsing error.\n  // This operation takes O(1) time.\n  bool GetUncompressedLength(const char* compressed, size_t compressed_length,\n                             size_t* result);\n\n  // Returns true iff the contents of \"compressed[]\" can be uncompressed\n  // successfully.  Does not return the uncompressed data.  Takes\n  // time proportional to compressed_length, but is usually at least\n  // a factor of four faster than actual decompression.\n  bool IsValidCompressedBuffer(const char* compressed,\n                               size_t compressed_length);\n\n  // The size of a compression block. Note that many parts of the compression\n  // code assumes that kBlockSize <= 65536; in particular, the hash table\n  // can only store 16-bit offsets, and EmitCopy() also assumes the offset\n  // is 65535 bytes or less. Note also that if you change this, it will\n  // affect the framing format (see framing_format.txt).\n  //\n  // Note that there might be older data around that is compressed with larger\n  // block sizes, so the decompression code should not rely on the\n  // non-existence of long backreferences.\n  static const int kBlockLog = 16;\n  static const size_t kBlockSize = 1 << kBlockLog;\n\n  static const int kMaxHashTableBits = 14;\n  static const size_t kMaxHashTableSize = 1 << kMaxHashTableBits;\n\n}  // end namespace snappy\n\n\n#endif  // UTIL_SNAPPY_SNAPPY_H__\n"
  },
  {
    "path": "deps/snappy-1.1.0/snappy_unittest.cc",
    "content": "// Copyright 2005 and onwards Google Inc.\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 <math.h>\n#include <stdlib.h>\n\n\n#include <algorithm>\n#include <string>\n#include <vector>\n\n#include \"snappy.h\"\n#include \"snappy-internal.h\"\n#include \"snappy-test.h\"\n#include \"snappy-sinksource.h\"\n\nDEFINE_int32(start_len, -1,\n             \"Starting prefix size for testing (-1: just full file contents)\");\nDEFINE_int32(end_len, -1,\n             \"Starting prefix size for testing (-1: just full file contents)\");\nDEFINE_int32(bytes, 10485760,\n             \"How many bytes to compress/uncompress per file for timing\");\n\nDEFINE_bool(zlib, false,\n            \"Run zlib compression (http://www.zlib.net)\");\nDEFINE_bool(lzo, false,\n            \"Run LZO compression (http://www.oberhumer.com/opensource/lzo/)\");\nDEFINE_bool(quicklz, false,\n            \"Run quickLZ compression (http://www.quicklz.com/)\");\nDEFINE_bool(liblzf, false,\n            \"Run libLZF compression \"\n            \"(http://www.goof.com/pcg/marc/liblzf.html)\");\nDEFINE_bool(fastlz, false,\n            \"Run FastLZ compression (http://www.fastlz.org/\");\nDEFINE_bool(snappy, true, \"Run snappy compression\");\n\n\nDEFINE_bool(write_compressed, false,\n            \"Write compressed versions of each file to <file>.comp\");\nDEFINE_bool(write_uncompressed, false,\n            \"Write uncompressed versions of each file to <file>.uncomp\");\n\nnamespace snappy {\n\n\n#ifdef HAVE_FUNC_MMAP\n\n// To test against code that reads beyond its input, this class copies a\n// string to a newly allocated group of pages, the last of which\n// is made unreadable via mprotect. Note that we need to allocate the\n// memory with mmap(), as POSIX allows mprotect() only on memory allocated\n// with mmap(), and some malloc/posix_memalign implementations expect to\n// be able to read previously allocated memory while doing heap allocations.\nclass DataEndingAtUnreadablePage {\n public:\n  explicit DataEndingAtUnreadablePage(const string& s) {\n    const size_t page_size = getpagesize();\n    const size_t size = s.size();\n    // Round up space for string to a multiple of page_size.\n    size_t space_for_string = (size + page_size - 1) & ~(page_size - 1);\n    alloc_size_ = space_for_string + page_size;\n    mem_ = mmap(NULL, alloc_size_,\n                PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);\n    CHECK_NE(MAP_FAILED, mem_);\n    protected_page_ = reinterpret_cast<char*>(mem_) + space_for_string;\n    char* dst = protected_page_ - size;\n    memcpy(dst, s.data(), size);\n    data_ = dst;\n    size_ = size;\n    // Make guard page unreadable.\n    CHECK_EQ(0, mprotect(protected_page_, page_size, PROT_NONE));\n  }\n\n  ~DataEndingAtUnreadablePage() {\n    // Undo the mprotect.\n    CHECK_EQ(0, mprotect(protected_page_, getpagesize(), PROT_READ|PROT_WRITE));\n    CHECK_EQ(0, munmap(mem_, alloc_size_));\n  }\n\n  const char* data() const { return data_; }\n  size_t size() const { return size_; }\n\n private:\n  size_t alloc_size_;\n  void* mem_;\n  char* protected_page_;\n  const char* data_;\n  size_t size_;\n};\n\n#else  // HAVE_FUNC_MMAP\n\n// Fallback for systems without mmap.\ntypedef string DataEndingAtUnreadablePage;\n\n#endif\n\nenum CompressorType {\n  ZLIB, LZO, LIBLZF, QUICKLZ, FASTLZ, SNAPPY\n};\n\nconst char* names[] = {\n  \"ZLIB\", \"LZO\", \"LIBLZF\", \"QUICKLZ\", \"FASTLZ\", \"SNAPPY\"\n};\n\nstatic size_t MinimumRequiredOutputSpace(size_t input_size,\n                                         CompressorType comp) {\n  switch (comp) {\n#ifdef ZLIB_VERSION\n    case ZLIB:\n      return ZLib::MinCompressbufSize(input_size);\n#endif  // ZLIB_VERSION\n\n#ifdef LZO_VERSION\n    case LZO:\n      return input_size + input_size/64 + 16 + 3;\n#endif  // LZO_VERSION\n\n#ifdef LZF_VERSION\n    case LIBLZF:\n      return input_size;\n#endif  // LZF_VERSION\n\n#ifdef QLZ_VERSION_MAJOR\n    case QUICKLZ:\n      return input_size + 36000;  // 36000 is used for scratch.\n#endif  // QLZ_VERSION_MAJOR\n\n#ifdef FASTLZ_VERSION\n    case FASTLZ:\n      return max(static_cast<int>(ceil(input_size * 1.05)), 66);\n#endif  // FASTLZ_VERSION\n\n    case SNAPPY:\n      return snappy::MaxCompressedLength(input_size);\n\n    default:\n      LOG(FATAL) << \"Unknown compression type number \" << comp;\n  }\n}\n\n// Returns true if we successfully compressed, false otherwise.\n//\n// If compressed_is_preallocated is set, do not resize the compressed buffer.\n// This is typically what you want for a benchmark, in order to not spend\n// time in the memory allocator. If you do set this flag, however,\n// \"compressed\" must be preinitialized to at least MinCompressbufSize(comp)\n// number of bytes, and may contain junk bytes at the end after return.\nstatic bool Compress(const char* input, size_t input_size, CompressorType comp,\n                     string* compressed, bool compressed_is_preallocated) {\n  if (!compressed_is_preallocated) {\n    compressed->resize(MinimumRequiredOutputSpace(input_size, comp));\n  }\n\n  switch (comp) {\n#ifdef ZLIB_VERSION\n    case ZLIB: {\n      ZLib zlib;\n      uLongf destlen = compressed->size();\n      int ret = zlib.Compress(\n          reinterpret_cast<Bytef*>(string_as_array(compressed)),\n          &destlen,\n          reinterpret_cast<const Bytef*>(input),\n          input_size);\n      CHECK_EQ(Z_OK, ret);\n      if (!compressed_is_preallocated) {\n        compressed->resize(destlen);\n      }\n      return true;\n    }\n#endif  // ZLIB_VERSION\n\n#ifdef LZO_VERSION\n    case LZO: {\n      unsigned char* mem = new unsigned char[LZO1X_1_15_MEM_COMPRESS];\n      lzo_uint destlen;\n      int ret = lzo1x_1_15_compress(\n          reinterpret_cast<const uint8*>(input),\n          input_size,\n          reinterpret_cast<uint8*>(string_as_array(compressed)),\n          &destlen,\n          mem);\n      CHECK_EQ(LZO_E_OK, ret);\n      delete[] mem;\n      if (!compressed_is_preallocated) {\n        compressed->resize(destlen);\n      }\n      break;\n    }\n#endif  // LZO_VERSION\n\n#ifdef LZF_VERSION\n    case LIBLZF: {\n      int destlen = lzf_compress(input,\n                                 input_size,\n                                 string_as_array(compressed),\n                                 input_size);\n      if (destlen == 0) {\n        // lzf *can* cause lots of blowup when compressing, so they\n        // recommend to limit outsize to insize, and just not compress\n        // if it's bigger.  Ideally, we'd just swap input and output.\n        compressed->assign(input, input_size);\n        destlen = input_size;\n      }\n      if (!compressed_is_preallocated) {\n        compressed->resize(destlen);\n      }\n      break;\n    }\n#endif  // LZF_VERSION\n\n#ifdef QLZ_VERSION_MAJOR\n    case QUICKLZ: {\n      qlz_state_compress *state_compress = new qlz_state_compress;\n      int destlen = qlz_compress(input,\n                                 string_as_array(compressed),\n                                 input_size,\n                                 state_compress);\n      delete state_compress;\n      CHECK_NE(0, destlen);\n      if (!compressed_is_preallocated) {\n        compressed->resize(destlen);\n      }\n      break;\n    }\n#endif  // QLZ_VERSION_MAJOR\n\n#ifdef FASTLZ_VERSION\n    case FASTLZ: {\n      // Use level 1 compression since we mostly care about speed.\n      int destlen = fastlz_compress_level(\n          1,\n          input,\n          input_size,\n          string_as_array(compressed));\n      if (!compressed_is_preallocated) {\n        compressed->resize(destlen);\n      }\n      CHECK_NE(destlen, 0);\n      break;\n    }\n#endif  // FASTLZ_VERSION\n\n    case SNAPPY: {\n      size_t destlen;\n      snappy::RawCompress(input, input_size,\n                          string_as_array(compressed),\n                          &destlen);\n      CHECK_LE(destlen, snappy::MaxCompressedLength(input_size));\n      if (!compressed_is_preallocated) {\n        compressed->resize(destlen);\n      }\n      break;\n    }\n\n\n    default: {\n      return false;     // the asked-for library wasn't compiled in\n    }\n  }\n  return true;\n}\n\nstatic bool Uncompress(const string& compressed, CompressorType comp,\n                       int size, string* output) {\n  switch (comp) {\n#ifdef ZLIB_VERSION\n    case ZLIB: {\n      output->resize(size);\n      ZLib zlib;\n      uLongf destlen = output->size();\n      int ret = zlib.Uncompress(\n          reinterpret_cast<Bytef*>(string_as_array(output)),\n          &destlen,\n          reinterpret_cast<const Bytef*>(compressed.data()),\n          compressed.size());\n      CHECK_EQ(Z_OK, ret);\n      CHECK_EQ(static_cast<uLongf>(size), destlen);\n      break;\n    }\n#endif  // ZLIB_VERSION\n\n#ifdef LZO_VERSION\n    case LZO: {\n      output->resize(size);\n      lzo_uint destlen;\n      int ret = lzo1x_decompress(\n          reinterpret_cast<const uint8*>(compressed.data()),\n          compressed.size(),\n          reinterpret_cast<uint8*>(string_as_array(output)),\n          &destlen,\n          NULL);\n      CHECK_EQ(LZO_E_OK, ret);\n      CHECK_EQ(static_cast<lzo_uint>(size), destlen);\n      break;\n    }\n#endif  // LZO_VERSION\n\n#ifdef LZF_VERSION\n    case LIBLZF: {\n      output->resize(size);\n      int destlen = lzf_decompress(compressed.data(),\n                                   compressed.size(),\n                                   string_as_array(output),\n                                   output->size());\n      if (destlen == 0) {\n        // This error probably means we had decided not to compress,\n        // and thus have stored input in output directly.\n        output->assign(compressed.data(), compressed.size());\n        destlen = compressed.size();\n      }\n      CHECK_EQ(destlen, size);\n      break;\n    }\n#endif  // LZF_VERSION\n\n#ifdef QLZ_VERSION_MAJOR\n    case QUICKLZ: {\n      output->resize(size);\n      qlz_state_decompress *state_decompress = new qlz_state_decompress;\n      int destlen = qlz_decompress(compressed.data(),\n                                   string_as_array(output),\n                                   state_decompress);\n      delete state_decompress;\n      CHECK_EQ(destlen, size);\n      break;\n    }\n#endif  // QLZ_VERSION_MAJOR\n\n#ifdef FASTLZ_VERSION\n    case FASTLZ: {\n      output->resize(size);\n      int destlen = fastlz_decompress(compressed.data(),\n                                      compressed.length(),\n                                      string_as_array(output),\n                                      size);\n      CHECK_EQ(destlen, size);\n      break;\n    }\n#endif  // FASTLZ_VERSION\n\n    case SNAPPY: {\n      snappy::RawUncompress(compressed.data(), compressed.size(),\n                            string_as_array(output));\n      break;\n    }\n\n\n    default: {\n      return false;     // the asked-for library wasn't compiled in\n    }\n  }\n  return true;\n}\n\nstatic void Measure(const char* data,\n                    size_t length,\n                    CompressorType comp,\n                    int repeats,\n                    int block_size) {\n  // Run tests a few time and pick median running times\n  static const int kRuns = 5;\n  double ctime[kRuns];\n  double utime[kRuns];\n  int compressed_size = 0;\n\n  {\n    // Chop the input into blocks\n    int num_blocks = (length + block_size - 1) / block_size;\n    vector<const char*> input(num_blocks);\n    vector<size_t> input_length(num_blocks);\n    vector<string> compressed(num_blocks);\n    vector<string> output(num_blocks);\n    for (int b = 0; b < num_blocks; b++) {\n      int input_start = b * block_size;\n      int input_limit = min<int>((b+1)*block_size, length);\n      input[b] = data+input_start;\n      input_length[b] = input_limit-input_start;\n\n      // Pre-grow the output buffer so we don't measure string append time.\n      compressed[b].resize(MinimumRequiredOutputSpace(block_size, comp));\n    }\n\n    // First, try one trial compression to make sure the code is compiled in\n    if (!Compress(input[0], input_length[0], comp, &compressed[0], true)) {\n      LOG(WARNING) << \"Skipping \" << names[comp] << \": \"\n                   << \"library not compiled in\";\n      return;\n    }\n\n    for (int run = 0; run < kRuns; run++) {\n      CycleTimer ctimer, utimer;\n\n      for (int b = 0; b < num_blocks; b++) {\n        // Pre-grow the output buffer so we don't measure string append time.\n        compressed[b].resize(MinimumRequiredOutputSpace(block_size, comp));\n      }\n\n      ctimer.Start();\n      for (int b = 0; b < num_blocks; b++)\n        for (int i = 0; i < repeats; i++)\n          Compress(input[b], input_length[b], comp, &compressed[b], true);\n      ctimer.Stop();\n\n      // Compress once more, with resizing, so we don't leave junk\n      // at the end that will confuse the decompressor.\n      for (int b = 0; b < num_blocks; b++) {\n        Compress(input[b], input_length[b], comp, &compressed[b], false);\n      }\n\n      for (int b = 0; b < num_blocks; b++) {\n        output[b].resize(input_length[b]);\n      }\n\n      utimer.Start();\n      for (int i = 0; i < repeats; i++)\n        for (int b = 0; b < num_blocks; b++)\n          Uncompress(compressed[b], comp, input_length[b], &output[b]);\n      utimer.Stop();\n\n      ctime[run] = ctimer.Get();\n      utime[run] = utimer.Get();\n    }\n\n    compressed_size = 0;\n    for (int i = 0; i < compressed.size(); i++) {\n      compressed_size += compressed[i].size();\n    }\n  }\n\n  sort(ctime, ctime + kRuns);\n  sort(utime, utime + kRuns);\n  const int med = kRuns/2;\n\n  float comp_rate = (length / ctime[med]) * repeats / 1048576.0;\n  float uncomp_rate = (length / utime[med]) * repeats / 1048576.0;\n  string x = names[comp];\n  x += \":\";\n  string urate = (uncomp_rate >= 0)\n                 ? StringPrintf(\"%.1f\", uncomp_rate)\n                 : string(\"?\");\n  printf(\"%-7s [b %dM] bytes %6d -> %6d %4.1f%%  \"\n         \"comp %5.1f MB/s  uncomp %5s MB/s\\n\",\n         x.c_str(),\n         block_size/(1<<20),\n         static_cast<int>(length), static_cast<uint32>(compressed_size),\n         (compressed_size * 100.0) / max<int>(1, length),\n         comp_rate,\n         urate.c_str());\n}\n\n\nstatic int VerifyString(const string& input) {\n  string compressed;\n  DataEndingAtUnreadablePage i(input);\n  const size_t written = snappy::Compress(i.data(), i.size(), &compressed);\n  CHECK_EQ(written, compressed.size());\n  CHECK_LE(compressed.size(),\n           snappy::MaxCompressedLength(input.size()));\n  CHECK(snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));\n\n  string uncompressed;\n  DataEndingAtUnreadablePage c(compressed);\n  CHECK(snappy::Uncompress(c.data(), c.size(), &uncompressed));\n  CHECK_EQ(uncompressed, input);\n  return uncompressed.size();\n}\n\n\n// Test that data compressed by a compressor that does not\n// obey block sizes is uncompressed properly.\nstatic void VerifyNonBlockedCompression(const string& input) {\n  if (input.length() > snappy::kBlockSize) {\n    // We cannot test larger blocks than the maximum block size, obviously.\n    return;\n  }\n\n  string prefix;\n  Varint::Append32(&prefix, input.size());\n\n  // Setup compression table\n  snappy::internal::WorkingMemory wmem;\n  int table_size;\n  uint16* table = wmem.GetHashTable(input.size(), &table_size);\n\n  // Compress entire input in one shot\n  string compressed;\n  compressed += prefix;\n  compressed.resize(prefix.size()+snappy::MaxCompressedLength(input.size()));\n  char* dest = string_as_array(&compressed) + prefix.size();\n  char* end = snappy::internal::CompressFragment(input.data(), input.size(),\n                                                dest, table, table_size);\n  compressed.resize(end - compressed.data());\n\n  // Uncompress into string\n  string uncomp_str;\n  CHECK(snappy::Uncompress(compressed.data(), compressed.size(), &uncomp_str));\n  CHECK_EQ(uncomp_str, input);\n\n}\n\n// Expand the input so that it is at least K times as big as block size\nstatic string Expand(const string& input) {\n  static const int K = 3;\n  string data = input;\n  while (data.size() < K * snappy::kBlockSize) {\n    data += input;\n  }\n  return data;\n}\n\nstatic int Verify(const string& input) {\n  VLOG(1) << \"Verifying input of size \" << input.size();\n\n  // Compress using string based routines\n  const int result = VerifyString(input);\n\n\n  VerifyNonBlockedCompression(input);\n  if (!input.empty()) {\n    VerifyNonBlockedCompression(Expand(input));\n  }\n\n\n  return result;\n}\n\n// This test checks to ensure that snappy doesn't coredump if it gets\n// corrupted data.\n\nstatic bool IsValidCompressedBuffer(const string& c) {\n  return snappy::IsValidCompressedBuffer(c.data(), c.size());\n}\nstatic bool Uncompress(const string& c, string* u) {\n  return snappy::Uncompress(c.data(), c.size(), u);\n}\n\nTYPED_TEST(CorruptedTest, VerifyCorrupted) {\n  string source = \"making sure we don't crash with corrupted input\";\n  VLOG(1) << source;\n  string dest;\n  TypeParam uncmp;\n  snappy::Compress(source.data(), source.size(), &dest);\n\n  // Mess around with the data. It's hard to simulate all possible\n  // corruptions; this is just one example ...\n  CHECK_GT(dest.size(), 3);\n  dest[1]--;\n  dest[3]++;\n  // this really ought to fail.\n  CHECK(!IsValidCompressedBuffer(TypeParam(dest)));\n  CHECK(!Uncompress(TypeParam(dest), &uncmp));\n\n  // This is testing for a security bug - a buffer that decompresses to 100k\n  // but we lie in the snappy header and only reserve 0 bytes of memory :)\n  source.resize(100000);\n  for (int i = 0; i < source.length(); ++i) {\n    source[i] = 'A';\n  }\n  snappy::Compress(source.data(), source.size(), &dest);\n  dest[0] = dest[1] = dest[2] = dest[3] = 0;\n  CHECK(!IsValidCompressedBuffer(TypeParam(dest)));\n  CHECK(!Uncompress(TypeParam(dest), &uncmp));\n\n  if (sizeof(void *) == 4) {\n    // Another security check; check a crazy big length can't DoS us with an\n    // over-allocation.\n    // Currently this is done only for 32-bit builds.  On 64-bit builds,\n    // where 3 GB might be an acceptable allocation size, Uncompress()\n    // attempts to decompress, and sometimes causes the test to run out of\n    // memory.\n    dest[0] = dest[1] = dest[2] = dest[3] = 0xff;\n    // This decodes to a really large size, i.e., about 3 GB.\n    dest[4] = 'k';\n    CHECK(!IsValidCompressedBuffer(TypeParam(dest)));\n    CHECK(!Uncompress(TypeParam(dest), &uncmp));\n  } else {\n    LOG(WARNING) << \"Crazy decompression lengths not checked on 64-bit build\";\n  }\n\n  // This decodes to about 2 MB; much smaller, but should still fail.\n  dest[0] = dest[1] = dest[2] = 0xff;\n  dest[3] = 0x00;\n  CHECK(!IsValidCompressedBuffer(TypeParam(dest)));\n  CHECK(!Uncompress(TypeParam(dest), &uncmp));\n\n  // try reading stuff in from a bad file.\n  for (int i = 1; i <= 3; ++i) {\n    string data = ReadTestDataFile(StringPrintf(\"baddata%d.snappy\", i).c_str());\n    string uncmp;\n    // check that we don't return a crazy length\n    size_t ulen;\n    CHECK(!snappy::GetUncompressedLength(data.data(), data.size(), &ulen)\n          || (ulen < (1<<20)));\n    uint32 ulen2;\n    snappy::ByteArraySource source(data.data(), data.size());\n    CHECK(!snappy::GetUncompressedLength(&source, &ulen2) ||\n          (ulen2 < (1<<20)));\n    CHECK(!IsValidCompressedBuffer(TypeParam(data)));\n    CHECK(!Uncompress(TypeParam(data), &uncmp));\n  }\n}\n\n// Helper routines to construct arbitrary compressed strings.\n// These mirror the compression code in snappy.cc, but are copied\n// here so that we can bypass some limitations in the how snappy.cc\n// invokes these routines.\nstatic void AppendLiteral(string* dst, const string& literal) {\n  if (literal.empty()) return;\n  int n = literal.size() - 1;\n  if (n < 60) {\n    // Fit length in tag byte\n    dst->push_back(0 | (n << 2));\n  } else {\n    // Encode in upcoming bytes\n    char number[4];\n    int count = 0;\n    while (n > 0) {\n      number[count++] = n & 0xff;\n      n >>= 8;\n    }\n    dst->push_back(0 | ((59+count) << 2));\n    *dst += string(number, count);\n  }\n  *dst += literal;\n}\n\nstatic void AppendCopy(string* dst, int offset, int length) {\n  while (length > 0) {\n    // Figure out how much to copy in one shot\n    int to_copy;\n    if (length >= 68) {\n      to_copy = 64;\n    } else if (length > 64) {\n      to_copy = 60;\n    } else {\n      to_copy = length;\n    }\n    length -= to_copy;\n\n    if ((to_copy < 12) && (offset < 2048)) {\n      assert(to_copy-4 < 8);            // Must fit in 3 bits\n      dst->push_back(1 | ((to_copy-4) << 2) | ((offset >> 8) << 5));\n      dst->push_back(offset & 0xff);\n    } else if (offset < 65536) {\n      dst->push_back(2 | ((to_copy-1) << 2));\n      dst->push_back(offset & 0xff);\n      dst->push_back(offset >> 8);\n    } else {\n      dst->push_back(3 | ((to_copy-1) << 2));\n      dst->push_back(offset & 0xff);\n      dst->push_back((offset >> 8) & 0xff);\n      dst->push_back((offset >> 16) & 0xff);\n      dst->push_back((offset >> 24) & 0xff);\n    }\n  }\n}\n\nTEST(Snappy, SimpleTests) {\n  Verify(\"\");\n  Verify(\"a\");\n  Verify(\"ab\");\n  Verify(\"abc\");\n\n  Verify(\"aaaaaaa\" + string(16, 'b') + string(\"aaaaa\") + \"abc\");\n  Verify(\"aaaaaaa\" + string(256, 'b') + string(\"aaaaa\") + \"abc\");\n  Verify(\"aaaaaaa\" + string(2047, 'b') + string(\"aaaaa\") + \"abc\");\n  Verify(\"aaaaaaa\" + string(65536, 'b') + string(\"aaaaa\") + \"abc\");\n  Verify(\"abcaaaaaaa\" + string(65536, 'b') + string(\"aaaaa\") + \"abc\");\n}\n\n// Verify max blowup (lots of four-byte copies)\nTEST(Snappy, MaxBlowup) {\n  string input;\n  for (int i = 0; i < 20000; i++) {\n    ACMRandom rnd(i);\n    uint32 bytes = static_cast<uint32>(rnd.Next());\n    input.append(reinterpret_cast<char*>(&bytes), sizeof(bytes));\n  }\n  for (int i = 19999; i >= 0; i--) {\n    ACMRandom rnd(i);\n    uint32 bytes = static_cast<uint32>(rnd.Next());\n    input.append(reinterpret_cast<char*>(&bytes), sizeof(bytes));\n  }\n  Verify(input);\n}\n\nTEST(Snappy, RandomData) {\n  ACMRandom rnd(FLAGS_test_random_seed);\n\n  const int num_ops = 20000;\n  for (int i = 0; i < num_ops; i++) {\n    if ((i % 1000) == 0) {\n      VLOG(0) << \"Random op \" << i << \" of \" << num_ops;\n    }\n\n    string x;\n    int len = rnd.Uniform(4096);\n    if (i < 100) {\n      len = 65536 + rnd.Uniform(65536);\n    }\n    while (x.size() < len) {\n      int run_len = 1;\n      if (rnd.OneIn(10)) {\n        run_len = rnd.Skewed(8);\n      }\n      char c = (i < 100) ? rnd.Uniform(256) : rnd.Skewed(3);\n      while (run_len-- > 0 && x.size() < len) {\n        x += c;\n      }\n    }\n\n    Verify(x);\n  }\n}\n\nTEST(Snappy, FourByteOffset) {\n  // The new compressor cannot generate four-byte offsets since\n  // it chops up the input into 32KB pieces.  So we hand-emit the\n  // copy manually.\n\n  // The two fragments that make up the input string.\n  string fragment1 = \"012345689abcdefghijklmnopqrstuvwxyz\";\n  string fragment2 = \"some other string\";\n\n  // How many times each fragment is emitted.\n  const int n1 = 2;\n  const int n2 = 100000 / fragment2.size();\n  const int length = n1 * fragment1.size() + n2 * fragment2.size();\n\n  string compressed;\n  Varint::Append32(&compressed, length);\n\n  AppendLiteral(&compressed, fragment1);\n  string src = fragment1;\n  for (int i = 0; i < n2; i++) {\n    AppendLiteral(&compressed, fragment2);\n    src += fragment2;\n  }\n  AppendCopy(&compressed, src.size(), fragment1.size());\n  src += fragment1;\n  CHECK_EQ(length, src.size());\n\n  string uncompressed;\n  CHECK(snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));\n  CHECK(snappy::Uncompress(compressed.data(), compressed.size(), &uncompressed));\n  CHECK_EQ(uncompressed, src);\n}\n\n\nstatic bool CheckUncompressedLength(const string& compressed,\n                                    size_t* ulength) {\n  const bool result1 = snappy::GetUncompressedLength(compressed.data(),\n                                                     compressed.size(),\n                                                     ulength);\n\n  snappy::ByteArraySource source(compressed.data(), compressed.size());\n  uint32 length;\n  const bool result2 = snappy::GetUncompressedLength(&source, &length);\n  CHECK_EQ(result1, result2);\n  return result1;\n}\n\nTEST(SnappyCorruption, TruncatedVarint) {\n  string compressed, uncompressed;\n  size_t ulength;\n  compressed.push_back('\\xf0');\n  CHECK(!CheckUncompressedLength(compressed, &ulength));\n  CHECK(!snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));\n  CHECK(!snappy::Uncompress(compressed.data(), compressed.size(),\n                            &uncompressed));\n}\n\nTEST(SnappyCorruption, UnterminatedVarint) {\n  string compressed, uncompressed;\n  size_t ulength;\n  compressed.push_back(128);\n  compressed.push_back(128);\n  compressed.push_back(128);\n  compressed.push_back(128);\n  compressed.push_back(128);\n  compressed.push_back(10);\n  CHECK(!CheckUncompressedLength(compressed, &ulength));\n  CHECK(!snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));\n  CHECK(!snappy::Uncompress(compressed.data(), compressed.size(),\n                            &uncompressed));\n}\n\nTEST(Snappy, ReadPastEndOfBuffer) {\n  // Check that we do not read past end of input\n\n  // Make a compressed string that ends with a single-byte literal\n  string compressed;\n  Varint::Append32(&compressed, 1);\n  AppendLiteral(&compressed, \"x\");\n\n  string uncompressed;\n  DataEndingAtUnreadablePage c(compressed);\n  CHECK(snappy::Uncompress(c.data(), c.size(), &uncompressed));\n  CHECK_EQ(uncompressed, string(\"x\"));\n}\n\n// Check for an infinite loop caused by a copy with offset==0\nTEST(Snappy, ZeroOffsetCopy) {\n  const char* compressed = \"\\x40\\x12\\x00\\x00\";\n  //  \\x40              Length (must be > kMaxIncrementCopyOverflow)\n  //  \\x12\\x00\\x00      Copy with offset==0, length==5\n  char uncompressed[100];\n  EXPECT_FALSE(snappy::RawUncompress(compressed, 4, uncompressed));\n}\n\nTEST(Snappy, ZeroOffsetCopyValidation) {\n  const char* compressed = \"\\x05\\x12\\x00\\x00\";\n  //  \\x05              Length\n  //  \\x12\\x00\\x00      Copy with offset==0, length==5\n  EXPECT_FALSE(snappy::IsValidCompressedBuffer(compressed, 4));\n}\n\n\nnamespace {\n\nint TestFindMatchLength(const char* s1, const char *s2, unsigned length) {\n  return snappy::internal::FindMatchLength(s1, s2, s2 + length);\n}\n\n}  // namespace\n\nTEST(Snappy, FindMatchLength) {\n  // Exercise all different code paths through the function.\n  // 64-bit version:\n\n  // Hit s1_limit in 64-bit loop, hit s1_limit in single-character loop.\n  EXPECT_EQ(6, TestFindMatchLength(\"012345\", \"012345\", 6));\n  EXPECT_EQ(11, TestFindMatchLength(\"01234567abc\", \"01234567abc\", 11));\n\n  // Hit s1_limit in 64-bit loop, find a non-match in single-character loop.\n  EXPECT_EQ(9, TestFindMatchLength(\"01234567abc\", \"01234567axc\", 9));\n\n  // Same, but edge cases.\n  EXPECT_EQ(11, TestFindMatchLength(\"01234567abc!\", \"01234567abc!\", 11));\n  EXPECT_EQ(11, TestFindMatchLength(\"01234567abc!\", \"01234567abc?\", 11));\n\n  // Find non-match at once in first loop.\n  EXPECT_EQ(0, TestFindMatchLength(\"01234567xxxxxxxx\", \"?1234567xxxxxxxx\", 16));\n  EXPECT_EQ(1, TestFindMatchLength(\"01234567xxxxxxxx\", \"0?234567xxxxxxxx\", 16));\n  EXPECT_EQ(4, TestFindMatchLength(\"01234567xxxxxxxx\", \"01237654xxxxxxxx\", 16));\n  EXPECT_EQ(7, TestFindMatchLength(\"01234567xxxxxxxx\", \"0123456?xxxxxxxx\", 16));\n\n  // Find non-match in first loop after one block.\n  EXPECT_EQ(8, TestFindMatchLength(\"abcdefgh01234567xxxxxxxx\",\n                                   \"abcdefgh?1234567xxxxxxxx\", 24));\n  EXPECT_EQ(9, TestFindMatchLength(\"abcdefgh01234567xxxxxxxx\",\n                                   \"abcdefgh0?234567xxxxxxxx\", 24));\n  EXPECT_EQ(12, TestFindMatchLength(\"abcdefgh01234567xxxxxxxx\",\n                                    \"abcdefgh01237654xxxxxxxx\", 24));\n  EXPECT_EQ(15, TestFindMatchLength(\"abcdefgh01234567xxxxxxxx\",\n                                    \"abcdefgh0123456?xxxxxxxx\", 24));\n\n  // 32-bit version:\n\n  // Short matches.\n  EXPECT_EQ(0, TestFindMatchLength(\"01234567\", \"?1234567\", 8));\n  EXPECT_EQ(1, TestFindMatchLength(\"01234567\", \"0?234567\", 8));\n  EXPECT_EQ(2, TestFindMatchLength(\"01234567\", \"01?34567\", 8));\n  EXPECT_EQ(3, TestFindMatchLength(\"01234567\", \"012?4567\", 8));\n  EXPECT_EQ(4, TestFindMatchLength(\"01234567\", \"0123?567\", 8));\n  EXPECT_EQ(5, TestFindMatchLength(\"01234567\", \"01234?67\", 8));\n  EXPECT_EQ(6, TestFindMatchLength(\"01234567\", \"012345?7\", 8));\n  EXPECT_EQ(7, TestFindMatchLength(\"01234567\", \"0123456?\", 8));\n  EXPECT_EQ(7, TestFindMatchLength(\"01234567\", \"0123456?\", 7));\n  EXPECT_EQ(7, TestFindMatchLength(\"01234567!\", \"0123456??\", 7));\n\n  // Hit s1_limit in 32-bit loop, hit s1_limit in single-character loop.\n  EXPECT_EQ(10, TestFindMatchLength(\"xxxxxxabcd\", \"xxxxxxabcd\", 10));\n  EXPECT_EQ(10, TestFindMatchLength(\"xxxxxxabcd?\", \"xxxxxxabcd?\", 10));\n  EXPECT_EQ(13, TestFindMatchLength(\"xxxxxxabcdef\", \"xxxxxxabcdef\", 13));\n\n  // Same, but edge cases.\n  EXPECT_EQ(12, TestFindMatchLength(\"xxxxxx0123abc!\", \"xxxxxx0123abc!\", 12));\n  EXPECT_EQ(12, TestFindMatchLength(\"xxxxxx0123abc!\", \"xxxxxx0123abc?\", 12));\n\n  // Hit s1_limit in 32-bit loop, find a non-match in single-character loop.\n  EXPECT_EQ(11, TestFindMatchLength(\"xxxxxx0123abc\", \"xxxxxx0123axc\", 13));\n\n  // Find non-match at once in first loop.\n  EXPECT_EQ(6, TestFindMatchLength(\"xxxxxx0123xxxxxxxx\",\n                                   \"xxxxxx?123xxxxxxxx\", 18));\n  EXPECT_EQ(7, TestFindMatchLength(\"xxxxxx0123xxxxxxxx\",\n                                   \"xxxxxx0?23xxxxxxxx\", 18));\n  EXPECT_EQ(8, TestFindMatchLength(\"xxxxxx0123xxxxxxxx\",\n                                   \"xxxxxx0132xxxxxxxx\", 18));\n  EXPECT_EQ(9, TestFindMatchLength(\"xxxxxx0123xxxxxxxx\",\n                                   \"xxxxxx012?xxxxxxxx\", 18));\n\n  // Same, but edge cases.\n  EXPECT_EQ(6, TestFindMatchLength(\"xxxxxx0123\", \"xxxxxx?123\", 10));\n  EXPECT_EQ(7, TestFindMatchLength(\"xxxxxx0123\", \"xxxxxx0?23\", 10));\n  EXPECT_EQ(8, TestFindMatchLength(\"xxxxxx0123\", \"xxxxxx0132\", 10));\n  EXPECT_EQ(9, TestFindMatchLength(\"xxxxxx0123\", \"xxxxxx012?\", 10));\n\n  // Find non-match in first loop after one block.\n  EXPECT_EQ(10, TestFindMatchLength(\"xxxxxxabcd0123xx\",\n                                    \"xxxxxxabcd?123xx\", 16));\n  EXPECT_EQ(11, TestFindMatchLength(\"xxxxxxabcd0123xx\",\n                                    \"xxxxxxabcd0?23xx\", 16));\n  EXPECT_EQ(12, TestFindMatchLength(\"xxxxxxabcd0123xx\",\n                                    \"xxxxxxabcd0132xx\", 16));\n  EXPECT_EQ(13, TestFindMatchLength(\"xxxxxxabcd0123xx\",\n                                    \"xxxxxxabcd012?xx\", 16));\n\n  // Same, but edge cases.\n  EXPECT_EQ(10, TestFindMatchLength(\"xxxxxxabcd0123\", \"xxxxxxabcd?123\", 14));\n  EXPECT_EQ(11, TestFindMatchLength(\"xxxxxxabcd0123\", \"xxxxxxabcd0?23\", 14));\n  EXPECT_EQ(12, TestFindMatchLength(\"xxxxxxabcd0123\", \"xxxxxxabcd0132\", 14));\n  EXPECT_EQ(13, TestFindMatchLength(\"xxxxxxabcd0123\", \"xxxxxxabcd012?\", 14));\n}\n\nTEST(Snappy, FindMatchLengthRandom) {\n  const int kNumTrials = 10000;\n  const int kTypicalLength = 10;\n  ACMRandom rnd(FLAGS_test_random_seed);\n\n  for (int i = 0; i < kNumTrials; i++) {\n    string s, t;\n    char a = rnd.Rand8();\n    char b = rnd.Rand8();\n    while (!rnd.OneIn(kTypicalLength)) {\n      s.push_back(rnd.OneIn(2) ? a : b);\n      t.push_back(rnd.OneIn(2) ? a : b);\n    }\n    DataEndingAtUnreadablePage u(s);\n    DataEndingAtUnreadablePage v(t);\n    int matched = snappy::internal::FindMatchLength(\n        u.data(), v.data(), v.data() + t.size());\n    if (matched == t.size()) {\n      EXPECT_EQ(s, t);\n    } else {\n      EXPECT_NE(s[matched], t[matched]);\n      for (int j = 0; j < matched; j++) {\n        EXPECT_EQ(s[j], t[j]);\n      }\n    }\n  }\n}\n\n\nstatic void CompressFile(const char* fname) {\n  string fullinput;\n  file::ReadFileToString(fname, &fullinput, file::Defaults()).CheckSuccess();\n\n  string compressed;\n  Compress(fullinput.data(), fullinput.size(), SNAPPY, &compressed, false);\n\n  file::WriteStringToFile(\n      string(fname).append(\".comp\").c_str(), compressed,\n      file::Defaults()).CheckSuccess();\n}\n\nstatic void UncompressFile(const char* fname) {\n  string fullinput;\n  file::ReadFileToString(fname, &fullinput, file::Defaults()).CheckSuccess();\n\n  size_t uncompLength;\n  CHECK(CheckUncompressedLength(fullinput, &uncompLength));\n\n  string uncompressed;\n  uncompressed.resize(uncompLength);\n  CHECK(snappy::Uncompress(fullinput.data(), fullinput.size(), &uncompressed));\n\n  file::WriteStringToFile(\n      string(fname).append(\".uncomp\").c_str(), uncompressed,\n      file::Defaults()).CheckSuccess();\n}\n\nstatic void MeasureFile(const char* fname) {\n  string fullinput;\n  file::ReadFileToString(fname, &fullinput, file::Defaults()).CheckSuccess();\n  printf(\"%-40s :\\n\", fname);\n\n  int start_len = (FLAGS_start_len < 0) ? fullinput.size() : FLAGS_start_len;\n  int end_len = fullinput.size();\n  if (FLAGS_end_len >= 0) {\n    end_len = min<int>(fullinput.size(), FLAGS_end_len);\n  }\n  for (int len = start_len; len <= end_len; len++) {\n    const char* const input = fullinput.data();\n    int repeats = (FLAGS_bytes + len) / (len + 1);\n    if (FLAGS_zlib)     Measure(input, len, ZLIB, repeats, 1024<<10);\n    if (FLAGS_lzo)      Measure(input, len, LZO, repeats, 1024<<10);\n    if (FLAGS_liblzf)   Measure(input, len, LIBLZF, repeats, 1024<<10);\n    if (FLAGS_quicklz)  Measure(input, len, QUICKLZ, repeats, 1024<<10);\n    if (FLAGS_fastlz)   Measure(input, len, FASTLZ, repeats, 1024<<10);\n    if (FLAGS_snappy)    Measure(input, len, SNAPPY, repeats, 4096<<10);\n\n    // For block-size based measurements\n    if (0 && FLAGS_snappy) {\n      Measure(input, len, SNAPPY, repeats, 8<<10);\n      Measure(input, len, SNAPPY, repeats, 16<<10);\n      Measure(input, len, SNAPPY, repeats, 32<<10);\n      Measure(input, len, SNAPPY, repeats, 64<<10);\n      Measure(input, len, SNAPPY, repeats, 256<<10);\n      Measure(input, len, SNAPPY, repeats, 1024<<10);\n    }\n  }\n}\n\nstatic struct {\n  const char* label;\n  const char* filename;\n} files[] = {\n  { \"html\", \"html\" },\n  { \"urls\", \"urls.10K\" },\n  { \"jpg\", \"house.jpg\" },\n  { \"pdf\", \"mapreduce-osdi-1.pdf\" },\n  { \"html4\", \"html_x_4\" },\n  { \"cp\", \"cp.html\" },\n  { \"c\", \"fields.c\" },\n  { \"lsp\", \"grammar.lsp\" },\n  { \"xls\", \"kennedy.xls\" },\n  { \"txt1\", \"alice29.txt\" },\n  { \"txt2\", \"asyoulik.txt\" },\n  { \"txt3\", \"lcet10.txt\" },\n  { \"txt4\", \"plrabn12.txt\" },\n  { \"bin\", \"ptt5\" },\n  { \"sum\", \"sum\" },\n  { \"man\", \"xargs.1\" },\n  { \"pb\", \"geo.protodata\" },\n  { \"gaviota\", \"kppkn.gtb\" },\n};\n\nstatic void BM_UFlat(int iters, int arg) {\n  StopBenchmarkTiming();\n\n  // Pick file to process based on \"arg\"\n  CHECK_GE(arg, 0);\n  CHECK_LT(arg, ARRAYSIZE(files));\n  string contents = ReadTestDataFile(files[arg].filename);\n\n  string zcontents;\n  snappy::Compress(contents.data(), contents.size(), &zcontents);\n  char* dst = new char[contents.size()];\n\n  SetBenchmarkBytesProcessed(static_cast<int64>(iters) *\n                             static_cast<int64>(contents.size()));\n  SetBenchmarkLabel(files[arg].label);\n  StartBenchmarkTiming();\n  while (iters-- > 0) {\n    CHECK(snappy::RawUncompress(zcontents.data(), zcontents.size(), dst));\n  }\n  StopBenchmarkTiming();\n\n  delete[] dst;\n}\nBENCHMARK(BM_UFlat)->DenseRange(0, 17);\n\nstatic void BM_UValidate(int iters, int arg) {\n  StopBenchmarkTiming();\n\n  // Pick file to process based on \"arg\"\n  CHECK_GE(arg, 0);\n  CHECK_LT(arg, ARRAYSIZE(files));\n  string contents = ReadTestDataFile(files[arg].filename);\n\n  string zcontents;\n  snappy::Compress(contents.data(), contents.size(), &zcontents);\n\n  SetBenchmarkBytesProcessed(static_cast<int64>(iters) *\n                             static_cast<int64>(contents.size()));\n  SetBenchmarkLabel(files[arg].label);\n  StartBenchmarkTiming();\n  while (iters-- > 0) {\n    CHECK(snappy::IsValidCompressedBuffer(zcontents.data(), zcontents.size()));\n  }\n  StopBenchmarkTiming();\n}\nBENCHMARK(BM_UValidate)->DenseRange(0, 4);\n\n\nstatic void BM_ZFlat(int iters, int arg) {\n  StopBenchmarkTiming();\n\n  // Pick file to process based on \"arg\"\n  CHECK_GE(arg, 0);\n  CHECK_LT(arg, ARRAYSIZE(files));\n  string contents = ReadTestDataFile(files[arg].filename);\n\n  char* dst = new char[snappy::MaxCompressedLength(contents.size())];\n\n  SetBenchmarkBytesProcessed(static_cast<int64>(iters) *\n                             static_cast<int64>(contents.size()));\n  StartBenchmarkTiming();\n\n  size_t zsize = 0;\n  while (iters-- > 0) {\n    snappy::RawCompress(contents.data(), contents.size(), dst, &zsize);\n  }\n  StopBenchmarkTiming();\n  const double compression_ratio =\n      static_cast<double>(zsize) / std::max<size_t>(1, contents.size());\n  SetBenchmarkLabel(StringPrintf(\"%s (%.2f %%)\",\n                                 files[arg].label, 100.0 * compression_ratio));\n  VLOG(0) << StringPrintf(\"compression for %s: %zd -> %zd bytes\",\n                          files[arg].label, contents.size(), zsize);\n  delete[] dst;\n}\nBENCHMARK(BM_ZFlat)->DenseRange(0, 17);\n\n\n}  // namespace snappy\n\n\nint main(int argc, char** argv) {\n  InitGoogle(argv[0], &argc, &argv, true);\n  File::Init();\n  RunSpecifiedBenchmarks();\n\n\n  if (argc >= 2) {\n    for (int arg = 1; arg < argc; arg++) {\n      if (FLAGS_write_compressed) {\n        CompressFile(argv[arg]);\n      } else if (FLAGS_write_uncompressed) {\n        UncompressFile(argv[arg]);\n      } else {\n        MeasureFile(argv[arg]);\n      }\n    }\n    return 0;\n  }\n\n  return RUN_ALL_TESTS();\n}\n"
  },
  {
    "path": "docs/README.md",
    "content": "* View online: http://www.ideawu.com/ssdb/\n* Contribute to SSDB documentation project: https://github.com/ideawu/ssdb-docs"
  },
  {
    "path": "src/Makefile",
    "content": "include ../build_config.mk\n\nOBJS = proc_sys.o proc_kv.o proc_hash.o proc_zset.o proc_queue.o \\\n\tbackend_dump.o backend_sync.o slave.o \\\n\tserv.o\nLIBS = ./ssdb/libssdb.a ./util/libutil.a ./net/libnet.a\nEXES = ../ssdb-server\n\n\nall: ${OBJS} ssdb-server.o\n\t${CXX} -o ../ssdb-server ssdb-server.o ${OBJS} ${LIBS} ${CLIBS} client/SSDB_impl.o\n\nssdb-server.o: ssdb-server.cpp\n\t${CXX} ${CFLAGS} -c ssdb-server.cpp\nslave.o: slave.h slave.cpp\n\t${CXX} ${CFLAGS} -c slave.cpp\nbackend_dump.o: backend_dump.h backend_dump.cpp\n\t${CXX} ${CFLAGS} -c backend_dump.cpp\nbackend_sync.o: backend_sync.h backend_sync.cpp\n\t${CXX} ${CFLAGS} -c backend_sync.cpp\n\nproc.o: serv.h proc.cpp\n\t${CXX} ${CFLAGS} -c proc.cpp\nproc_sys.o: proc_sys.cpp\n\t${CXX} ${CFLAGS} -c proc_sys.cpp\nproc_kv.o: proc_kv.cpp\n\t${CXX} ${CFLAGS} -c proc_kv.cpp\nproc_hash.o: proc_hash.cpp\n\t${CXX} ${CFLAGS} -c proc_hash.cpp\nproc_zset.o: proc_zset.cpp\n\t${CXX} ${CFLAGS} -c proc_zset.cpp\nproc_queue.o: proc_queue.cpp\n\t${CXX} ${CFLAGS} -c proc_queue.cpp\n\nserv.o: serv.h serv.cpp\n\t${CXX} ${CFLAGS} -c serv.cpp\n\nclean:\n\trm -f ${EXES} *.o *.exe *.a\n\n"
  },
  {
    "path": "src/backend_dump.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include <pthread.h>\n#include \"backend_dump.h\"\n#include \"util/log.h\"\n\nBackendDump::BackendDump(SSDB *ssdb){\n\tthis->ssdb = ssdb;\n}\n\nBackendDump::~BackendDump(){\n\tlog_debug(\"BackendDump finalized\");\n}\n\nvoid BackendDump::proc(const Link *link){\n\tlog_info(\"accept dump client: %d\", link->fd());\n\tstruct run_arg *arg = new run_arg();\n\targ->link = link;\n\targ->backend = this;\n\n\tpthread_t tid;\n\tint err = pthread_create(&tid, NULL, &BackendDump::_run_thread, arg);\n\tif(err != 0){\n\t\tlog_error(\"can't create thread: %s\", strerror(err));\n\t\tdelete link;\n\t}\n}\n\nvoid* BackendDump::_run_thread(void *arg){\n\tpthread_detach(pthread_self());\n\tstruct run_arg *p = (struct run_arg*)arg;\n\tconst BackendDump *backend = p->backend;\n\tLink *link = (Link *)p->link;\n\tdelete p;\n\n\t//\n\tlink->noblock(false);\n\n\tconst std::vector<Bytes>* req = link->last_recv();\n\n\tstd::string start = \"\";\n\tif(req->size() > 1){\n\t\tBytes b = req->at(1);\n\t\tstart.assign(b.data(), b.size());\n\t}\n\tif(start.empty()){\n\t\tstart = \"A\";\n\t}\n\tstd::string end = \"\";\n\tif(req->size() > 2){\n\t\tBytes b = req->at(2);\n\t\tend.assign(b.data(), b.size());\n\t}\n\tuint64_t limit = 10;\n\tif(req->size() > 3){\n\t\tBytes b = req->at(3);\n\t\tlimit = b.Uint64();\n\t}\n\n\tlog_info(\"fd: %d, begin to dump data: '%s', '%s', %\" PRIu64 \"\",\n\t\tlink->fd(), start.c_str(), end.c_str(), limit);\n\n\tBuffer *output = link->output;\n\n\tint count = 0;\n\tbool quit = false;\n\tIterator *it = backend->ssdb->iterator(start, end, limit);\n\t\n\tlink->send(\"begin\");\n\twhile(!quit){\n\t\tif(!it->next()){\n\t\t\tquit = true;\n\t\t\tchar buf[20];\n\t\t\tsnprintf(buf, sizeof(buf), \"%d\", count);\n\t\t\tlink->send(\"end\", buf);\n\t\t}else{\n\t\t\tcount ++;\n\t\t\tBytes key = it->key();\n\t\t\tBytes val = it->val();\n\n\t\t\toutput->append_record(\"set\");\n\t\t\toutput->append_record(key);\n\t\t\toutput->append_record(val);\n\t\t\toutput->append('\\n');\n\n\t\t\tif(output->size() < 32 * 1024){\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif(link->flush() == -1){\n\t\t\tlog_error(\"fd: %d, send error: %s\", link->fd(), strerror(errno));\n\t\t\tbreak;\n\t\t}\n\t}\n\t// wait for client to close connection,\n\t// or client may get a \"Connection reset by peer\" error.\n\tlink->read();\n\n\tlog_info(\"fd: %d, delete link\", link->fd());\n\tdelete link;\n\tdelete it;\n\treturn (void *)NULL;\n}\n"
  },
  {
    "path": "src/backend_dump.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef SSDB_BACKEND_DUMP_H_\n#define SSDB_BACKEND_DUMP_H_\n\n#include \"include.h\"\n#include \"ssdb/ssdb.h\"\n#include \"net/link.h\"\n\nclass BackendDump{\nprivate:\n\tstruct run_arg{\n\t\tconst Link *link;\n\t\tconst BackendDump *backend;\n\t};\n\tstatic void* _run_thread(void *arg);\n\tSSDB *ssdb;\npublic:\n\tBackendDump(SSDB *ssdb);\n\t~BackendDump();\n\tvoid proc(const Link *link);\n};\n\n#endif\n"
  },
  {
    "path": "src/backend_sync.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include <pthread.h>\n#include <assert.h>\n#include <errno.h>\n#include <string>\n#include \"backend_sync.h\"\n#include \"util/log.h\"\n#include \"util/string_util.h\"\n\nBackendSync::BackendSync(SSDBImpl *ssdb, int sync_speed){\n\tthread_quit = false;\n\tthis->ssdb = ssdb;\n\tthis->sync_speed = sync_speed;\n}\n\nBackendSync::~BackendSync(){\n\tthread_quit = true;\n\tint retry = 0;\n\tint MAX_RETRY = 100;\n\twhile(retry++ < MAX_RETRY){\n\t\t// there is something wrong that sleep makes other threads\n\t\t// unable to acquire the mutex\n\t\t{\n\t\t\tLocking l(&mutex);\n\t\t\tif(workers.empty()){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tusleep(50 * 1000);\n\t}\n\tif(retry >= MAX_RETRY){\n\t\tlog_info(\"Backend worker not exit expectedly\");\n\t}\n\tlog_debug(\"BackendSync finalized\");\n}\n\nstd::vector<std::string> BackendSync::stats(){\n\tstd::vector<std::string> ret;\n\tstd::map<pthread_t, Client *>::iterator it;\n\n\tLocking l(&mutex);\n\tfor(it = workers.begin(); it != workers.end(); it++){\n\t\tClient *client = it->second;\n\t\tret.push_back(client->stats());\n\t}\n\treturn ret;\n}\n\nvoid BackendSync::proc(const Link *link){\n\tlog_info(\"fd: %d, accept sync client\", link->fd());\n\tstruct run_arg *arg = new run_arg();\n\targ->link = link;\n\targ->backend = this;\n\n\tpthread_t tid;\n\tint err = pthread_create(&tid, NULL, &BackendSync::_run_thread, arg);\n\tif(err != 0){\n\t\tlog_error(\"can't create thread: %s\", strerror(err));\n\t\tdelete link;\n\t}\n}\n\nvoid* BackendSync::_run_thread(void *arg){\n\tpthread_detach(pthread_self());\n\tstruct run_arg *p = (struct run_arg*)arg;\n\tBackendSync *backend = (BackendSync *)p->backend;\n\tLink *link = (Link *)p->link;\n\tdelete p;\n\n\t// set Link non block\n\tlink->noblock(false);\n\n\tSSDBImpl *ssdb = (SSDBImpl *)backend->ssdb;\n\tBinlogQueue *logs = ssdb->binlogs;\n\n\tClient client(backend);\n\tclient.link = link;\n\tclient.init();\n\n\t{\n\t\tpthread_t tid = pthread_self();\n\t\tLocking l(&backend->mutex);\n\t\tbackend->workers[tid] = &client;\n\t}\n\n// sleep longer to reduce logs.find\n#define TICK_INTERVAL_MS\t300\n#define NOOP_IDLES\t\t\t(3000/TICK_INTERVAL_MS)\n\n\tint idle = 0;\n\twhile(!backend->thread_quit){\n\t\t// TODO: test\n\t\t//usleep(2000 * 1000);\n\t\t\n\t\tbool is_empty = true;\n\t\tif(client.status == Client::OUT_OF_SYNC){\n\t\t\t// will sleep afterwards.\n\t\t\t// ssdb doesn't do anything, let people interfere, normally, people\n\t\t\t// should make a backup of slave, stop, delete the meta and data\n\t\t\t// folders, and startup again.\n\t\t}else{\n\t\t\t// WARN: MUST do first sync() before first copy(), because\n\t\t\t// sync() will refresh last_seq, and copy() will not\n\t\t\tif(client.sync(logs)){ // sync seq or binlog\n\t\t\t\tis_empty = false;\n\t\t\t}\n\t\t\tif(client.status == Client::COPY){\n\t\t\t\tif(client.copy()){\n\t\t\t\t\tis_empty = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif(is_empty){\n\t\t\tif(idle >= NOOP_IDLES){\n\t\t\t\tidle = 0;\n\t\t\t\tclient.noop();\n\t\t\t}else{\n\t\t\t\tidle ++;\n\t\t\t\tusleep(TICK_INTERVAL_MS * 1000);\n\t\t\t}\n\t\t}else{\n\t\t\tidle = 0;\n\t\t}\n\n\t\tif(link->flush() == -1){\n\t\t\tlog_info(\"%s:%d fd: %d, send error: %s\", link->remote_ip, link->remote_port, link->fd(), strerror(errno));\n\t\t\tbreak;\n\t\t}\n\t\tif(backend->sync_speed > 0){\n\t\t\tfloat data_size_mb = link->output->size() / 1024.0 / 1024.0;\n\t\t\tusleep((data_size_mb / backend->sync_speed) * 1000 * 1000);\n\t\t}\n\t}\n\n\tlog_info(\"Sync Client quit, %s:%d fd: %d, delete link\", link->remote_ip, link->remote_port, link->fd());\n\tdelete link;\n\n\tLocking l(&backend->mutex);\n\tbackend->workers.erase(pthread_self());\n\treturn (void *)NULL;\n}\n\n\n/* Client */\n\nBackendSync::Client::Client(const BackendSync *backend){\n\tstatus = Client::INIT;\n\tthis->backend = backend;\n\tlink = NULL;\n\tlast_seq = 0;\n\tlast_noop_seq = 0;\n\tlast_key = \"\";\n\tis_mirror = false;\n\titer = NULL;\n}\n\nBackendSync::Client::~Client(){\n\tif(iter){\n\t\tdelete iter;\n\t\titer = NULL;\n\t}\n}\n\nstd::string BackendSync::Client::stats(){\n\tstd::string s;\n\ts.append(\"client \" + str(link->remote_ip) + \":\" + str(link->remote_port) + \"\\n\");\n\ts.append(\"    type     : \");\n\tif(is_mirror){\n\t\ts.append(\"mirror\\n\");\n\t}else{\n\t\ts.append(\"sync\\n\");\n\t}\n\t\n\ts.append(\"    status   : \");\n\tswitch(status){\n\tcase INIT:\n\t\ts.append(\"INIT\\n\");\n\t\tbreak;\n\tcase OUT_OF_SYNC:\n\t\ts.append(\"OUT_OF_SYNC\\n\");\n\t\tbreak;\n\tcase COPY:\n\t\ts.append(\"COPY\\n\");\n\t\tbreak;\n\tcase SYNC:\n\t\ts.append(\"SYNC\\n\");\n\t\tbreak;\n\t}\n\t\n\ts.append(\"    last_seq : \" + str(last_seq) + \"\");\n\treturn s;\n}\n\nvoid BackendSync::Client::init(){\n\tconst std::vector<Bytes> *req = this->link->last_recv();\n\tlast_seq = 0;\n\tif(req->size() > 1){\n\t\tlast_seq = req->at(1).Uint64();\n\t}\n\tlast_key = \"\";\n\tif(req->size() > 2){\n\t\tlast_key = req->at(2).String();\n\t}\n\t// is_mirror\n\tif(req->size() > 3){\n\t\tif(req->at(3).String() == \"mirror\"){\n\t\t\tis_mirror = true;\n\t\t}\n\t}\n\t\n\tSSDBImpl *ssdb = (SSDBImpl *)backend->ssdb;\n\tBinlogQueue *logs = ssdb->binlogs;\n\tif(last_seq != 0 && (last_seq > logs->max_seq() || last_seq < logs->min_seq())){\n\t\tlog_error(\"%s:%d fd: %d OUT_OF_SYNC! seq: %\" PRIu64 \" not in [%\" PRIu64 \", %\" PRIu64 \"]\",\n\t\t\tlink->remote_ip, link->remote_port, link->fd(),\n\t\t\tlast_seq, logs->min_seq(), logs->max_seq()\n\t\t\t);\n\t\tthis->out_of_sync();\n\t\treturn;\n\t}\n\t\n\tconst char *type = is_mirror? \"mirror\" : \"sync\";\n\t// a slave must reset its last_key when receiving 'copy_end' command\n\tif(last_key == \"\" && last_seq != 0){\n\t\tlog_info(\"[%s] %s:%d fd: %d, sync recover, seq: %\" PRIu64 \", key: '%s'\",\n\t\t\ttype,\n\t\t\tlink->remote_ip, link->remote_port,\n\t\t\tlink->fd(),\n\t\t\tlast_seq, hexmem(last_key.data(), last_key.size()).c_str()\n\t\t\t);\n\t\tthis->status = Client::SYNC;\n\t\t\n\t\tBinlog log(this->last_seq, BinlogType::COPY, BinlogCommand::END, \"\");\n\t\tlog_trace(\"fd: %d, %s\", link->fd(), log.dumps().c_str());\n\t\tlink->send(log.repr(), \"copy_end\");\n\t}else if(last_key == \"\" && last_seq == 0){\n\t\tlog_info(\"[%s] %s:%d fd: %d, copy begin, seq: %\" PRIu64 \", key: '%s'\",\n\t\t\ttype,\n\t\t\tlink->remote_ip, link->remote_port,\n\t\t\tlink->fd(),\n\t\t\tlast_seq, hexmem(last_key.data(), last_key.size()).c_str()\n\t\t\t);\n\t\tthis->reset();\n\t}else{\n\t\tlog_info(\"[%s] %s:%d fd: %d, copy recover, seq: %\" PRIu64 \", key: '%s'\",\n\t\t\ttype,\n\t\t\tlink->remote_ip, link->remote_port,\n\t\t\tlink->fd(),\n\t\t\tlast_seq, hexmem(last_key.data(), last_key.size()).c_str()\n\t\t\t);\n\t\tthis->status = Client::COPY;\n\t}\n}\n\nvoid BackendSync::Client::reset(){\n\tlog_info(\"%s:%d fd: %d, copy begin\", link->remote_ip, link->remote_port, link->fd());\n\tthis->status = Client::COPY;\n\tthis->last_seq = 0;\n\tthis->last_key = \"\";\n\n\tBinlog log(this->last_seq, BinlogType::COPY, BinlogCommand::BEGIN, \"\");\n\tlog_trace(\"fd: %d, %s\", link->fd(), log.dumps().c_str());\n\tlink->send(log.repr(), \"copy_begin\");\n}\n\nvoid BackendSync::Client::out_of_sync(){\n\tthis->status = Client::OUT_OF_SYNC;\n\tBinlog noop(this->last_seq, BinlogType::CTRL, BinlogCommand::NONE, \"OUT_OF_SYNC\");\n\tlink->send(noop.repr());\n}\n\nvoid BackendSync::Client::noop(){\n\tuint64_t seq;\n\tif(this->status == Client::COPY && this->last_key.empty()){\n\t\tseq = 0;\n\t}else{\n\t\tseq = this->last_seq;\n\t\tthis->last_noop_seq = this->last_seq;\n\t}\n\tBinlog noop(seq, BinlogType::NOOP, BinlogCommand::NONE, \"\");\n\t//log_debug(\"fd: %d, %s\", link->fd(), noop.dumps().c_str());\n\tlink->send(noop.repr(), \"noop\");\n}\n\nint BackendSync::Client::copy(){\n\tif(this->iter == NULL){\n\t\tlog_info(\"new iterator, last_key: '%s'\", hexmem(last_key.data(), last_key.size()).c_str());\n\t\tstd::string key = this->last_key;\n\t\tif(this->last_key.empty()){\n\t\t\tkey.push_back(DataType::MIN_PREFIX);\n\t\t}\n\t\tthis->iter = backend->ssdb->iterator(key, \"\", -1);\n\t\tlog_info(\"iterator created, last_key: '%s'\", hexmem(last_key.data(), last_key.size()).c_str());\n\t}\n\tint ret = 0;\n\tint iterate_count = 0;\n\tint64_t stime = time_ms();\n\twhile(true){\n\t\t// Prevent copy() from blocking too long\n\t\tif(++iterate_count > 1000 || link->output->size() > 2 * 1024 * 1024){\n\t\t\tbreak;\n\t\t}\n\t\t\n\t\tif(!iter->next()){\n\t\t\tgoto copy_end;\n\t\t}\n\t\tBytes key = iter->key();\n\t\tif(key.size() == 0){\n\t\t\tcontinue;\n\t\t}\n\t\t// finish copying all valid data types\n\t\tif(key.data()[0] > DataType::MAX_PREFIX){\n\t\t\tgoto copy_end;\n\t\t}\n\t\tBytes val = iter->val();\n\t\tthis->last_key = key.String();\n\t\t\t\n\t\tchar cmd = 0;\n\t\tchar data_type = key.data()[0];\n\t\tif(data_type == DataType::KV){\n\t\t\tcmd = BinlogCommand::KSET;\n\t\t}else if(data_type == DataType::HASH){\n\t\t\tcmd = BinlogCommand::HSET;\n\t\t}else if(data_type == DataType::ZSET){\n\t\t\tcmd = BinlogCommand::ZSET;\n\t\t}else if(data_type == DataType::QUEUE){\n\t\t\tcmd = BinlogCommand::QPUSH_BACK;\n\t\t}else{\n\t\t\tcontinue;\n\t\t}\n\t\tret++;\n\t\t\n\t\tBinlog log(this->last_seq, BinlogType::COPY, cmd, slice(key));\n\t\tlog_trace(\"fd: %d, %s\", link->fd(), log.dumps().c_str());\n\t\tlink->send(log.repr(), val);\n\t\t\n\t\tif(time_ms() - stime > 3000){\n\t\t\tlog_info(\"copy blocks too long, flush\");\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn ret;\n\ncopy_end:\t\t\n\tlog_info(\"%s:%d fd: %d, copy end\", link->remote_ip, link->remote_port, link->fd());\n\tthis->status = Client::SYNC;\n\tdelete this->iter;\n\tthis->iter = NULL;\n\n\tBinlog log(this->last_seq, BinlogType::COPY, BinlogCommand::END, \"\");\n\tlog_trace(\"fd: %d, %s\", link->fd(), log.dumps().c_str());\n\tlink->send(log.repr(), \"copy_end\");\n\treturn 1;\n}\n\n// sync seq and/or binlog\nint BackendSync::Client::sync(BinlogQueue *logs){\n\tBinlog log;\n\twhile(1){\n\t\tint ret = 0;\n\t\tuint64_t expect_seq = this->last_seq + 1;\n\t\tif(this->status == Client::COPY && this->last_seq == 0){\n\t\t\tret = logs->find_last(&log);\n\t\t}else{\n\t\t\tret = logs->find_next(expect_seq, &log);\n\t\t}\n\t\tif(ret == 0){\n\t\t\treturn 0;\n\t\t}\n\t\tif(this->status == Client::COPY && log.key() > this->last_key){\n\t\t\tlog_debug(\"fd: %d, last_key: '%s', drop: %s\",\n\t\t\t\tlink->fd(),\n\t\t\t\thexmem(this->last_key.data(), this->last_key.size()).c_str(),\n\t\t\t\tlog.dumps().c_str());\n\t\t\tthis->last_seq = log.seq();\n\t\t\t// WARN: When there are writes behind last_key, we MUST create\n\t\t\t// a new iterator, because iterator will not know this key.\n\t\t\t// Because iterator ONLY iterates throught keys written before\n\t\t\t// iterator is created.\n\t\t\tif(this->iter){\n\t\t\t\tdelete this->iter;\n\t\t\t\tthis->iter = NULL;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif(this->last_seq != 0 && log.seq() != expect_seq){\n\t\t\tlog_warn(\"%s:%d fd: %d, OUT_OF_SYNC! log.seq: %\" PRIu64 \", expect_seq: %\" PRIu64 \"\",\n\t\t\t\tlink->remote_ip, link->remote_port,\n\t\t\t\tlink->fd(),\n\t\t\t\tlog.seq(),\n\t\t\t\texpect_seq\n\t\t\t\t);\n\t\t\tthis->out_of_sync();\n\t\t\treturn 1;\n\t\t}\n\t\n\t\t// update last_seq\n\t\tthis->last_seq = log.seq();\n\n\t\tchar type = log.type();\n\t\tif(type == BinlogType::MIRROR && this->is_mirror){\n\t\t\tif(this->last_seq - this->last_noop_seq >= 1000){\n\t\t\t\tthis->noop();\n\t\t\t\treturn 1;\n\t\t\t}else{\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\t\n\t\tbreak;\n\t}\n\n\tint ret = 0;\n\tstd::string val;\n\tswitch(log.cmd()){\n\t\tcase BinlogCommand::KSET:\n\t\tcase BinlogCommand::HSET:\n\t\tcase BinlogCommand::ZSET:\n\t\t\tret = backend->ssdb->raw_get(log.key(), &val);\n\t\t\tif(ret == -1){\n\t\t\t\tlog_error(\"fd: %d, raw_get error!\", link->fd());\n\t\t\t}else if(ret == 0){\n\t\t\t\t//log_debug(\"%s\", hexmem(log.key().data(), log.key().size()).c_str());\n\t\t\t\tlog_trace(\"fd: %d, skip not found: %s\", link->fd(), log.dumps().c_str());\n\t\t\t}else{\n\t\t\t\tlog_trace(\"fd: %d, %s\", link->fd(), log.dumps().c_str());\n\t\t\t\tlink->send(log.repr(), val);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase BinlogCommand::QSET:\n\t\tcase BinlogCommand::QPUSH_BACK:\n\t\tcase BinlogCommand::QPUSH_FRONT:\n\t\t\tret = backend->ssdb->raw_get(log.key(), &val);\n\t\t\tif(ret == -1){\n\t\t\t\tlog_error(\"fd: %d, raw_get error!\", link->fd());\n\t\t\t}else{\n\t\t\t\t// ret == 0: element popped, push an empty value(pop later in binlog)\n\t\t\t\tlog_trace(\"fd: %d, %s\", link->fd(), log.dumps().c_str());\n\t\t\t\tlink->send(log.repr(), val);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase BinlogCommand::KDEL:\n\t\tcase BinlogCommand::HDEL:\n\t\tcase BinlogCommand::ZDEL:\n\t\tcase BinlogCommand::QPOP_BACK:\n\t\tcase BinlogCommand::QPOP_FRONT:\n\t\t\tlog_trace(\"fd: %d, %s\", link->fd(), log.dumps().c_str());\n\t\t\tlink->send(log.repr());\n\t\t\tbreak;\n\t}\n\treturn 1;\n}\n"
  },
  {
    "path": "src/backend_sync.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef SSDB_BACKEND_SYNC_H_\n#define SSDB_BACKEND_SYNC_H_\n\n#include \"include.h\"\n#include <vector>\n#include <string>\n#include <map>\n\n#include \"ssdb/ssdb_impl.h\"\n#include \"ssdb/binlog.h\"\n#include \"net/link.h\"\n#include \"util/thread.h\"\n\nclass BackendSync{\nprivate:\n\tstruct Client;\nprivate:\n\tstd::vector<Client *> clients;\n\tstd::vector<Client *> clients_tmp;\n\n\tstruct run_arg{\n\t\tconst Link *link;\n\t\tconst BackendSync *backend;\n\t};\n\tvolatile bool thread_quit;\n\tstatic void* _run_thread(void *arg);\n\tMutex mutex;\n\tstd::map<pthread_t, Client *> workers;\n\tSSDBImpl *ssdb;\n\tint sync_speed;\npublic:\n\tBackendSync(SSDBImpl *ssdb, int sync_speed);\n\t~BackendSync();\n\tvoid proc(const Link *link);\n\t\n\tstd::vector<std::string> stats();\n};\n\nstruct BackendSync::Client{\n\tstatic const int INIT = 0;\n\tstatic const int OUT_OF_SYNC = 1;\n\tstatic const int COPY = 2;\n\tstatic const int SYNC = 4;\n\n\tint status;\n\tLink *link;\n\tuint64_t last_seq;\n\tuint64_t last_noop_seq;\n\tstd::string last_key;\n\tconst BackendSync *backend;\n\tbool is_mirror;\n\t\n\tIterator *iter;\n\n\tClient(const BackendSync *backend);\n\t~Client();\n\tvoid init();\n\tvoid reset();\n\tvoid noop();\n\tint copy();\n\tint sync(BinlogQueue *logs);\n\tvoid out_of_sync();\n\n\tstd::string stats();\n};\n\n#endif\n"
  },
  {
    "path": "src/client/Doxyfile",
    "content": "# Doxyfile 1.8.5\n\n# This file describes the settings to be used by the documentation system\n# doxygen (www.doxygen.org) for a project.\n#\n# All text after a double hash (##) is considered a comment and is placed in\n# front of the TAG it is preceding.\n#\n# All text after a single hash (#) is considered a comment and will be ignored.\n# The format is:\n# TAG = value [value, ...]\n# For lists, items can also be appended using:\n# TAG += value [value, ...]\n# Values that contain spaces should be placed between quotes (\\\" \\\").\n\n#---------------------------------------------------------------------------\n# Project related configuration options\n#---------------------------------------------------------------------------\n\n# This tag specifies the encoding used for all characters in the config file\n# that follow. The default is UTF-8 which is also the encoding used for all text\n# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv\n# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv\n# for the list of possible encodings.\n# The default value is: UTF-8.\n\nDOXYFILE_ENCODING      = UTF-8\n\n# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by\n# double-quotes, unless you are using Doxywizard) that should identify the\n# project for which the documentation is generated. This name is used in the\n# title of most generated pages and in a few other places.\n# The default value is: My Project.\n\nPROJECT_NAME           = \"SSDB C++ API\"\n\n# The PROJECT_NUMBER tag can be used to enter a project or revision number. This\n# could be handy for archiving the generated documentation or if some version\n# control system is used.\n\nPROJECT_NUMBER         =\n\n# Using the PROJECT_BRIEF tag one can provide an optional one line description\n# for a project that appears at the top of each page and should give viewer a\n# quick idea about the purpose of the project. Keep the description short.\n\nPROJECT_BRIEF          = \"The C++ Client API for SSDB server\"\n\n# With the PROJECT_LOGO tag one can specify an logo or icon that is included in\n# the documentation. The maximum height of the logo should not exceed 55 pixels\n# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo\n# to the output directory.\n\nPROJECT_LOGO           =\n\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path\n# into which the generated documentation will be written. If a relative path is\n# entered, it will be relative to the location where doxygen was started. If\n# left blank the current directory will be used.\n\nOUTPUT_DIRECTORY       = ../../docs/cpp/\n\n# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-\n# directories (in 2 levels) under the output directory of each output format and\n# will distribute the generated files over these directories. Enabling this\n# option can be useful when feeding doxygen a huge amount of source files, where\n# putting all generated files in the same directory would otherwise causes\n# performance problems for the file system.\n# The default value is: NO.\n\nCREATE_SUBDIRS         = NO\n\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all\n# documentation generated by doxygen is written. Doxygen will use this\n# information to generate all constant output in the proper language.\n# Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-\n# Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi,\n# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en,\n# Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish,\n# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish,\n# Turkish, Ukrainian and Vietnamese.\n# The default value is: English.\n\nOUTPUT_LANGUAGE        = English\n\n# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member\n# descriptions after the members that are listed in the file and class\n# documentation (similar to Javadoc). Set to NO to disable this.\n# The default value is: YES.\n\nBRIEF_MEMBER_DESC      = YES\n\n# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief\n# description of a member or function before the detailed description\n#\n# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the\n# brief descriptions will be completely suppressed.\n# The default value is: YES.\n\nREPEAT_BRIEF           = YES\n\n# This tag implements a quasi-intelligent brief description abbreviator that is\n# used to form the text in various listings. Each string in this list, if found\n# as the leading text of the brief description, will be stripped from the text\n# and the result, after processing the whole list, is used as the annotated\n# text. Otherwise, the brief description is used as-is. If left blank, the\n# following values are used ($name is automatically replaced with the name of\n# the entity):The $name class, The $name widget, The $name file, is, provides,\n# specifies, contains, represents, a, an and the.\n\nABBREVIATE_BRIEF       =\n\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then\n# doxygen will generate a detailed section even if there is only a brief\n# description.\n# The default value is: NO.\n\nALWAYS_DETAILED_SEC    = NO\n\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all\n# inherited members of a class in the documentation of that class as if those\n# members were ordinary class members. Constructors, destructors and assignment\n# operators of the base classes will not be shown.\n# The default value is: NO.\n\nINLINE_INHERITED_MEMB  = NO\n\n# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path\n# before files name in the file list and in the header files. If set to NO the\n# shortest path that makes the file name unique will be used\n# The default value is: YES.\n\nFULL_PATH_NAMES        = YES\n\n# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.\n# Stripping is only done if one of the specified strings matches the left-hand\n# part of the path. The tag can be used to show relative paths in the file list.\n# If left blank the directory from which doxygen is run is used as the path to\n# strip.\n#\n# Note that you can specify absolute paths here, but also relative paths, which\n# will be relative from the directory where doxygen is started.\n# This tag requires that the tag FULL_PATH_NAMES is set to YES.\n\nSTRIP_FROM_PATH        =\n\n# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the\n# path mentioned in the documentation of a class, which tells the reader which\n# header file to include in order to use a class. If left blank only the name of\n# the header file containing the class definition is used. Otherwise one should\n# specify the list of include paths that are normally passed to the compiler\n# using the -I flag.\n\nSTRIP_FROM_INC_PATH    =\n\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but\n# less readable) file names. This can be useful is your file systems doesn't\n# support long names like on DOS, Mac, or CD-ROM.\n# The default value is: NO.\n\nSHORT_NAMES            = NO\n\n# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the\n# first line (until the first dot) of a Javadoc-style comment as the brief\n# description. If set to NO, the Javadoc-style will behave just like regular Qt-\n# style comments (thus requiring an explicit @brief command for a brief\n# description.)\n# The default value is: NO.\n\nJAVADOC_AUTOBRIEF      = YES\n\n# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first\n# line (until the first dot) of a Qt-style comment as the brief description. If\n# set to NO, the Qt-style will behave just like regular Qt-style comments (thus\n# requiring an explicit \\brief command for a brief description.)\n# The default value is: NO.\n\nQT_AUTOBRIEF           = NO\n\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a\n# multi-line C++ special comment block (i.e. a block of //! or /// comments) as\n# a brief description. This used to be the default behavior. The new default is\n# to treat a multi-line C++ comment block as a detailed description. Set this\n# tag to YES if you prefer the old behavior instead.\n#\n# Note that setting this tag to YES also means that rational rose comments are\n# not recognized any more.\n# The default value is: NO.\n\nMULTILINE_CPP_IS_BRIEF = NO\n\n# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the\n# documentation from any documented member that it re-implements.\n# The default value is: YES.\n\nINHERIT_DOCS           = YES\n\n# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a\n# new page for each member. If set to NO, the documentation of a member will be\n# part of the file/class/namespace that contains it.\n# The default value is: NO.\n\nSEPARATE_MEMBER_PAGES  = NO\n\n# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen\n# uses this value to replace tabs by spaces in code fragments.\n# Minimum value: 1, maximum value: 16, default value: 4.\n\nTAB_SIZE               = 4\n\n# This tag can be used to specify a number of aliases that act as commands in\n# the documentation. An alias has the form:\n# name=value\n# For example adding\n# \"sideeffect=@par Side Effects:\\n\"\n# will allow you to put the command \\sideeffect (or @sideeffect) in the\n# documentation, which will result in a user-defined paragraph with heading\n# \"Side Effects:\". You can put \\n's in the value part of an alias to insert\n# newlines.\n\nALIASES                =\n\n# This tag can be used to specify a number of word-keyword mappings (TCL only).\n# A mapping has the form \"name=value\". For example adding \"class=itcl::class\"\n# will allow you to use the command class in the itcl::class meaning.\n\nTCL_SUBST              =\n\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources\n# only. Doxygen will then generate output that is more tailored for C. For\n# instance, some of the names that are used will be different. The list of all\n# members will be omitted, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_FOR_C  = NO\n\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or\n# Python sources only. Doxygen will then generate output that is more tailored\n# for that language. For instance, namespaces will be presented as packages,\n# qualified scopes will look different, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_JAVA   = NO\n\n# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran\n# sources. Doxygen will then generate output that is tailored for Fortran.\n# The default value is: NO.\n\nOPTIMIZE_FOR_FORTRAN   = NO\n\n# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL\n# sources. Doxygen will then generate output that is tailored for VHDL.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_VHDL   = NO\n\n# Doxygen selects the parser to use depending on the extension of the files it\n# parses. With this tag you can assign which parser to use for a given\n# extension. Doxygen has a built-in mapping, but you can override or extend it\n# using this tag. The format is ext=language, where ext is a file extension, and\n# language is one of the parsers supported by doxygen: IDL, Java, Javascript,\n# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make\n# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C\n# (default is Fortran), use: inc=Fortran f=C.\n#\n# Note For files without extension you can use no_extension as a placeholder.\n#\n# Note that for custom extensions you also need to set FILE_PATTERNS otherwise\n# the files are not read by doxygen.\n\nEXTENSION_MAPPING      =\n\n# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments\n# according to the Markdown format, which allows for more readable\n# documentation. See http://daringfireball.net/projects/markdown/ for details.\n# The output of markdown processing is further processed by doxygen, so you can\n# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in\n# case of backward compatibilities issues.\n# The default value is: YES.\n\nMARKDOWN_SUPPORT       = YES\n\n# When enabled doxygen tries to link words that correspond to documented\n# classes, or namespaces to their corresponding documentation. Such a link can\n# be prevented in individual cases by by putting a % sign in front of the word\n# or globally by setting AUTOLINK_SUPPORT to NO.\n# The default value is: YES.\n\nAUTOLINK_SUPPORT       = YES\n\n# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want\n# to include (a tag file for) the STL sources as input, then you should set this\n# tag to YES in order to let doxygen match functions declarations and\n# definitions whose arguments contain STL classes (e.g. func(std::string);\n# versus func(std::string) {}). This also make the inheritance and collaboration\n# diagrams that involve STL classes more complete and accurate.\n# The default value is: NO.\n\nBUILTIN_STL_SUPPORT    = NO\n\n# If you use Microsoft's C++/CLI language, you should set this option to YES to\n# enable parsing support.\n# The default value is: NO.\n\nCPP_CLI_SUPPORT        = NO\n\n# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:\n# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen\n# will parse them like normal C++ but will assume all classes use public instead\n# of private inheritance when no explicit protection keyword is present.\n# The default value is: NO.\n\nSIP_SUPPORT            = NO\n\n# For Microsoft's IDL there are propget and propput attributes to indicate\n# getter and setter methods for a property. Setting this option to YES will make\n# doxygen to replace the get and set methods by a property in the documentation.\n# This will only work if the methods are indeed getting or setting a simple\n# type. If this is not the case, or you want to show the methods anyway, you\n# should set this option to NO.\n# The default value is: YES.\n\nIDL_PROPERTY_SUPPORT   = YES\n\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC\n# tag is set to YES, then doxygen will reuse the documentation of the first\n# member in the group (if any) for the other members of the group. By default\n# all members of a group must be documented explicitly.\n# The default value is: NO.\n\nDISTRIBUTE_GROUP_DOC   = NO\n\n# Set the SUBGROUPING tag to YES to allow class member groups of the same type\n# (for instance a group of public functions) to be put as a subgroup of that\n# type (e.g. under the Public Functions section). Set it to NO to prevent\n# subgrouping. Alternatively, this can be done per class using the\n# \\nosubgrouping command.\n# The default value is: YES.\n\nSUBGROUPING            = YES\n\n# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions\n# are shown inside the group in which they are included (e.g. using \\ingroup)\n# instead of on a separate page (for HTML and Man pages) or section (for LaTeX\n# and RTF).\n#\n# Note that this feature does not work in combination with\n# SEPARATE_MEMBER_PAGES.\n# The default value is: NO.\n\nINLINE_GROUPED_CLASSES = NO\n\n# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions\n# with only public data fields or simple typedef fields will be shown inline in\n# the documentation of the scope in which they are defined (i.e. file,\n# namespace, or group documentation), provided this scope is documented. If set\n# to NO, structs, classes, and unions are shown on a separate page (for HTML and\n# Man pages) or section (for LaTeX and RTF).\n# The default value is: NO.\n\nINLINE_SIMPLE_STRUCTS  = NO\n\n# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or\n# enum is documented as struct, union, or enum with the name of the typedef. So\n# typedef struct TypeS {} TypeT, will appear in the documentation as a struct\n# with name TypeT. When disabled the typedef will appear as a member of a file,\n# namespace, or class. And the struct will be named TypeS. This can typically be\n# useful for C code in case the coding convention dictates that all compound\n# types are typedef'ed and only the typedef is referenced, never the tag name.\n# The default value is: NO.\n\nTYPEDEF_HIDES_STRUCT   = NO\n\n# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This\n# cache is used to resolve symbols given their name and scope. Since this can be\n# an expensive process and often the same symbol appears multiple times in the\n# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small\n# doxygen will become slower. If the cache is too large, memory is wasted. The\n# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range\n# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536\n# symbols. At the end of a run doxygen will report the cache usage and suggest\n# the optimal cache size from a speed point of view.\n# Minimum value: 0, maximum value: 9, default value: 0.\n\nLOOKUP_CACHE_SIZE      = 0\n\n#---------------------------------------------------------------------------\n# Build related configuration options\n#---------------------------------------------------------------------------\n\n# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in\n# documentation are documented, even if no documentation was available. Private\n# class members and static file members will be hidden unless the\n# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.\n# Note: This will also disable the warnings about undocumented members that are\n# normally produced when WARNINGS is set to YES.\n# The default value is: NO.\n\nEXTRACT_ALL            = NO\n\n# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will\n# be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PRIVATE        = NO\n\n# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal\n# scope will be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PACKAGE        = NO\n\n# If the EXTRACT_STATIC tag is set to YES all static members of a file will be\n# included in the documentation.\n# The default value is: NO.\n\nEXTRACT_STATIC         = NO\n\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined\n# locally in source files will be included in the documentation. If set to NO\n# only classes defined in header files are included. Does not have any effect\n# for Java sources.\n# The default value is: YES.\n\nEXTRACT_LOCAL_CLASSES  = YES\n\n# This flag is only useful for Objective-C code. When set to YES local methods,\n# which are defined in the implementation section but not in the interface are\n# included in the documentation. If set to NO only methods in the interface are\n# included.\n# The default value is: NO.\n\nEXTRACT_LOCAL_METHODS  = NO\n\n# If this flag is set to YES, the members of anonymous namespaces will be\n# extracted and appear in the documentation as a namespace called\n# 'anonymous_namespace{file}', where file will be replaced with the base name of\n# the file that contains the anonymous namespace. By default anonymous namespace\n# are hidden.\n# The default value is: NO.\n\nEXTRACT_ANON_NSPACES   = NO\n\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all\n# undocumented members inside documented classes or files. If set to NO these\n# members will be included in the various overviews, but no documentation\n# section is generated. This option has no effect if EXTRACT_ALL is enabled.\n# The default value is: NO.\n\nHIDE_UNDOC_MEMBERS     = NO\n\n# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all\n# undocumented classes that are normally visible in the class hierarchy. If set\n# to NO these classes will be included in the various overviews. This option has\n# no effect if EXTRACT_ALL is enabled.\n# The default value is: NO.\n\nHIDE_UNDOC_CLASSES     = NO\n\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend\n# (class|struct|union) declarations. If set to NO these declarations will be\n# included in the documentation.\n# The default value is: NO.\n\nHIDE_FRIEND_COMPOUNDS  = NO\n\n# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any\n# documentation blocks found inside the body of a function. If set to NO these\n# blocks will be appended to the function's detailed documentation block.\n# The default value is: NO.\n\nHIDE_IN_BODY_DOCS      = NO\n\n# The INTERNAL_DOCS tag determines if documentation that is typed after a\n# \\internal command is included. If the tag is set to NO then the documentation\n# will be excluded. Set it to YES to include the internal documentation.\n# The default value is: NO.\n\nINTERNAL_DOCS          = NO\n\n# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file\n# names in lower-case letters. If set to YES upper-case letters are also\n# allowed. This is useful if you have classes or files whose names only differ\n# in case and if your file system supports case sensitive file names. Windows\n# and Mac users are advised to set this option to NO.\n# The default value is: system dependent.\n\nCASE_SENSE_NAMES       = NO\n\n# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with\n# their full class and namespace scopes in the documentation. If set to YES the\n# scope will be hidden.\n# The default value is: NO.\n\nHIDE_SCOPE_NAMES       = NO\n\n# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of\n# the files that are included by a file in the documentation of that file.\n# The default value is: YES.\n\nSHOW_INCLUDE_FILES     = YES\n\n# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include\n# files with double quotes in the documentation rather than with sharp brackets.\n# The default value is: NO.\n\nFORCE_LOCAL_INCLUDES   = NO\n\n# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the\n# documentation for inline members.\n# The default value is: YES.\n\nINLINE_INFO            = YES\n\n# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the\n# (detailed) documentation of file and class members alphabetically by member\n# name. If set to NO the members will appear in declaration order.\n# The default value is: YES.\n\nSORT_MEMBER_DOCS       = YES\n\n# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief\n# descriptions of file, namespace and class members alphabetically by member\n# name. If set to NO the members will appear in declaration order.\n# The default value is: NO.\n\nSORT_BRIEF_DOCS        = NO\n\n# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the\n# (brief and detailed) documentation of class members so that constructors and\n# destructors are listed first. If set to NO the constructors will appear in the\n# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.\n# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief\n# member documentation.\n# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting\n# detailed member documentation.\n# The default value is: NO.\n\nSORT_MEMBERS_CTORS_1ST = NO\n\n# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy\n# of group names into alphabetical order. If set to NO the group names will\n# appear in their defined order.\n# The default value is: NO.\n\nSORT_GROUP_NAMES       = NO\n\n# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by\n# fully-qualified names, including namespaces. If set to NO, the class list will\n# be sorted only by class name, not including the namespace part.\n# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.\n# Note: This option applies only to the class list, not to the alphabetical\n# list.\n# The default value is: NO.\n\nSORT_BY_SCOPE_NAME     = NO\n\n# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper\n# type resolution of all parameters of a function it will reject a match between\n# the prototype and the implementation of a member function even if there is\n# only one candidate or it is obvious which candidate to choose by doing a\n# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still\n# accept a match between prototype and implementation in such cases.\n# The default value is: NO.\n\nSTRICT_PROTO_MATCHING  = NO\n\n# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the\n# todo list. This list is created by putting \\todo commands in the\n# documentation.\n# The default value is: YES.\n\nGENERATE_TODOLIST      = YES\n\n# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the\n# test list. This list is created by putting \\test commands in the\n# documentation.\n# The default value is: YES.\n\nGENERATE_TESTLIST      = YES\n\n# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug\n# list. This list is created by putting \\bug commands in the documentation.\n# The default value is: YES.\n\nGENERATE_BUGLIST       = YES\n\n# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)\n# the deprecated list. This list is created by putting \\deprecated commands in\n# the documentation.\n# The default value is: YES.\n\nGENERATE_DEPRECATEDLIST= YES\n\n# The ENABLED_SECTIONS tag can be used to enable conditional documentation\n# sections, marked by \\if <section_label> ... \\endif and \\cond <section_label>\n# ... \\endcond blocks.\n\nENABLED_SECTIONS       =\n\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the\n# initial value of a variable or macro / define can have for it to appear in the\n# documentation. If the initializer consists of more lines than specified here\n# it will be hidden. Use a value of 0 to hide initializers completely. The\n# appearance of the value of individual variables and macros / defines can be\n# controlled using \\showinitializer or \\hideinitializer command in the\n# documentation regardless of this setting.\n# Minimum value: 0, maximum value: 10000, default value: 30.\n\nMAX_INITIALIZER_LINES  = 30\n\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at\n# the bottom of the documentation of classes and structs. If set to YES the list\n# will mention the files that were used to generate the documentation.\n# The default value is: YES.\n\nSHOW_USED_FILES        = YES\n\n# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This\n# will remove the Files entry from the Quick Index and from the Folder Tree View\n# (if specified).\n# The default value is: YES.\n\nSHOW_FILES             = YES\n\n# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces\n# page. This will remove the Namespaces entry from the Quick Index and from the\n# Folder Tree View (if specified).\n# The default value is: YES.\n\nSHOW_NAMESPACES        = YES\n\n# The FILE_VERSION_FILTER tag can be used to specify a program or script that\n# doxygen should invoke to get the current version for each file (typically from\n# the version control system). Doxygen will invoke the program by executing (via\n# popen()) the command command input-file, where command is the value of the\n# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided\n# by doxygen. Whatever the program writes to standard output is used as the file\n# version. For an example see the documentation.\n\nFILE_VERSION_FILTER    =\n\n# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed\n# by doxygen. The layout file controls the global structure of the generated\n# output files in an output format independent way. To create the layout file\n# that represents doxygen's defaults, run doxygen with the -l option. You can\n# optionally specify a file name after the option, if omitted DoxygenLayout.xml\n# will be used as the name of the layout file.\n#\n# Note that if you run doxygen from a directory containing a file called\n# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE\n# tag is left empty.\n\nLAYOUT_FILE            =\n\n# The CITE_BIB_FILES tag can be used to specify one or more bib files containing\n# the reference definitions. This must be a list of .bib files. The .bib\n# extension is automatically appended if omitted. This requires the bibtex tool\n# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.\n# For LaTeX the style of the bibliography can be controlled using\n# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the\n# search path. Do not use file names with spaces, bibtex cannot handle them. See\n# also \\cite for info how to create references.\n\nCITE_BIB_FILES         =\n\n#---------------------------------------------------------------------------\n# Configuration options related to warning and progress messages\n#---------------------------------------------------------------------------\n\n# The QUIET tag can be used to turn on/off the messages that are generated to\n# standard output by doxygen. If QUIET is set to YES this implies that the\n# messages are off.\n# The default value is: NO.\n\nQUIET                  = NO\n\n# The WARNINGS tag can be used to turn on/off the warning messages that are\n# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES\n# this implies that the warnings are on.\n#\n# Tip: Turn warnings on while writing the documentation.\n# The default value is: YES.\n\nWARNINGS               = YES\n\n# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate\n# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag\n# will automatically be disabled.\n# The default value is: YES.\n\nWARN_IF_UNDOCUMENTED   = YES\n\n# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for\n# potential errors in the documentation, such as not documenting some parameters\n# in a documented function, or documenting parameters that don't exist or using\n# markup commands wrongly.\n# The default value is: YES.\n\nWARN_IF_DOC_ERROR      = YES\n\n# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that\n# are documented, but have no documentation for their parameters or return\n# value. If set to NO doxygen will only warn about wrong or incomplete parameter\n# documentation, but not about the absence of documentation.\n# The default value is: NO.\n\nWARN_NO_PARAMDOC       = NO\n\n# The WARN_FORMAT tag determines the format of the warning messages that doxygen\n# can produce. The string should contain the $file, $line, and $text tags, which\n# will be replaced by the file and line number from which the warning originated\n# and the warning text. Optionally the format may contain $version, which will\n# be replaced by the version of the file (if it could be obtained via\n# FILE_VERSION_FILTER)\n# The default value is: $file:$line: $text.\n\nWARN_FORMAT            = \"$file:$line: $text\"\n\n# The WARN_LOGFILE tag can be used to specify a file to which warning and error\n# messages should be written. If left blank the output is written to standard\n# error (stderr).\n\nWARN_LOGFILE           =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the input files\n#---------------------------------------------------------------------------\n\n# The INPUT tag is used to specify the files and/or directories that contain\n# documented source files. You may enter file names like myfile.cpp or\n# directories like /usr/src/myproject. Separate the files or directories with\n# spaces.\n# Note: If this tag is empty the current directory is searched.\n\nINPUT                  = ./SSDB.h README.md\n\n# This tag can be used to specify the character encoding of the source files\n# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses\n# libiconv (or the iconv built into libc) for the transcoding. See the libiconv\n# documentation (see: http://www.gnu.org/software/libiconv) for the list of\n# possible encodings.\n# The default value is: UTF-8.\n\nINPUT_ENCODING         = UTF-8\n\n# If the value of the INPUT tag contains directories, you can use the\n# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and\n# *.h) to filter out the source-files in the directories. If left blank the\n# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,\n# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,\n# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,\n# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,\n# *.qsf, *.as and *.js.\n\nFILE_PATTERNS          =\n\n# The RECURSIVE tag can be used to specify whether or not subdirectories should\n# be searched for input files as well.\n# The default value is: NO.\n\nRECURSIVE              = NO\n\n# The EXCLUDE tag can be used to specify files and/or directories that should be\n# excluded from the INPUT source files. This way you can easily exclude a\n# subdirectory from a directory tree whose root is specified with the INPUT tag.\n#\n# Note that relative paths are relative to the directory from which doxygen is\n# run.\n\nEXCLUDE                =\n\n# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or\n# directories that are symbolic links (a Unix file system feature) are excluded\n# from the input.\n# The default value is: NO.\n\nEXCLUDE_SYMLINKS       = NO\n\n# If the value of the INPUT tag contains directories, you can use the\n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude\n# certain files from those directories.\n#\n# Note that the wildcards are matched against the file with absolute path, so to\n# exclude all test directories for example use the pattern */test/*\n\nEXCLUDE_PATTERNS       =\n\n# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names\n# (namespaces, classes, functions, etc.) that should be excluded from the\n# output. The symbol name can be a fully qualified name, a word, or if the\n# wildcard * is used, a substring. Examples: ANamespace, AClass,\n# AClass::ANamespace, ANamespace::*Test\n#\n# Note that the wildcards are matched against the file with absolute path, so to\n# exclude all test directories use the pattern */test/*\n\nEXCLUDE_SYMBOLS        =\n\n# The EXAMPLE_PATH tag can be used to specify one or more files or directories\n# that contain example code fragments that are included (see the \\include\n# command).\n\nEXAMPLE_PATH           =\n\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the\n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and\n# *.h) to filter out the source-files in the directories. If left blank all\n# files are included.\n\nEXAMPLE_PATTERNS       =\n\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be\n# searched for input files to be used with the \\include or \\dontinclude commands\n# irrespective of the value of the RECURSIVE tag.\n# The default value is: NO.\n\nEXAMPLE_RECURSIVE      = NO\n\n# The IMAGE_PATH tag can be used to specify one or more files or directories\n# that contain images that are to be included in the documentation (see the\n# \\image command).\n\nIMAGE_PATH             =\n\n# The INPUT_FILTER tag can be used to specify a program that doxygen should\n# invoke to filter for each input file. Doxygen will invoke the filter program\n# by executing (via popen()) the command:\n#\n# <filter> <input-file>\n#\n# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the\n# name of an input file. Doxygen will then use the output that the filter\n# program writes to standard output. If FILTER_PATTERNS is specified, this tag\n# will be ignored.\n#\n# Note that the filter must not add or remove lines; it is applied before the\n# code is scanned, but not when the output code is generated. If lines are added\n# or removed, the anchors will not be placed correctly.\n\nINPUT_FILTER           =\n\n# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern\n# basis. Doxygen will compare the file name with each pattern and apply the\n# filter if there is a match. The filters are a list of the form: pattern=filter\n# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how\n# filters are used. If the FILTER_PATTERNS tag is empty or if none of the\n# patterns match the file name, INPUT_FILTER is applied.\n\nFILTER_PATTERNS        =\n\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using\n# INPUT_FILTER ) will also be used to filter the input files that are used for\n# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).\n# The default value is: NO.\n\nFILTER_SOURCE_FILES    = NO\n\n# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file\n# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and\n# it is also possible to disable source filtering for a specific pattern using\n# *.ext= (so without naming a filter).\n# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.\n\nFILTER_SOURCE_PATTERNS =\n\n# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that\n# is part of the input, its contents will be placed on the main page\n# (index.html). This can be useful if you have a project on for instance GitHub\n# and want to reuse the introduction page also for the doxygen output.\n\nUSE_MDFILE_AS_MAINPAGE =\n\n#---------------------------------------------------------------------------\n# Configuration options related to source browsing\n#---------------------------------------------------------------------------\n\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will be\n# generated. Documented entities will be cross-referenced with these sources.\n#\n# Note: To get rid of all source code in the generated output, make sure that\n# also VERBATIM_HEADERS is set to NO.\n# The default value is: NO.\n\nSOURCE_BROWSER         = NO\n\n# Setting the INLINE_SOURCES tag to YES will include the body of functions,\n# classes and enums directly into the documentation.\n# The default value is: NO.\n\nINLINE_SOURCES         = NO\n\n# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any\n# special comment blocks from generated source code fragments. Normal C, C++ and\n# Fortran comments will always remain visible.\n# The default value is: YES.\n\nSTRIP_CODE_COMMENTS    = YES\n\n# If the REFERENCED_BY_RELATION tag is set to YES then for each documented\n# function all documented functions referencing it will be listed.\n# The default value is: NO.\n\nREFERENCED_BY_RELATION = NO\n\n# If the REFERENCES_RELATION tag is set to YES then for each documented function\n# all documented entities called/used by that function will be listed.\n# The default value is: NO.\n\nREFERENCES_RELATION    = NO\n\n# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set\n# to YES, then the hyperlinks from functions in REFERENCES_RELATION and\n# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will\n# link to the documentation.\n# The default value is: YES.\n\nREFERENCES_LINK_SOURCE = YES\n\n# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the\n# source code will show a tooltip with additional information such as prototype,\n# brief description and links to the definition and documentation. Since this\n# will make the HTML file larger and loading of large files a bit slower, you\n# can opt to disable this feature.\n# The default value is: YES.\n# This tag requires that the tag SOURCE_BROWSER is set to YES.\n\nSOURCE_TOOLTIPS        = YES\n\n# If the USE_HTAGS tag is set to YES then the references to source code will\n# point to the HTML generated by the htags(1) tool instead of doxygen built-in\n# source browser. The htags tool is part of GNU's global source tagging system\n# (see http://www.gnu.org/software/global/global.html). You will need version\n# 4.8.6 or higher.\n#\n# To use it do the following:\n# - Install the latest version of global\n# - Enable SOURCE_BROWSER and USE_HTAGS in the config file\n# - Make sure the INPUT points to the root of the source tree\n# - Run doxygen as normal\n#\n# Doxygen will invoke htags (and that will in turn invoke gtags), so these\n# tools must be available from the command line (i.e. in the search path).\n#\n# The result: instead of the source browser generated by doxygen, the links to\n# source code will now point to the output of htags.\n# The default value is: NO.\n# This tag requires that the tag SOURCE_BROWSER is set to YES.\n\nUSE_HTAGS              = NO\n\n# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a\n# verbatim copy of the header file for each class for which an include is\n# specified. Set to NO to disable this.\n# See also: Section \\class.\n# The default value is: YES.\n\nVERBATIM_HEADERS       = YES\n\n# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the\n# clang parser (see: http://clang.llvm.org/) for more acurate parsing at the\n# cost of reduced performance. This can be particularly helpful with template\n# rich C++ code for which doxygen's built-in parser lacks the necessary type\n# information.\n# Note: The availability of this option depends on whether or not doxygen was\n# compiled with the --with-libclang option.\n# The default value is: NO.\n\nCLANG_ASSISTED_PARSING = NO\n\n# If clang assisted parsing is enabled you can provide the compiler with command\n# line options that you would normally use when invoking the compiler. Note that\n# the include paths will already be set by doxygen for the files and directories\n# specified with INPUT and INCLUDE_PATH.\n# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.\n\nCLANG_OPTIONS          =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the alphabetical class index\n#---------------------------------------------------------------------------\n\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all\n# compounds will be generated. Enable this if the project contains a lot of\n# classes, structs, unions or interfaces.\n# The default value is: YES.\n\nALPHABETICAL_INDEX     = YES\n\n# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in\n# which the alphabetical index list will be split.\n# Minimum value: 1, maximum value: 20, default value: 5.\n# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.\n\nCOLS_IN_ALPHA_INDEX    = 5\n\n# In case all classes in a project start with a common prefix, all classes will\n# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag\n# can be used to specify a prefix (or a list of prefixes) that should be ignored\n# while generating the index headers.\n# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.\n\nIGNORE_PREFIX          =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the HTML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output\n# The default value is: YES.\n\nGENERATE_HTML          = YES\n\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: html.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_OUTPUT            = .\n\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each\n# generated HTML page (for example: .htm, .php, .asp).\n# The default value is: .html.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FILE_EXTENSION    = .html\n\n# The HTML_HEADER tag can be used to specify a user-defined HTML header file for\n# each generated HTML page. If the tag is left blank doxygen will generate a\n# standard header.\n#\n# To get valid HTML the header file that includes any scripts and style sheets\n# that doxygen needs, which is dependent on the configuration options used (e.g.\n# the setting GENERATE_TREEVIEW). It is highly recommended to start with a\n# default header using\n# doxygen -w html new_header.html new_footer.html new_stylesheet.css\n# YourConfigFile\n# and then modify the file new_header.html. See also section \"Doxygen usage\"\n# for information on how to generate the default header that doxygen normally\n# uses.\n# Note: The header is subject to change so you typically have to regenerate the\n# default header when upgrading to a newer version of doxygen. For a description\n# of the possible markers and block names see the documentation.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_HEADER            =\n\n# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each\n# generated HTML page. If the tag is left blank doxygen will generate a standard\n# footer. See HTML_HEADER for more information on how to generate a default\n# footer and what special commands can be used inside the footer. See also\n# section \"Doxygen usage\" for information on how to generate the default footer\n# that doxygen normally uses.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FOOTER            =\n\n# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style\n# sheet that is used by each HTML page. It can be used to fine-tune the look of\n# the HTML output. If left blank doxygen will generate a default style sheet.\n# See also section \"Doxygen usage\" for information on how to generate the style\n# sheet that doxygen normally uses.\n# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as\n# it is more robust and this tag (HTML_STYLESHEET) will in the future become\n# obsolete.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_STYLESHEET        =\n\n# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-\n# defined cascading style sheet that is included after the standard style sheets\n# created by doxygen. Using this option one can overrule certain style aspects.\n# This is preferred over using HTML_STYLESHEET since it does not replace the\n# standard style sheet and is therefor more robust against future updates.\n# Doxygen will copy the style sheet file to the output directory. For an example\n# see the documentation.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_EXTRA_STYLESHEET  =\n\n# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the HTML output directory. Note\n# that these files will be copied to the base HTML output directory. Use the\n# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these\n# files. In the HTML_STYLESHEET file, use the file name only. Also note that the\n# files will be copied as-is; there are no commands or markers available.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_EXTRA_FILES       =\n\n# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen\n# will adjust the colors in the stylesheet and background images according to\n# this color. Hue is specified as an angle on a colorwheel, see\n# http://en.wikipedia.org/wiki/Hue for more information. For instance the value\n# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300\n# purple, and 360 is red again.\n# Minimum value: 0, maximum value: 359, default value: 220.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_HUE    = 220\n\n# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors\n# in the HTML output. For a value of 0 the output will use grayscales only. A\n# value of 255 will produce the most vivid colors.\n# Minimum value: 0, maximum value: 255, default value: 100.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_SAT    = 100\n\n# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the\n# luminance component of the colors in the HTML output. Values below 100\n# gradually make the output lighter, whereas values above 100 make the output\n# darker. The value divided by 100 is the actual gamma applied, so 80 represents\n# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not\n# change the gamma.\n# Minimum value: 40, maximum value: 240, default value: 80.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_GAMMA  = 80\n\n# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML\n# page will contain the date and time when the page was generated. Setting this\n# to NO can help when comparing the output of multiple runs.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_TIMESTAMP         = YES\n\n# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML\n# documentation will contain sections that can be hidden and shown after the\n# page has loaded.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_DYNAMIC_SECTIONS  = NO\n\n# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries\n# shown in the various tree structured indices initially; the user can expand\n# and collapse entries dynamically later on. Doxygen will expand the tree to\n# such a level that at most the specified number of entries are visible (unless\n# a fully collapsed tree already exceeds this amount). So setting the number of\n# entries 1 will produce a full collapsed tree by default. 0 is a special value\n# representing an infinite number of entries and will result in a full expanded\n# tree by default.\n# Minimum value: 0, maximum value: 9999, default value: 100.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_INDEX_NUM_ENTRIES = 100\n\n# If the GENERATE_DOCSET tag is set to YES, additional index files will be\n# generated that can be used as input for Apple's Xcode 3 integrated development\n# environment (see: http://developer.apple.com/tools/xcode/), introduced with\n# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a\n# Makefile in the HTML output directory. Running make will produce the docset in\n# that directory and running make install will install the docset in\n# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at\n# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html\n# for more information.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_DOCSET        = NO\n\n# This tag determines the name of the docset feed. A documentation feed provides\n# an umbrella under which multiple documentation sets from a single provider\n# (such as a company or product suite) can be grouped.\n# The default value is: Doxygen generated docs.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_FEEDNAME        = \"Doxygen generated docs\"\n\n# This tag specifies a string that should uniquely identify the documentation\n# set bundle. This should be a reverse domain-name style string, e.g.\n# com.mycompany.MyDocSet. Doxygen will append .docset to the name.\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_BUNDLE_ID       = org.doxygen.Project\n\n# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify\n# the documentation publisher. This should be a reverse domain-name style\n# string, e.g. com.mycompany.MyDocSet.documentation.\n# The default value is: org.doxygen.Publisher.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_PUBLISHER_ID    = org.doxygen.Publisher\n\n# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.\n# The default value is: Publisher.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_PUBLISHER_NAME  = Publisher\n\n# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three\n# additional HTML index files: index.hhp, index.hhc, and index.hhk. The\n# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop\n# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on\n# Windows.\n#\n# The HTML Help Workshop contains a compiler that can convert all HTML output\n# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML\n# files are now used as the Windows 98 help format, and will replace the old\n# Windows help format (.hlp) on all Windows platforms in the future. Compressed\n# HTML files also contain an index, a table of contents, and you can search for\n# words in the documentation. The HTML workshop also contains a viewer for\n# compressed HTML files.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_HTMLHELP      = NO\n\n# The CHM_FILE tag can be used to specify the file name of the resulting .chm\n# file. You can add a path in front of the file if the result should not be\n# written to the html output directory.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nCHM_FILE               =\n\n# The HHC_LOCATION tag can be used to specify the location (absolute path\n# including file name) of the HTML help compiler ( hhc.exe). If non-empty\n# doxygen will try to run the HTML help compiler on the generated index.hhp.\n# The file has to be specified with full path.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nHHC_LOCATION           =\n\n# The GENERATE_CHI flag controls if a separate .chi index file is generated (\n# YES) or that it should be included in the master .chm file ( NO).\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nGENERATE_CHI           = NO\n\n# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)\n# and project file content.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nCHM_INDEX_ENCODING     =\n\n# The BINARY_TOC flag controls whether a binary table of contents is generated (\n# YES) or a normal table of contents ( NO) in the .chm file.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nBINARY_TOC             = NO\n\n# The TOC_EXPAND flag can be set to YES to add extra items for group members to\n# the table of contents of the HTML help documentation and to the tree view.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nTOC_EXPAND             = NO\n\n# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and\n# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that\n# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help\n# (.qch) of the generated HTML documentation.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_QHP           = NO\n\n# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify\n# the file name of the resulting .qch file. The path specified is relative to\n# the HTML output folder.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQCH_FILE               =\n\n# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help\n# Project output. For more information please see Qt Help Project / Namespace\n# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_NAMESPACE          = org.doxygen.Project\n\n# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt\n# Help Project output. For more information please see Qt Help Project / Virtual\n# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-\n# folders).\n# The default value is: doc.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_VIRTUAL_FOLDER     = doc\n\n# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom\n# filter to add. For more information please see Qt Help Project / Custom\n# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-\n# filters).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_CUST_FILTER_NAME   =\n\n# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the\n# custom filter to add. For more information please see Qt Help Project / Custom\n# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-\n# filters).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_CUST_FILTER_ATTRS  =\n\n# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this\n# project's filter section matches. Qt Help Project / Filter Attributes (see:\n# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_SECT_FILTER_ATTRS  =\n\n# The QHG_LOCATION tag can be used to specify the location of Qt's\n# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the\n# generated .qhp file.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHG_LOCATION           =\n\n# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be\n# generated, together with the HTML files, they form an Eclipse help plugin. To\n# install this plugin and make it available under the help contents menu in\n# Eclipse, the contents of the directory containing the HTML and XML files needs\n# to be copied into the plugins directory of eclipse. The name of the directory\n# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.\n# After copying Eclipse needs to be restarted before the help appears.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_ECLIPSEHELP   = NO\n\n# A unique identifier for the Eclipse help plugin. When installing the plugin\n# the directory name containing the HTML and XML files should also have this\n# name. Each documentation set should have its own identifier.\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.\n\nECLIPSE_DOC_ID         = org.doxygen.Project\n\n# If you want full control over the layout of the generated HTML pages it might\n# be necessary to disable the index and replace it with your own. The\n# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top\n# of each HTML page. A value of NO enables the index and the value YES disables\n# it. Since the tabs in the index contain the same information as the navigation\n# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nDISABLE_INDEX          = NO\n\n# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index\n# structure should be generated to display hierarchical information. If the tag\n# value is set to YES, a side panel will be generated containing a tree-like\n# index structure (just like the one that is generated for HTML Help). For this\n# to work a browser that supports JavaScript, DHTML, CSS and frames is required\n# (i.e. any modern browser). Windows users are probably better off using the\n# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can\n# further fine-tune the look of the index. As an example, the default style\n# sheet generated by doxygen has an example that shows how to put an image at\n# the root of the tree instead of the PROJECT_NAME. Since the tree basically has\n# the same information as the tab index, you could consider setting\n# DISABLE_INDEX to YES when enabling this option.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_TREEVIEW      = NO\n\n# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that\n# doxygen will group on one line in the generated HTML documentation.\n#\n# Note that a value of 0 will completely suppress the enum values from appearing\n# in the overview section.\n# Minimum value: 0, maximum value: 20, default value: 4.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nENUM_VALUES_PER_LINE   = 4\n\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used\n# to set the initial width (in pixels) of the frame in which the tree is shown.\n# Minimum value: 0, maximum value: 1500, default value: 250.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nTREEVIEW_WIDTH         = 250\n\n# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to\n# external symbols imported via tag files in a separate window.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nEXT_LINKS_IN_WINDOW    = NO\n\n# Use this tag to change the font size of LaTeX formulas included as images in\n# the HTML documentation. When you change the font size after a successful\n# doxygen run you need to manually remove any form_*.png images from the HTML\n# output directory to force them to be regenerated.\n# Minimum value: 8, maximum value: 50, default value: 10.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFORMULA_FONTSIZE       = 10\n\n# Use the FORMULA_TRANPARENT tag to determine whether or not the images\n# generated for formulas are transparent PNGs. Transparent PNGs are not\n# supported properly for IE 6.0, but are supported on all modern browsers.\n#\n# Note that when changing this option you need to delete any form_*.png files in\n# the HTML output directory before the changes have effect.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFORMULA_TRANSPARENT    = YES\n\n# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see\n# http://www.mathjax.org) which uses client side Javascript for the rendering\n# instead of using prerendered bitmaps. Use this if you do not have LaTeX\n# installed or if you want to formulas look prettier in the HTML output. When\n# enabled you may also need to install MathJax separately and configure the path\n# to it using the MATHJAX_RELPATH option.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nUSE_MATHJAX            = NO\n\n# When MathJax is enabled you can set the default output format to be used for\n# the MathJax output. See the MathJax site (see:\n# http://docs.mathjax.org/en/latest/output.html) for more details.\n# Possible values are: HTML-CSS (which is slower, but has the best\n# compatibility), NativeMML (i.e. MathML) and SVG.\n# The default value is: HTML-CSS.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_FORMAT         = HTML-CSS\n\n# When MathJax is enabled you need to specify the location relative to the HTML\n# output directory using the MATHJAX_RELPATH option. The destination directory\n# should contain the MathJax.js script. For instance, if the mathjax directory\n# is located at the same level as the HTML output directory, then\n# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax\n# Content Delivery Network so you can quickly see the result without installing\n# MathJax. However, it is strongly recommended to install a local copy of\n# MathJax from http://www.mathjax.org before deployment.\n# The default value is: http://cdn.mathjax.org/mathjax/latest.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest\n\n# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax\n# extension names that should be enabled during MathJax rendering. For example\n# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_EXTENSIONS     =\n\n# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces\n# of code that will be used on startup of the MathJax code. See the MathJax site\n# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an\n# example see the documentation.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_CODEFILE       =\n\n# When the SEARCHENGINE tag is enabled doxygen will generate a search box for\n# the HTML output. The underlying search engine uses javascript and DHTML and\n# should work on any modern browser. Note that when using HTML help\n# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)\n# there is already a search function so this one should typically be disabled.\n# For large projects the javascript based search engine can be slow, then\n# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to\n# search using the keyboard; to jump to the search box use <access key> + S\n# (what the <access key> is depends on the OS and browser, but it is typically\n# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down\n# key> to jump into the search results window, the results can be navigated\n# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel\n# the search. The filter options can be selected when the cursor is inside the\n# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>\n# to select a filter and <Enter> or <escape> to activate or cancel the filter\n# option.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nSEARCHENGINE           = NO\n\n# When the SERVER_BASED_SEARCH tag is enabled the search engine will be\n# implemented using a web server instead of a web client using Javascript. There\n# are two flavours of web server based searching depending on the\n# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for\n# searching and an index file used by the script. When EXTERNAL_SEARCH is\n# enabled the indexing and searching needs to be provided by external tools. See\n# the section \"External Indexing and Searching\" for details.\n# The default value is: NO.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSERVER_BASED_SEARCH    = NO\n\n# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP\n# script for searching. Instead the search results are written to an XML file\n# which needs to be processed by an external indexer. Doxygen will invoke an\n# external search engine pointed to by the SEARCHENGINE_URL option to obtain the\n# search results.\n#\n# Doxygen ships with an example indexer ( doxyindexer) and search engine\n# (doxysearch.cgi) which are based on the open source search engine library\n# Xapian (see: http://xapian.org/).\n#\n# See the section \"External Indexing and Searching\" for details.\n# The default value is: NO.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTERNAL_SEARCH        = NO\n\n# The SEARCHENGINE_URL should point to a search engine hosted by a web server\n# which will return the search results when EXTERNAL_SEARCH is enabled.\n#\n# Doxygen ships with an example indexer ( doxyindexer) and search engine\n# (doxysearch.cgi) which are based on the open source search engine library\n# Xapian (see: http://xapian.org/). See the section \"External Indexing and\n# Searching\" for details.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSEARCHENGINE_URL       =\n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed\n# search data is written to a file for indexing by an external tool. With the\n# SEARCHDATA_FILE tag the name of this file can be specified.\n# The default file is: searchdata.xml.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSEARCHDATA_FILE        = searchdata.xml\n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the\n# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is\n# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple\n# projects and redirect the results back to the right project.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTERNAL_SEARCH_ID     =\n\n# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen\n# projects other than the one defined by this configuration file, but that are\n# all added to the same external search index. Each project needs to have a\n# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of\n# to a relative location where the documentation can be found. The format is:\n# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTRA_SEARCH_MAPPINGS  =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the LaTeX output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.\n# The default value is: YES.\n\nGENERATE_LATEX         = NO\n\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: latex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_OUTPUT           = latex\n\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be\n# invoked.\n#\n# Note that when enabling USE_PDFLATEX this option is only used for generating\n# bitmaps for formulas in the HTML output, but not in the Makefile that is\n# written to the output directory.\n# The default file is: latex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_CMD_NAME         = latex\n\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate\n# index for LaTeX.\n# The default file is: makeindex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nMAKEINDEX_CMD_NAME     = makeindex\n\n# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX\n# documents. This may be useful for small projects and may help to save some\n# trees in general.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nCOMPACT_LATEX          = NO\n\n# The PAPER_TYPE tag can be used to set the paper type that is used by the\n# printer.\n# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x\n# 14 inches) and executive (7.25 x 10.5 inches).\n# The default value is: a4.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nPAPER_TYPE             = a4\n\n# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names\n# that should be included in the LaTeX output. To get the times font for\n# instance you can specify\n# EXTRA_PACKAGES=times\n# If left blank no extra packages will be included.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nEXTRA_PACKAGES         =\n\n# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the\n# generated LaTeX document. The header should contain everything until the first\n# chapter. If it is left blank doxygen will generate a standard header. See\n# section \"Doxygen usage\" for information on how to let doxygen write the\n# default header to a separate file.\n#\n# Note: Only use a user-defined header if you know what you are doing! The\n# following commands have a special meaning inside the header: $title,\n# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will\n# replace them by respectively the title of the page, the current date and time,\n# only the current date, the version number of doxygen, the project name (see\n# PROJECT_NAME), or the project number (see PROJECT_NUMBER).\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_HEADER           =\n\n# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the\n# generated LaTeX document. The footer should contain everything after the last\n# chapter. If it is left blank doxygen will generate a standard footer.\n#\n# Note: Only use a user-defined footer if you know what you are doing!\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_FOOTER           =\n\n# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the LATEX_OUTPUT output\n# directory. Note that the files will be copied as-is; there are no commands or\n# markers available.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_EXTRA_FILES      =\n\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is\n# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will\n# contain links (just like the HTML output) instead of page references. This\n# makes the output suitable for online browsing using a PDF viewer.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nPDF_HYPERLINKS         = YES\n\n# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate\n# the PDF file directly from the LaTeX files. Set this option to YES to get a\n# higher quality PDF documentation.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nUSE_PDFLATEX           = YES\n\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode\n# command to the generated LaTeX files. This will instruct LaTeX to keep running\n# if errors occur, instead of asking the user for help. This option is also used\n# when generating formulas in HTML.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_BATCHMODE        = NO\n\n# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the\n# index chapters (such as File Index, Compound Index, etc.) in the output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_HIDE_INDICES     = NO\n\n# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source\n# code with syntax highlighting in the LaTeX output.\n#\n# Note that which sources are shown also depends on other settings such as\n# SOURCE_BROWSER.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_SOURCE_CODE      = NO\n\n# The LATEX_BIB_STYLE tag can be used to specify the style to use for the\n# bibliography, e.g. plainnat, or ieeetr. See\n# http://en.wikipedia.org/wiki/BibTeX and \\cite for more info.\n# The default value is: plain.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_BIB_STYLE        = plain\n\n#---------------------------------------------------------------------------\n# Configuration options related to the RTF output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The\n# RTF output is optimized for Word 97 and may not look too pretty with other RTF\n# readers/editors.\n# The default value is: NO.\n\nGENERATE_RTF           = NO\n\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: rtf.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_OUTPUT             = rtf\n\n# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF\n# documents. This may be useful for small projects and may help to save some\n# trees in general.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nCOMPACT_RTF            = NO\n\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will\n# contain hyperlink fields. The RTF file will contain links (just like the HTML\n# output) instead of page references. This makes the output suitable for online\n# browsing using Word or some other Word compatible readers that support those\n# fields.\n#\n# Note: WordPad (write) and others do not support links.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_HYPERLINKS         = NO\n\n# Load stylesheet definitions from file. Syntax is similar to doxygen's config\n# file, i.e. a series of assignments. You only have to provide replacements,\n# missing definitions are set to their default value.\n#\n# See also section \"Doxygen usage\" for information on how to generate the\n# default style sheet that doxygen normally uses.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_STYLESHEET_FILE    =\n\n# Set optional variables used in the generation of an RTF document. Syntax is\n# similar to doxygen's config file. A template extensions file can be generated\n# using doxygen -e rtf extensionFile.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_EXTENSIONS_FILE    =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the man page output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for\n# classes and files.\n# The default value is: NO.\n\nGENERATE_MAN           = NO\n\n# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it. A directory man3 will be created inside the directory specified by\n# MAN_OUTPUT.\n# The default directory is: man.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_OUTPUT             = man\n\n# The MAN_EXTENSION tag determines the extension that is added to the generated\n# man pages. In case the manual section does not start with a number, the number\n# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is\n# optional.\n# The default value is: .3.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_EXTENSION          = .3\n\n# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it\n# will generate one additional man file for each entity documented in the real\n# man page(s). These additional files only source the real man page, but without\n# them the man command would be unable to find the correct page.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_LINKS              = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the XML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that\n# captures the structure of the code including all documentation.\n# The default value is: NO.\n\nGENERATE_XML           = NO\n\n# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: xml.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_OUTPUT             = xml\n\n# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a\n# validating XML parser to check the syntax of the XML files.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_SCHEMA             =\n\n# The XML_DTD tag can be used to specify a XML DTD, which can be used by a\n# validating XML parser to check the syntax of the XML files.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_DTD                =\n\n# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program\n# listings (including syntax highlighting and cross-referencing information) to\n# the XML output. Note that enabling this will significantly increase the size\n# of the XML output.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_PROGRAMLISTING     = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to the DOCBOOK output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files\n# that can be used to generate PDF.\n# The default value is: NO.\n\nGENERATE_DOCBOOK       = NO\n\n# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in\n# front of it.\n# The default directory is: docbook.\n# This tag requires that the tag GENERATE_DOCBOOK is set to YES.\n\nDOCBOOK_OUTPUT         = docbook\n\n#---------------------------------------------------------------------------\n# Configuration options for the AutoGen Definitions output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen\n# Definitions (see http://autogen.sf.net) file that captures the structure of\n# the code including all documentation. Note that this feature is still\n# experimental and incomplete at the moment.\n# The default value is: NO.\n\nGENERATE_AUTOGEN_DEF   = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the Perl module output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module\n# file that captures the structure of the code including all documentation.\n#\n# Note that this feature is still experimental and incomplete at the moment.\n# The default value is: NO.\n\nGENERATE_PERLMOD       = NO\n\n# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary\n# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI\n# output from the Perl module output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_LATEX          = NO\n\n# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely\n# formatted so it can be parsed by a human reader. This is useful if you want to\n# understand what is going on. On the other hand, if this tag is set to NO the\n# size of the Perl module output will be much smaller and Perl will parse it\n# just the same.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_PRETTY         = YES\n\n# The names of the make variables in the generated doxyrules.make file are\n# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful\n# so different doxyrules.make files included by the same Makefile don't\n# overwrite each other's variables.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_MAKEVAR_PREFIX =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the preprocessor\n#---------------------------------------------------------------------------\n\n# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all\n# C-preprocessor directives found in the sources and include files.\n# The default value is: YES.\n\nENABLE_PREPROCESSING   = YES\n\n# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names\n# in the source code. If set to NO only conditional compilation will be\n# performed. Macro expansion can be done in a controlled way by setting\n# EXPAND_ONLY_PREDEF to YES.\n# The default value is: NO.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nMACRO_EXPANSION        = NO\n\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then\n# the macro expansion is limited to the macros specified with the PREDEFINED and\n# EXPAND_AS_DEFINED tags.\n# The default value is: NO.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nEXPAND_ONLY_PREDEF     = NO\n\n# If the SEARCH_INCLUDES tag is set to YES the includes files in the\n# INCLUDE_PATH will be searched if a #include is found.\n# The default value is: YES.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nSEARCH_INCLUDES        = YES\n\n# The INCLUDE_PATH tag can be used to specify one or more directories that\n# contain include files that are not input files but should be processed by the\n# preprocessor.\n# This tag requires that the tag SEARCH_INCLUDES is set to YES.\n\nINCLUDE_PATH           =\n\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard\n# patterns (like *.h and *.hpp) to filter out the header-files in the\n# directories. If left blank, the patterns specified with FILE_PATTERNS will be\n# used.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nINCLUDE_FILE_PATTERNS  =\n\n# The PREDEFINED tag can be used to specify one or more macro names that are\n# defined before the preprocessor is started (similar to the -D option of e.g.\n# gcc). The argument of the tag is a list of macros of the form: name or\n# name=definition (no spaces). If the definition and the \"=\" are omitted, \"=1\"\n# is assumed. To prevent a macro definition from being undefined via #undef or\n# recursively expanded use the := operator instead of the = operator.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nPREDEFINED             =\n\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this\n# tag can be used to specify a list of macro names that should be expanded. The\n# macro definition that is found in the sources will be used. Use the PREDEFINED\n# tag if you want to use a different macro definition that overrules the\n# definition found in the source code.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nEXPAND_AS_DEFINED      =\n\n# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will\n# remove all refrences to function-like macros that are alone on a line, have an\n# all uppercase name, and do not end with a semicolon. Such function macros are\n# typically used for boiler-plate code, and will confuse the parser if not\n# removed.\n# The default value is: YES.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nSKIP_FUNCTION_MACROS   = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to external references\n#---------------------------------------------------------------------------\n\n# The TAGFILES tag can be used to specify one or more tag files. For each tag\n# file the location of the external documentation should be added. The format of\n# a tag file without this location is as follows:\n# TAGFILES = file1 file2 ...\n# Adding location for the tag files is done as follows:\n# TAGFILES = file1=loc1 \"file2 = loc2\" ...\n# where loc1 and loc2 can be relative or absolute paths or URLs. See the\n# section \"Linking to external documentation\" for more information about the use\n# of tag files.\n# Note: Each tag file must have an unique name (where the name does NOT include\n# the path). If a tag file is not located in the directory in which doxygen is\n# run, you must also specify the path to the tagfile here.\n\nTAGFILES               =\n\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create a\n# tag file that is based on the input files it reads. See section \"Linking to\n# external documentation\" for more information about the usage of tag files.\n\nGENERATE_TAGFILE       =\n\n# If the ALLEXTERNALS tag is set to YES all external class will be listed in the\n# class index. If set to NO only the inherited external classes will be listed.\n# The default value is: NO.\n\nALLEXTERNALS           = NO\n\n# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in\n# the modules index. If set to NO, only the current project's groups will be\n# listed.\n# The default value is: YES.\n\nEXTERNAL_GROUPS        = YES\n\n# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in\n# the related pages index. If set to NO, only the current project's pages will\n# be listed.\n# The default value is: YES.\n\nEXTERNAL_PAGES         = YES\n\n# The PERL_PATH should be the absolute path and name of the perl script\n# interpreter (i.e. the result of 'which perl').\n# The default file (with absolute path) is: /usr/bin/perl.\n\nPERL_PATH              = /usr/bin/perl\n\n#---------------------------------------------------------------------------\n# Configuration options related to the dot tool\n#---------------------------------------------------------------------------\n\n# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram\n# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to\n# NO turns the diagrams off. Note that this option also works with HAVE_DOT\n# disabled, but it is recommended to install and use dot, since it yields more\n# powerful graphs.\n# The default value is: YES.\n\nCLASS_DIAGRAMS         = YES\n\n# You can define message sequence charts within doxygen comments using the \\msc\n# command. Doxygen will then run the mscgen tool (see:\n# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the\n# documentation. The MSCGEN_PATH tag allows you to specify the directory where\n# the mscgen tool resides. If left empty the tool is assumed to be found in the\n# default search path.\n\nMSCGEN_PATH            =\n\n# If set to YES, the inheritance and collaboration graphs will hide inheritance\n# and usage relations if the target is undocumented or is not a class.\n# The default value is: YES.\n\nHIDE_UNDOC_RELATIONS   = YES\n\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is\n# available from the path. This tool is part of Graphviz (see:\n# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent\n# Bell Labs. The other options in this section have no effect if this option is\n# set to NO\n# The default value is: NO.\n\nHAVE_DOT               = NO\n\n# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed\n# to run in parallel. When set to 0 doxygen will base this on the number of\n# processors available in the system. You can set it explicitly to a value\n# larger than 0 to get control over the balance between CPU load and processing\n# speed.\n# Minimum value: 0, maximum value: 32, default value: 0.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_NUM_THREADS        = 0\n\n# When you want a differently looking font n the dot files that doxygen\n# generates you can specify the font name using DOT_FONTNAME. You need to make\n# sure dot is able to find the font, which can be done by putting it in a\n# standard location or by setting the DOTFONTPATH environment variable or by\n# setting DOT_FONTPATH to the directory containing the font.\n# The default value is: Helvetica.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTNAME           = Helvetica\n\n# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of\n# dot graphs.\n# Minimum value: 4, maximum value: 24, default value: 10.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTSIZE           = 10\n\n# By default doxygen will tell dot to use the default font as specified with\n# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set\n# the path where dot can find it using this tag.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTPATH           =\n\n# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for\n# each documented class showing the direct and indirect inheritance relations.\n# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCLASS_GRAPH            = YES\n\n# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a\n# graph for each documented class showing the direct and indirect implementation\n# dependencies (inheritance, containment, and class references variables) of the\n# class with other documented classes.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCOLLABORATION_GRAPH    = YES\n\n# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for\n# groups, showing the direct groups dependencies.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGROUP_GRAPHS           = YES\n\n# If the UML_LOOK tag is set to YES doxygen will generate inheritance and\n# collaboration diagrams in a style similar to the OMG's Unified Modeling\n# Language.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nUML_LOOK               = NO\n\n# If the UML_LOOK tag is enabled, the fields and methods are shown inside the\n# class node. If there are many fields or methods and many nodes the graph may\n# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the\n# number of items for each type to make the size more manageable. Set this to 0\n# for no limit. Note that the threshold may be exceeded by 50% before the limit\n# is enforced. So when you set the threshold to 10, up to 15 fields may appear,\n# but if the number exceeds 15, the total amount of fields shown is limited to\n# 10.\n# Minimum value: 0, maximum value: 100, default value: 10.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nUML_LIMIT_NUM_FIELDS   = 10\n\n# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and\n# collaboration graphs will show the relations between templates and their\n# instances.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nTEMPLATE_RELATIONS     = NO\n\n# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to\n# YES then doxygen will generate a graph for each documented file showing the\n# direct and indirect include dependencies of the file with other documented\n# files.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINCLUDE_GRAPH          = YES\n\n# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are\n# set to YES then doxygen will generate a graph for each documented file showing\n# the direct and indirect include dependencies of the file with other documented\n# files.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINCLUDED_BY_GRAPH      = YES\n\n# If the CALL_GRAPH tag is set to YES then doxygen will generate a call\n# dependency graph for every global function or class method.\n#\n# Note that enabling this option will significantly increase the time of a run.\n# So in most cases it will be better to enable call graphs for selected\n# functions only using the \\callgraph command.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCALL_GRAPH             = NO\n\n# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller\n# dependency graph for every global function or class method.\n#\n# Note that enabling this option will significantly increase the time of a run.\n# So in most cases it will be better to enable caller graphs for selected\n# functions only using the \\callergraph command.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCALLER_GRAPH           = NO\n\n# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical\n# hierarchy of all classes instead of a textual one.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGRAPHICAL_HIERARCHY    = YES\n\n# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the\n# dependencies a directory has on other directories in a graphical way. The\n# dependency relations are determined by the #include relations between the\n# files in the directories.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDIRECTORY_GRAPH        = YES\n\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images\n# generated by dot.\n# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order\n# to make the SVG files visible in IE 9+ (other browsers do not have this\n# requirement).\n# Possible values are: png, jpg, gif and svg.\n# The default value is: png.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_IMAGE_FORMAT       = png\n\n# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to\n# enable generation of interactive SVG images that allow zooming and panning.\n#\n# Note that this requires a modern browser other than Internet Explorer. Tested\n# and working are Firefox, Chrome, Safari, and Opera.\n# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make\n# the SVG files visible. Older versions of IE do not have SVG support.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINTERACTIVE_SVG        = NO\n\n# The DOT_PATH tag can be used to specify the path where the dot tool can be\n# found. If left blank, it is assumed the dot tool can be found in the path.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_PATH               =\n\n# The DOTFILE_DIRS tag can be used to specify one or more directories that\n# contain dot files that are included in the documentation (see the \\dotfile\n# command).\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOTFILE_DIRS           =\n\n# The MSCFILE_DIRS tag can be used to specify one or more directories that\n# contain msc files that are included in the documentation (see the \\mscfile\n# command).\n\nMSCFILE_DIRS           =\n\n# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes\n# that will be shown in the graph. If the number of nodes in a graph becomes\n# larger than this value, doxygen will truncate the graph, which is visualized\n# by representing a node as a red box. Note that doxygen if the number of direct\n# children of the root node in a graph is already larger than\n# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that\n# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.\n# Minimum value: 0, maximum value: 10000, default value: 50.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_GRAPH_MAX_NODES    = 50\n\n# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs\n# generated by dot. A depth value of 3 means that only nodes reachable from the\n# root by following a path via at most 3 edges will be shown. Nodes that lay\n# further from the root node will be omitted. Note that setting this option to 1\n# or 2 may greatly reduce the computation time needed for large code bases. Also\n# note that the size of a graph can be further restricted by\n# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.\n# Minimum value: 0, maximum value: 1000, default value: 0.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nMAX_DOT_GRAPH_DEPTH    = 0\n\n# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent\n# background. This is disabled by default, because dot on Windows does not seem\n# to support this out of the box.\n#\n# Warning: Depending on the platform used, enabling this option may lead to\n# badly anti-aliased labels on the edges of a graph (i.e. they become hard to\n# read).\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_TRANSPARENT        = NO\n\n# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output\n# files in one run (i.e. multiple -o and -T options on the command line). This\n# makes dot run faster, but since only newer versions of dot (>1.8.10) support\n# this, this feature is disabled by default.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_MULTI_TARGETS      = NO\n\n# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page\n# explaining the meaning of the various boxes and arrows in the dot generated\n# graphs.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGENERATE_LEGEND        = YES\n\n# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot\n# files that are used to generate the various graphs.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_CLEANUP            = YES\n"
  },
  {
    "path": "src/client/Makefile",
    "content": "include ../../build_config.mk\n\nall: lib\n\t${CXX} -o demo demo.cpp libssdb-client.a\n\t${CXX} -o hello-ssdb hello-ssdb.cpp libssdb-client.a\n\nlib: SSDB_client.h SSDB_impl.h SSDB_impl.cpp\n\t${CXX} -I../ ${CFLAGS} -c SSDB_impl.cpp\n\tar -cru libssdb-client.a\\\n\t\tSSDB_impl.o\\\n\t\t../util/bytes.o\\\n\t\t../net/link.o ../net/link_addr.o\n\tcp SSDB_client.h libssdb-client.a ../../api/cpp\n\nclean:\n\trm -f demo hello-ssdb *.a *.o\n\n"
  },
  {
    "path": "src/client/README.md",
    "content": "SSDB C++ API Documentation {#mainpage}\n============\n\n@author: [ideawu](http://www.ideawu.com/)\n\n## Build the static library(libssdb-client.a)\n\nDownload the SSDB source code from [github](https://github.com/ideawu/ssdb).\n\n    make\n\nThe shell commands above will compile the C++ API codes, and generate a `libssdb-client.a` file.\n\n## Sample code\n\n\t#include <stdio.h>\n\t#include <stdlib.h>\n\t#include <string>\n\t#include <vector>\n\t#include \"SSDB_client.h\"\n\t\n\tint main(int argc, char **argv){\n\t\tconst char *ip = (argc >= 2)? argv[1] : \"127.0.0.1\";\n\t\tint port = (argc >= 3)? atoi(argv[2]) : 8888;\n\t\t\n\t\tssdb::Client *client = ssdb::Client::connect(ip, port);\n\t\tif(client == NULL){\n\t\t\tprintf(\"fail to connect to server!\\n\");\n\t\t\treturn 0;\n\t\t}\n\t\t\n\t\tssdb::Status s;\n\t\ts = client->set(\"k\", \"hello ssdb!\");\n\t\tif(s.ok()){\n\t\t\tprintf(\"k = hello ssdb!\\n\");\n\t\t}else{\n\t\t\tprintf(\"error!\\n\");\n\t\t}\n\t\t\n\t\tdelete client;\n\t\treturn 0;\n\t}\n\nSave the codes above into a file named `hello-ssdb.cpp`.\n\n## Compile sample code\n\nIf you are under the directory `api/cpp`, compile it like this\n\n\tg++ -o hello-ssdb hello-ssdb.cpp libssdb-client.a\n\t./hello-ssdb\n\nBefore you run `hello-ssdb`, you have to start ssdb-server with the default configuration. The output would be like\n\n\tk = hello ssdb!\n\nConnect to ssdb-server with `ssdb-cli`, to verify the key `k` is stored with the value \"hello ssdb!\".\n\nIf your `hello-ssdb.cpp` file is not under the directory `api/cpp`, you will compile it like this\n\n\tg++ -o hello-ssdb -I<path of api/cpp> hello-ssdb.cpp <path of api/cpp>/libssdb-client.a\n\n"
  },
  {
    "path": "src/client/SSDB_client.h",
    "content": "#ifndef SSDB_API_CPP\n#define SSDB_API_CPP\n\n#ifndef __STDC_FORMAT_MACROS\n#define __STDC_FORMAT_MACROS\n#endif\n\n#include <inttypes.h>\n#include <string>\n#include <vector>\n#include <map>\n\nnamespace ssdb{\n\n/**\n * Client requests' return status.\n */\nclass Status{\npublic:\n\t/**\n\t * Returns <code>true</code> if the request succeeded.\n\t */\n\tbool ok(){\n\t\treturn code_ == \"ok\";\n\t}\n\t/**\n\t * Returns <code>true</code> if the requested key is not found. When this method\n\t * returns <code>true</code>, ok() will always returns <code>false</code>.\n\t */\n\tbool not_found(){\n\t\treturn code_ == \"not_found\";\n\t}\n\t/**\n\t * Returns <code>true</code> if error occurs during the request.\n\t * It might be a server error, or a client error.\n\t */\n\tbool error(){\n\t\treturn code_ != \"ok\";\n\t}\n\tbool disconnected(){\n\t\treturn code_ == \"disconnected\";\n\t}\n\t/**\n\t * The response code.\n\t */\n\tstd::string code(){\n\t\treturn code_;\n\t}\n\n\tStatus(){}\n\tStatus(const std::string &code){\n\t\tcode_ = code;\n\t}\n\tStatus(const std::vector<std::string> *resp){\n\t\tif(resp == NULL){\n\t\t\tcode_ = \"disconnected\";\n\t\t\treturn;\n\t\t}\n\t\tif(resp && resp->size() > 0){\n\t\t\tcode_ = resp->at(0);\n\t\t}else{\n\t\t\tcode_ = \"error\";\n\t\t}\n\t}\nprivate:\n\tstd::string code_;\n};\n\n/**\n * The SSDB client used to connect to SSDB server.\n */\nclass Client{\npublic:\n\tstatic Client* connect(const char *ip, int port);\n\tstatic Client* connect(const std::string &ip, int port);\n\tClient(){};\n\tvirtual ~Client(){};\n\n\t/// @name Free hand methods\n\t/// All these methods return NULL if error; vector<std::string> if response ready,\n\t/// the first element is response code.\n\t/// @{\n\tvirtual const std::vector<std::string>* request(const std::vector<std::string> &req) = 0;\n\tvirtual const std::vector<std::string>* request(const std::string &cmd) = 0;\n\tvirtual const std::vector<std::string>* request(const std::string &cmd, const std::string &s2) = 0;\n\tvirtual const std::vector<std::string>* request(const std::string &cmd, const std::string &s2, const std::string &s3) = 0;\n\tvirtual const std::vector<std::string>* request(const std::string &cmd, const std::string &s2, const std::string &s3, const std::string &s4) = 0;\n\tvirtual const std::vector<std::string>* request(const std::string &cmd, const std::string &s2, const std::string &s3, const std::string &s4, const std::string &s5) = 0;\n\tvirtual const std::vector<std::string>* request(const std::string &cmd, const std::string &s2, const std::string &s3, const std::string &s4, const std::string &s5, const std::string &s6) = 0;\n\tvirtual const std::vector<std::string>* request(const std::string &cmd, const std::vector<std::string> &s2) = 0;\n\tvirtual const std::vector<std::string>* request(const std::string &cmd, const std::string &s2, const std::vector<std::string> &s3) = 0;\n\t/// @}\n\t\n\tvirtual Status dbsize(int64_t *ret) = 0;\n\tvirtual Status get_kv_range(std::string *start, std::string *end) = 0;\n\tvirtual Status set_kv_range(const std::string &start, const std::string &end) = 0;\n\n\t/// @name KV methods\n\t/// @{\n\tvirtual Status get(const std::string &key, std::string *val) = 0;\n\tvirtual Status set(const std::string &key, const std::string &val) = 0;\n\t/**\n\t * Set the value of the key, with a time to live.\n\t */\n\tvirtual Status setx(const std::string &key, const std::string &val, int ttl) = 0;\n\tvirtual Status del(const std::string &key) = 0;\n\tvirtual Status incr(const std::string &key, int64_t incrby, int64_t *ret) = 0;\n\t/**\n\t * @param key_start Empty string means no limit.\n\t * @param key_end Empty string means no limit.\n\t */\n\tvirtual Status keys(const std::string &key_start, const std::string &key_end,\n\t\tuint64_t limit, std::vector<std::string> *ret) = 0;\n\t/**\n\t * Return key-value pairs.\n\t * The two elements at ret[n] and ret[n+1] form a key-value pair, n=0,2,4,...\n\t */\n\tvirtual Status scan(const std::string &key_start, const std::string &key_end,\n\t \tuint64_t limit, std::vector<std::string> *ret) = 0;\n\t/**\n\t * Return key-value pairs.\n\t * The two elements at ret[n] and ret[n+1] form a key-value pair, n=0,2,4,...\n\t */\n\tvirtual Status rscan(const std::string &key_start, const std::string &key_end,\n\t\tuint64_t limit, std::vector<std::string> *ret) = 0;\n\t/**\n\t * Return key-value pairs.\n\t * The two elements at ret[n] and ret[n+1] form a key-value pair, n=0,2,4,...\n\t */\n\tvirtual Status multi_get(const std::vector<std::string> &keys, std::vector<std::string> *vals) = 0;\n\tvirtual Status multi_set(const std::map<std::string, std::string> &kvs) = 0;\n\tvirtual Status multi_del(const std::vector<std::string> &keys) = 0;\n\t/// @}\n\n\n\t/// @name Map(Hash) methods\n\t/// @{\n\tvirtual Status hget(const std::string &name, const std::string &key, std::string *val) = 0;\n\tvirtual Status hset(const std::string &name, const std::string &key, const std::string &val) = 0;\n\tvirtual Status hdel(const std::string &name, const std::string &key) = 0;\n\tvirtual Status hincr(const std::string &name, const std::string &key, int64_t incrby, int64_t *ret) = 0;\n\tvirtual Status hsize(const std::string &name, int64_t *ret) = 0;\n\t/**\n\t * Delete all of the keys in a hashmap, return the number of keys deleted.\n\t */\n\tvirtual Status hclear(const std::string &name, int64_t *ret=NULL) = 0;\n\t/**\n\t * @param key_start Empty string means no limit.\n\t * @param key_end Empty string means no limit.\n\t */\n\tvirtual Status hkeys(const std::string &name, \n\t\tconst std::string &key_start, const std::string &key_end,\n\t\tuint64_t limit, std::vector<std::string> *ret) = 0;\n\t/**\n\t * Return all hashmap key-value pairs.\n\t * The two elements at ret[n] and ret[n+1] form a key-value pair, n=0,2,4,...\n\t */\n\tvirtual Status hgetall(const std::string &name, std::vector<std::string> *ret) = 0;\n\t/**\n\t * Return key-value pairs.\n\t * The two elements at ret[n] and ret[n+1] form a key-value pair, n=0,2,4,...\n\t */\n\tvirtual Status hscan(const std::string &name, \n\t\tconst std::string &key_start, const std::string &key_end,\n\t \tuint64_t limit, std::vector<std::string> *ret) = 0;\n\t/**\n\t * Return key-value pairs.\n\t * The two elements at ret[n] and ret[n+1] form a key-value pair, n=0,2,4,...\n\t */\n\tvirtual Status hrscan(const std::string &name, \n\t\tconst std::string &key_start, const std::string &key_end,\n\t\tuint64_t limit, std::vector<std::string> *ret) = 0;\n\t/**\n\t * Return key-value pairs.\n\t * The two elements at ret[n] and ret[n+1] form a key-value pair, n=0,2,4,...\n\t */\n\tvirtual Status multi_hget(const std::string &name, const std::vector<std::string> &keys,\n\t\tstd::vector<std::string> *ret) = 0;\n\tvirtual Status multi_hset(const std::string &name, const std::map<std::string, std::string> &kvs) = 0;\n\tvirtual Status multi_hdel(const std::string &name, const std::vector<std::string> &keys) = 0;\n\t/// @}\n\n\n\t/// @name Zset methods\n\t/// @{\n\tvirtual Status zget(const std::string &name, const std::string &key, int64_t *ret) = 0;\n\tvirtual Status zset(const std::string &name, const std::string &key, int64_t score) = 0;\n\tvirtual Status zdel(const std::string &name, const std::string &key) = 0;\n\tvirtual Status zincr(const std::string &name, const std::string &key, int64_t incrby, int64_t *ret) = 0;\n\tvirtual Status zsize(const std::string &name, int64_t *ret) = 0;\n\t/**\n\t * Delete all of the keys in a zset, return the number of keys deleted.\n\t */\n\tvirtual Status zclear(const std::string &name, int64_t *ret=NULL) = 0;\n\t/**\n\t * <b>Important! This method may be extremly SLOW!</b>\n\t */\n\tvirtual Status zrank(const std::string &name, const std::string &key, int64_t *ret) = 0;\n\t/**\n\t * <b>Important! This method may be extremly SLOW!</b>\n\t */\n\tvirtual Status zrrank(const std::string &name, const std::string &key, int64_t *ret) = 0;\n\t/**\n\t * <b>Important! This method is SLOW for large offset!</b>\n\t */\n\tvirtual Status zrange(const std::string &name,\n\t\tuint64_t offset, uint64_t limit,\n\t\tstd::vector<std::string> *ret) = 0;\n\t/**\n\t * <b>Important! This method is SLOW for large offset!</b>\n\t */\n\tvirtual Status zrrange(const std::string &name,\n\t\tuint64_t offset, uint64_t limit,\n\t\tstd::vector<std::string> *ret) = 0;\n\t/**\n\t * @param score_start NULL means no limit.\n\t * @param score_end NULL means no limit.\n\t */\n\tvirtual Status zkeys(const std::string &name, const std::string &key_start,\n\t\tint64_t *score_start, int64_t *score_end,\n\t\tuint64_t limit, std::vector<std::string> *ret) = 0;\n\t/**\n\t * Return key-score pairs.\n\t * The two elements at ret[n] and ret[n+1] form a key-score pair, n=0,2,4,...\n\t */\n\tvirtual Status zscan(const std::string &name, const std::string &key_start,\n\t\tint64_t *score_start, int64_t *score_end,\n\t\tuint64_t limit, std::vector<std::string> *ret) = 0;\n\t/**\n\t * Return key-score pairs.\n\t * The two elements at ret[n] and ret[n+1] form a key-score pair, n=0,2,4,...\n\t */\n\tvirtual Status zrscan(const std::string &name, const std::string &key_start,\n\t\tint64_t *score_start, int64_t *score_end,\n\t\tuint64_t limit, std::vector<std::string> *ret) = 0;\n\t/**\n\t * Return key-value pairs.\n\t * The two elements at ret[n] and ret[n+1] form a key-value pair, n=0,2,4,...\n\t */\n\tvirtual Status multi_zget(const std::string &name, const std::vector<std::string> &keys,\n\t\tstd::vector<std::string> *scores) = 0;\n\tvirtual Status multi_zset(const std::string &name, const std::map<std::string, int64_t> &kss) = 0;\n\tvirtual Status multi_zdel(const std::string &name, const std::vector<std::string> &keys) = 0;\n\t/// @}\n\n\tvirtual Status qpush(const std::string &name, const std::string &item, int64_t *ret_size=NULL) = 0;\n\tvirtual Status qpush(const std::string &name, const std::vector<std::string> &items, int64_t *ret_size=NULL) = 0;\n\tvirtual Status qpush_front(const std::string &name, const std::string &item, int64_t *ret_size=NULL) = 0;\n\tvirtual Status qpush_front(const std::string &name, const std::vector<std::string> &items, int64_t *ret_size=NULL) = 0;\n\tvirtual Status qpop(const std::string &name, std::string *ret) = 0;\n\tvirtual Status qpop(const std::string &name, int64_t limit, std::vector<std::string> *ret) = 0;\n\tvirtual Status qpop_back(const std::string &name, std::string *ret) = 0;\n\tvirtual Status qpop_back(const std::string &name, int64_t limit, std::vector<std::string> *ret) = 0;\n\tvirtual Status qslice(const std::string &name, int64_t begin, int64_t end, std::vector<std::string> *ret) = 0;\n\tvirtual Status qrange(const std::string &name, int64_t begin, int64_t limit, std::vector<std::string> *ret) = 0;\n\tvirtual Status qclear(const std::string &name, int64_t *ret=NULL) = 0;\n\tvirtual Status qsize(const std::string &name, int64_t *ret) = 0;\n\tvirtual Status qtrim_front(const std::string &name, int64_t limit, int64_t *ret=NULL) = 0;\n\tvirtual Status qtrim_back(const std::string &name, int64_t limit, int64_t *ret=NULL) = 0;\n\tvirtual Status qfront(const std::string &name, std::string *ret) = 0;\n\tvirtual Status qback(const std::string &name, std::string *ret) = 0;\n\tvirtual Status qset(const std::string &name, int64_t index, const std::string &val) = 0;\n\tvirtual Status qget(const std::string &name, int64_t index, std::string *val) = 0;\nprivate:\n\t// No copying allowed\n\tClient(const Client&);\n\tvoid operator=(const Client&);\n};\n\n}; // namespace ssdb\n\n#endif\n"
  },
  {
    "path": "src/client/SSDB_impl.cpp",
    "content": "#include \"SSDB_impl.h\"\n#include \"util/string_util.h\"\n#include <signal.h>\n\nnamespace ssdb{\n\ninline static\nStatus _read_list(const std::vector<std::string> *resp, std::vector<std::string> *ret){\n\tStatus s(resp);\n\tif(s.ok()){\n\t\tstd::vector<std::string>::const_iterator it;\n\t\tfor(it = resp->begin() + 1; it != resp->end(); it++){\n\t\t\tret->push_back(*it);\n\t\t}\n\t}\n\treturn s;\n}\n\ninline static\nStatus _read_int64(const std::vector<std::string> *resp, int64_t *ret){\n\tStatus s(resp);\n\tif(s.ok()){\n\t\tif(resp->size() >= 2){\n\t\t\tif(ret){\n\t\t\t\t*ret = str_to_int64(resp->at(1));\n\t\t\t}\n\t\t}else{\n\t\t\treturn Status(\"server_error\");\n\t\t}\n\t}\n\treturn s;\n}\n\ninline static\nStatus _read_str(const std::vector<std::string> *resp, std::string *ret){\n\tStatus s(resp);\n\tif(s.ok()){\n\t\tif(resp->size() >= 2){\n\t\t\t*ret = resp->at(1);\n\t\t}else{\n\t\t\treturn Status(\"server_error\");\n\t\t}\n\t}\n\treturn s;\n}\n\nClientImpl::ClientImpl(){\n\tlink = NULL;\n}\n\nClientImpl::~ClientImpl(){\n\tif(link){\n\t\tdelete link;\n\t}\n}\n\nClient* Client::connect(const char *ip, int port){\n\treturn Client::connect(std::string(ip), port);\n}\n\nClient* Client::connect(const std::string &ip, int port){\n\tstatic bool inited = false;\n\tif(!inited){\n\t\tinited = true;\n\t\tsignal(SIGPIPE, SIG_IGN);\n\t}\n\tClientImpl *client = new ClientImpl();\n\tclient->link = Link::connect(ip.c_str(), port);\n\tif(client->link == NULL){\n\t\tdelete client;\n\t\treturn NULL;\n\t}\n\treturn client;\n}\n\nconst std::vector<std::string>* ClientImpl::request(const std::vector<std::string> &req){\n\tif(link->send(req) == -1){\n\t\treturn NULL;\n\t}\n\tif(link->flush() == -1){\n\t\treturn NULL;\n\t}\n\tconst std::vector<Bytes> *packet = link->response();\n\tif(packet == NULL){\n\t\treturn NULL;\n\t}\n\tresp_.clear();\n\tfor(std::vector<Bytes>::const_iterator it=packet->begin(); it!=packet->end(); it++){\n\t\tconst Bytes &b = *it;\n\t\tresp_.push_back(b.String());\n\t}\n\treturn &resp_;\n}\n\nconst std::vector<std::string>* ClientImpl::request(const std::string &cmd){\n\tstd::vector<std::string> req;\n\treq.push_back(cmd);\n\treturn request(req);\n}\n\nconst std::vector<std::string>* ClientImpl::request(const std::string &cmd, const std::string &s2){\n\tstd::vector<std::string> req;\n\treq.push_back(cmd);\n\treq.push_back(s2);\n\treturn request(req);\n}\n\nconst std::vector<std::string>* ClientImpl::request(const std::string &cmd, const std::string &s2, const std::string &s3){\n\tstd::vector<std::string> req;\n\treq.push_back(cmd);\n\treq.push_back(s2);\n\treq.push_back(s3);\n\treturn request(req);\n}\n\nconst std::vector<std::string>* ClientImpl::request(const std::string &cmd, const std::string &s2, const std::string &s3, const std::string &s4){\n\tstd::vector<std::string> req;\n\treq.push_back(cmd);\n\treq.push_back(s2);\n\treq.push_back(s3);\n\treq.push_back(s4);\n\treturn request(req);\n}\n\nconst std::vector<std::string>* ClientImpl::request(const std::string &cmd, const std::string &s2, const std::string &s3, const std::string &s4, const std::string &s5){\n\tstd::vector<std::string> req;\n\treq.push_back(cmd);\n\treq.push_back(s2);\n\treq.push_back(s3);\n\treq.push_back(s4);\n\treq.push_back(s5);\n\treturn request(req);\n}\n\nconst std::vector<std::string>* ClientImpl::request(const std::string &cmd, const std::string &s2, const std::string &s3, const std::string &s4, const std::string &s5, const std::string &s6){\n\tstd::vector<std::string> req;\n\treq.push_back(cmd);\n\treq.push_back(s2);\n\treq.push_back(s3);\n\treq.push_back(s4);\n\treq.push_back(s5);\n\treq.push_back(s6);\n\treturn request(req);\n}\n\nconst std::vector<std::string>* ClientImpl::request(const std::string &cmd, const std::vector<std::string> &s2){\n\tstd::vector<std::string> req;\n\treq.push_back(cmd);\n\tfor(std::vector<std::string>::const_iterator it = s2.begin(); it != s2.end(); ++it){\n\t\treq.push_back(*it);\n\t}\n\treturn request(req);\n}\n\nconst std::vector<std::string>* ClientImpl::request(const std::string &cmd, const std::string &s2, const std::vector<std::string> &s3){\n\tstd::vector<std::string> req;\n\treq.push_back(cmd);\n\treq.push_back(s2);\n\tfor(std::vector<std::string>::const_iterator it = s3.begin(); it != s3.end(); ++it){\n\t\treq.push_back(*it);\n\t}\n\treturn request(req);\n}\n\n/******************** misc *************************/\n\nStatus ClientImpl::dbsize(int64_t *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"dbsize\");\n\treturn _read_int64(resp, ret);\n}\n\nStatus ClientImpl::get_kv_range(std::string *start, std::string *end){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"get_kv_range\");\n\tStatus s(resp);\n\tif(s.ok()){\n\t\t*start = resp->at(1);\n\t\t*end = resp->at(2);\n\t}\n\treturn s;\n}\n\nStatus ClientImpl::set_kv_range(const std::string &start, const std::string &end){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"set_kv_range\", start, end);\n\tStatus s(resp);\n\treturn s;\n}\n\n/******************** KV *************************/\n\nStatus ClientImpl::get(const std::string &key, std::string *val){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"get\", key);\n\treturn _read_str(resp, val);\n}\n\nStatus ClientImpl::set(const std::string &key, const std::string &val){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"set\", key, val);\n\tStatus s(resp);\n\treturn s;\n}\n\nStatus ClientImpl::setx(const std::string &key, const std::string &val, int ttl){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"setx\", key, val, str(ttl));\n\tStatus s(resp);\n\treturn s;\n}\n\nStatus ClientImpl::del(const std::string &key){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"del\", key);\n\tStatus s(resp);\n\treturn s;\n}\n\nStatus ClientImpl::incr(const std::string &key, int64_t incrby, int64_t *ret){\n\tstd::string s_incrby = str(incrby);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"incr\", key, s_incrby);\n\treturn _read_int64(resp, ret);\n}\n\nStatus ClientImpl::keys(const std::string &key_start, const std::string &key_end,\n\tuint64_t limit, std::vector<std::string> *ret)\n{\n\tstd::string s_limit = str(limit);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"keys\", key_start, key_end, s_limit);\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::scan(const std::string &key_start, const std::string &key_end,\n\tuint64_t limit, std::vector<std::string> *ret)\n{\n\tstd::string s_limit = str(limit);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"scan\", key_start, key_end, s_limit);\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::rscan(const std::string &key_start, const std::string &key_end,\n\tuint64_t limit, std::vector<std::string> *ret)\n{\n\tstd::string s_limit = str(limit);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"rscan\", key_start, key_end, s_limit);\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::multi_get(const std::vector<std::string> &keys, std::vector<std::string> *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"multi_get\", keys);\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::multi_set(const std::map<std::string, std::string> &kvs){\n\tconst std::vector<std::string> *resp;\n\tstd::vector<std::string> list;\n\tfor(std::map<std::string, std::string>::const_iterator it = kvs.begin();\n\t\tit != kvs.end(); ++it)\n\t{\n\t\tlist.push_back(it->first);\n\t\tlist.push_back(it->second);\n\t}\n\tresp = this->request(\"multi_set\", list);\n\tStatus s(resp);\n\treturn s;\n}\n\nStatus ClientImpl::multi_del(const std::vector<std::string> &keys){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"multi_del\", keys);\n\tStatus s(resp);\n\treturn s;\n}\n\n\n/******************** hash *************************/\n\n\nStatus ClientImpl::hget(const std::string &name, const std::string &key, std::string *val){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"hget\", name, key);\n\treturn _read_str(resp, val);\n}\n\nStatus ClientImpl::hset(const std::string &name, const std::string &key, const std::string &val){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"hset\", name, key, val);\n\tStatus s(resp);\n\treturn s;\n}\n\nStatus ClientImpl::hdel(const std::string &name, const std::string &key){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"hdel\", name, key);\n\tStatus s(resp);\n\treturn s;\n}\n\nStatus ClientImpl::hincr(const std::string &name, const std::string &key, int64_t incrby, int64_t *ret){\n\tstd::string s_incrby = str(incrby);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"hincr\", name, key, s_incrby);\n\treturn _read_int64(resp, ret);\n}\n\nStatus ClientImpl::hsize(const std::string &name, int64_t *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"hsize\", name);\n\treturn _read_int64(resp, ret);\n}\n\nStatus ClientImpl::hclear(const std::string &name, int64_t *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"hclear\", name);\n\treturn _read_int64(resp, ret);\n}\n\nStatus ClientImpl::hkeys(const std::string &name,\n\tconst std::string &key_start, const std::string &key_end,\n\tuint64_t limit, std::vector<std::string> *ret)\n{\n\tstd::string s_limit = str(limit);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"hkeys\", name, key_start, key_end, s_limit);\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::hgetall(const std::string &name,\n\t std::vector<std::string> *ret)\n{\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"hgetall\", name );\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::hscan(const std::string &name,\n\tconst std::string &key_start, const std::string &key_end,\n\tuint64_t limit, std::vector<std::string> *ret)\n{\n\tstd::string s_limit = str(limit);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"hscan\", name, key_start, key_end, s_limit);\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::hrscan(const std::string &name,\n\tconst std::string &key_start, const std::string &key_end,\n\tuint64_t limit, std::vector<std::string> *ret)\n{\n\tstd::string s_limit = str(limit);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"hrscan\", name, key_start, key_end, s_limit);\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::multi_hget(const std::string &name, const std::vector<std::string> &keys,\n\tstd::vector<std::string> *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"multi_hget\", name, keys);\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::multi_hset(const std::string &name, const std::map<std::string, std::string> &kvs){\n\tconst std::vector<std::string> *resp;\n\tstd::vector<std::string> list;\n\tfor(std::map<std::string, std::string>::const_iterator it = kvs.begin();\n\t\tit != kvs.end(); ++it)\n\t{\n\t\tlist.push_back(it->first);\n\t\tlist.push_back(it->second);\n\t}\n\tresp = this->request(\"multi_hset\", name, list);\n\tStatus s(resp);\n\treturn s;\n}\n\nStatus ClientImpl::multi_hdel(const std::string &name, const std::vector<std::string> &keys){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"multi_hdel\", name, keys);\n\tStatus s(resp);\n\treturn s;\n}\n\n/******************** zset *************************/\n\n\n\nStatus ClientImpl::zget(const std::string &name, const std::string &key, int64_t *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"zget\", name, key);\n\treturn _read_int64(resp, ret);\n}\n\nStatus ClientImpl::zset(const std::string &name, const std::string &key, int64_t score){\n\tstd::string s_score = str(score);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"zset\", name, key, s_score);\n\tStatus s(resp);\n\treturn s;\n}\n\nStatus ClientImpl::zdel(const std::string &name, const std::string &key){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"zdel\", name, key);\n\tStatus s(resp);\n\treturn s;\n}\n\nStatus ClientImpl::zincr(const std::string &name, const std::string &key, int64_t incrby, int64_t *ret){\n\tstd::string s_incrby = str(incrby);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"zincr\", name, key, s_incrby);\n\treturn _read_int64(resp, ret);\n}\n\nStatus ClientImpl::zsize(const std::string &name, int64_t *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"zsize\", name);\n\treturn _read_int64(resp, ret);\n}\n\nStatus ClientImpl::zclear(const std::string &name, int64_t *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"zclear\", name);\n\treturn _read_int64(resp, ret);\n}\n\nStatus ClientImpl::zrank(const std::string &name, const std::string &key, int64_t *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"zrank\", name, key);\n\treturn _read_int64(resp, ret);\n}\n\nStatus ClientImpl::zrrank(const std::string &name, const std::string &key, int64_t *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"zrrank\", name, key);\n\treturn _read_int64(resp, ret);\n}\n\nStatus ClientImpl::zrange(const std::string &name,\n\t\tuint64_t offset, uint64_t limit,\n\t\tstd::vector<std::string> *ret)\n{\n\tstd::string s_offset = str(offset);\n\tstd::string s_limit = str(limit);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"zrange\", name, s_offset, s_limit);\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::zrrange(const std::string &name,\n\t\tuint64_t offset, uint64_t limit,\n\t\tstd::vector<std::string> *ret)\n{\n\tstd::string s_offset = str(offset);\n\tstd::string s_limit = str(limit);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"zrrange\", name, s_offset, s_limit);\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::zkeys(const std::string &name, const std::string &key_start,\n\tint64_t *score_start, int64_t *score_end,\n\tuint64_t limit, std::vector<std::string> *ret)\n{\n\tstd::string s_score_start = score_start? str(*score_start) : \"\";\n\tstd::string s_score_end = score_end? str(*score_end) : \"\";\n\tstd::string s_limit = str(limit);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"zkeys\", name, key_start, s_score_start, s_score_end, s_limit);\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::zscan(const std::string &name, const std::string &key_start,\n\tint64_t *score_start, int64_t *score_end,\n\tuint64_t limit, std::vector<std::string> *ret)\n{\n\tstd::string s_score_start = score_start? str(*score_start) : \"\";\n\tstd::string s_score_end = score_end? str(*score_end) : \"\";\n\tstd::string s_limit = str(limit);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"zscan\", name, key_start, s_score_start, s_score_end, s_limit);\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::zrscan(const std::string &name, const std::string &key_start,\n\tint64_t *score_start, int64_t *score_end,\n\tuint64_t limit, std::vector<std::string> *ret)\n{\n\tstd::string s_score_start = score_start? str(*score_start) : \"\";\n\tstd::string s_score_end = score_end? str(*score_end) : \"\";\n\tstd::string s_limit = str(limit);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"zrscan\", name, key_start, s_score_start, s_score_end, s_limit);\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::multi_zget(const std::string &name, const std::vector<std::string> &keys,\n\tstd::vector<std::string> *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"multi_zget\", name, keys);\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::multi_zset(const std::string &name, const std::map<std::string, int64_t> &kss){\n\tconst std::vector<std::string> *resp;\n\tstd::vector<std::string> s_kss;\n\tfor(std::map<std::string, int64_t>::const_iterator it = kss.begin();\n\t\tit != kss.end(); ++it)\n\t{\n\t\ts_kss.push_back(it->first);\n\t\ts_kss.push_back(str(it->second));\n\t}\n\tresp = this->request(\"multi_zset\", name, s_kss);\n\tStatus s(resp);\n\treturn s;\n}\n\nStatus ClientImpl::multi_zdel(const std::string &name, const std::vector<std::string> &keys){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"multi_zdel\", name, keys);\n\tStatus s(resp);\n\treturn s;\n}\n\nStatus ClientImpl::qpush(const std::string &name, const std::string &item, int64_t *ret_size){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"qpush\", name, item);\n\tStatus s(resp);\n\tif(ret_size != NULL && s.ok()){\n\t\tif(resp->size() > 1){\n\t\t\t*ret_size = str_to_int64(resp->at(1));\n\t\t}else{\n\t\t\treturn Status(\"error\");\n\t\t}\n\t}\n\treturn s;\n}\n\nStatus ClientImpl::qpush(const std::string &name, const std::vector<std::string> &items, int64_t *ret_size){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"qpush\", name, items);\n\tStatus s(resp);\n\tif(ret_size != NULL && s.ok()){\n\t\tif(resp->size() > 1){\n\t\t\t*ret_size = str_to_int64(resp->at(1));\n\t\t}else{\n\t\t\treturn Status(\"error\");\n\t\t}\n\t}\n\treturn s;\n}\n\nStatus ClientImpl::qpush_front(const std::string &name, const std::string &item, int64_t *ret_size){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"qpush_front\", name, item);\n\tStatus s(resp);\n\tif(ret_size != NULL && s.ok()){\n\t\tif(resp->size() > 1){\n\t\t\t*ret_size = str_to_int64(resp->at(1));\n\t\t}else{\n\t\t\treturn Status(\"error\");\n\t\t}\n\t}\n\treturn s;\n}\n\nStatus ClientImpl::qpush_front(const std::string &name, const std::vector<std::string> &items, int64_t *ret_size){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"qpush_front\", name, items);\n\tStatus s(resp);\n\tif(ret_size != NULL && s.ok()){\n\t\tif(resp->size() > 1){\n\t\t\t*ret_size = str_to_int64(resp->at(1));\n\t\t}else{\n\t\t\treturn Status(\"error\");\n\t\t}\n\t}\n\treturn s;\n}\n\nStatus ClientImpl::qpop(const std::string &name, std::string *item){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"qpop\", name);\n\treturn _read_str(resp, item);\n}\n\nStatus ClientImpl::qpop(const std::string &name, int64_t limit, std::vector<std::string> *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"qpop\", name, str(limit));\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::qpop_back(const std::string &name, std::string *item){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"qpop_back\", name);\n\treturn _read_str(resp, item);\n}\n\nStatus ClientImpl::qpop_back(const std::string &name, int64_t limit, std::vector<std::string> *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"qpop_back\", name, str(limit));\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::qslice(const std::string &name,\n\t\tint64_t begin, int64_t end,\n\t\tstd::vector<std::string> *ret)\n{\n\tstd::string s_begin = str(begin);\n\tstd::string s_end = str(end);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"qslice\", name, s_begin, s_end);\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::qrange(const std::string &name, int64_t begin, int64_t limit, std::vector<std::string> *ret){\n\tstd::string s_begin = str(begin);\n\tstd::string s_limit = str(limit);\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"qrange\", name, s_begin, s_limit);\n\treturn _read_list(resp, ret);\n}\n\nStatus ClientImpl::qclear(const std::string &name, int64_t *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"qclear\", name);\n\treturn _read_int64(resp, ret);\n}\n\nStatus ClientImpl::qsize(const std::string &name, int64_t *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"qsize\", name);\n\treturn _read_int64(resp, ret);\n}\n\nStatus ClientImpl::qtrim_front(const std::string &name, int64_t limit, int64_t *ret){\n\tconst std::vector<std::string> *resp;\n\tstd::string s_limit = str(limit);\n\tresp = this->request(\"qtrim_front\", name, s_limit);\n\treturn _read_int64(resp, ret);\n}\n\nStatus ClientImpl::qtrim_back(const std::string &name, int64_t limit, int64_t *ret){\n\tconst std::vector<std::string> *resp;\n\tstd::string s_limit = str(limit);\n\tresp = this->request(\"qtrim_back\", name, s_limit);\n\treturn _read_int64(resp, ret);\n}\n\nStatus ClientImpl::qfront(const std::string &name, std::string *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"qfront\", name);\n\treturn _read_str(resp, ret);\n}\n\nStatus ClientImpl::qback(const std::string &name, std::string *ret){\n\tconst std::vector<std::string> *resp;\n\tresp = this->request(\"qback\", name);\n\treturn _read_str(resp, ret);\n}\n\nStatus ClientImpl::qset(const std::string &name, int64_t index, const std::string &val){\n\tconst std::vector<std::string> *resp;\n\tstd::string s_index = str(index);\n\tresp = this->request(\"qset\", name, s_index, val);\n\tStatus s(resp);\n\treturn s;\n}\n\nStatus ClientImpl::qget(const std::string &name, int64_t index, std::string *val){\n\tconst std::vector<std::string> *resp;\n\tstd::string s_index = str(index);\n\tresp = this->request(\"qget\", name, s_index);\n\treturn _read_str(resp, val);\n}\n\n}; // namespace ssdb\n"
  },
  {
    "path": "src/client/SSDB_impl.h",
    "content": "#ifndef SSDB_API_IMPL_CPP\n#define SSDB_API_IMPL_CPP\n\n#include \"SSDB_client.h\"\n#include \"net/link.h\"\n\nnamespace ssdb{\n\nclass ClientImpl : public Client{\nprivate:\n\tfriend class Client;\n\t\n\tLink *link;\n\tstd::vector<std::string> resp_;\npublic:\n\tClientImpl();\n\t~ClientImpl();\n\n\tvirtual const std::vector<std::string>* request(const std::vector<std::string> &req);\n\tvirtual const std::vector<std::string>* request(const std::string &cmd);\n\tvirtual const std::vector<std::string>* request(const std::string &cmd, const std::string &s2);\n\tvirtual const std::vector<std::string>* request(const std::string &cmd, const std::string &s2, const std::string &s3);\n\tvirtual const std::vector<std::string>* request(const std::string &cmd, const std::string &s2, const std::string &s3, const std::string &s4);\n\tvirtual const std::vector<std::string>* request(const std::string &cmd, const std::string &s2, const std::string &s3, const std::string &s4, const std::string &s5);\n\tvirtual const std::vector<std::string>* request(const std::string &cmd, const std::string &s2, const std::string &s3, const std::string &s4, const std::string &s5, const std::string &s6);\n\tvirtual const std::vector<std::string>* request(const std::string &cmd, const std::vector<std::string> &s2);\n\tvirtual const std::vector<std::string>* request(const std::string &cmd, const std::string &s2, const std::vector<std::string> &s3);\n\n\tvirtual Status dbsize(int64_t *ret);\n\tvirtual Status get_kv_range(std::string *start, std::string *end);\n\tvirtual Status set_kv_range(const std::string &start, const std::string &end);\n\n\tvirtual Status get(const std::string &key, std::string *val);\n\tvirtual Status set(const std::string &key, const std::string &val);\n\tvirtual Status setx(const std::string &key, const std::string &val, int ttl);\n\tvirtual Status del(const std::string &key);\n\tvirtual Status incr(const std::string &key, int64_t incrby, int64_t *ret);\n\tvirtual Status keys(const std::string &key_start, const std::string &key_end,\n\t\tuint64_t limit, std::vector<std::string> *ret);\n\tvirtual Status scan(const std::string &key_start, const std::string &key_end,\n\t\tuint64_t limit, std::vector<std::string> *ret);\n\tvirtual Status rscan(const std::string &key_start, const std::string &key_end,\n\t\tuint64_t limit, std::vector<std::string> *ret);\n\tvirtual Status multi_get(const std::vector<std::string> &keys, std::vector<std::string> *ret);\n\tvirtual Status multi_set(const std::map<std::string, std::string> &kvs);\n\tvirtual Status multi_del(const std::vector<std::string> &keys);\n\t\n\tvirtual Status hget(const std::string &name, const std::string &key, std::string *val);\n\tvirtual Status hset(const std::string &name, const std::string &key, const std::string &val);\n\tvirtual Status hdel(const std::string &name, const std::string &key);\n\tvirtual Status hincr(const std::string &name, const std::string &key, int64_t incrby, int64_t *ret);\n\tvirtual Status hsize(const std::string &name, int64_t *ret);\n\tvirtual Status hclear(const std::string &name, int64_t *ret=NULL);\n\tvirtual Status hkeys(const std::string &name, const std::string &key_start, const std::string &key_end,\n\t\tuint64_t limit, std::vector<std::string> *ret);\n\tvirtual Status hgetall(const std::string &name, std::vector<std::string> *ret);\n\tvirtual Status hscan(const std::string &name, const std::string &key_start, const std::string &key_end,\n\t\tuint64_t limit, std::vector<std::string> *ret);\n\tvirtual Status hrscan(const std::string &name, const std::string &key_start, const std::string &key_end,\n\t\tuint64_t limit, std::vector<std::string> *ret);\n\tvirtual Status multi_hget(const std::string &name, const std::vector<std::string> &keys,\n\t\tstd::vector<std::string> *ret);\n\tvirtual Status multi_hset(const std::string &name, const std::map<std::string, std::string> &kvs);\n\tvirtual Status multi_hdel(const std::string &name, const std::vector<std::string> &keys);\n\n\tvirtual Status zget(const std::string &name, const std::string &key, int64_t *ret);\n\tvirtual Status zset(const std::string &name, const std::string &key, int64_t score);\n\tvirtual Status zdel(const std::string &name, const std::string &key);\n\tvirtual Status zincr(const std::string &name, const std::string &key, int64_t incrby, int64_t *ret);\n\tvirtual Status zsize(const std::string &name, int64_t *ret);\n\tvirtual Status zclear(const std::string &name, int64_t *ret=NULL);\n\tvirtual Status zrank(const std::string &name, const std::string &key, int64_t *ret);\n\tvirtual Status zrrank(const std::string &name, const std::string &key, int64_t *ret);\n\tvirtual Status zrange(const std::string &name,\n\t\tuint64_t offset, uint64_t limit,\n\t\tstd::vector<std::string> *ret);\n\tvirtual Status zrrange(const std::string &name,\n\t\tuint64_t offset, uint64_t limit,\n\t\tstd::vector<std::string> *ret);\n\tvirtual Status zkeys(const std::string &name, const std::string &key_start,\n\t\tint64_t *score_start, int64_t *score_end,\n\t\tuint64_t limit, std::vector<std::string> *ret);\n\tvirtual Status zscan(const std::string &name, const std::string &key_start,\n\t\tint64_t *score_start, int64_t *score_end,\n\t\tuint64_t limit, std::vector<std::string> *ret);\n\tvirtual Status zrscan(const std::string &name, const std::string &key_start,\n\t\tint64_t *score_start, int64_t *score_end,\n\t\tuint64_t limit, std::vector<std::string> *ret);\n\tvirtual Status multi_zget(const std::string &name, const std::vector<std::string> &keys,\n\t\tstd::vector<std::string> *scores);\n\tvirtual Status multi_zset(const std::string &name, const std::map<std::string, int64_t> &kss);\n\tvirtual Status multi_zdel(const std::string &name, const std::vector<std::string> &keys);\n\n\tvirtual Status qpush(const std::string &name, const std::string &item, int64_t *ret_size=NULL);\n\tvirtual Status qpush(const std::string &name, const std::vector<std::string> &items, int64_t *ret_size=NULL);\n\tvirtual Status qpush_front(const std::string &name, const std::string &item, int64_t *ret_size=NULL);\n\tvirtual Status qpush_front(const std::string &name, const std::vector<std::string> &items, int64_t *ret_size=NULL);\n\tvirtual Status qpop(const std::string &name, std::string *item);\n\tvirtual Status qpop(const std::string &name, int64_t limit, std::vector<std::string> *ret);\n\tvirtual Status qpop_back(const std::string &name, std::string *ret);\n\tvirtual Status qpop_back(const std::string &name, int64_t limit, std::vector<std::string> *ret);\n\tvirtual Status qslice(const std::string &name, int64_t begin, int64_t end, std::vector<std::string> *ret);\n\tvirtual Status qrange(const std::string &name, int64_t begin, int64_t limit, std::vector<std::string> *ret);\n\tvirtual Status qclear(const std::string &name, int64_t *ret=NULL);\n\tvirtual Status qsize(const std::string &name, int64_t *ret);\n\tvirtual Status qtrim_front(const std::string &name, int64_t limit, int64_t *ret=NULL);\n\tvirtual Status qtrim_back(const std::string &name, int64_t limit, int64_t *ret=NULL);\n\tvirtual Status qfront(const std::string &name, std::string *ret);\n\tvirtual Status qback(const std::string &name, std::string *ret);\n\tvirtual Status qset(const std::string &name, int64_t index, const std::string &val);\n\tvirtual Status qget(const std::string &name, int64_t index, std::string *val);\n};\n\n}; // namespace ssdb\n\n#endif\n"
  },
  {
    "path": "src/client/demo.cpp",
    "content": "#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <assert.h>\n#include <string>\n#include <vector>\n#include \"SSDB_client.h\"\n\nchar* readline(char *buf, int num){\n\tchar *ret = fgets(buf, num , stdin);\n\tif(!ret){\n\t\treturn NULL;\n\t}\n\tif(strlen(ret) > 0){\n\t\tret[strlen(ret) - 1] = '\\0';\n\t}\n\treturn ret;\n}\n\nint main(int argc, char **argv){\n\tprintf(\"Usage: %s [host] [port]\\n\", argv[0]);\n\tconst char *ip = (argc >= 2)? argv[1] : \"127.0.0.1\";\n\tint port = (argc >= 3)? atoi(argv[2]) : 8888;\n\n\t// connect to server\n\tssdb::Client *client = ssdb::Client::connect(ip, port);\n\tif(client == NULL){\n\t\tprintf(\"fail to connect to server!\\n\");\n\t\treturn 0;\n\t}\n\t\n\tssdb::Status s;\n\tstd::string hash = \"h\";\n\tstd::string zset = \"z\";\n\tstd::string key = \"k\";\n\tstd::string test_val = \"test_val\";\n\tstd::string val;\n\t\n\tprintf(\"\\n\");\n\t{\n\t\ts = client->setx(key, \"test_val\", 3);\n\t\tassert(s.ok());\n\n\t\ts = client->set(key, \"test_val\");\n\t\tassert(s.ok());\n\n\t\ts = client->get(key, &val);\n\t\tassert(s.ok() && (val == test_val));\n\t\tprintf(\"%s = %s\\n\", key.c_str(), val.c_str());\n\n\t\ts = client->del(key);\n\t\tassert(s.ok());\n\n\t\ts = client->get(key, &val);\n\t\tassert(s.not_found());\n\t\t\n\t\tint64_t ret;\n\t\ts = client->incr(key, 3, &ret);\n\t\tassert(s.ok() && (ret == 3));\n\t\ts = client->incr(key, -1, &ret);\n\t\tassert(s.ok() && (ret == 2));\n\t\t\n\t\tstd::vector<std::string> list;\n\t\ts = client->keys(\"\", \"\", 2, &list);\n\t\tassert(s.ok() && list.size() <= 2);\n\t\t\n\t\tlist.clear();\n\t\ts = client->scan(\"\", \"\", 2, &list);\n\t\tassert(s.ok() && list.size() <= 4);\n\t\tfor(int i=0; i<list.size(); i++){\n\t\t\tif(i%2 == 0){\n\t\t\t\tprintf(\"%s=\", list[i].c_str());\n\t\t\t}else{\n\t\t\t\tprintf(\"%s, \", list[i].c_str());\n\t\t\t}\n\t\t}\n\t\tprintf(\"\\n\");\n\t\t\n\t\tlist.clear();\n\t\ts = client->rscan(\"\", \"\", 2, &list);\n\t\tassert(s.ok() && list.size() <= 4);\n\t\tfor(int i=0; i<list.size(); i++){\n\t\t\tif(i%2 == 0){\n\t\t\t\tprintf(\"%s=\", list[i].c_str());\n\t\t\t}else{\n\t\t\t\tprintf(\"%s, \", list[i].c_str());\n\t\t\t}\n\t\t}\n\t\tprintf(\"\\n\");\n\n\t\tstd::map<std::string, std::string> kvs;\n\t\tkvs.insert(std::make_pair(\"k1\", \"v1\"));\n\t\tkvs.insert(std::make_pair(\"k2\", \"v2\"));\n\t\ts = client->multi_set(kvs);\n\t\tassert(s.ok());\n\n\t\tlist.clear();\n\t\tstd::vector<std::string> keys;\n\t\tkeys.push_back(\"k1\");\n\t\tkeys.push_back(\"k2\");\n\t\ts = client->multi_get(keys, &list);\n\t\tassert(s.ok());\n\t\tfor(int i=0; i<list.size(); i++){\n\t\t\tif(i%2 == 0){\n\t\t\t\tprintf(\"%s=\", list[i].c_str());\n\t\t\t}else{\n\t\t\t\tprintf(\"%s, \", list[i].c_str());\n\t\t\t}\n\t\t}\n\t\ts = client->multi_del(keys);\n\t\tassert(s.ok());\n\t\tprintf(\"\\n\");\n\t}\n\t\n\tprintf(\"\\n\");\n\t{\n\t\ts = client->hset(hash, key, \"test_val\");\n\t\tassert(s.ok());\n\n\t\ts = client->hget(hash, key, &val);\n\t\tassert(s.ok() && (val == test_val));\n\t\tprintf(\"%s = %s\\n\", key.c_str(), val.c_str());\n\n\t\ts = client->hdel(hash, key);\n\t\tassert(s.ok());\n\n\t\ts = client->hget(hash, key, &val);\n\t\tassert(s.not_found());\n\t\t\n\t\tint64_t ret;\n\t\tret = -1;\n\t\ts = client->hsize(hash, &ret);\n\t\tassert(s.ok() && (ret != -1));\n\t\ts = client->hincr(hash, key, 3, &ret);\n\t\tassert(s.ok() && (ret == 3));\n\t\ts = client->hincr(hash, key, -1, &ret);\n\t\tassert(s.ok() && (ret == 2));\n\t\t\n\t\tstd::vector<std::string> list;\n\t\ts = client->hkeys(hash, \"\", \"\", 2, &list);\n\t\tassert(s.ok() && list.size() <= 2);\n\t\t\n\t\tlist.clear();\n\t\ts = client->hscan(hash, \"\", \"\", 2, &list);\n\t\tassert(s.ok() && list.size() <= 4);\n\t\tfor(int i=0; i<list.size(); i++){\n\t\t\tif(i%2 == 0){\n\t\t\t\tprintf(\"%s=\", list[i].c_str());\n\t\t\t}else{\n\t\t\t\tprintf(\"%s, \", list[i].c_str());\n\t\t\t}\n\t\t}\n\t\tprintf(\"\\n\");\n\t\t\n\t\tlist.clear();\n\t\ts = client->hrscan(hash, \"\", \"\", 2, &list);\n\t\tassert(s.ok() && list.size() <= 4);\n\t\tfor(int i=0; i<list.size(); i++){\n\t\t\tif(i%2 == 0){\n\t\t\t\tprintf(\"%s=\", list[i].c_str());\n\t\t\t}else{\n\t\t\t\tprintf(\"%s, \", list[i].c_str());\n\t\t\t}\n\t\t}\n\t\tprintf(\"\\n\");\n\n\t\tstd::map<std::string, std::string> kvs;\n\t\tkvs.insert(std::make_pair(\"k1\", \"v1\"));\n\t\tkvs.insert(std::make_pair(\"k2\", \"v2\"));\n\t\ts = client->multi_hset(hash, kvs);\n\t\tassert(s.ok());\n\t\t\n\t\tlist.clear();\n\t\tstd::vector<std::string> keys;\n\t\tkeys.push_back(\"k1\");\n\t\tkeys.push_back(\"k2\");\n\t\ts = client->multi_hget(hash, keys, &list);\n\t\tassert(s.ok());\n\t\tfor(int i=0; i<list.size(); i++){\n\t\t\tif(i%2 == 0){\n\t\t\t\tprintf(\"%s=\", list[i].c_str());\n\t\t\t}else{\n\t\t\t\tprintf(\"%s, \", list[i].c_str());\n\t\t\t}\n\t\t}\n\t\ts = client->multi_hdel(hash, keys);\n\t\tassert(s.ok());\n\t\tprintf(\"\\n\");\n\n\t\tret = -1;\n\t\ts = client->hclear(hash, &ret);\n\t\tassert(s.ok() && ret != -1);\n\t}\n\t\n\tprintf(\"\\n\");\n\t{\n\t\tstd::vector<std::string> list;\n\t\tint64_t test_score = 100;\n\t\tint64_t score;\n\t\ts = client->zset(zset, key, test_score);\n\t\tassert(s.ok());\n\n\t\ts = client->zget(zset, key, &score);\n\t\tassert(s.ok() && (score == test_score));\n\t\tprintf(\"%s = %d\\n\", key.c_str(), (int)score);\n\n\t\ts = client->zdel(zset, key);\n\t\tassert(s.ok());\n\n\t\ts = client->zget(zset, key, &score);\n\t\tassert(s.not_found());\n\t\t\n\t\tint64_t ret;\n\t\tret = -1;\n\t\ts = client->zsize(zset, &ret);\n\t\tassert(s.ok() && (ret != -1));\n\t\ts = client->zincr(zset, key, 3, &ret);\n\t\tassert(s.ok() && (ret == 3));\n\t\ts = client->zincr(zset, key, -1, &ret);\n\t\tassert(s.ok() && (ret == 2));\n\t\t\n\t\tclient->zset(zset, \"a\", -1);\n\t\tclient->zset(zset, \"b\", 3);\n\t\tclient->zset(zset, \"c\", 4);\n\t\tint64_t score_max = 90;\n\t\n\t\tlist.clear();\n\t\ts = client->zkeys(zset, \"\", NULL, &score_max, 2, &list);\n\t\tassert(s.ok() && list.size() <= 2);\n\t\n\t\tlist.clear();\n\t\ts = client->zrange(zset, 0, 2, &list);\n\t\tassert(s.ok() && list.size() <= 4);\n\t\tlist.clear();\n\t\ts = client->zrrange(zset, 0, 2, &list);\n\t\tassert(s.ok() && list.size() <= 4);\n\t\n\t\tlist.clear();\n\t\ts = client->zscan(zset, \"\", NULL, &score_max, 2, &list);\n\t\tassert(s.ok() && list.size() <= 4);\n\t\tfor(int i=0; i<list.size(); i++){\n\t\t\tif(i%2 == 0){\n\t\t\t\tprintf(\"%s=\", list[i].c_str());\n\t\t\t}else{\n\t\t\t\tprintf(\"%s, \", list[i].c_str());\n\t\t\t}\n\t\t}\n\t\tprintf(\"\\n\");\n\t\t\n\t\tlist.clear();\n\t\ts = client->zrscan(zset, \"\", &score_max, NULL, 2, &list);\n\t\tassert(s.ok() && list.size() <= 4);\n\t\tfor(int i=0; i<list.size(); i++){\n\t\t\tif(i%2 == 0){\n\t\t\t\tprintf(\"%s=\", list[i].c_str());\n\t\t\t}else{\n\t\t\t\tprintf(\"%s, \", list[i].c_str());\n\t\t\t}\n\t\t}\n\t\tprintf(\"\\n\");\n\n\t\tstd::map<std::string, int64_t> kss;\n\t\tkss.insert(std::make_pair(\"k1\", 123));\n\t\tkss.insert(std::make_pair(\"k2\", 124));\n\t\ts = client->multi_zset(zset, kss);\n\t\tassert(s.ok());\n\t\t\n\t\tlist.clear();\n\t\tstd::vector<std::string> keys;\n\t\tkeys.push_back(\"k1\");\n\t\tkeys.push_back(\"k2\");\n\t\ts = client->multi_zget(zset, keys, &list);\n\t\tassert(s.ok());\n\t\tfor(int i=0; i<list.size(); i++){\n\t\t\tif(i%2 == 0){\n\t\t\t\tprintf(\"%s=\", list[i].c_str());\n\t\t\t}else{\n\t\t\t\tprintf(\"%s, \", list[i].c_str());\n\t\t\t}\n\t\t}\n\t\ts = client->multi_zdel(zset, keys);\n\t\tassert(s.ok());\n\t\tprintf(\"\\n\");\n\n\t\tint64_t rank = -1;\n\t\tclient->zrank(zset, \"b\", &rank);\n\t\tassert(s.ok() && (rank != -1));\n\t\tclient->zrrank(zset, \"b\", &rank);\n\t\tassert(s.ok() && (rank != -1));\n\n\t\tret = -1;\n\t\ts = client->zclear(zset, &ret);\n\t\tassert(s.ok() && ret != -1);\n\t}\n\t\n\t{\n\t\tstd::vector<std::string> list;\n\t\tstd::string item;\n\t\tint64_t size;\n\t\tint64_t size2;\n\t\t\n\t\ts = client->qclear(\"q\");\n\t\tassert(s.ok());\n\t\t\n\t\ts = client->qpush(\"q\", \"a\", &size);\n\t\tassert(s.ok());\n\t\t\n\t\tlist.push_back(\"k1\");\n\t\tlist.push_back(\"k2\");\n\t\ts = client->qpush(\"q\", list, &size2);\n\t\tassert(s.ok());\n\t\tassert(size2 = size + list.size());\n\t\t\n\t\ts = client->qpop(\"q\", &item);\n\t\tassert(s.ok());\n\t\t\n\t\tlist.clear();\n\t\ts = client->qpop(\"q\", 2, &list);\n\t\tassert(s.ok());\n\t\tassert(list.size() == 2);\n\t\t\n\t\tlist.clear();\n\t\ts = client->qrange(\"q\", 0, -1, &list);\n\t\tassert(s.ok());\n\n\t\ts = client->qpush_front(\"q\", \"A\", &size);\n\t\tassert(s.ok());\n\t\t\n\t\tlist.push_back(\"B\");\n\t\tlist.push_back(\"C\");\n\t\ts = client->qpush_front(\"q\", list, &size2);\n\t\tassert(s.ok());\n\t\tassert(size2 = size + list.size());\n\t\t\n\t\tlist.clear();\n\t\ts = client->qpop_back(\"q\", &item);\n\t\tassert(s.ok());\n\t\tassert(item == std::string(\"A\"));\n\n\t\tlist.clear();\n\t\ts = client->qpop_back(\"q\", 2, &list);\n\t\tassert(s.ok());\n\t\tassert(list.size() == 2);\n\t\tassert(list[0] == std::string(\"B\"));\n\t\tassert(list[1] == std::string(\"C\"));\n\t\t\n\t\ts = client->qpush(\"q\", \"1\");\n\t\ts = client->qpush(\"q\", \"2\");\n\n\t\ts = client->qfront(\"q\", &item);\n\t\tassert(s.ok());\n\t\tassert(item == std::string(\"1\"));\n\n\t\ts = client->qback(\"q\", &item);\n\t\tassert(s.ok());\n\t\tassert(item == std::string(\"2\"));\n\n\t\ts = client->qset(\"q\", 0, \"A\");\n\n\t\ts = client->qget(\"q\", 0, &item);\n\t\tprintf(\"%s\\n\", s.code().c_str());\n\t\tassert(s.ok());\n\t\tassert(item == std::string(\"A\"));\n\n\t\ts = client->qtrim_front(\"q\", 1);\n\t\tassert(s.ok());\n\t\t\n\t\ts = client->qtrim_back(\"q\", 1);\n\t\tassert(s.ok());\n\t\t\n\t\ts = client->qsize(\"q\", &size);\n\t\tassert(s.ok());\n\t\tassert(size == 0);\n\t}\n\t\n\tdelete client;\n\treturn 0;\n}\n"
  },
  {
    "path": "src/client/hello-ssdb.cpp",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n#include <string>\n#include <vector>\n#include \"SSDB_client.h\"\n\nint main(int argc, char **argv){\n\tconst char *ip = (argc >= 2)? argv[1] : \"127.0.0.1\";\n\tint port = (argc >= 3)? atoi(argv[2]) : 8888;\n\n\tssdb::Client *client = ssdb::Client::connect(ip, port);\n\tif(client == NULL){\n\t\tprintf(\"fail to connect to server!\\n\");\n\t\treturn 0;\n\t}\n\n\tssdb::Status s;\n\tstd::string val;\n\tstd::vector<std::string> vals;\n\n\t// set and get\n\ts = client->set(\"k\", \"hello ssdb!\");\n\tif(s.ok()){\n\t\tprintf(\"k = hello ssdb!\\n\");\n\t}else{\n\t\tprintf(\"error!\\n\");\n\t}\n\ts = client->get(\"k\", &val);\n\tprintf(\"length: %d\\n\", (int)val.size());\n\n\t// qpush, qslice, qpop\n\ts = client->qpush(\"k\", \"hello1!\");\n\tif(s.ok()){\n\t\tprintf(\"qpush k = hello1!\\n\");\n\t}else{\n\t\tprintf(\"error!\\n\");\n\t}\n\ts = client->qpush(\"k\", \"hello2!\");\n\tif(s.ok()){\n\t\tprintf(\"qpush k = hello2!\\n\");\n\t}else{\n\t\tprintf(\"error!\\n\");\n\t}\n\n\tvals.clear();\n\ts = client->qslice(\"k\", 0, 1, &vals);\n\tif(s.ok()){\n\t\tprintf(\"qslice 0 1\\n\");\n\t\tfor(int i = 0; i < (int)vals.size(); i++){\n\t\t\tprintf(\"    %d %s\\n\", i, vals[i].c_str());\n\t\t}\n\t}else{\n\t\tprintf(\"error!\\n\");\n\t}\n\ts = client->qpop(\"k\", &val);\n\tif(s.ok()){\n\t\tprintf(\"qpop k = %s\\n\", val.c_str());\n\t}else{\n\t\tprintf(\"error!\\n\");\n\t}\n\ts = client->qpop(\"k\", &val);\n\tif(s.ok()){\n\t\tprintf(\"qpop k = %s\\n\", val.c_str());\n\t}else{\n\t\tprintf(\"error!\\n\");\n\t}\n\n\tvals.clear();\n\ts = client->hgetall(\"h\", &vals);\n\tif(s.ok()){\n\t\tprintf(\"hgetall h\\n\");\n\t\tstd::string key, val;\n\t\tfor(int i = 0; i < (int)vals.size(); i++){\n\t\t\tif(i%2 == 0){\n\t\t\t\tkey = vals[i];\n\t\t\t}else{\n\t\t\t\tval = vals[i];\n\t\t\t\tprintf(\"    %d %s=%s\\n\", i/2, key.c_str(), val.c_str());\n\t\t\t}\n\t\t}\n\t}else{\n\t\tprintf(\"error!\\n\");\n\t}\n\n\tdelete client;\n\treturn 0;\n}\n"
  },
  {
    "path": "src/include.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef SSDB_INCLUDE_H_\n#define SSDB_INCLUDE_H_\n\n#include <inttypes.h>\n#include <unistd.h>\n#include <stdarg.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <limits.h>\n#include <errno.h>\n#include <string.h>\n#include <math.h>\n#include <fcntl.h>\n#include <assert.h>\n#include <signal.h>\n#include <time.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n\n#include \"version.h\"\n\n#ifndef UINT64_MAX\n\t#define UINT64_MAX\t\t18446744073709551615ULL\n#endif\n#ifndef INT64_MAX\n\t#define INT64_MAX\t\t0x7fffffffffffffffLL\n#endif\n\n\nstatic inline double microtime(){\n\tstruct timeval now;\n\tgettimeofday(&now, NULL);\n\tdouble ret = now.tv_sec + now.tv_usec/1000.0/1000.0;\n\treturn ret;\n}\n\nstatic inline int64_t time_ms(){\n\tstruct timeval now;\n\tgettimeofday(&now, NULL);\n\treturn (int64_t)now.tv_sec * 1000 + (int64_t)now.tv_usec/1000;\n}\n\n#endif\n\n"
  },
  {
    "path": "src/net/.gitignore",
    "content": "test\n\n"
  },
  {
    "path": "src/net/Makefile",
    "content": "include ../../build_config.mk\n\nOBJS = server.o resp.o proc.o worker.o fde.o link.o link_addr.o\nUTIL_OBJS = ../util/log.o ../util/config.o ../util/bytes.o\nEXES = test\n\nall: ${OBJS}\n\tar -cru ./libnet.a ${OBJS}\n\nfde.o: fde.h fde.cpp fde_select.cpp fde_epoll.cpp\n\t${CXX} ${CFLAGS} -c fde.cpp\nlink_addr.o: link_addr.h link_addr.cpp\n\t${CXX} ${CFLAGS} -c link_addr.cpp\nlink.o: link.h link.cpp link_redis.h link_redis.cpp\n\t${CXX} ${CFLAGS} -c link.cpp\nresp.o: resp.h resp.cpp\n\t${CXX} ${CFLAGS} -c resp.cpp\nproc.o: proc.h proc.cpp\n\t${CXX} ${CFLAGS} -c proc.cpp\nworker.o: worker.h worker.cpp\n\t${CXX} ${CFLAGS} -c worker.cpp\nserver.o: server.h server.cpp\n\t${CXX} ${CFLAGS} -c server.cpp\n\ntest: all\n\t${CXX} -o test.out test.cpp ${CFLAGS} ${OBJS} ${UTIL_OBJS} ${CLIBS}\n\t${CXX} -o test2.out test2.cpp ${CFLAGS} ${OBJS} ${UTIL_OBJS} ${CLIBS}\n\nclean:\n\trm -f ${EXES} *.a *.o *.exe\n"
  },
  {
    "path": "src/net/fde.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"fde.h\"\n\nstruct Fdevent* Fdevents::get_fde(int fd){\n\twhile((int)events.size() <= fd){\n\t\tstruct Fdevent *fde = new Fdevent();\n\t\tfde->fd = events.size();\n\t\tfde->s_flags = FDEVENT_NONE;\n\t\tfde->data.num = 0;\n\t\tfde->data.ptr = NULL;\n\t\tevents.push_back(fde);\n\t}\n\treturn events[fd];\n}\n\n\n#ifdef HAVE_EPOLL\n#include \"fde_epoll.cpp\"\n#else\n#include \"fde_select.cpp\"\n#endif\n"
  },
  {
    "path": "src/net/fde.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef UTIL_FDE_H\n#define UTIL_FDE_H\n\n#include \"../include.h\"\n\n#ifdef __linux__\n\t#define HAVE_EPOLL 1\n#endif\n\n#define FDEVENT_NONE\t(0)\n#define FDEVENT_IN\t\t(1<<0)\n#define FDEVENT_PRI\t\t(1<<1)\n#define FDEVENT_OUT\t\t(1<<2)\n#define FDEVENT_HUP\t\t(1<<3)\n#define FDEVENT_ERR\t\t(1<<4)\n\nstruct Fdevent{\n\tint fd;\n\tint s_flags; // subscribed events\n\tint events;\t // ready events\n\tstruct{\n\t\tint num;\n\t\tvoid *ptr;\n\t}data;\n};\n\n#include <vector>\n#ifdef HAVE_EPOLL\n\t#include <sys/epoll.h>\n#else\n\t#include <sys/select.h>\n#endif\n\n\nclass Fdevents{\n\tpublic:\n\t\ttypedef std::vector<struct Fdevent *> events_t;\n\tprivate:\n#ifdef HAVE_EPOLL\n\t\tstatic const int MAX_FDS = 8 * 1024;\n\t\tint ep_fd;\n\t\tstruct epoll_event ep_events[MAX_FDS];\n#else\n\t\tint maxfd;\n\t\tfd_set readset;\n\t\tfd_set writeset;\n#endif\n\t\tevents_t events;\n\t\tevents_t ready_events;\n\n\t\tstruct Fdevent *get_fde(int fd);\n\tpublic:\n\t\tFdevents();\n\t\t~Fdevents();\n\n\t\tbool isset(int fd, int flag);\n\t\tint set(int fd, int flags, int data_num, void *data_ptr);\n\t\tint del(int fd);\n\t\tint clr(int fd, int flags);\n\t\tconst events_t* wait(int timeout_ms=-1);\n};\n\n#endif\n"
  },
  {
    "path": "src/net/fde_epoll.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef UTIL_FDE_EPOLL_H\n#define UTIL_FDE_EPOLL_H\n\nFdevents::Fdevents(){\n\tep_fd = epoll_create(1024);\n}\n\nFdevents::~Fdevents(){\n\tfor(int i=0; i<(int)events.size(); i++){\n\t\tdelete events[i];\n\t}\n\tif(ep_fd){\n\t\t::close(ep_fd);\n\t}\n\tevents.clear();\n\tready_events.clear();\n}\n\nbool Fdevents::isset(int fd, int flag){\n\tstruct Fdevent *fde = get_fde(fd);\n\treturn (bool)(fde->s_flags & flag);\n}\n\nint Fdevents::set(int fd, int flags, int data_num, void *data_ptr){\n\tstruct Fdevent *fde = get_fde(fd);\n\tif(fde->s_flags & flags){\n\t\treturn 0;\n\t}\n\tint ctl_op = fde->s_flags? EPOLL_CTL_MOD : EPOLL_CTL_ADD;\n\n\tfde->s_flags |= flags;\n\tfde->data.num = data_num;\n\tfde->data.ptr = data_ptr;\n\n\tstruct epoll_event epe;\n\tepe.data.ptr = fde;\n\tepe.events = 0;\n\tif(fde->s_flags & FDEVENT_IN)  epe.events |= EPOLLIN;\n\tif(fde->s_flags & FDEVENT_OUT) epe.events |= EPOLLOUT;\n\n\tint ret = epoll_ctl(ep_fd, ctl_op, fd, &epe);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nint Fdevents::del(int fd){\n\tstruct epoll_event epe;\n\tint ret = epoll_ctl(ep_fd, EPOLL_CTL_DEL, fd, &epe);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\n\tstruct Fdevent *fde = get_fde(fd);\n\tfde->s_flags = FDEVENT_NONE;\n\treturn 0;\n}\n\nint Fdevents::clr(int fd, int flags){\n\tstruct Fdevent *fde = get_fde(fd);\n\tif(!(fde->s_flags & flags)){\n\t\treturn 0;\n\t}\n\n\tfde->s_flags &= ~flags;\n\tint ctl_op = fde->s_flags? EPOLL_CTL_MOD: EPOLL_CTL_DEL;\n\n\tstruct epoll_event epe;\n\tepe.data.ptr = fde;\n\tepe.events = 0;\n\tif(fde->s_flags & FDEVENT_IN)  epe.events |= EPOLLIN;\n\tif(fde->s_flags & FDEVENT_OUT) epe.events |= EPOLLOUT;\n\n\tint ret = epoll_ctl(ep_fd, ctl_op, fd, &epe);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nconst Fdevents::events_t* Fdevents::wait(int timeout_ms){\n\tready_events.clear();\n\n\tint nfds = epoll_wait(ep_fd, ep_events, MAX_FDS, timeout_ms);\n\tif(nfds == -1){\n\t\tif(errno == EINTR){\n\t\t\treturn &ready_events;\n\t\t}\n\t\treturn NULL;\n\t}\n\n\tfor(int i = 0; i < nfds; i++){\n\t\tstruct epoll_event *epe = &ep_events[i];\n\t\tstruct Fdevent *fde = (struct Fdevent *)epe->data.ptr;\n\n\t\tfde->events = FDEVENT_NONE;\n\t\tif(epe->events & EPOLLIN)  fde->events |= FDEVENT_IN;\n\t\tif(epe->events & EPOLLPRI) fde->events |= FDEVENT_IN;\n\t\tif(epe->events & EPOLLOUT) fde->events |= FDEVENT_OUT;\n\t\tif(epe->events & EPOLLHUP) fde->events |= FDEVENT_ERR;\n\t\tif(epe->events & EPOLLERR) fde->events |= FDEVENT_ERR;\n\n\t\tready_events.push_back(fde);\n\t}\n\treturn &ready_events;\n}\n\n#endif\n\n"
  },
  {
    "path": "src/net/fde_select.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef UTIL_FDE_SELECT_H\n#define UTIL_FDE_SELECT_H\n\nFdevents::Fdevents(){\n\tmaxfd = -1;\n\tFD_ZERO(&readset);\n\tFD_ZERO(&writeset);\n}\n\nFdevents::~Fdevents(){\n\tfor(size_t i=0; i<events.size(); i++){\n\t\tdelete events[i];\n\t}\n\tevents.clear();\n\tready_events.clear();\n}\n\nbool Fdevents::isset(int fd, int flag){\n\tstruct Fdevent *fde = get_fde(fd);\n\treturn (bool)(fde->s_flags & flag);\n}\n\nint Fdevents::set(int fd, int flags, int data_num, void *data_ptr){\n\tif(fd > FD_SETSIZE - 1){\n\t\treturn -1;\n\t}\n\n\tstruct Fdevent *fde = get_fde(fd);\n\tif(fde->s_flags & flags){\n\t\treturn 0;\n\t}\n\n\tif(flags & FDEVENT_IN)  FD_SET(fd, &readset);\n\tif(flags & FDEVENT_OUT) FD_SET(fd, &writeset);\n\n\tfde->data.num = data_num;\n\tfde->data.ptr = data_ptr;\n\tfde->s_flags |= flags;\n\tmaxfd = fd > maxfd? fd: maxfd;\n\n\treturn 0;\n}\n\nint Fdevents::del(int fd){\n\tFD_CLR(fd, &readset);\n\tFD_CLR(fd, &writeset);\n\n\tstruct Fdevent *fde = get_fde(fd);\n\tfde->s_flags = FDEVENT_NONE;\n\twhile(maxfd >= 0 && this->events[maxfd]->s_flags == 0){\n\t\tmaxfd --;\n\t}\n\treturn 0;\n}\n\nint Fdevents::clr(int fd, int flags){\n\tstruct Fdevent *fde = get_fde(fd);\n\tif(!(fde->s_flags & flags)){\n\t\treturn 0;\n\t}\n\tif(flags & FDEVENT_IN)  FD_CLR(fd, &readset);\n\tif(flags & FDEVENT_OUT) FD_CLR(fd, &writeset);\n\n\tfde->s_flags &= ~flags;\n\twhile(this->events[maxfd]->s_flags == 0){\n\t\tmaxfd --;\n\t}\n\treturn 0;\n}\n\nconst Fdevents::events_t* Fdevents::wait(int timeout_ms){\n\tstruct timeval tv;\n\tstruct Fdevent *fde;\n\tint i, ret;\n\n\tready_events.clear();\n\t\n\tfd_set t_readset = readset;\n\tfd_set t_writeset = writeset;\n\n\tif(timeout_ms >= 0){\n\t\ttv.tv_sec =  timeout_ms / 1000;\n\t\ttv.tv_usec = (timeout_ms % 1000) * 1000;\n\t\tret = ::select(maxfd + 1, &t_readset, &t_writeset, NULL, &tv);\n\t}else{\n\t\tret = ::select(maxfd + 1, &t_readset, &t_writeset, NULL, NULL);\n\t}\n\tif(ret < 0){\n\t\tif(errno == EINTR){\n\t\t\treturn &ready_events;\n\t\t}\n\t\treturn NULL;\n\t}\n\n\tif(ret > 0){\n\t\tfor(i = 0; i <= maxfd && (int)ready_events.size() < ret; i++){\n\t\t\tfde = this->events[i];\n\n\t\t\tfde->events = FDEVENT_NONE;\n\t\t\tif(FD_ISSET(i, &t_readset))  fde->events |= FDEVENT_IN;\n\t\t\tif(FD_ISSET(i, &t_writeset)) fde->events |= FDEVENT_OUT;\n\n\t\t\tif(fde->events){\n\t\t\t\tready_events.push_back(fde);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &ready_events;\n}\n\n#endif\n"
  },
  {
    "path": "src/net/link.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include <errno.h>\n#include <fcntl.h>\n#include <string.h>\n#include <stdarg.h>\n#include <sys/socket.h>\n#include <netdb.h>\n\n#include \"link.h\"\n#include \"link_addr.h\"\n\n#include \"link_redis.cpp\"\n\n#define INIT_BUFFER_SIZE  1024\n#define BEST_BUFFER_SIZE  (8 * 1024)\n\n\nLink::Link(bool is_server){\n\tredis = NULL;\n\n\tsock = -1;\n\tnoblock_ = false;\n\terror_ = false;\n\tremote_ip[0] = '\\0';\n\tremote_port = -1;\n\tauth = false;\n\tignore_key_range = false;\n\t\n\tif(is_server){\n\t\tinput = output = NULL;\n\t}else{\n\t\tinput = new Buffer(INIT_BUFFER_SIZE);\n\t\toutput = new Buffer(INIT_BUFFER_SIZE);\n\t}\n}\n\nLink::~Link(){\n\tif(redis){\n\t\tdelete redis;\n\t}\n\tif(input){\n\t\tdelete input;\n\t}\n\tif(output){\n\t\tdelete output;\n\t}\n\tthis->close();\n}\n\nvoid Link::close(){\n\tif(sock >= 0){\n\t\t::close(sock);\n\t}\n}\n\nvoid Link::nodelay(bool enable){\n\tint opt = enable? 1 : 0;\n\t::setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&opt, sizeof(opt));\n}\n\nvoid Link::keepalive(bool enable){\n\tint opt = enable? 1 : 0;\n\t::setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&opt, sizeof(opt));\n}\n\nvoid Link::noblock(bool enable){\n\tnoblock_ = enable;\n\tif(enable){\n\t\t::fcntl(sock, F_SETFL, O_NONBLOCK | O_RDWR);\n\t}else{\n\t\t::fcntl(sock, F_SETFL, O_RDWR);\n\t}\n}\n\n// TODO: check less than 256\nstatic bool is_ip(const char *host){\n\tif(strchr(host, ':') != NULL){\n\t\treturn true;\n\t}\n\tint dot_count = 0;\n\tint digit_count = 0;\n\tfor(const char *p = host; *p; p++){\n\t\tif(*p == '.'){\n\t\t\tdot_count += 1;\n\t\t\tif(digit_count >= 1 && digit_count <= 3){ \n\t\t\t\tdigit_count = 0;\n\t\t\t}else{\n\t\t\t\treturn false;\n\t\t\t}   \n\t\t}else if(*p >= '0' && *p <= '9'){\n\t\t\tdigit_count += 1;\n\t\t}else{\n\t\t\treturn false;\n\t\t}   \n\t}   \n\treturn dot_count == 3;\n}\n\nLink* Link::connect(const char *host, int port){\n\tLink *link;\n\tint sock = -1;\n\n\tchar ip_resolve[INET6_ADDRSTRLEN];\n\tif(!is_ip(host)){\n\t\tstruct hostent *hptr = gethostbyname(host);\n\t\tfor(int i=0; hptr && hptr->h_addr_list[i] != NULL; i++){\n\t\t\tstruct in_addr *addr = (struct in_addr *)hptr->h_addr_list[i];\n\t\t\tif(inet_ntop(AF_INET, addr, ip_resolve, sizeof(ip_resolve))){\n\t\t\t\t//printf(\"resolve %s: %s\\n\", host, ip_resolve);\n\t\t\t\thost = ip_resolve;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tLinkAddr addr(host, port);\n\n\tif((sock = ::socket(addr.family, SOCK_STREAM, 0)) == -1){\n\t\tgoto sock_err;\n\t}\n\tif(::connect(sock, addr.addr(), addr.addrlen) == -1){\n\t\tgoto sock_err;\n\t}\n\n\t//log_debug(\"fd: %d, connect to %s:%d\", sock, ip, port);\n\tlink = new Link();\n\tlink->ipv4 = addr.ipv4;\n\tlink->sock = sock;\n\tlink->keepalive(true);\n\treturn link;\nsock_err:\n\t//log_debug(\"connect to %s:%d failed: %s\", ip, port, strerror(errno));\n\tif(sock >= 0){\n\t\t::close(sock);\n\t}\n\treturn NULL;\n}\n\nLink* Link::listen(const char *ip, int port){\n\tLink *link;\n\tint sock = -1;\n\tLinkAddr addr(ip, port);\n\n\tint opt = 1;\n\tif((sock = ::socket(addr.family, SOCK_STREAM, 0)) == -1){\n\t\tgoto sock_err;\n\t}\n\tif(::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1){\n\t\tgoto sock_err;\n\t}\n\tif(::bind(sock, addr.addr(), addr.addrlen) == -1){\n\t\tgoto sock_err;\n\t}\n\tif(::listen(sock, 1024) == -1){\n\t\tgoto sock_err;\n\t}\n\t//log_debug(\"server socket fd: %d, listen on: %s:%d\", sock, ip, port);\n\n\tlink = new Link(true);\n\tlink->ipv4 = addr.ipv4;\n\tlink->sock = sock;\n\tsnprintf(link->remote_ip, sizeof(link->remote_ip), \"%s\", ip);\n\tlink->remote_port = port;\n\treturn link;\nsock_err:\n\t//log_debug(\"listen %s:%d failed: %s\", ip, port, strerror(errno));\n\tif(sock >= 0){\n\t\t::close(sock);\n\t}\n\treturn NULL;\n}\n\nLink* Link::accept(){\n\tLink *link;\n\tint client_sock;\n\tLinkAddr addr(this->ipv4);\n\n\twhile((client_sock = ::accept(sock, addr.addr(), &addr.addrlen)) == -1){\n\t\tif(errno != EINTR){\n\t\t\t//log_error(\"socket %d accept failed: %s\", sock, strerror(errno));\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\t// avoid client side TIME_WAIT\n\tstruct linger opt = {1, 0};\n\tint ret = ::setsockopt(client_sock, SOL_SOCKET, SO_LINGER, (void *)&opt, sizeof(opt));\n\tif (ret != 0) {\n\t\t//log_error(\"socket %d set linger failed: %s\", client_sock, strerror(errno));\n\t}\n\n\tlink = new Link();\n\tlink->sock = client_sock;\n\tlink->keepalive(true);\n\tlink->remote_port = addr.port();\n\tinet_ntop(addr.family, addr.sin_addr(), link->remote_ip, sizeof(link->remote_ip));\n\tif(!addr.ipv4){\n\t\tif(strchr(link->remote_ip, '.')){\n\t\t\tchar *p = strrchr(link->remote_ip, ':');\n\t\t\tif(p){\n\t\t\t\tp += 1;\n\t\t\t\tchar *s = link->remote_ip;\n\t\t\t\twhile(*p != '\\0'){\n\t\t\t\t\t*s = *p;\n\t\t\t\t\ts ++;\n\t\t\t\t\tp ++;\n\t\t\t\t}\n\t\t\t\t*s = '\\0';\n\t\t\t}\n\t\t}\n\t}\n\treturn link;\n}\n\nint Link::read(){\n\tint ret = 0;\n\tint want;\n\t\n\tinput->nice();\n\t// 由于 recv() 返回的数据是指向 input 所占的内存, 所以, 不能在 recv()\n\t// 之后立即就释放内存, 只能在下一次read()的时候再释放.\n\tif(input->size() == 0 && input->total() > BEST_BUFFER_SIZE){\n\t\tinput->shrink(BEST_BUFFER_SIZE);\n\t}\n\t\n\twhile((want = input->space()) > 0){\n\t\t// test\n\t\t//want = 1;\n\t\tint len = ::read(sock, input->slot(), want);\n\t\tif(len == -1){\n\t\t\tif(errno == EINTR){\n\t\t\t\tcontinue;\n\t\t\t}else if(errno == EWOULDBLOCK){\n\t\t\t\tbreak;\n\t\t\t}else{\n\t\t\t\t//log_debug(\"fd: %d, read: -1, want: %d, error: %s\", sock, want, strerror(errno));\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}else{\n\t\t\t//log_debug(\"fd: %d, want=%d, read: %d\", sock, want, len);\n\t\t\tif(len == 0){\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tret += len;\n\t\t\tinput->incr(len);\n\t\t}\n\t\tif(!noblock_){\n\t\t\tbreak;\n\t\t}\n\t}\n\t//log_debug(\"read %d\", ret);\n\t//printf(\"%s\\n\", hexmem(input->data(), input->size()).c_str());\n\treturn ret;\n}\n\nint Link::write(){\n\tint ret = 0;\n\tint want;\n\twhile((want = output->size()) > 0){\n\t\t// test\n\t\t//want = 1;\n\t\tint len = ::write(sock, output->data(), want);\n\t\tif(len == -1){\n\t\t\tif(errno == EINTR){\n\t\t\t\tcontinue;\n\t\t\t}else if(errno == EWOULDBLOCK){\n\t\t\t\tbreak;\n\t\t\t}else{\n\t\t\t\t//log_debug(\"fd: %d, write: -1, error: %s\", sock, strerror(errno));\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}else{\n\t\t\t//log_debug(\"fd: %d, want: %d, write: %d\", sock, want, len);\n\t\t\tif(len == 0){\n\t\t\t\t// ?\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tret += len;\n\t\t\toutput->decr(len);\n\t\t}\n\t\tif(!noblock_){\n\t\t\tbreak;\n\t\t}\n\t}\n\toutput->nice();\n\tif(output->size() == 0 && output->total() > BEST_BUFFER_SIZE){\n\t\toutput->shrink(BEST_BUFFER_SIZE);\n\t}\n\treturn ret;\n}\n\nint Link::flush(){\n\tint len = 0;\n\twhile(!output->empty()){\n\t\tint ret = this->write();\n\t\tif(ret == -1){\n\t\t\treturn -1;\n\t\t}\n\t\tlen += ret;\n\t}\n\treturn len;\n}\n\nconst std::vector<Bytes>* Link::recv(){\n\tthis->recv_data.clear();\n\n\tif(input->empty()){\n\t\treturn &this->recv_data;\n\t}\n\n\t// TODO: 记住上回的解析状态\n\tint parsed = 0;\n\tint size = input->size();\n\tchar *head = input->data();\n\n\t// ignore leading empty lines\n\twhile(size > 0 && (head[0] == '\\n' || head[0] == '\\r')){\n\t\thead ++;\n\t\tsize --;\n\t\tparsed ++;\n\t}\n\t\n\t// Redis protocol supports\n\tif(head[0] == '*'){\n\t\tif(redis == NULL){\n\t\t\tredis = new RedisLink();\n\t\t}\n\t\tconst std::vector<Bytes> *ret = redis->recv_req(input);\n\t\tif(ret){\n\t\t\tthis->recv_data = *ret;\n\t\t\treturn &this->recv_data;\n\t\t}else{\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\twhile(size > 0){\n\t\tchar *body = (char *)memchr(head, '\\n', size);\n\t\tif(body == NULL){\n\t\t\tbreak;\n\t\t}\n\t\tbody ++;\n\n\t\tint head_len = body - head;\n\t\tif(head_len == 1 || (head_len == 2 && head[0] == '\\r')){\n\t\t\t// packet end\n\t\t\tparsed += head_len;\n\t\t\tinput->decr(parsed);\n\t\t\treturn &this->recv_data;;\n\t\t}\n\t\tif(head[0] < '0' || head[0] > '9'){\n\t\t\t//log_warn(\"bad format\");\n\t\t\treturn NULL;\n\t\t}\n\n\t\tchar head_str[20];\n\t\tif(head_len > (int)sizeof(head_str) - 1){\n\t\t\treturn NULL;\n\t\t}\n\t\tmemcpy(head_str, head, head_len - 1); // no '\\n'\n\t\thead_str[head_len - 1] = '\\0';\n\n\t\tint body_len = atoi(head_str);\n\t\tif(body_len < 0){\n\t\t\t//log_warn(\"bad format\");\n\t\t\treturn NULL;\n\t\t}\n\t\t//log_debug(\"size: %d, head_len: %d, body_len: %d\", size, head_len, body_len);\n\t\tsize -= head_len + body_len;\n\t\tif(size < 0){\n\t\t\tbreak;\n\t\t}\n\n\t\tthis->recv_data.push_back(Bytes(body, body_len));\n\n\t\thead += head_len + body_len;\n\t\tparsed += head_len + body_len;\n\t\tif(size >= 1 && head[0] == '\\n'){\n\t\t\thead += 1;\n\t\t\tsize -= 1;\n\t\t\tparsed += 1;\n\t\t}else if(size >= 2 && head[0] == '\\r' && head[1] == '\\n'){\n\t\t\thead += 2;\n\t\t\tsize -= 2;\n\t\t\tparsed += 2;\n\t\t}else if(size >= 2){\n\t\t\t// bad format\n\t\t\treturn NULL;\n\t\t}else{\n\t\t\tbreak;\n\t\t}\n\t\tif(parsed > MAX_PACKET_SIZE){\n\t\t\t //log_warn(\"fd: %d, exceed max packet size, parsed: %d\", this->sock, parsed);\n\t\t\t return NULL;\n\t\t}\n\t}\n\n\tif(input->space() == 0){\n\t\tinput->nice();\n\t\tif(input->space() == 0){\n\t\t\tif(input->grow() == -1){\n\t\t\t\t//log_error(\"fd: %d, unable to resize input buffer!\", this->sock);\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t\t//log_debug(\"fd: %d, resize input buffer, %s\", this->sock, input->stats().c_str());\n\t\t}\n\t}\n\n\t// not ready\n\tthis->recv_data.clear();\n\treturn &this->recv_data;\n}\n\nint Link::send(const std::vector<std::string> &resp){\n\tif(resp.empty()){\n\t\treturn 0;\n\t}\n\t// Redis protocol supports\n\tif(this->redis){\n\t\treturn this->redis->send_resp(this->output, resp);\n\t}\n\t\n\tfor(int i=0; i<resp.size(); i++){\n\t\toutput->append_record(resp[i]);\n\t}\n\toutput->append('\\n');\n\treturn 0;\n}\n\nint Link::send(const std::vector<Bytes> &resp){\n\tfor(int i=0; i<resp.size(); i++){\n\t\toutput->append_record(resp[i]);\n\t}\n\toutput->append('\\n');\n\treturn 0;\n}\n\nint Link::send(const Bytes &s1){\n\toutput->append_record(s1);\n\toutput->append('\\n');\n\treturn 0;\n}\n\nint Link::send(const Bytes &s1, const Bytes &s2){\n\toutput->append_record(s1);\n\toutput->append_record(s2);\n\toutput->append('\\n');\n\treturn 0;\n}\n\nint Link::send(const Bytes &s1, const Bytes &s2, const Bytes &s3){\n\toutput->append_record(s1);\n\toutput->append_record(s2);\n\toutput->append_record(s3);\n\toutput->append('\\n');\n\treturn 0;\n}\n\nint Link::send(const Bytes &s1, const Bytes &s2, const Bytes &s3, const Bytes &s4){\n\toutput->append_record(s1);\n\toutput->append_record(s2);\n\toutput->append_record(s3);\n\toutput->append_record(s4);\n\toutput->append('\\n');\n\treturn 0;\n}\n\nint Link::send(const Bytes &s1, const Bytes &s2, const Bytes &s3, const Bytes &s4, const Bytes &s5){\n\toutput->append_record(s1);\n\toutput->append_record(s2);\n\toutput->append_record(s3);\n\toutput->append_record(s4);\n\toutput->append_record(s5);\n\toutput->append('\\n');\n\treturn 0;\n}\n\nconst std::vector<Bytes>* Link::response(){\n\twhile(1){\n\t\tconst std::vector<Bytes> *resp = this->recv();\n\t\tif(resp == NULL){\n\t\t\treturn NULL;\n\t\t}else if(resp->empty()){\n\t\t\tif(this->read() <= 0){\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t}else{\n\t\t\treturn resp;\n\t\t}\n\t}\n\treturn NULL;\n}\n\nconst std::vector<Bytes>* Link::request(const Bytes &s1){\n\tif(this->send(s1) == -1){\n\t\treturn NULL;\n\t}\n\tif(this->flush() == -1){\n\t\treturn NULL;\n\t}\n\treturn this->response();\n}\n\nconst std::vector<Bytes>* Link::request(const Bytes &s1, const Bytes &s2){\n\tif(this->send(s1, s2) == -1){\n\t\treturn NULL;\n\t}\n\tif(this->flush() == -1){\n\t\treturn NULL;\n\t}\n\treturn this->response();\n}\n\nconst std::vector<Bytes>* Link::request(const Bytes &s1, const Bytes &s2, const Bytes &s3){\n\tif(this->send(s1, s2, s3) == -1){\n\t\treturn NULL;\n\t}\n\tif(this->flush() == -1){\n\t\treturn NULL;\n\t}\n\treturn this->response();\n}\n\nconst std::vector<Bytes>* Link::request(const Bytes &s1, const Bytes &s2, const Bytes &s3, const Bytes &s4){\n\tif(this->send(s1, s2, s3, s4) == -1){\n\t\treturn NULL;\n\t}\n\tif(this->flush() == -1){\n\t\treturn NULL;\n\t}\n\treturn this->response();\n}\n\nconst std::vector<Bytes>* Link::request(const Bytes &s1, const Bytes &s2, const Bytes &s3, const Bytes &s4, const Bytes &s5){\n\tif(this->send(s1, s2, s3, s4, s5) == -1){\n\t\treturn NULL;\n\t}\n\tif(this->flush() == -1){\n\t\treturn NULL;\n\t}\n\treturn this->response();\n}\n\n#if 0\nint main(){\n\t//Link link;\n\t//link.listen(\"127.0.0.1\", 8888);\n\tLink *link = Link::connect(\"127.0.0.1\", 8080);\n\tprintf(\"%d\\n\", link);\n\tgetchar();\n\treturn 0;\n}\n#endif\n"
  },
  {
    "path": "src/net/link.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef NET_LINK_H_\n#define NET_LINK_H_\n\n#include <vector>\n#include <unistd.h>\n#include <arpa/inet.h>\n#include <netinet/in.h>\n#include <netinet/tcp.h>\n\n#include \"../util/bytes.h\"\n\n#include \"link_redis.h\"\n\nclass Link{\n\tprivate:\n\t\tint sock;\n\t\tbool noblock_;\n\t\tbool error_;\n\t\tbool ipv4;\n\t\tstd::vector<Bytes> recv_data;\n\n\t\tRedisLink *redis;\n\tpublic:\n\t\tconst static int MAX_PACKET_SIZE = 128 * 1024 * 1024;\n\n\t\tchar remote_ip[INET6_ADDRSTRLEN];\n\t\tint remote_port;\n\n\t\tbool auth;\n\t\tbool ignore_key_range;\n\n\t\tBuffer *input;\n\t\tBuffer *output;\n\t\t\n\t\tdouble create_time;\n\t\tdouble active_time;\n\n\t\tLink(bool is_server=false);\n\t\t~Link();\n\t\tvoid close();\n\t\tvoid nodelay(bool enable=true);\n\t\t// noblock(true) is supposed to corperate with IO Multiplex,\n\t\t// otherwise, flush() may cause a lot unneccessary write calls.\n\t\tvoid noblock(bool enable=true);\n\t\tvoid keepalive(bool enable=true);\n\n\t\tint fd() const{\n\t\t\treturn sock;\n\t\t}\n\t\tbool error() const{\n\t\t\treturn error_;\n\t\t}\n\t\tvoid mark_error(){\n\t\t\terror_ = true;\n\t\t}\n\n\t\tstatic Link* connect(const char *ip, int port);\n\t\tstatic Link* listen(const char *ip, int port);\n\t\tLink* accept();\n\n\t\t// read network data info buffer\n\t\tint read();\n\t\tint write();\n\t\t// flush buffered data to network\n\t\t// REQUIRES: nonblock\n\t\tint flush();\n\n\t\t/**\n\t\t * parse received data, and return -\n\t\t * NULL: error\n\t\t * empty vector: recv not ready\n\t\t * vector<Bytes>: recv ready\n\t\t */\n\t\tconst std::vector<Bytes>* recv();\n\t\t// wait until a response received.\n\t\tconst std::vector<Bytes>* response();\n\n\t\t// need to call flush to ensure all data has flush into network\n\t\tint send(const std::vector<std::string> &packet);\n\t\tint send(const std::vector<Bytes> &packet);\n\t\tint send(const Bytes &s1);\n\t\tint send(const Bytes &s1, const Bytes &s2);\n\t\tint send(const Bytes &s1, const Bytes &s2, const Bytes &s3);\n\t\tint send(const Bytes &s1, const Bytes &s2, const Bytes &s3, const Bytes &s4);\n\t\tint send(const Bytes &s1, const Bytes &s2, const Bytes &s3, const Bytes &s4, const Bytes &s5);\n\n\t\tconst std::vector<Bytes>* last_recv(){\n\t\t\treturn &recv_data;\n\t\t}\n\t\t\n\t\t/** these methods will send a request to the server, and wait until a response received.\n\t\t * @return\n\t\t * NULL: error\n\t\t * vector<Bytes>: response ready\n\t\t */\n\t\tconst std::vector<Bytes>* request(const Bytes &s1);\n\t\tconst std::vector<Bytes>* request(const Bytes &s1, const Bytes &s2);\n\t\tconst std::vector<Bytes>* request(const Bytes &s1, const Bytes &s2, const Bytes &s3);\n\t\tconst std::vector<Bytes>* request(const Bytes &s1, const Bytes &s2, const Bytes &s3, const Bytes &s4);\n\t\tconst std::vector<Bytes>* request(const Bytes &s1, const Bytes &s2, const Bytes &s3, const Bytes &s4, const Bytes &s5);\n};\n\n#endif\n"
  },
  {
    "path": "src/net/link_addr.cpp",
    "content": "#include <string.h>\n#include <stdio.h>\n#include \"link_addr.h\"\n\nLinkAddr::LinkAddr(const char *ip, int port){\n\tparse(ip, port);\n}\n\nLinkAddr::LinkAddr(bool is_ipv4){\n\tthis->is_ipv4(is_ipv4);\n}\n\nvoid LinkAddr::is_ipv4(bool yn){\n\tif(yn){\n\t\tipv4 = true;\n\t\tfamily = AF_INET;\n\t\taddrlen = sizeof(addr4);\n\t}else{\n\t\tipv4 = false;\n\t\tfamily = AF_INET6;\n\t\taddrlen = sizeof(addr6);\n\t}\n}\n\nvoid LinkAddr::parse(const char *ip, int port){\n\tthis->is_ipv4(strchr(ip, ':') == NULL);\n\tif(ipv4){\n\t\tbzero(&addr4, sizeof(addr4));\n\t\taddr4.sin_family = family;\n\t\taddr4.sin_port = htons((short)port);\n\t\tinet_pton(family, ip, &addr4.sin_addr);\n\t}else{\n\t\tbzero(&addr6, sizeof(addr6));\n\t\taddr6.sin6_family = family;\n\t\taddr6.sin6_port = htons((short)port);\n\t\tinet_pton(family, ip, &addr6.sin6_addr);\n\t}\n}\n"
  },
  {
    "path": "src/net/link_addr.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef NET_LINK_ADDR_H_\n#define NET_LINK_ADDR_H_\n\n#include <unistd.h>\n#include <arpa/inet.h>\n#include <netinet/in.h>\n#include <netinet/tcp.h>\n\nstruct LinkAddr\n{\n\tbool ipv4;\n\tshort family;\n\tsocklen_t addrlen;\n\t\n\tLinkAddr(bool is_ipv4);\n\tLinkAddr(const char *ip, int port);\n\tvoid parse(const char *ip, int port);\n\t\n\tunsigned short port(){\n\t\treturn ipv4? ntohs(addr4.sin_port) : ntohs(addr6.sin6_port);\n\t}\n\tstruct sockaddr* addr(){\n\t\treturn ipv4? (struct sockaddr *)&addr4 : (struct sockaddr *)&addr6;\n\t}\n\tvoid* sin_addr(){\n\t\treturn ipv4? (void*)&addr4.sin_addr : (void*)&addr6.sin6_addr;\n\t}\n\t\nprivate:\n\tstruct sockaddr_in addr4;\n\tstruct sockaddr_in6 addr6;\n\n\tLinkAddr(){};\n\tvoid is_ipv4(bool yn);\n};\n\n#endif\n"
  },
  {
    "path": "src/net/link_redis.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"link_redis.h\"\n#include <map>\n\nenum REPLY{\n\tREPLY_BULK = 0,\n\tREPLY_MULTI_BULK,\n\tREPLY_INT,\n\tREPLY_STATUS\n};\n\nenum STRATEGY{\n\tSTRATEGY_AUTO,\n\tSTRATEGY_PING,\n\tSTRATEGY_MGET,\n\tSTRATEGY_HMGET,\n\tSTRATEGY_HGETALL,\n\tSTRATEGY_HKEYS,\n\tSTRATEGY_HVALS,\n\tSTRATEGY_SETEX,\n\tSTRATEGY_ZRANGE,\n\tSTRATEGY_ZREVRANGE,\n\tSTRATEGY_ZRANGEBYSCORE,\n\tSTRATEGY_ZREVRANGEBYSCORE,\n\tSTRATEGY_ZADD,\n\tSTRATEGY_ZINCRBY,\n\tSTRATEGY_REMRANGEBYRANK,\n\tSTRATEGY_REMRANGEBYSCORE,\n\tSTRATEGY_NULL\n};\n\nstatic bool inited = false;\nstatic std::map<std::string, RedisRequestDesc> cmd_table;\n\nstruct RedisCommand_raw\n{\n\tint strategy;\n\tconst char *redis_cmd;\n\tconst char *ssdb_cmd;\n\tint reply_type;\n};\n\nstatic RedisCommand_raw cmds_raw[] = {\n\t{STRATEGY_AUTO, \"auth\",\t\t\"auth\",\t\t\tREPLY_STATUS},\n\t{STRATEGY_PING, \"ping\",\t\t\"ping\",\t\t\tREPLY_STATUS},\n\n\t{STRATEGY_AUTO, \"get\",\t\t\"get\",\t\t\tREPLY_BULK},\n\t{STRATEGY_AUTO, \"getset\",\t\"getset\",\t\tREPLY_BULK},\n\t{STRATEGY_AUTO, \"set\",\t\t\"set\",\t\t\tREPLY_STATUS},\n\t{STRATEGY_AUTO, \"setnx\",\t\"setnx\",\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \"exists\",\t\"exists\",\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \"incr\",\t\t\"incr\",\t\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \"decr\",\t\t\"decr\",\t\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \"ttl\",\t\t\"ttl\",\t\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \"expire\",\t\"expire\",\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \"getbit\",\t\"getbit\",\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \"setbit\",\t\"setbit\",\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \"strlen\",\t\"strlen\",\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \"bitcount\",\t\"bitcount\",\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \"substr\",\t\"getrange\",\t\tREPLY_BULK},\n\t{STRATEGY_AUTO, \"getrange\",\t\"getrange\",\t\tREPLY_BULK},\n\t{STRATEGY_AUTO, \"keys\", \t\"keys\", \t\tREPLY_MULTI_BULK},\n\n\t{STRATEGY_AUTO, \"hset\",\t\t\"hset\",\t\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \"hget\",\t\t\"hget\",\t\t\tREPLY_BULK},\n\t{STRATEGY_AUTO, \"hexists\",\t\"hexists\",\t\tREPLY_INT},\n\n\t{STRATEGY_AUTO, \"del\",\t\t\"multi_del\",\tREPLY_INT},\n\t{STRATEGY_AUTO, \"mset\",\t\t\"multi_set\",\tREPLY_STATUS},\n\t{STRATEGY_AUTO, \"incrby\",\t\"incr\",\t\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \"decrby\",\t\"decr\",\t\t\tREPLY_INT},\n\n\t{STRATEGY_AUTO, \"hmset\",\t\"multi_hset\",\tREPLY_STATUS},\n\t{STRATEGY_AUTO, \"hdel\",\t\t\"multi_hdel\",\tREPLY_INT},\n\t{STRATEGY_AUTO, \"hmdel\",\t\"multi_hdel\",\tREPLY_INT},\n\t{STRATEGY_AUTO, \"hlen\",\t\t\"hsize\",\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \"hincrby\",\t\"hincr\",\t\tREPLY_INT},\n\n\t{STRATEGY_AUTO, \"zcard\",\t\"zsize\",\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \"zscore\",\t\"zget\",\t\t\tREPLY_BULK},\n\t{STRATEGY_AUTO, \"zrem\",\t\t\"multi_zdel\",\tREPLY_INT},\n\t{STRATEGY_AUTO, \"zrank\",\t\"zrank\",\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \"zrevrank\",\t\"zrrank\",\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \"zcount\",\t\"zcount\",\t\tREPLY_INT},\n\t{STRATEGY_REMRANGEBYRANK, \"zremrangebyrank\",\t\"zremrangebyrank\",\t\tREPLY_INT},\n\t{STRATEGY_REMRANGEBYSCORE, \"zremrangebyscore\",\t\"zremrangebyscore\",\t\tREPLY_INT},\n\t\n\t/////////////////////////////////////\n\t{STRATEGY_MGET, \"mget\",\t\t\"multi_get\",\tREPLY_MULTI_BULK},\n\t{STRATEGY_HMGET, \"hmget\",\t\"multi_hget\",\tREPLY_MULTI_BULK},\n\t\n\t{STRATEGY_HGETALL,\t\"hgetall\",\t\t\"hgetall\",\t\tREPLY_MULTI_BULK},\n\t{STRATEGY_HKEYS,\t\"hkeys\", \t\t\"hkeys\", \t\tREPLY_MULTI_BULK},\n\t{STRATEGY_HVALS,\t\"hvals\", \t\t\"hvals\", \t\tREPLY_MULTI_BULK},\n\t{STRATEGY_SETEX,\t\"setex\",\t\t\"setx\", \t\tREPLY_STATUS},\n\t{STRATEGY_ZRANGE,\t\"zrange\",\t\t\"zrange\",\t\tREPLY_MULTI_BULK},\n\t{STRATEGY_ZREVRANGE,\"zrevrange\",\t\"zrrange\",\t\tREPLY_MULTI_BULK},\n\t{STRATEGY_ZADD,\t\t\"zadd\",\t\t\t\"multi_zset\", \tREPLY_INT},\n\t{STRATEGY_ZINCRBY,\t\"zincrby\",\t\t\"zincr\", \t\tREPLY_BULK},\n\t{STRATEGY_ZRANGEBYSCORE,\t\"zrangebyscore\",\t\"zscan\",\tREPLY_MULTI_BULK},\n\t{STRATEGY_ZREVRANGEBYSCORE,\t\"zrevrangebyscore\",\t\"zrscan\",\tREPLY_MULTI_BULK},\n\n\t{STRATEGY_AUTO,\t\t\"lpush\",\t\t\"qpush_front\", \t\tREPLY_INT},\n\t{STRATEGY_AUTO,\t\t\"rpush\",\t\t\"qpush_back\", \t\tREPLY_INT},\n\t{STRATEGY_AUTO,\t\t\"lpop\",\t\t\t\"qpop_front\", \t\tREPLY_BULK},\n\t{STRATEGY_AUTO,\t\t\"rpop\",\t\t\t\"qpop_back\", \t\tREPLY_BULK},\n\t{STRATEGY_AUTO, \t\"llen\",\t\t\t\"qsize\",\t\t\tREPLY_INT},\n\t{STRATEGY_AUTO, \t\"lsize\",\t\t\"qsize\",\t\t\tREPLY_INT},\n\t{STRATEGY_AUTO,\t\t\"lindex\",\t\t\"qget\", \t\t\tREPLY_BULK},\n\t{STRATEGY_AUTO,\t\t\"lset\",\t\t    \"qset\", \t\t\tREPLY_STATUS},\n\t{STRATEGY_AUTO,\t\t\"lrange\",\t\t\"qslice\",\t\t\tREPLY_MULTI_BULK},\n\n\t{STRATEGY_AUTO, \tNULL,\t\t\tNULL,\t\t\t0}\n};\n\nint RedisLink::convert_req(){\n\tif(!inited){\n\t\tinited = true;\n\t\t\n\t\tRedisCommand_raw *def = &cmds_raw[0];\n\t\twhile(def->redis_cmd != NULL){\n\t\t\tRedisRequestDesc desc;\n\t\t\tdesc.strategy = def->strategy;\n\t\t\tdesc.redis_cmd = def->redis_cmd;\n\t\t\tdesc.ssdb_cmd = def->ssdb_cmd;\n\t\t\tdesc.reply_type = def->reply_type;\n\t\t\tcmd_table[desc.redis_cmd] = desc;\n\t\t\tdef += 1;\n\t\t}\n\t}\n\t\n\tthis->req_desc = NULL;\n\t\n\tstd::map<std::string, RedisRequestDesc>::iterator it;\n\tit = cmd_table.find(cmd);\n\tif(it == cmd_table.end()){\n\t\trecv_string.push_back(cmd);\n\t\tfor(int i=1; i<recv_bytes.size(); i++){\n\t\t\trecv_string.push_back(recv_bytes[i].String());\n\t\t}\n\t\treturn 0;\n\t}\n\tthis->req_desc = &(it->second);\n\n\tif(this->req_desc->strategy == STRATEGY_HKEYS\n\t\t\t||  this->req_desc->strategy == STRATEGY_HVALS\n\t){\n\t\trecv_string.push_back(req_desc->ssdb_cmd);\n\t\tif(recv_bytes.size() == 2){\n\t\t\trecv_string.push_back(recv_bytes[1].String());\n\t\t\trecv_string.push_back(\"\");\n\t\t\trecv_string.push_back(\"\");\n\t\t\trecv_string.push_back(\"2000000000\");\n\t\t}\n\t\treturn 0;\n\t}\n\tif(this->req_desc->strategy == STRATEGY_SETEX){\n\t\trecv_string.push_back(req_desc->ssdb_cmd);\n\t\tif(recv_bytes.size() == 4){\n\t\t\trecv_string.push_back(recv_bytes[1].String());\n\t\t\trecv_string.push_back(recv_bytes[3].String());\n\t\t\trecv_string.push_back(recv_bytes[2].String());\n\t\t}\n\t\treturn 0;\n\t}\n\tif(this->req_desc->strategy == STRATEGY_ZADD){\n\t\trecv_string.push_back(req_desc->ssdb_cmd);\n\t\tif(recv_bytes.size() >= 2){\n\t\t\trecv_string.push_back(recv_bytes[1].String());\n\t\t\tfor(int i=2; i<=recv_bytes.size()-2; i+=2){\n\t\t\t\trecv_string.push_back(recv_bytes[i+1].String());\n\t\t\t\tint64_t score = (int64_t)recv_bytes[i].Double();\n\t\t\t\trecv_string.push_back(str(score));\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n\tif(this->req_desc->strategy == STRATEGY_ZINCRBY){\n\t\trecv_string.push_back(req_desc->ssdb_cmd);\n\t\tif(recv_bytes.size() == 4){\n\t\t\trecv_string.push_back(recv_bytes[1].String());\n\t\t\trecv_string.push_back(recv_bytes[3].String());\n\t\t\trecv_string.push_back(recv_bytes[2].String());\n\t\t}\n\t\treturn 0;\n\t}\n\tif(this->req_desc->strategy == STRATEGY_REMRANGEBYRANK\n\t\t|| this->req_desc->strategy == STRATEGY_REMRANGEBYSCORE)\n\t{\n\t\trecv_string.push_back(req_desc->ssdb_cmd);\n\t\tif(recv_bytes.size() >= 4){\n\t\t\trecv_string.push_back(recv_bytes[1].String());\n\t\t\trecv_string.push_back(recv_bytes[2].String());\n\t\t\trecv_string.push_back(recv_bytes[3].String());\n\t\t}\n\t\treturn 0;\n\t}\n\tif(this->req_desc->strategy == STRATEGY_ZRANGE || this->req_desc->strategy == STRATEGY_ZREVRANGE){\n\t\tstd::string cmd = \"redis_\";\n\t\tcmd += req_desc->ssdb_cmd;\n\t\t\n\t\trecv_string.push_back(cmd);\n\t\trecv_string.push_back(recv_bytes[1].String());\n\t\tif(recv_bytes.size() >= 4){\n\t\t\trecv_string.push_back(recv_bytes[2].String());\n\t\t\trecv_string.push_back(recv_bytes[3].String());\n\t\t}\n\t\tif(recv_bytes.size() >= 5){\n\t\t\tstd::string s = recv_bytes[4].String();\n\t\t\tstrtolower(&s);\n\t\t\trecv_string.push_back(s);\n\t\t}\n\t\treturn 0;\n\t}\n\tif(this->req_desc->strategy == STRATEGY_ZRANGEBYSCORE || this->req_desc->strategy == STRATEGY_ZREVRANGEBYSCORE){\n\t\trecv_string.push_back(req_desc->ssdb_cmd);\n\t\tstd::string name, smin, smax, withscores, offset, count;\n\t\tif(recv_bytes.size() >= 4){\n\t\t\tname = recv_bytes[1].String();\n\t\t\tsmin = recv_bytes[2].String();\n\t\t\tsmax = recv_bytes[3].String();\n\t\t\t\n\t\t\tbool after_limit = false;\n\t\t\tfor(int i=4; i<recv_bytes.size(); i++){\n\t\t\t\tstd::string s = recv_bytes[i].String();\n\t\t\t\tif(after_limit){\n\t\t\t\t\tif(offset.empty()){\n\t\t\t\t\t\toffset = s;\n\t\t\t\t\t}else{\n\t\t\t\t\t\tcount = s;\n\t\t\t\t\t\tafter_limit = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstrtolower(&s);\n\t\t\t\tif(s == \"withscores\"){\n\t\t\t\t\twithscores = s;\n\t\t\t\t}else if(s == \"limit\"){\n\t\t\t\t\tafter_limit = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif(smin.empty() || smax.empty()){\n\t\t\treturn 0;\n\t\t}\n\t\t\n\t\trecv_string.push_back(name);\n\t\trecv_string.push_back(\"\");\n\t\t\n\t\tif(smin == \"-inf\" || smin == \"+inf\"){\n\t\t\trecv_string.push_back(\"\");\n\t\t}else{\n\t\t\tif(smin[0] == '('){\n\t\t\t\tstd::string tmp(smin.data() + 1, smin.size() - 1);\n\t\t\t\tchar buf[32];\n\t\t\t\tif(this->req_desc->strategy == STRATEGY_ZRANGEBYSCORE){\n\t\t\t\t\tsnprintf(buf, sizeof(buf), \"%d\", str_to_int(tmp) + 1);\n\t\t\t\t}else{\n\t\t\t\t\tsnprintf(buf, sizeof(buf), \"%d\", str_to_int(tmp) - 1);\n\t\t\t\t}\n\t\t\t\tsmin = buf;\n\t\t\t}\n\t\t\trecv_string.push_back(smin);\n\t\t}\n\t\tif(smax == \"-inf\" || smax == \"+inf\"){\n\t\t\trecv_string.push_back(\"\");\n\t\t}else{\n\t\t\tif(smax[0] == '('){\n\t\t\t\tstd::string tmp(smax.data() + 1, smax.size() - 1);\n\t\t\t\tchar buf[32];\n\t\t\t\tif(this->req_desc->strategy == STRATEGY_ZRANGEBYSCORE){\n\t\t\t\t\tsnprintf(buf, sizeof(buf), \"%d\", str_to_int(tmp) - 1);\n\t\t\t\t}else{\n\t\t\t\t\tsnprintf(buf, sizeof(buf), \"%d\", str_to_int(tmp) + 1);\n\t\t\t\t}\n\t\t\t\tsmax = buf;\n\t\t\t}\n\t\t\trecv_string.push_back(smax);\n\t\t}\n\t\tif(offset.empty()){\n\t\t\trecv_string.push_back(\"0\");\n\t\t}else{\n\t\t\trecv_string.push_back(offset);\n\t\t}\n\t\tif(count.empty()){\n\t\t\trecv_string.push_back(\"2000000000\");\n\t\t}else{\n\t\t\trecv_string.push_back(count);\n\t\t}\n\n\t\trecv_string.push_back(withscores);\n\t\treturn 0;\n\t}\n\n\trecv_string.push_back(req_desc->ssdb_cmd);\n\tfor(int i=1; i<recv_bytes.size(); i++){\n\t\trecv_string.push_back(recv_bytes[i].String());\n\t}\n\t\n\treturn 0;\n}\n\nconst std::vector<Bytes>* RedisLink::recv_req(Buffer *input){\n\tint ret = this->parse_req(input);\n\tif(ret == -1){\n\t\treturn NULL;\n\t}\n\tif(recv_bytes.empty()){\n\t\tif(input->space() == 0){\n\t\t\tinput->nice();\n\t\t\tif(input->space() == 0){\n\t\t\t\tif(input->grow() == -1){\n\t\t\t\t\t//log_error(\"fd: %d, unable to resize input buffer!\", this->sock);\n\t\t\t\t\treturn NULL;\n\t\t\t\t}\n\t\t\t\t//log_debug(\"fd: %d, resize input buffer, %s\", this->sock, input->stats().c_str());\n\t\t\t}\n\t\t}\n\t\treturn &recv_bytes;\n\t}\n\n\tcmd = recv_bytes[0].String();\n\tstrtolower(&cmd);\n\t\n\trecv_string.clear();\n\t\n\tthis->convert_req();\n\n\t// Bytes don't hold memory, so we firstly copy Bytes into string and store\n\t// in a vector of string, then create Bytes-es prointing to strings\n\trecv_bytes.clear();\n\tfor(int i=0; i<recv_string.size(); i++){\n\t\tstd::string *str = &recv_string[i];\n\t\trecv_bytes.push_back(Bytes(str->data(), str->size()));\n\t}\n\t\n\treturn &recv_bytes;\n}\n\nint RedisLink::send_resp(Buffer *output, const std::vector<std::string> &resp){\n\tif(resp.empty()){\n\t\treturn 0;\n\t}\n\tif(resp[0] != \"ok\"){\n\t\tif(resp[0] == \"error\" || resp[0] == \"fail\" || resp[0] == \"client_error\"){\n\t\t\toutput->append(\"-ERR \");\n\t\t\tif(resp.size() >= 2){\n\t\t\t\toutput->append(resp[1]);\n\t\t\t}\n\t\t\toutput->append(\"\\r\\n\");\n\t\t}else if(resp[0] == \"not_found\"){\n\t\t\toutput->append(\"$-1\\r\\n\");\n\t\t}else if(resp[0] == \"noauth\"){\n\t\t\toutput->append(\"-NOAUTH \");\n\t\t\tif(resp.size() >= 2){\n\t\t\t\toutput->append(resp[1]);\n\t\t\t}\n\t\t\toutput->append(\"\\r\\n\");\n\t\t}else{\n\t\t\toutput->append(\"-ERR server error\\r\\n\");\n\t\t}\n\t\treturn 0;\n\t}\n\t\n\t// not supported command\n\tif(req_desc == NULL){\n\t\t{\n\t\t\tchar buf[32];\n\t\t\tsnprintf(buf, sizeof(buf), \"*%d\\r\\n\", (int)resp.size() - 1);\n\t\t\toutput->append(buf);\n\t\t}\n\t\tfor(int i=1; i<resp.size(); i++){\n\t\t\tconst std::string &val = resp[i];\n\t\t\tchar buf[32];\n\t\t\tsnprintf(buf, sizeof(buf), \"$%d\\r\\n\", (int)val.size());\n\t\t\toutput->append(buf);\n\t\t\toutput->append(val.data(), val.size());\n\t\t\toutput->append(\"\\r\\n\");\n\t\t}\n\t\treturn 0;\n\t}\n\t\n\tif(req_desc->strategy == STRATEGY_PING){\n\t\toutput->append(\"+PONG\\r\\n\");\n\t\treturn 0;\n\t}\n\tif(req_desc->reply_type == REPLY_STATUS){\n\t\toutput->append(\"+OK\\r\\n\");\n\t\treturn 0;\n\t}\n\tif(req_desc->reply_type == REPLY_BULK){\n\t\tif(resp.size() >= 2){\n\t\t\tconst std::string &val = resp[1];\n\t\t\tchar buf[32];\n\t\t\tsnprintf(buf, sizeof(buf), \"$%d\\r\\n\", (int)val.size());\n\t\t\toutput->append(buf);\n\t\t\toutput->append(val.data(), val.size());\n\t\t\toutput->append(\"\\r\\n\");\n\t\t}else{\n\t\t\toutput->append(\"$0\\r\\n\");\n\t\t}\n\t\treturn 0;\n\t}\n\tif(req_desc->reply_type == REPLY_INT){\n\t\tif(resp.size() >= 2){\n\t\t\tconst std::string &val = resp[1];\n\t\t\toutput->append(\":\");\n\t\t\toutput->append(val.data(), val.size());\n\t\t\toutput->append(\"\\r\\n\");\n\t\t}else{\n\t\t\toutput->append(\"$0\\r\\n\");\n\t\t}\n\t\treturn 0;\n\t}\n\tif(req_desc->strategy == STRATEGY_MGET || req_desc->strategy == STRATEGY_HMGET){\n\t\tif(resp.size() % 2 != 1){\n\t\t\toutput->append(\"*0\");\n\t\t\t//log_error(\"bad response for multi_(h)get\");\n\t\t\treturn 0;\n\t\t}\n\t\tchar buf[32];\n\t\tstd::vector<std::string>::const_iterator req_it, resp_it;\n\t\tif(req_desc->strategy == STRATEGY_MGET){\n\t\t\treq_it = recv_string.begin() + 1;\n\t\t\tsnprintf(buf, sizeof(buf), \"*%d\\r\\n\", (int)recv_string.size() - 1);\n\t\t}else{\n\t\t\treq_it = recv_string.begin() + 2;\n\t\t\tsnprintf(buf, sizeof(buf), \"*%d\\r\\n\", (int)recv_string.size() - 2);\n\t\t}\n\t\toutput->append(buf);\n\t\t\n\t\tresp_it = resp.begin() + 1;\n\n\t\twhile(req_it != recv_string.end()){\n\t\t\tconst std::string &req_key = *req_it;\n\t\t\treq_it ++;\n\t\t\tif(resp_it == resp.end()){\n\t\t\t\toutput->append(\"$-1\\r\\n\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst std::string &resp_key = *resp_it;\n\t\t\t//log_debug(\"%s %s\", req_key.c_str(), resp_key.c_str());\n\t\t\tif(req_key != resp_key){\n\t\t\t\toutput->append(\"$-1\\r\\n\");\n\t\t\t\t// loop until we find value to the requested key\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t\t\n\t\t\tconst std::string &val = *(resp_it + 1);\n\t\t\tchar buf[32];\n\t\t\tsnprintf(buf, sizeof(buf), \"$%d\\r\\n\", (int)val.size());\n\t\t\toutput->append(buf);\n\t\t\toutput->append(val.data(), val.size());\n\t\t\toutput->append(\"\\r\\n\");\n\t\t\t\t\n\t\t\tresp_it += 2;\n\t\t}\n\n\t\treturn 0;\n\t}\n\t\n\tif(req_desc->reply_type == REPLY_MULTI_BULK){\n\t\tbool withscores = true;\n\t\tif(req_desc->strategy == STRATEGY_ZRANGE || req_desc->strategy == STRATEGY_ZREVRANGE){\n\t\t\tif(recv_string.size() < 5 || recv_string[4] != \"withscores\"){\n\t\t\t\twithscores = false;\n\t\t\t}\n\t\t}\n\t\tif(req_desc->strategy == STRATEGY_ZRANGEBYSCORE || req_desc->strategy == STRATEGY_ZREVRANGEBYSCORE){\n\t\t\tif(recv_string[recv_string.size() - 1] != \"withscores\"){\n\t\t\t\twithscores = false;\n\t\t\t}\n\t\t}\n\t\t{\n\t\t\tchar buf[32];\n\t\t\tif(withscores){\n\t\t\t\tsnprintf(buf, sizeof(buf), \"*%d\\r\\n\", (int)resp.size() - 1);\n\t\t\t}else{\n\t\t\t\tsnprintf(buf, sizeof(buf), \"*%d\\r\\n\", ((int)resp.size() - 1)/2);\n\t\t\t}\n\t\t\toutput->append(buf);\n\t\t}\n\t\tfor(int i=1; i<resp.size(); i++){\n\t\t\tconst std::string &val = resp[i];\n\t\t\tchar buf[32];\n\t\t\tsnprintf(buf, sizeof(buf), \"$%d\\r\\n\", (int)val.size());\n\t\t\toutput->append(buf);\n\t\t\toutput->append(val.data(), val.size());\n\t\t\toutput->append(\"\\r\\n\");\n\t\t\tif(!withscores){\n\t\t\t\ti += 1;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n\t\n\toutput->append(\"-ERR server error\\r\\n\");\n\treturn 0;\n}\n\nint RedisLink::parse_req(Buffer *input){\n\trecv_bytes.clear();\n\n\tint parsed = 0;\n\tint size = input->size();\n\tchar *ptr = input->data();\n\t\n\t// ignore leading empty lines\n\twhile(size > 0 && (ptr[0] == '\\n' || ptr[0] == '\\r')){\n\t\tptr ++;\n\t\tsize --;\n\t\tparsed ++;\n\t}\n\t//dump(ptr, size);\n\t\n\tif(ptr[0] != '*'){\n\t\treturn -1;\n\t}\n\n\tint num_args = 0;\t\n\twhile(size > 0){\n\t\tchar *lf = (char *)memchr(ptr, '\\n', size);\n\t\tif(lf == NULL){\n\t\t\tbreak;\n\t\t}\n\t\tlf += 1;\n\t\tsize -= (lf - ptr);\n\t\tparsed += (lf - ptr);\n\t\t\n\t\tint len = (int)strtol(ptr + 1, NULL, 10); // ptr + 1: skip '$' or '*'\n\t\tif(errno == EINVAL){\n\t\t\treturn -1;\n\t\t}\n\t\tptr = lf;\n\t\tif(len < 0){\n\t\t\treturn -1;\n\t\t}\n\t\tif(num_args == 0){\n\t\t\tif(len <= 0){\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tnum_args = len;\n\t\t\tcontinue;\n\t\t}\n\t\t\n\t\tif(len > size - 1){\n\t\t\tbreak;\n\t\t}\n\t\t\n\t\trecv_bytes.push_back(Bytes(ptr, len));\n\t\t\n\t\tptr += len + 1;\n\t\tsize -= len + 1;\n\t\tparsed += len + 1;\n\t\t// compatiabl with both CRLF and LF\n\t\tif(size > 0 && *ptr == '\\n'){\n\t\t\tptr += 1;\n\t\t\tsize -= 1;\n\t\t\tparsed += 1;\n\t\t}\n\n\t\tnum_args --;\n\t\tif(num_args == 0){\n\t\t\tinput->decr(parsed);\n\t\t\treturn 1;\n\t\t}\n\t}\n\t\n\trecv_bytes.clear();\n\treturn 0;\n}\n"
  },
  {
    "path": "src/net/link_redis.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef NET_REDIS_LINK_H_\n#define NET_REDIS_LINK_H_\n\n#include <vector>\n#include <string>\n#include \"../util/bytes.h\"\n\nstruct RedisRequestDesc\n{\n\tint strategy;\n\tstd::string redis_cmd;\n\tstd::string ssdb_cmd;\n\tint reply_type;\n};\n\nclass RedisLink\n{\nprivate:\n\tstd::string cmd;\n\tRedisRequestDesc *req_desc;\n\n\tstd::vector<Bytes> recv_bytes;\n\tstd::vector<std::string> recv_string;\n\tint parse_req(Buffer *input);\n\tint convert_req();\n\t\npublic:\n\tRedisLink(){\n\t\treq_desc = NULL;\n\t}\n\t\n\tconst std::vector<Bytes>* recv_req(Buffer *input);\n\tint send_resp(Buffer *output, const std::vector<std::string> &resp);\n};\n\n#endif\n"
  },
  {
    "path": "src/net/proc.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"proc.h\"\n#include \"server.h\"\n#include \"../util/log.h\"\n\nProcMap::ProcMap(){\n}\n\nProcMap::~ProcMap(){\n\tproc_map_t::iterator it;\n\tfor(it=proc_map.begin(); it!=proc_map.end(); it++){\n\t\tdelete it->second;\n\t}\n\tproc_map.clear();\n}\n\nvoid ProcMap::set_proc(const std::string &c, proc_t proc){\n\tthis->set_proc(c, \"t\", proc);\n}\n\nvoid ProcMap::set_proc(const std::string &c, const char *sflags, proc_t proc){\n\tCommand *cmd = this->get_proc(c);\n\tif(!cmd){\n\t\tcmd = new Command();\n\t\tcmd->name = c;\n\t\tproc_map[cmd->name] = cmd;\n\t}\n\tcmd->proc = proc;\n\tcmd->flags = 0;\n\tfor(const char *p=sflags; *p!='\\0'; p++){\n\t\tswitch(*p){\n\t\t\tcase 'r':\n\t\t\t\tcmd->flags |= Command::FLAG_READ;\n\t\t\t\tbreak;\n\t\t\tcase 'w': // w 必须和 t 同时出现, 因为某些写操作依赖单线程\n\t\t\t\tcmd->flags |= Command::FLAG_WRITE;\n\t\t\t\tcmd->flags |= Command::FLAG_THREAD;\n\t\t\t\tbreak;\n\t\t\tcase 'b':\n\t\t\t\tcmd->flags |= Command::FLAG_BACKEND;\n\t\t\t\tbreak;\n\t\t\tcase 't':\n\t\t\t\tcmd->flags |= Command::FLAG_THREAD;\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\nCommand* ProcMap::get_proc(const Bytes &str){\n\tproc_map_t::iterator it = proc_map.find(str);\n\tif(it != proc_map.end()){\n\t\treturn it->second;\n\t}\n\treturn NULL;\n}\n"
  },
  {
    "path": "src/net/proc.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef NET_PROC_H_\n#define NET_PROC_H_\n\n#include <vector>\n#include \"resp.h\"\n#include \"../util/bytes.h\"\n\nclass Link;\nclass NetworkServer;\n\n#define PROC_OK\t\t\t0\n#define PROC_ERROR\t\t-1\n#define PROC_THREAD     1\n#define PROC_BACKEND\t100\n\n#define DEF_PROC(f) int proc_##f(NetworkServer *net, Link *link, const Request &req, Response *resp)\n\ntypedef std::vector<Bytes> Request;\ntypedef int (*proc_t)(NetworkServer *net, Link *link, const Request &req, Response *resp);\n\nstruct Command{\n\tstatic const int FLAG_READ\t\t= (1 << 0);\n\tstatic const int FLAG_WRITE\t\t= (1 << 1);\n\tstatic const int FLAG_BACKEND\t= (1 << 2);\n\tstatic const int FLAG_THREAD\t= (1 << 3);\n\n\tstd::string name;\n\tint flags;\n\tproc_t proc;\n\tuint64_t calls;\n\tdouble time_wait;\n\tdouble time_proc;\n\t\n\tCommand(){\n\t\tflags = 0;\n\t\tproc = NULL;\n\t\tcalls = 0;\n\t\ttime_wait = 0;\n\t\ttime_proc = 0;\n\t}\n};\n\nstruct ProcJob{\n\tint result;\n\tNetworkServer *serv;\n\tLink *link;\n\tCommand *cmd;\n\tdouble stime;     // in seconds\n\tdouble time_wait; // in ms\n\tdouble time_proc; // in ms\n\t\n\tconst Request *req;\n\tResponse resp;\n\t\n\tProcJob(){\n\t\tresult = 0;\n\t\tserv = NULL;\n\t\tlink = NULL;\n\t\tcmd = NULL;\n\t\tstime = 0;\n\t\ttime_wait = 0;\n\t\ttime_proc = 0;\n\t}\n\t~ProcJob(){\n\t}\n};\n\n\nstruct BytesEqual{\n\tbool operator()(const Bytes &s1, const Bytes &s2) const {\n\t\treturn (bool)(s1.compare(s2) == 0);\n\t}\n};\nstruct BytesHash{\n\tsize_t operator()(const Bytes &s1) const {\n\t\tunsigned long __h = 0;\n\t\tconst char *p = s1.data();\n\t\tfor (int i=0 ; i<s1.size(); i++)\n\t\t\t__h = 5*__h + p[i];\n\t\treturn size_t(__h);\n\t}\n};\n\n\n#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)\n#if GCC_VERSION >= 403\n\t#include <tr1/unordered_map>\n\ttypedef std::tr1::unordered_map<Bytes, Command *, BytesHash, BytesEqual> proc_map_t;\n#else\n\t#ifdef NEW_MAC\n\t\t#include <unordered_map>\n\t\ttypedef std::unordered_map<Bytes, Command *, BytesHash, BytesEqual> proc_map_t;\n\t#else\n\t\t#include <ext/hash_map>\n\t\ttypedef __gnu_cxx::hash_map<Bytes, Command *, BytesHash, BytesEqual> proc_map_t;\n\t#endif\n#endif\n\n\nclass ProcMap\n{\nprivate:\n\tproc_map_t proc_map;\n\npublic:\n\tProcMap();\n\t~ProcMap();\n\tvoid set_proc(const std::string &cmd, const char *sflags, proc_t proc);\n\tvoid set_proc(const std::string &cmd, proc_t proc);\n\tCommand* get_proc(const Bytes &str);\n\t\n\tproc_map_t::iterator begin(){\n\t\treturn proc_map.begin();\n\t}\n\tproc_map_t::iterator end(){\n\t\treturn proc_map.end();\n\t}\n};\n\n\n\n#include \"../util/string_util.h\"\n\ntemplate<class T>\nstatic std::string serialize_req(T &req){\n\tstd::string ret;\n\tret.reserve(1024);\n\tchar buf[50];\n\tfor(int i=0; i<req.size(); i++){\n\t\tif(i >= 5 && i < req.size() - 1){\n\t\t\tsprintf(buf, \"[%d more...]\", (int)req.size() - i);\n\t\t\tret.append(buf);\n\t\t\tbreak;\n\t\t}\n\t\tif(req[i].size() < 50){\n\t\t\tif(req[i].size() == 0){\n\t\t\t\tret.append(\"\\\"\\\"\");\n\t\t\t}else{\n\t\t\t\tstr_escape(req[i].data(), req[i].size(), &ret);\n\t\t\t}\n\t\t}else{\n\t\t\tsprintf(buf, \"[%d]\", (int)req[i].size());\n\t\t\tret.append(buf);\n\t\t}\n\t\tif(i < req.size() - 1){\n\t\t\tret.append(\" \");\n\t\t}\n\t}\n\treturn ret;\n}\n\n#endif\n"
  },
  {
    "path": "src/net/resp.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"resp.h\"\n#include <stdio.h>\n\nint Response::size() const{\n\treturn (int)resp.size();\n}\n\nvoid Response::push_back(const std::string &s){\n\tresp.push_back(s);\n}\n\nvoid Response::add(int s){\n\tadd((int64_t)s);\n}\n\nvoid Response::add(int64_t s){\n\tchar buf[20];\n\tsprintf(buf, \"%\" PRId64 \"\", s);\n\tresp.push_back(buf);\n}\n\nvoid Response::add(uint64_t s){\n\tchar buf[20];\n\tsprintf(buf, \"%\" PRIu64 \"\", s);\n\tresp.push_back(buf);\n}\n\nvoid Response::add(double s){\n\tchar buf[30];\n\tsnprintf(buf, sizeof(buf), \"%f\", s);\n\tresp.push_back(buf);\n}\n\nvoid Response::add(const std::string &s){\n\tresp.push_back(s);\n}\n\nvoid Response::reply_status(int status, const char *errmsg){\n\tif(status == -1){\n\t\tresp.push_back(\"error\");\n\t\tif(errmsg){\n\t\t\tresp.push_back(errmsg);\n\t\t}\n\t}else{\n\t\tresp.push_back(\"ok\");\n\t}\n}\n\nvoid Response::reply_bool(int status, const char *errmsg){\n\tif(status == -1){\n\t\tresp.push_back(\"error\");\n\t\tif(errmsg){\n\t\t\tresp.push_back(errmsg);\n\t\t}\n\t}else if(status == 0){\n\t\tresp.push_back(\"ok\");\n\t\tresp.push_back(\"0\");\n\t}else{\n\t\tresp.push_back(\"ok\");\n\t\tresp.push_back(\"1\");\n\t}\n}\n\nvoid Response::reply_int(int status, int64_t val){\n\tif(status == -1){\n\t\tresp.push_back(\"error\");\n\t}else{\n\t\tresp.push_back(\"ok\");\n\t\tthis->add(val);\n\t}\n}\n\nvoid Response::reply_get(int status, const std::string *val, const char *errmsg){\n\tif(status == -1){\n\t\tresp.push_back(\"error\");\n\t}else if(status == 0){\n\t\tresp.push_back(\"not_found\");\n\t}else{\n\t\tresp.push_back(\"ok\");\n\t\tif(val){\n\t\t\tresp.push_back(*val);\n\t\t}\n\t\treturn;\n\t}\n\tif(errmsg){\n\t\tresp.push_back(errmsg);\n\t}\n} \n\nvoid Response::reply_list(int status, const std::vector<std::string> &list){\n\tif(status == -1){\n\t\tresp.push_back(\"error\");\n\t}else{\n\t\tresp.push_back(\"ok\");\n\t\tfor(int i=0; i<list.size(); i++){\n\t\t\tresp.push_back(list[i]);\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "src/net/resp.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef NET_RESP_H_\n#define NET_RESP_H_\n\n#include <unistd.h>\n#include <inttypes.h>\n#include <string>\n#include <vector>\n\nclass Response\n{\npublic:\n\tstd::vector<std::string> resp;\n\n\tint size() const;\n\tvoid push_back(const std::string &s);\n\tvoid add(int s);\n\tvoid add(int64_t s);\n\tvoid add(uint64_t s);\n\tvoid add(double s);\n\tvoid add(const std::string &s);\n\n\tvoid reply_status(int status, const char *errmsg=NULL);\n\tvoid reply_bool(int status, const char *errmsg=NULL);\n\tvoid reply_int(int status, int64_t val);\n\t// the same as Redis.REPLY_BULK\n\tvoid reply_get(int status, const std::string *val=NULL, const char *errmsg=NULL);\n\tvoid reply_list(int status, const std::vector<std::string> &list);\n};\n\n#endif\n"
  },
  {
    "path": "src/net/server.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"server.h\"\n#include \"../util/string_util.h\"\n#include \"../util/file.h\"\n#include \"../util/config.h\"\n#include \"../util/log.h\"\n#include \"../util/ip_filter.h\"\n#include \"link.h\"\n#include <vector>\n\nstatic DEF_PROC(ping);\nstatic DEF_PROC(info);\nstatic DEF_PROC(auth);\nstatic DEF_PROC(list_allow_ip);\nstatic DEF_PROC(add_allow_ip);\nstatic DEF_PROC(del_allow_ip);\nstatic DEF_PROC(list_deny_ip);\nstatic DEF_PROC(add_deny_ip);\nstatic DEF_PROC(del_deny_ip);\n\n#define TICK_INTERVAL          100 // ms\n#define STATUS_REPORT_TICKS    (300 * 1000/TICK_INTERVAL) // second\nstatic const int READER_THREADS = 10;\nstatic const int WRITER_THREADS = 1;  // 必须为1, 因为某些写操作依赖单线程\n\nvolatile bool quit = false;\nvolatile uint32_t g_ticks = 0;\n\nvoid signal_handler(int sig){\n\tswitch(sig){\n\t\tcase SIGTERM:\n\t\tcase SIGINT:{\n\t\t\tquit = true;\n\t\t\tbreak;\n\t\t}\n\t\tcase SIGALRM:{\n\t\t\tg_ticks ++;\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nNetworkServer::NetworkServer(){\n\tnum_readers = READER_THREADS;\n\tnum_writers = WRITER_THREADS;\n\t\n\ttick_interval = TICK_INTERVAL;\n\tstatus_report_ticks = STATUS_REPORT_TICKS;\n\n\t//conf = NULL;\n\tserv_link = NULL;\n\tlink_count = 0;\n\n\tfdes = new Fdevents();\n\tip_filter = new IpFilter();\n\t\n\treadonly = false;\n\tslowlog_timeout = 0;\n\n\t// add built-in procs, can be overridden\n\tproc_map.set_proc(\"ping\", \"r\", proc_ping);\n\tproc_map.set_proc(\"info\", \"r\", proc_info);\n\tproc_map.set_proc(\"auth\", \"r\", proc_auth);\n\tproc_map.set_proc(\"list_allow_ip\", \"r\", proc_list_allow_ip);\n\tproc_map.set_proc(\"add_allow_ip\",  \"r\", proc_add_allow_ip);\n\tproc_map.set_proc(\"del_allow_ip\",  \"r\", proc_del_allow_ip);\n\tproc_map.set_proc(\"list_deny_ip\",  \"r\", proc_list_deny_ip);\n\tproc_map.set_proc(\"add_deny_ip\",   \"r\", proc_add_deny_ip);\n\tproc_map.set_proc(\"del_deny_ip\",   \"r\", proc_del_deny_ip);\n\n\tsignal(SIGPIPE, SIG_IGN);\n\tsignal(SIGINT, signal_handler);\n\tsignal(SIGTERM, signal_handler);\n#ifndef __CYGWIN__\n\tsignal(SIGALRM, signal_handler);\n\t{\n\t\tstruct itimerval tv;\n\t\ttv.it_interval.tv_sec = (TICK_INTERVAL / 1000);\n\t\ttv.it_interval.tv_usec = (TICK_INTERVAL % 1000) * 1000;\n\t\ttv.it_value.tv_sec = 1;\n\t\ttv.it_value.tv_usec = 0;\n\t\tsetitimer(ITIMER_REAL, &tv, NULL);\n\t}\n#endif\n}\n\t\nNetworkServer::~NetworkServer(){\n\t//delete conf;\n\tdelete serv_link;\n\tdelete fdes;\n\tdelete ip_filter;\n\n\twriter->stop();\n\tdelete writer;\n\treader->stop();\n\tdelete reader;\n}\n\nNetworkServer* NetworkServer::init(const char *conf_file, int num_readers, int num_writers){\n\tif(!is_file(conf_file)){\n\t\tfprintf(stderr, \"'%s' is not a file or not exists!\\n\", conf_file);\n\t\texit(1);\n\t}\n\n\tConfig *conf = Config::load(conf_file);\n\tif(!conf){\n\t\tfprintf(stderr, \"error loading conf file: '%s'\\n\", conf_file);\n\t\texit(1);\n\t}\n\t{\n\t\tstd::string conf_dir = real_dirname(conf_file);\n\t\tif(chdir(conf_dir.c_str()) == -1){\n\t\t\tfprintf(stderr, \"error chdir: %s\\n\", conf_dir.c_str());\n\t\t\texit(1);\n\t\t}\n\t}\n\tNetworkServer* serv = init(*conf, num_readers, num_writers);\n\tdelete conf;\n\treturn serv;\n}\n\nNetworkServer* NetworkServer::init(const Config &conf, int num_readers, int num_writers){\n\tstatic bool inited = false;\n\tif(inited){\n\t\treturn NULL;\n\t}\n\tinited = true;\n\t\n\tNetworkServer *serv = new NetworkServer();\n\tif(num_readers >= 0){\n\t\tserv->num_readers = num_readers;\n\t}\n\tif(num_writers >= 0){\n\t\tserv->num_writers = num_writers;\n\t}\n\t\n\t{ // server\n\t\tconst char *ip = conf.get_str(\"server.ip\");\n\t\tint port = conf.get_num(\"server.port\");\n\t\tif(ip == NULL || ip[0] == '\\0'){\n\t\t\tip = \"127.0.0.1\";\n\t\t}\n\t\t\n\t\tserv->serv_link = Link::listen(ip, port);\n\t\tif(serv->serv_link == NULL){\n\t\t\tlog_fatal(\"error opening server socket! %s\", strerror(errno));\n\t\t\tfprintf(stderr, \"error opening server socket! %s\\n\", strerror(errno));\n\t\t\texit(1);\n\t\t}\n\t\t// see UNP\n\t\t// if client send RST between server's calls of select() and accept(),\n\t\t// accept() will block until next connection.\n\t\t// so, set server socket nonblock.\n\t\tserv->serv_link->noblock();\n\t\tlog_info(\"server listen on %s:%d\", ip, port);\n\n    \t// init auth\n    \t{\n    \t\tConfig *cc = (Config *)conf.get(\"server\");\n    \t\tif(cc != NULL){\n    \t\t\tstd::vector<Config *> *children = &cc->children;\n    \t\t\tstd::vector<Config *>::iterator it;\n    \t\t\tfor(it = children->begin(); it != children->end(); it++){\n    \t\t\t\tif((*it)->key == \"auth\"){\n                \t\tstd::string password = (*it)->str();\n                \t\tif(password.size() && (password.size() < 32 || password == \"very-strong-password\")){\n                \t\t\tlog_fatal(\"weak password is not allowed!\");\n                \t\t\tfprintf(stderr, \"WARNING! Weak password is not allowed!\\n\");\n                \t\t\texit(1);\n                \t\t}\n                        serv->passwords.insert(password);\n                    }\n                }\n            }\n    \t\tif(serv->passwords.empty()){\n    \t\t\tserv->need_auth = false;\n    \t\t\tlog_info(\"    auth    : off\");\n    \t\t}else{\n    \t\t\tserv->need_auth = true;\n    \t\t\tlog_info(\"    auth    : on\");\n    \t\t}\n        }\n\t}\n\n\t// init ip_filter\n\t{\n\t\tConfig *cc = (Config *)conf.get(\"server\");\n\t\tif(cc != NULL){\n\t\t\tstd::vector<Config *> *children = &cc->children;\n\t\t\tstd::vector<Config *>::iterator it;\n\t\t\tfor(it = children->begin(); it != children->end(); it++){\n\t\t\t\tif((*it)->key == \"allow\"){\n\t\t\t\t\tconst char *ip = (*it)->str();\n\t\t\t\t\tlog_info(\"    allow   : %s\", ip);\n\t\t\t\t\tserv->ip_filter->add_allow(ip);\n\t\t\t\t}\n\t\t\t\tif((*it)->key == \"deny\"){\n\t\t\t\t\tconst char *ip = (*it)->str();\n\t\t\t\t\tlog_info(\"    deny    : %s\", ip);\n\t\t\t\t\tserv->ip_filter->add_deny(ip);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\tstd::string readonly = conf.get_str(\"server.readonly\");\n\tstrtolower(&readonly);\n\tif(readonly == \"yes\"){\n\t\tserv->readonly = true;\n\t}else{\n\t\treadonly = \"no\";\n\t\tserv->readonly = false;\n\t}\n\tlog_info(\"    readonly: %s\", readonly.c_str());\n\t\n\t// slowlog_timeout\n\t{\n\t\tstd::string t = conf.get_str(\"server.slowlog_timeout\");\n\t\tif(t.length() > 0){\n\t\t\tdouble timeout = str_to_double(t.c_str(), t.length());\n\t\t\tif(timeout > 0){\n\t\t\t\tserv->slowlog_timeout = timeout;\n\t\t\t\tlog_info(\"    slowlog_timeout: %.3f ms\", serv->slowlog_timeout);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn serv;\n}\n\nvoid NetworkServer::serve(){\n\twriter = new ProcWorkerPool(\"writer\");\n\twriter->start(num_writers);\n\treader = new ProcWorkerPool(\"reader\");\n\treader->start(num_readers);\n\n\tready_list_t ready_list;\n\tready_list_t ready_list_2;\n\tready_list_t::iterator it;\n\tconst Fdevents::events_t *events;\n\n\tfdes->set(serv_link->fd(), FDEVENT_IN, 0, serv_link);\n\tfdes->set(this->reader->fd(), FDEVENT_IN, 0, this->reader);\n\tfdes->set(this->writer->fd(), FDEVENT_IN, 0, this->writer);\n\t\n\tuint32_t last_ticks = g_ticks;\n\t\n\twhile(!quit){\n\t\tdouble loop_stime = microtime();\n\n\t\t// status report\n\t\tif((uint32_t)(g_ticks - last_ticks) >= STATUS_REPORT_TICKS){\n\t\t\tlast_ticks = g_ticks;\n\t\t\tlog_info(\"server running, links: %d\", this->link_count);\n\t\t}\n\t\t\n\t\tready_list.swap(ready_list_2);\n\t\tready_list_2.clear();\n\t\t\n\t\tif(!ready_list.empty()){\n\t\t\t// ready_list not empty, so we should return immediately\n\t\t\tevents = fdes->wait(0);\n\t\t}else{\n\t\t\tevents = fdes->wait(50);\n\t\t}\n\t\tif(events == NULL){\n\t\t\tlog_fatal(\"events.wait error: %s\", strerror(errno));\n\t\t\tbreak;\n\t\t}\n\n\t\tdouble loop_time_0 = microtime() - loop_stime;\n\t\t\n\t\tfor(int i=0; i<(int)events->size(); i++){\n\t\t\tconst Fdevent *fde = events->at(i);\n\t\t\tif(fde->data.ptr == serv_link){\n\t\t\t\tLink *link = accept_link();\n\t\t\t\tif(link){\n\t\t\t\t\tthis->link_count ++;\t\t\t\t\n\t\t\t\t\tlog_debug(\"new link from %s:%d, fd: %d, links: %d\",\n\t\t\t\t\t\tlink->remote_ip, link->remote_port, link->fd(), this->link_count);\n\t\t\t\t\tfdes->set(link->fd(), FDEVENT_IN, 1, link);\n\t\t\t\t}else{\n\t\t\t\t\tlog_debug(\"accept return NULL\");\n\t\t\t\t}\n\t\t\t}else if(fde->data.ptr == this->reader || fde->data.ptr == this->writer){\n\t\t\t\tProcWorkerPool *worker = (ProcWorkerPool *)fde->data.ptr;\n\t\t\t\tProcJob *job = NULL;\n\t\t\t\tif(worker->pop(&job) == 0){\n\t\t\t\t\tlog_fatal(\"reading result from workers error!\");\n\t\t\t\t\texit(0);\n\t\t\t\t}\n\t\t\t\tproc_result(job, &ready_list);\n\t\t\t}else{\n\t\t\t\tproc_client_event(fde, &ready_list);\n\t\t\t}\n\t\t}\n\n\t\tdouble loop_time_1 = microtime() - loop_stime;\n\n\t\tfor(it = ready_list.begin(); it != ready_list.end(); it ++){\n\t\t\tLink *link = *it;\n\t\t\tfdes->del(link->fd());\n\n\t\t\tif(link->error()){\n\t\t\t\tthis->link_count --;\n\t\t\t\tdelete link;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst Request *req = link->recv();\n\t\t\tif(req == NULL){\n\t\t\t\tlog_warn(\"fd: %d, link parse error, delete link\", link->fd());\n\t\t\t\tlink->mark_error();\n\t\t\t\tready_list_2.push_back(link);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif(req->empty()){\n\t\t\t\tfdes->set(link->fd(), FDEVENT_IN, 1, link);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t\n\t\t\tlink->active_time = microtime();\n\n\t\t\tProcJob *job = new ProcJob();\n\t\t\tjob->link = link;\n\t\t\tjob->req = link->last_recv();\n\t\t\tint result = this->proc(job);\n\t\t\tif(result == PROC_THREAD){\n\t\t\t\t//\n\t\t\t}else if(result == PROC_BACKEND){\n\t\t\t\t// link_count does not include backend links\n\t\t\t\tthis->link_count --;\n\t\t\t}else{\n\t\t\t\tproc_result(job, &ready_list_2);\n\t\t\t}\n\t\t} // end foreach ready link\n\n\t\tdouble loop_time = microtime() - loop_stime;\n\t\tif(loop_time > 0.5){\n\t\t\tlog_warn(\"long loop time: %.3f %.3f %.3f\", loop_time_0, loop_time_1, loop_time);\n\t\t}\n\t}\n}\n\nLink* NetworkServer::accept_link(){\n\tLink *link = serv_link->accept();\n\tif(link == NULL){\n\t\tlog_error(\"accept failed! %s\", strerror(errno));\n\t\treturn NULL;\n\t}\n\tif(!ip_filter->check_pass(link->remote_ip)){\n\t\tlog_debug(\"ip_filter deny link from %s:%d\", link->remote_ip, link->remote_port);\n\t\tdelete link;\n\t\treturn NULL;\n\t}\n\t\t\t\t\n\tlink->nodelay();\n\tlink->noblock();\n\tlink->create_time = microtime();\n\tlink->active_time = link->create_time;\n\treturn link;\n}\n\nint NetworkServer::proc_result(ProcJob *job, ready_list_t *ready_list){\n\tLink *link = job->link;\n\tint result = job->result;\n\n\tif(log_level() >= Logger::LEVEL_DEBUG){ // serialize_req is expensive\n\t\tif(this->slowlog_timeout > 0 && job->time_wait + job->time_proc >= this->slowlog_timeout){\n\t\t\tlog_warn(\"slowlog w:%.3f,p:%.3f, req: %s, resp: %s\",\n\t\t\t\tjob->time_wait, job->time_proc,\n\t\t\t\tserialize_req(*job->req).c_str(),\n\t\t\t\tserialize_req(job->resp.resp).c_str());\n\t\t}else{\n\t\t\tlog_debug(\"w:%.3f,p:%.3f, req: %s, resp: %s\",\n\t\t\t\tjob->time_wait, job->time_proc,\n\t\t\t\tserialize_req(*job->req).c_str(),\n\t\t\t\tserialize_req(job->resp.resp).c_str());\n\t\t}\n\t}\n\tif(job->cmd){\n\t\tjob->cmd->calls += 1;\n\t\tjob->cmd->time_wait += job->time_wait;\n\t\tjob->cmd->time_proc += job->time_proc;\n\t}\n\tdelete job;\n\t\n\tif(result == PROC_ERROR){\n\t\tlink->mark_error();\n\t\tready_list->push_back(link);\n\t}else{\n\t\tif(link->output->empty()){\n\t\t\tfdes->clr(link->fd(), FDEVENT_OUT);\n\t\t\tif(link->input->empty()){\n\t\t\t\tfdes->set(link->fd(), FDEVENT_IN, 1, link);\n\t\t\t}else{\n\t\t\t\tready_list->push_back(link);\n\t\t\t}\n\t\t}else{\n\t\t\tfdes->clr(link->fd(), FDEVENT_IN);\n\t\t\tfdes->set(link->fd(), FDEVENT_OUT, 1, link);\n\t\t}\n\t}\n\treturn result;\n}\n\n/*\nevent:\n\tread => ready_list OR close\n\twrite => ready_list\nproc_result =>\n\tdone: write & (read OR ready_list)\n\tasync: stop (read & write)\n\t\n1. When writing to a link, it may happen to be in the ready_list,\nso we cannot close that link in write process, we could only\njust mark it as closed.\n\n2. When reading from a link, it is never in the ready_list, so it\nis safe to close it in read process, also safe to put it into\nready_list.\n\n3. Ignore FDEVENT_ERR\n\nA link is in either one of these places:\n\t1. ready list\n\t2. async worker queue\n\t3. fdes\nSo it safe to delete link when processing ready list and async worker result.\n*/\nint NetworkServer::proc_client_event(const Fdevent *fde, ready_list_t *ready_list){\n\tLink *link = (Link *)fde->data.ptr;\n\tif(fde->events & FDEVENT_IN){\n\t\tint len = link->read();\n\t\t//log_debug(\"fd: %d read: %d\", link->fd(), len);\n\t\tif(len <= 0){\n\t\t\tdouble serv_time = microtime() - link->create_time;\n\t\t\tlog_debug(\"fd: %d, read: %d, delete link, s:%.3f\", link->fd(), len, serv_time);\n\t\t\tlink->mark_error();\n\t\t\tready_list->push_back(link);\n\t\t\treturn 0;\n\t\t}\n\t\tready_list->push_back(link);\n\t}else if(fde->events & FDEVENT_OUT){\n\t\tint len = link->write();\n\t\t//log_debug(\"fd: %d, write: %d\", link->fd(), len);\n\t\tif(len <= 0){\n\t\t\tlog_debug(\"fd: %d, write: %d, delete link\", link->fd(), len);\n\t\t\tlink->mark_error();\n\t\t\tready_list->push_back(link);\n\t\t\treturn 0;\n\t\t}\n\t\t\n\t\tif(link->output->empty()){\n\t\t\tfdes->clr(link->fd(), FDEVENT_OUT);\n\t\t\tif(link->input->empty()){\n\t\t\t\tfdes->set(link->fd(), FDEVENT_IN, 1, link);\n\t\t\t}else{\n\t\t\t\tready_list->push_back(link);\n\t\t\t}\n\t\t}else{\n\t\t\tfdes->clr(link->fd(), FDEVENT_IN);\n\t\t\tfdes->set(link->fd(), FDEVENT_OUT, 1, link);\n\t\t}\n\t}\n\treturn 0;\n}\n\nint NetworkServer::proc(ProcJob *job){\n\tjob->serv = this;\n\tjob->result = PROC_OK;\n\tjob->stime = microtime();\n\n\tconst Request *req = job->req;\n\n\tdo{\n\t\t// AUTH\n\t\tif(this->need_auth && job->link->auth == false && req->at(0) != \"auth\"){\n\t\t\tjob->resp.push_back(\"noauth\");\n\t\t\tjob->resp.push_back(\"authentication required.\");\n\t\t\tbreak;\n\t\t}\n\t\t\n\t\tjob->cmd = proc_map.get_proc(req->at(0));\n\t\tif(!job->cmd){\n\t\t\tjob->resp.push_back(\"client_error\");\n\t\t\tjob->resp.push_back(\"Unknown Command: \" + req->at(0).String());\n\t\t\tbreak;\n\t\t}\n\n\t\tif(this->readonly && (job->cmd->flags & Command::FLAG_WRITE)){\n\t\t\tjob->resp.push_back(\"client_error\");\n\t\t\tjob->resp.push_back(\"Forbidden Command: \" + req->at(0).String());\n\t\t\tbreak;\n\t\t}\n\t\t\n\t\tif(job->cmd->flags & Command::FLAG_THREAD){\n\t\t\tif(job->cmd->flags & Command::FLAG_WRITE){\n\t\t\t\twriter->push(job);\n\t\t\t}else{\n\t\t\t\treader->push(job);\n\t\t\t}\n\t\t\treturn PROC_THREAD;\n\t\t}\n\n\t\tproc_t p = job->cmd->proc;\n\t\tjob->time_wait = 1000 * (microtime() - job->stime);\n\t\tjob->result = (*p)(this, job->link, *req, &job->resp);\n\t\tjob->time_proc = 1000 * (microtime() - job->stime) - job->time_wait;\n\t}while(0);\n\t\n\tif(job->link->send(job->resp.resp) == -1){\n\t\tjob->result = PROC_ERROR;\n\t}else{\n\t\t// try to write socket before it would be added to fdevents\n\t\t// socket is NONBLOCK, so it won't block.\n\t\tif(job->link->write() < 0){\n\t\t\tjob->result = PROC_ERROR;\n\t\t}\n\t}\n\n\treturn job->result;\n}\n\n\n/* built-in procs */\n\nstatic int proc_ping(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tresp->push_back(\"ok\");\n\treturn 0;\n}\n\nstatic int proc_info(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tresp->push_back(\"ok\");\n\tresp->push_back(\"ideawu's network server framework\");\n\tresp->push_back(\"version\");\n\tresp->push_back(\"1.0\");\n\tresp->push_back(\"links\");\n\tresp->add(net->link_count);\n\t{\n\t\tint64_t calls = 0;\n\t\tproc_map_t::iterator it;\n\t\tfor(it=net->proc_map.begin(); it!=net->proc_map.end(); it++){\n\t\t\tCommand *cmd = it->second;\n\t\t\tcalls += cmd->calls;\n\t\t}\n\t\tresp->push_back(\"total_calls\");\n\t\tresp->add(calls);\n\t}\n\treturn 0;\n}\n\nstatic int proc_auth(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tif(req.size() != 2){\n\t\tresp->push_back(\"client_error\");\n\t}else{\n\t\tif(!net->need_auth || net->passwords.count(req[1].String()) != 0){\n\t\t\tlink->auth = true;\n\t\t\tresp->push_back(\"ok\");\n\t\t\tresp->push_back(\"1\");\n\t\t}else{\n\t\t\tresp->push_back(\"error\");\n\t\t\tresp->push_back(\"invalid password\");\n\t\t}\n\t}\n\treturn 0;\n}\n\n#define ENSURE_LOCALHOST() do{ \\\n\t\tif(strcmp(link->remote_ip, \"127.0.0.1\") != 0 \\\n\t\t\t&& strcmp(link->remote_ip, \"::1\") != 0) \\\n\t\t{ \\\n\t\t\tresp->push_back(\"noauth\"); \\\n\t\t\tresp->push_back(\"this command is only available from localhost\"); \\\n\t\t\treturn 0; \\\n\t\t} \\\n\t}while(0)\n\nstatic int proc_list_allow_ip(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tENSURE_LOCALHOST();\n\n\tresp->push_back(\"ok\");\n\tIpFilter *ip_filter = net->ip_filter;\n\tif(ip_filter->allow_all){\n\t\tresp->push_back(\"all\");\n\t}\n\tstd::set<std::string>::const_iterator it;\n\tfor(it=ip_filter->allow.begin(); it!=ip_filter->allow.end(); it++){\n\t\tstd::string ip = *it;\n\t\tip = ip.substr(0, ip.size() - 1);\n\t\tresp->push_back(ip);\n\t}\n\n\treturn 0;\n}\n\nstatic int proc_add_allow_ip(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tENSURE_LOCALHOST();\n\tif(req.size() != 2){\n\t\tresp->push_back(\"client_error\");\n\t}else{\n\t\tIpFilter *ip_filter = net->ip_filter;\n\t\tip_filter->add_allow(req[1].String());\n\t\tresp->push_back(\"ok\");\n\t}\n\treturn 0;\n}\n\nstatic int proc_del_allow_ip(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tENSURE_LOCALHOST();\n\tif(req.size() != 2){\n\t\tresp->push_back(\"client_error\");\n\t}else{\n\t\tIpFilter *ip_filter = net->ip_filter;\n\t\tip_filter->del_allow(req[1].String());\n\t\tresp->push_back(\"ok\");\n\t}\n\treturn 0;\n}\n\nstatic int proc_list_deny_ip(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tENSURE_LOCALHOST();\n\n\tresp->push_back(\"ok\");\n\tIpFilter *ip_filter = net->ip_filter;\n\tif(!ip_filter->allow_all){\n\t\tresp->push_back(\"all\");\n\t}\n\tstd::set<std::string>::const_iterator it;\n\tfor(it=ip_filter->deny.begin(); it!=ip_filter->deny.end(); it++){\n\t\tstd::string ip = *it;\n\t\tip = ip.substr(0, ip.size() - 1);\n\t\tresp->push_back(ip);\n\t}\n\n\treturn 0;\n}\n\nstatic int proc_add_deny_ip(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tENSURE_LOCALHOST();\n\tif(req.size() != 2){\n\t\tresp->push_back(\"client_error\");\n\t}else{\n\t\tIpFilter *ip_filter = net->ip_filter;\n\t\tip_filter->add_deny(req[1].String());\n\t\tresp->push_back(\"ok\");\n\t}\n\treturn 0;\n}\n\nstatic int proc_del_deny_ip(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tENSURE_LOCALHOST();\n\tif(req.size() != 2){\n\t\tresp->push_back(\"client_error\");\n\t}else{\n\t\tIpFilter *ip_filter = net->ip_filter;\n\t\tip_filter->del_deny(req[1].String());\n\t\tresp->push_back(\"ok\");\n\t}\n\treturn 0;\n}\n\n"
  },
  {
    "path": "src/net/server.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef NET_SERVER_H_\n#define NET_SERVER_H_\n\n#include \"../include.h\"\n#include <string>\n#include <vector>\n#include <set>\n\n#include \"fde.h\"\n#include \"proc.h\"\n#include \"worker.h\"\n\nclass Link;\nclass Config;\nclass IpFilter;\nclass Fdevents;\n\ntypedef std::vector<Link *> ready_list_t;\n\nclass NetworkServer\n{\nprivate:\n\tint tick_interval;\n\tint status_report_ticks;\n\n\t//Config *conf;\n\tLink *serv_link;\n\tFdevents *fdes;\n\n\tLink* accept_link();\n\tint proc_result(ProcJob *job, ready_list_t *ready_list);\n\tint proc_client_event(const Fdevent *fde, ready_list_t *ready_list);\n\n\tint proc(ProcJob *job);\n\n\tint num_readers;\n\tint num_writers;\n\tProcWorkerPool *writer;\n\tProcWorkerPool *reader;\n\t\n\tbool readonly;\n\n\tNetworkServer();\n\nprotected:\n\tvoid usage(int argc, char **argv);\n\npublic:\n\tIpFilter *ip_filter;\n\tvoid *data;\n\tProcMap proc_map;\n\tint link_count;\n\tbool need_auth;\n    std::set<std::string> passwords;\n\tdouble slowlog_timeout; // in ms, but in config file, it's in seconds\n\n\t~NetworkServer();\n\t\n\t// could be called only once\n\tstatic NetworkServer* init(const char *conf_file, int num_readers=-1, int num_writers=-1);\n\tstatic NetworkServer* init(const Config &conf, int num_readers=-1, int num_writers=-1);\n\tvoid serve();\n};\n\n\n#endif\n"
  },
  {
    "path": "src/net/test.conf",
    "content": "pidfile = ./test.pid\n\nserver:\n\t#ip: 127.0.0.1\n\tip: ::1\n\tport: 9001\n\t# bind to public ip\n\t#ip: 0.0.0.0\n\t# format: allow|deny: all|ip_prefix\n\t# multiple allows or denys is supported\n\t#deny: all\n\tallow: 127.0.0.1\n\tallow: ::1\n\t#allow: 192.168\n\t# auth password must be longer than 31 characters\n\t#auth: very-strong-passwordwwwwwwwwwwwwww\n\tauth: a-123456789012345678901234567890\n\tauth: b-123456789012345678901234567890\n\treadonly: no\n\nlogger:\n\tlevel: debug\n\toutput: stdout\n\trotate:\n\t\tsize: 1000000000\n"
  },
  {
    "path": "src/net/test.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"server.h\"\n\nvoid usage(int argc, char **argv){\n\tprintf(\"Usage:\\n\");\n\tprintf(\"    %s [-d] /path/to/server.conf\\n\", argv[0]);\n\tprintf(\"Options:\\n\");\n\tprintf(\"    -d    run as daemon\\n\");\n}\n\nDEF_PROC(hello);\n\nint main(int argc, char **argv){\n\tbool is_daemon = false;\n\tconst char *conf_file = NULL;\n\tfor(int i=1; i<argc; i++){\n\t\tif(strcmp(argv[i], \"-d\") == 0){\n\t\t\tis_daemon = true;\n\t\t}else{\n\t\t\tconf_file = argv[i];\n\t\t}\n\t}\n\tif(conf_file == NULL){\n\t\tusage(argc, argv);\n\t\texit(1);\n\t}\n\n\tNetworkServer *serv = NetworkServer::init(conf_file);\n\tif(!serv){\n\t\texit(1);\n\t}\n\t// register command procedure\n\tserv->proc_map.set_proc(\"hello\", \"w\", proc_hello);\n\tserv->serve();\n\tdelete serv;\n\treturn 0;\n}\n\nint proc_hello(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tresp->push_back(\"ok\");\n\tresp->push_back(\"world!\");\n\tif(req.size() > 1){\n\t\t// The first argument start at index 1, just like argv.\n\t\tresp->push_back(req[1].String());\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "src/net/test2.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"server.h\"\n#include \"../util/config.h\"\n\nDEF_PROC(hello);\n\nint main(int argc, char **argv){\n\tfprintf(stderr, \"Usage: %s [ip] [port]\\n\\n\", argv[0]);\n\tConfig conf;\n\tconf.set(\"server.port\", \"9000\");\n\tif(argc > 1){\n\t\tconf.set(\"server.ip\", argv[1]);\n\t}\n\tif(argc > 2){\n\t\tconf.set(\"server.port\", argv[2]);\n\t}\n\tNetworkServer *serv = NetworkServer::init(conf);\n\tif(!serv){\n\t\texit(1);\n\t}\n\t// register command procedure\n\tserv->proc_map.set_proc(\"hello\", proc_hello);\n\tserv->serve();\n\tdelete serv;\n\treturn 0;\n}\n\nint proc_hello(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tresp->push_back(\"ok\");\n\tresp->push_back(\"world!\");\n\tif(req.size() > 1){\n\t\t// The first argument start at index 1, just like argv.\n\t\tresp->push_back(req[1].String());\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "src/net/worker.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"worker.h\"\n#include \"link.h\"\n#include \"proc.h\"\n#include \"../util/log.h\"\n#include \"../include.h\"\n\nProcWorker::ProcWorker(const std::string &name){\n\tthis->name = name;\n}\n\nvoid ProcWorker::init(){\n\tlog_debug(\"%s %d init\", this->name.c_str(), this->id);\n}\n\nint ProcWorker::proc(ProcJob *job){\n\tconst Request *req = job->req;\n\t\n\tproc_t p = job->cmd->proc;\n\tjob->time_wait = 1000 * (microtime() - job->stime);\n\tjob->result = (*p)(job->serv, job->link, *req, &job->resp);\n\tjob->time_proc = 1000 * (microtime() - job->stime) - job->time_wait;\n\n\tif(job->link->send(job->resp.resp) == -1){\n\t\tjob->result = PROC_ERROR;\n\t}else{\n\t\t// try to write socket before it would be added to fdevents\n\t\t// socket is NONBLOCK, so it won't block.\n\t\tif(job->link->write() < 0){\n\t\t\tjob->result = PROC_ERROR;\n\t\t}\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "src/net/worker.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef NET_WORKER_H_\n#define NET_WORKER_H_\n\n#include <string>\n#include \"../util/thread.h\"\n#include \"proc.h\"\n\n// WARN: pipe latency is about 20 us, it is really slow!\nclass ProcWorker : public WorkerPool<ProcWorker, ProcJob *>::Worker{\npublic:\n\tProcWorker(const std::string &name);\n\t~ProcWorker(){}\n\tvoid init();\n\tint proc(ProcJob *job);\n};\n\ntypedef WorkerPool<ProcWorker, ProcJob *> ProcWorkerPool;\n\n#endif\n"
  },
  {
    "path": "src/proc_hash.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"proc_hash.h\"\n\nint proc_hexists(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(3);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\n\tconst Bytes &name = req[1];\n\tconst Bytes &key = req[2];\n\tstd::string val;\n\tint ret = serv->ssdb->hget(name, key, &val);\n\tresp->reply_bool(ret);\n\treturn 0;\n}\n\nint proc_multi_hexists(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(3);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\n\tresp->push_back(\"ok\");\n\tconst Bytes &name = req[1];\n\tstd::string val;\n\tfor(Request::const_iterator it=req.begin()+2; it!=req.end(); it++){\n\t\tconst Bytes &key = *it;\n\t\tint64_t ret = serv->ssdb->hget(name, key, &val);\n\t\tresp->push_back(key.String());\n\t\tif(ret > 0){\n\t\t\tresp->push_back(\"1\");\n\t\t}else{\n\t\t\tresp->push_back(\"0\");\n\t\t}\n\t}\n\treturn 0;\n}\n\nint proc_multi_hsize(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(2);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\n\tresp->push_back(\"ok\");\n\tfor(Request::const_iterator it=req.begin()+1; it!=req.end(); it++){\n\t\tconst Bytes &key = *it;\n\t\tint64_t ret = serv->ssdb->hsize(key);\n\t\tresp->push_back(key.String());\n\t\tif(ret == -1){\n\t\t\tresp->push_back(\"-1\");\n\t\t}else{\n\t\t\tresp->add(ret);\n\t\t}\n\t}\n\treturn 0;\n}\n\nint proc_multi_hset(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tif(req.size() < 4 || req.size() % 2 != 0){\n\t\tresp->push_back(\"client_error\");\n\t}else{\n\t\tint num = 0;\n\t\tconst Bytes &name = req[1];\n\t\tstd::vector<Bytes>::const_iterator it = req.begin() + 2;\n\t\tfor(; it != req.end(); it += 2){\n\t\t\tconst Bytes &key = *it;\n\t\t\tconst Bytes &val = *(it + 1);\n\t\t\tint ret = serv->ssdb->hset(name, key, val);\n\t\t\tif(ret == -1){\n\t\t\t\tresp->push_back(\"error\");\n\t\t\t\treturn 0;\n\t\t\t}else{\n\t\t\t\tnum += ret;\n\t\t\t}\n\t\t}\n\t\tresp->reply_int(0, num);\n\t}\n\treturn 0;\n}\n\nint proc_multi_hdel(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(3);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\n\tint num = 0;\n\tconst Bytes &name = req[1];\n\tstd::vector<Bytes>::const_iterator it = req.begin() + 2;\n\tfor(; it != req.end(); it += 1){\n\t\tconst Bytes &key = *it;\n\t\tint ret = serv->ssdb->hdel(name, key);\n\t\tif(ret == -1){\n\t\t\tresp->push_back(\"error\");\n\t\t\treturn 0;\n\t\t}else{\n\t\t\tnum += ret;\n\t\t}\n\t}\n\tresp->reply_int(0, num);\n\treturn 0;\n}\n\nint proc_multi_hget(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(3);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\n\tresp->push_back(\"ok\");\n\tRequest::const_iterator it=req.begin() + 1;\n\tconst Bytes name = *it;\n\tit ++;\n\tfor(; it!=req.end(); it+=1){\n\t\tconst Bytes &key = *it;\n\t\tstd::string val;\n\t\tint ret = serv->ssdb->hget(name, key, &val);\n\t\tif(ret == 1){\n\t\t\tresp->push_back(key.String());\n\t\t\tresp->push_back(val);\n\t\t}\n\t}\n\treturn 0;\n}\n\nint proc_hsize(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(2);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\n\tint64_t ret = serv->ssdb->hsize(req[1]);\n\tresp->reply_int(ret, ret);\n\treturn 0;\n}\n\nint proc_hset(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(4);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\n\tint ret = serv->ssdb->hset(req[1], req[2], req[3]);\n\tresp->reply_bool(ret);\n\treturn 0;\n}\n\nint proc_hget(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(3);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\n\tstd::string val;\n\tint ret = serv->ssdb->hget(req[1], req[2], &val);\n\tresp->reply_get(ret, &val);\n\treturn 0;\n}\n\nint proc_hdel(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(3);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\n\tint ret = serv->ssdb->hdel(req[1], req[2]);\n\tresp->reply_bool(ret);\n\treturn 0;\n}\n\nint proc_hclear(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(2);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\t\n\tconst Bytes &name = req[1];\n\tint64_t count = serv->ssdb->hclear(name);\n\tresp->reply_int(0, count);\n\n\treturn 0;\n}\n\nint proc_hgetall(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(2);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\n\tHIterator *it = serv->ssdb->hscan(req[1], \"\", \"\", 2000000000);\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tresp->push_back(it->key);\n\t\tresp->push_back(it->val);\n\t}\n\tdelete it;\n\treturn 0;\n}\n\nint proc_hscan(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(5);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\n\tuint64_t limit = req[4].Uint64();\n\tHIterator *it = serv->ssdb->hscan(req[1], req[2], req[3], limit);\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tresp->push_back(it->key);\n\t\tresp->push_back(it->val);\n\t}\n\tdelete it;\n\treturn 0;\n}\n\nint proc_hrscan(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(5);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\n\tuint64_t limit = req[4].Uint64();\n\tHIterator *it = serv->ssdb->hrscan(req[1], req[2], req[3], limit);\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tresp->push_back(it->key);\n\t\tresp->push_back(it->val);\n\t}\n\tdelete it;\n\treturn 0;\n}\n\nint proc_hkeys(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(5);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\n\tuint64_t limit = req[4].Uint64();\n\tHIterator *it = serv->ssdb->hscan(req[1], req[2], req[3], limit);\n\tit->return_val(false);\n\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tresp->push_back(it->key);\n\t}\n\tdelete it;\n\treturn 0;\n}\n\nint proc_hvals(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(5);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\n\tuint64_t limit = req[4].Uint64();\n\tHIterator *it = serv->ssdb->hscan(req[1], req[2], req[3], limit);\n\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tresp->push_back(it->val);\n\t}\n\tdelete it;\n\treturn 0;\n}\n\nint proc_hlist(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(4);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\n\tuint64_t limit = req[3].Uint64();\n\tstd::vector<std::string> list;\n\tint ret = serv->ssdb->hlist(req[1], req[2], limit, &list);\n\tresp->reply_list(ret, list);\n\treturn 0;\n}\n\nint proc_hrlist(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tCHECK_NUM_PARAMS(4);\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\n\tuint64_t limit = req[3].Uint64();\n\tstd::vector<std::string> list;\n\tint ret = serv->ssdb->hrlist(req[1], req[2], limit, &list);\n\tresp->reply_list(ret, list);\n\treturn 0;\n}\n\n// dir := +1|-1\nstatic int _hincr(SSDB *ssdb, const Request &req, Response *resp, int dir){\n\tCHECK_NUM_PARAMS(3);\n\n\tint64_t by = 1;\n\tif(req.size() > 3){\n\t\tby = req[3].Int64();\n\t}\n\tint64_t new_val;\n\tint ret = ssdb->hincr(req[1], req[2], dir * by, &new_val);\n\tif(ret == 0){\n\t\tresp->reply_status(-1, \"value is not an integer or out of range\");\n\t}else{\n\t\tresp->reply_int(ret, new_val);\n\t}\n\treturn 0;\n}\n\nint proc_hincr(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\treturn _hincr(serv->ssdb, req, resp, 1);\n}\n\nint proc_hdecr(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\treturn _hincr(serv->ssdb, req, resp, -1);\n}\n\n\nint proc_hfix(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\t\n\tconst Bytes &name = req[1];\n\tint64_t ret = serv->ssdb->hfix(name);\n\tresp->reply_int(ret, ret);\n\treturn 0;\n}\n\n"
  },
  {
    "path": "src/proc_hash.h",
    "content": "/*\nCopyright (c) 2012-2018 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n/* hash commands */\n#include \"serv.h\"\n#include \"net/proc.h\"\n#include \"net/server.h\"\n\nDEF_PROC(hsize);\nDEF_PROC(hget);\nDEF_PROC(hset);\nDEF_PROC(hdel);\nDEF_PROC(hincr);\nDEF_PROC(hdecr);\nDEF_PROC(hclear);\nDEF_PROC(hgetall);\nDEF_PROC(hscan);\nDEF_PROC(hrscan);\nDEF_PROC(hkeys);\nDEF_PROC(hvals);\nDEF_PROC(hlist);\nDEF_PROC(hrlist);\nDEF_PROC(hexists);\nDEF_PROC(multi_hexists);\nDEF_PROC(multi_hsize);\nDEF_PROC(multi_hget);\nDEF_PROC(multi_hset);\nDEF_PROC(multi_hdel);\nDEF_PROC(hfix);\n"
  },
  {
    "path": "src/proc_kv.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"proc_kv.h\"\n\nint proc_get(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\tCHECK_KV_KEY_RANGE(1);\n\n\tstd::string val;\n\tint ret = serv->ssdb->get(req[1], &val);\n\tresp->reply_get(ret, &val);\n\treturn 0;\n}\n\nint proc_getset(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\tCHECK_KV_KEY_RANGE(1);\n\n\tstd::string val;\n\tint ret = serv->ssdb->getset(req[1], &val, req[2]);\n\tresp->reply_get(ret, &val);\n\treturn 0;\n}\n\nint proc_set(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\tCHECK_KV_KEY_RANGE(1);\n\n\tint ret = serv->ssdb->set(req[1], req[2]);\n\tif(ret == -1){\n\t\tresp->push_back(\"error\");\n\t}else{\n\t\tresp->push_back(\"ok\");\n\t\tresp->push_back(\"1\");\n\t}\n\treturn 0;\n}\n\nint proc_setnx(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\tCHECK_KV_KEY_RANGE(1);\n\n\tint ret = serv->ssdb->setnx(req[1], req[2]);\n\tresp->reply_bool(ret);\n\treturn 0;\n}\n\nint proc_setx(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\tCHECK_KV_KEY_RANGE(1);\n\n\tLocking l(&serv->expiration->mutex);\n\tint ret;\n\tret = serv->ssdb->set(req[1], req[2]);\n\tif(ret == -1){\n\t\tresp->push_back(\"error\");\n\t\treturn 0;\n\t}\n\tret = serv->expiration->set_ttl(req[1], req[3].Int());\n\tif(ret == -1){\n\t\tresp->push_back(\"error\");\n\t}else{\n\t\tresp->push_back(\"ok\");\n\t\tresp->push_back(\"1\");\n\t}\n\treturn 0;\n}\n\nint proc_ttl(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\tCHECK_KV_KEY_RANGE(1);\n\n\tint64_t ttl = serv->expiration->get_ttl(req[1]);\n\tresp->push_back(\"ok\");\n\tresp->push_back(str(ttl));\n\treturn 0;\n}\n\nint proc_expire(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\tCHECK_KV_KEY_RANGE(1);\n\n\tLocking l(&serv->expiration->mutex);\n\tstd::string val;\n\tint ret = serv->ssdb->get(req[1], &val);\n\tif(ret == 1){\n\t\tret = serv->expiration->set_ttl(req[1], req[2].Int());\n\t\tif(ret != -1){\n\t\t\tresp->push_back(\"ok\");\n\t\t\tresp->push_back(\"1\");\n\t\t}else{\n\t\t\tresp->push_back(\"error\");\n\t\t}\n\t\treturn 0;\n\t}\n\tresp->push_back(\"ok\");\n\tresp->push_back(\"0\");\n\treturn 0;\n}\n\nint proc_exists(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\tCHECK_KV_KEY_RANGE(1);\n\n\tconst Bytes key = req[1];\n\tstd::string val;\n\tint ret = serv->ssdb->get(key, &val);\n\tresp->reply_bool(ret);\n\treturn 0;\n}\n\nint proc_multi_exists(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\n\tresp->push_back(\"ok\");\n\tfor(Request::const_iterator it=req.begin()+1; it!=req.end(); it++){\n\t\tconst Bytes key = *it;\n\t\tstd::string val;\n\t\tint ret = serv->ssdb->get(key, &val);\n\t\tresp->push_back(key.String());\n\t\tif(ret == 1){\n\t\t\tresp->push_back(\"1\");\n\t\t}else if(ret == 0){\n\t\t\tresp->push_back(\"0\");\n\t\t}else{\n\t\t\tresp->push_back(\"0\");\n\t\t}\n\t}\n\treturn 0;\n}\n\nint proc_multi_set(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tif(req.size() < 3 || req.size() % 2 != 1){\n\t\tresp->push_back(\"client_error\");\n\t}else{\n\t\tint ret = serv->ssdb->multi_set(req, 1);\n\t\tresp->reply_int(0, ret);\n\t}\n\treturn 0;\n}\n\nint proc_multi_del(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\n\tLocking l(&serv->expiration->mutex);\n\tint ret = serv->ssdb->multi_del(req, 1);\n\tif(ret == -1){\n\t\tresp->push_back(\"error\");\n\t}else{\n\t\tfor(Request::const_iterator it=req.begin()+1; it!=req.end(); it++){\n\t\t\tconst Bytes key = *it;\n\t\t\tserv->expiration->del_ttl(key);\n\t\t}\n\t\tresp->reply_int(0, ret);\n\t}\n\treturn 0;\n}\n\nint proc_multi_get(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\n\tresp->push_back(\"ok\");\n\tfor(int i=1; i<req.size(); i++){\n\t\tstd::string val;\n\t\tint ret = serv->ssdb->get(req[i], &val);\n\t\tif(ret == 1){\n\t\t\tresp->push_back(req[i].String());\n\t\t\tresp->push_back(val);\n\t\t}\n\t}\n\treturn 0;\n}\n\nint proc_del(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\tCHECK_KV_KEY_RANGE(1);\n\n\tLocking l(&serv->expiration->mutex);\n\tint ret = serv->ssdb->del(req[1]);\n\tif(ret == -1){\n\t\tresp->push_back(\"error\");\n\t}else{\n\t\tserv->expiration->del_ttl(req[1]);\n\t\t\t\n\t\tresp->push_back(\"ok\");\n\t\tresp->push_back(\"1\");\n\t}\n\treturn 0;\n}\n\nint proc_scan(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tuint64_t limit = req[3].Uint64();\n\tKIterator *it = serv->ssdb->scan(req[1], req[2], limit);\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tresp->push_back(it->key);\n\t\tresp->push_back(it->val);\n\t}\n\tdelete it;\n\treturn 0;\n}\n\nint proc_rscan(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tuint64_t limit = req[3].Uint64();\n\tKIterator *it = serv->ssdb->rscan(req[1], req[2], limit);\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tresp->push_back(it->key);\n\t\tresp->push_back(it->val);\n\t}\n\tdelete it;\n\treturn 0;\n}\n\nint proc_keys(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tuint64_t limit = req[3].Uint64();\n\tKIterator *it = serv->ssdb->scan(req[1], req[2], limit);\n\tit->return_val(false);\n\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tresp->push_back(it->key);\n\t}\n\tdelete it;\n\treturn 0;\n}\n\nint proc_rkeys(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tuint64_t limit = req[3].Uint64();\n\tKIterator *it = serv->ssdb->rscan(req[1], req[2], limit);\n\tit->return_val(false);\n\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tresp->push_back(it->key);\n\t}\n\tdelete it;\n\treturn 0;\n}\n\n// dir := +1|-1\nstatic int _incr(SSDB *ssdb, const Request &req, Response *resp, int dir){\n\tCHECK_NUM_PARAMS(2);\n\tint64_t by = 1;\n\tif(req.size() > 2){\n\t\tby = req[2].Int64();\n\t}\n\tint64_t new_val;\n\tint ret = ssdb->incr(req[1], dir * by, &new_val);\n\tif(ret == 0){\n\t\tresp->reply_status(-1, \"value is not an integer or out of range\");\n\t}else{\n\t\tresp->reply_int(ret, new_val);\n\t}\n\treturn 0;\n}\n\nint proc_incr(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_KV_KEY_RANGE(1);\n\treturn _incr(serv->ssdb, req, resp, 1);\n}\n\nint proc_decr(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_KV_KEY_RANGE(1);\n\treturn _incr(serv->ssdb, req, resp, -1);\n}\n\nint proc_getbit(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\tCHECK_KV_KEY_RANGE(1);\n\n\tint ret = serv->ssdb->getbit(req[1], req[2].Int());\n\tresp->reply_bool(ret);\n\treturn 0;\n}\n\nint proc_setbit(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\tCHECK_KV_KEY_RANGE(1);\n\n\tconst Bytes &key = req[1];\n\tint offset = req[2].Int();\n\tif(req[3].size() == 0 || (req[3].data()[0] != '0' && req[3].data()[0] != '1')){\n\t\tresp->push_back(\"client_error\");\n\t\tresp->push_back(\"bit is not an integer or out of range\");\n\t\treturn 0;\n\t}\n\tif(offset < 0 || offset > Link::MAX_PACKET_SIZE * 8){\n\t\tstd::string msg = \"offset is out of range [0, \";\n\t\tmsg += str(Link::MAX_PACKET_SIZE * 8);\n\t\tmsg += \"]\";\n\t\tresp->push_back(\"client_error\");\n\t\tresp->push_back(msg);\n\t\treturn 0;\n\t}\n\tint on = req[3].Int();\n\tint ret = serv->ssdb->setbit(key, offset, on);\n\tresp->reply_bool(ret);\n\treturn 0;\n}\n\nint proc_countbit(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\tCHECK_KV_KEY_RANGE(1);\n\n\tconst Bytes &key = req[1];\n\tint start = 0;\n\tif(req.size() > 2){\n\t\tstart = req[2].Int();\n\t}\n\tstd::string val;\n\tint ret = serv->ssdb->get(key, &val);\n\tif(ret == -1){\n\t\tresp->push_back(\"error\");\n\t}else{\n\t\tstd::string str;\n\t\tint size = -1;\n\t\tif(req.size() > 3){\n\t\t\tsize = req[3].Int();\n\t\t\tstr = substr(val, start, size);\n\t\t}else{\n\t\t\tstr = substr(val, start, val.size());\n\t\t}\n\t\tint count = bitcount(str.data(), str.size());\n\t\tresp->reply_int(0, count);\n\t}\n\treturn 0;\n}\n\nint proc_bitcount(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\tCHECK_KV_KEY_RANGE(1);\n\n\tconst Bytes &key = req[1];\n\tint start = 0;\n\tif(req.size() > 2){\n\t\tstart = req[2].Int();\n\t}\n\tint end = -1;\n\tif(req.size() > 3){\n\t\tend = req[3].Int();\n\t}\n\tstd::string val;\n\tint ret = serv->ssdb->get(key, &val);\n\tif(ret == -1){\n\t\tresp->push_back(\"error\");\n\t}else{\n\t\tstd::string str = str_slice(val, start, end);\n\t\tint count = bitcount(str.data(), str.size());\n\t\tresp->reply_int(0, count);\n\t}\n\treturn 0;\n}\n\nint proc_substr(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\tCHECK_KV_KEY_RANGE(1);\n\n\tconst Bytes &key = req[1];\n\tint start = 0;\n\tif(req.size() > 2){\n\t\tstart = req[2].Int();\n\t}\n\tint size = 2000000000;\n\tif(req.size() > 3){\n\t\tsize = req[3].Int();\n\t}\n\tstd::string val;\n\tint ret = serv->ssdb->get(key, &val);\n\tif(ret == -1){\n\t\tresp->push_back(\"error\");\n\t}else{\n\t\tstd::string str = substr(val, start, size);\n\t\tresp->push_back(\"ok\");\n\t\tresp->push_back(str);\n\t}\n\treturn 0;\n}\n\nint proc_getrange(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\tCHECK_KV_KEY_RANGE(1);\n\n\tconst Bytes &key = req[1];\n\tint start = 0;\n\tif(req.size() > 2){\n\t\tstart = req[2].Int();\n\t}\n\tint size = -1;\n\tif(req.size() > 3){\n\t\tsize = req[3].Int();\n\t}\n\tstd::string val;\n\tint ret = serv->ssdb->get(key, &val);\n\tif(ret == -1){\n\t\tresp->push_back(\"error\");\n\t}else{\n\t\tstd::string str = str_slice(val, start, size);\n\t\tresp->push_back(\"ok\");\n\t\tresp->push_back(str);\n\t}\n\treturn 0;\n}\n\nint proc_strlen(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\tCHECK_KV_KEY_RANGE(1);\n\n\tconst Bytes &key = req[1];\n\tstd::string val;\n\tint ret = serv->ssdb->get(key, &val);\n\tresp->reply_int(ret, val.size());\n\treturn 0;\n}\n"
  },
  {
    "path": "src/proc_kv.h",
    "content": "/*\nCopyright (c) 2012-2018 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n/* kv commands */\n#include \"serv.h\"\n#include \"net/proc.h\"\n#include \"net/server.h\"\n\nDEF_PROC(get);\nDEF_PROC(set);\nDEF_PROC(setx);\nDEF_PROC(setnx);\nDEF_PROC(getset);\nDEF_PROC(getbit);\nDEF_PROC(setbit);\nDEF_PROC(countbit);\nDEF_PROC(substr);\nDEF_PROC(getrange);\nDEF_PROC(strlen);\nDEF_PROC(bitcount);\nDEF_PROC(del);\nDEF_PROC(incr);\nDEF_PROC(decr);\nDEF_PROC(scan);\nDEF_PROC(rscan);\nDEF_PROC(keys);\nDEF_PROC(rkeys);\nDEF_PROC(exists);\nDEF_PROC(multi_exists);\nDEF_PROC(multi_get);\nDEF_PROC(multi_set);\nDEF_PROC(multi_del);\nDEF_PROC(ttl);\nDEF_PROC(expire);\n"
  },
  {
    "path": "src/proc_queue.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"proc_queue.h\"\n\nint proc_qsize(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\n\tint64_t ret = serv->ssdb->qsize(req[1]);\n\tresp->reply_int(ret, ret);\n\treturn 0;\n}\n\nint proc_qfront(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\n\tstd::string item;\n\tint ret = serv->ssdb->qfront(req[1], &item);\n\tresp->reply_get(ret, &item);\n\treturn 0;\n}\n\nint proc_qback(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\n\tstd::string item;\n\tint ret = serv->ssdb->qback(req[1], &item);\n\tresp->reply_get(ret, &item);\n\treturn 0;\n}\n\nstatic int QFRONT = 2;\nstatic int QBACK  = 3;\n\nstatic inline\nint proc_qpush_func(NetworkServer *net, Link *link, const Request &req, Response *resp, int front_or_back){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\n\tint64_t size = 0;\n\tstd::vector<Bytes>::const_iterator it;\n\tit = req.begin() + 2;\n\tfor(; it != req.end(); it += 1){\n\t\tconst Bytes &item = *it;\n\t\tif(front_or_back == QFRONT){\n\t\t\tsize = serv->ssdb->qpush_front(req[1], item);\n\t\t}else{\n\t\t\tsize = serv->ssdb->qpush_back(req[1], item);\n\t\t}\n\t\tif(size == -1){\n\t\t\tresp->push_back(\"error\");\n\t\t\treturn 0;\n\t\t}\n\t}\n\tresp->reply_int(0, size);\n\treturn 0;\n}\n\nint proc_qpush_front(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\treturn proc_qpush_func(net, link, req, resp, QFRONT);\n}\n\nint proc_qpush_back(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\treturn proc_qpush_func(net, link, req, resp, QBACK);\n}\n\nint proc_qpush(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\treturn proc_qpush_func(net, link, req, resp, QBACK);\n}\n\n\nstatic inline\nint proc_qpop_func(NetworkServer *net, Link *link, const Request &req, Response *resp, int front_or_back){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\t\n\tuint64_t size = 1;\n\tif(req.size() > 2){\n\t\tsize = req[2].Uint64();\n\t}\n\t\t\n\tint ret;\n\tstd::string item;\n\n\tif(size == 1){\n\t\tif(front_or_back == QFRONT){\n\t\t\tret = serv->ssdb->qpop_front(req[1], &item);\n\t\t}else{\n\t\t\tret = serv->ssdb->qpop_back(req[1], &item);\n\t\t}\n\t\tresp->reply_get(ret, &item);\n\t}else{\n\t\tresp->push_back(\"ok\");\n\t\twhile(size-- > 0){\n\t\t\tif(front_or_back == QFRONT){\n\t\t\t\tret = serv->ssdb->qpop_front(req[1], &item);\n\t\t\t}else{\n\t\t\t\tret = serv->ssdb->qpop_back(req[1], &item);\n\t\t\t}\n\t\t\tif(ret <= 0){\n\t\t\t\tbreak;\n\t\t\t}else{\n\t\t\t\tresp->push_back(item);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nint proc_qpop_front(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\treturn proc_qpop_func(net, link, req, resp, QFRONT);\n}\n\nint proc_qpop_back(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\treturn proc_qpop_func(net, link, req, resp, QBACK);\n}\n\nint proc_qpop(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\treturn proc_qpop_func(net, link, req, resp, QFRONT);\n}\n\nstatic inline\nint proc_qtrim_func(NetworkServer *net, Link *link, const Request &req, Response *resp, int front_or_back){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\t\n\tuint64_t size = 1;\n\tif(req.size() > 2){\n\t\tsize = req[2].Uint64();\n\t}\n\t\t\n\tint count = 0;\n\tfor(; count<size; count++){\n\t\tint ret;\n\t\tstd::string item;\n\t\tif(front_or_back == QFRONT){\n\t\t\tret = serv->ssdb->qpop_front(req[1], &item);\n\t\t}else{\n\t\t\tret = serv->ssdb->qpop_back(req[1], &item);\n\t\t}\n\t\tif(ret <= 0){\n\t\t\tbreak;\n\t\t}\n\t}\n\tresp->reply_int(0, count);\n\n\treturn 0;\n}\n\nint proc_qtrim_front(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\treturn proc_qtrim_func(net, link, req, resp, QFRONT);\n}\n\nint proc_qtrim_back(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\treturn proc_qtrim_func(net, link, req, resp, QBACK);\n}\n\nint proc_qlist(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tuint64_t limit = req[3].Uint64();\n\tstd::vector<std::string> list;\n\tint ret = serv->ssdb->qlist(req[1], req[2], limit, &list);\n\tresp->reply_list(ret, list);\n\treturn 0;\n}\n\nint proc_qrlist(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tuint64_t limit = req[3].Uint64();\n\tstd::vector<std::string> list;\n\tint ret = serv->ssdb->qrlist(req[1], req[2], limit, &list);\n\tresp->reply_list(ret, list);\n\treturn 0;\n}\n\nint proc_qfix(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\n\tint ret = serv->ssdb->qfix(req[1]);\n\tif(ret == -1){\n\t\tresp->push_back(\"error\");\n\t}else{\n\t\tresp->push_back(\"ok\");\n\t}\n\treturn 0;\n}\n\nint proc_qclear(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\n\tint64_t count = 0;\n\twhile(1){\n\t\tstd::string item;\n\t\tint ret = serv->ssdb->qpop_front(req[1], &item);\n\t\tif(ret == 0){\n\t\t\tbreak;\n\t\t}\n\t\tif(ret == -1){\n\t\t\treturn -1;\n\t\t}\n\t\tcount += 1;\n\t}\n\tresp->reply_int(0, count);\n\treturn 0;\n}\n\nint proc_qslice(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tint64_t begin = req[2].Int64();\n\tint64_t end = req[3].Int64();\n\tstd::vector<std::string> list;\n\tint ret = serv->ssdb->qslice(req[1], begin, end, &list);\n\tresp->reply_list(ret, list);\n\treturn 0;\n}\n\nint proc_qrange(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tint64_t begin = req[2].Int64();\n\tint64_t limit = req[3].Uint64();\n\tint64_t end;\n\tif(limit >= 0){\n\t\tend = begin + limit - 1;\n\t}else{\n\t\tend = -1;\n\t}\n\tstd::vector<std::string> list;\n\tint ret = serv->ssdb->qslice(req[1], begin, end, &list);\n\tresp->reply_list(ret, list);\n\treturn 0;\n}\n\nint proc_qget(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\n\tint64_t index = req[2].Int64();\n\tstd::string item;\n\tint ret = serv->ssdb->qget(req[1], index, &item);\n\tresp->reply_get(ret, &item);\n\treturn 0;\n}\n\nint proc_qset(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tconst Bytes &name = req[1];\n\tint64_t index = req[2].Int64();\n\tconst Bytes &item = req[3];\n\tint ret = serv->ssdb->qset(name, index, item);\n\tif(ret == -1 || ret == 0){\n\t\tresp->push_back(\"error\");\n\t\tresp->push_back(\"index out of range\");\n\t}else{\n\t\tresp->push_back(\"ok\");\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "src/proc_queue.h",
    "content": "/*\nCopyright (c) 2012-2018 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n/* system commands */\n#include \"serv.h\"\n#include \"net/proc.h\"\n#include \"net/server.h\"\n\nDEF_PROC(qsize);\nDEF_PROC(qfront);\nDEF_PROC(qback);\nDEF_PROC(qpush);\nDEF_PROC(qpush_front);\nDEF_PROC(qpush_back);\nDEF_PROC(qpop);\nDEF_PROC(qpop_front);\nDEF_PROC(qpop_back);\nDEF_PROC(qtrim_front);\nDEF_PROC(qtrim_back);\nDEF_PROC(qfix);\nDEF_PROC(qclear);\nDEF_PROC(qlist);\nDEF_PROC(qrlist);\nDEF_PROC(qslice);\nDEF_PROC(qrange);\nDEF_PROC(qget);\nDEF_PROC(qset);\n"
  },
  {
    "path": "src/proc_sys.cpp",
    "content": "/*\nCopyright (c) 2012-2018 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"proc_sys.h\"\n\nint proc_flushdb(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tif(serv->slaves.size() > 0 || serv->backend_sync->stats().size() > 0){\n\t\tresp->push_back(\"error\");\n\t\tresp->push_back(\"flushdb is not allowed when replication is in use!\");\n\t\treturn 0;\n\t}\n\tserv->ssdb->flushdb();\n\tresp->push_back(\"ok\");\n\treturn 0;\n}\n\nint proc_compact(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tserv->ssdb->compact();\n\tresp->push_back(\"ok\");\n\treturn 0;\n}\n\nint proc_ignore_key_range(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tlink->ignore_key_range = true;\n\tresp->push_back(\"ok\");\n\treturn 0;\n}\n\n// get kv_range, hash_range, zset_range, list_range\nint proc_get_key_range(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tstd::string s, e;\n\tint ret = serv->get_kv_range(&s, &e);\n\tif(ret == -1){\n\t\tresp->push_back(\"error\");\n\t}else{\n\t\tresp->push_back(\"ok\");\n\t\tresp->push_back(s);\n\t\tresp->push_back(e);\n\t\t// TODO: hash_range, zset_range, list_range\n\t}\n\treturn 0;\n}\n\nint proc_get_kv_range(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tstd::string s, e;\n\tint ret = serv->get_kv_range(&s, &e);\n\tif(ret == -1){\n\t\tresp->push_back(\"error\");\n\t}else{\n\t\tresp->push_back(\"ok\");\n\t\tresp->push_back(s);\n\t\tresp->push_back(e);\n\t}\n\treturn 0;\n}\n\nint proc_set_kv_range(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tif(req.size() != 3){\n\t\tresp->push_back(\"client_error\");\n\t}else{\n\t\tserv->set_kv_range(req[1].String(), req[2].String());\n\t\tresp->push_back(\"ok\");\n\t}\n\treturn 0;\n}\n\nint proc_dbsize(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tuint64_t size = serv->ssdb->size();\n\tresp->push_back(\"ok\");\n\tresp->push_back(str(size));\n\treturn 0;\n}\n\nint proc_version(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tresp->push_back(\"ok\");\n\tresp->push_back(SSDB_VERSION);\n\treturn 0;\n}\n\nint proc_info(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tresp->push_back(\"ok\");\n\tresp->push_back(\"ssdb-server\");\n\tresp->push_back(\"version\");\n\tresp->push_back(SSDB_VERSION);\n\t{\n\t\tresp->push_back(\"links\");\n\t\tresp->add(net->link_count);\n\t}\n\t{\n\t\tint64_t calls = 0;\n\t\tproc_map_t::iterator it;\n\t\tfor(it=net->proc_map.begin(); it!=net->proc_map.end(); it++){\n\t\t\tCommand *cmd = it->second;\n\t\t\tcalls += cmd->calls;\n\t\t}\n\t\tresp->push_back(\"total_calls\");\n\t\tresp->add(calls);\n\t}\n\t\n\t{\n\t\tuint64_t size = serv->ssdb->size();\n\t\tresp->push_back(\"dbsize\");\n\t\tresp->push_back(str(size));\n\t}\n\n\t{\n\t\tstd::string s = serv->ssdb->binlogs->stats();\n\t\tresp->push_back(\"binlogs\");\n\t\tresp->push_back(s);\n\t}\n\t{\n\t\tstd::vector<std::string> syncs = serv->backend_sync->stats();\n\t\tstd::vector<std::string>::iterator it;\n\t\tfor(it = syncs.begin(); it != syncs.end(); it++){\n\t\t\tstd::string s = *it;\n\t\t\tresp->push_back(\"replication\");\n\t\t\tresp->push_back(s);\n\t\t}\n\t}\n\t{\n\t\tstd::vector<Slave *>::iterator it;\n\t\tfor(it = serv->slaves.begin(); it != serv->slaves.end(); it++){\n\t\t\tSlave *slave = *it;\n\t\t\tstd::string s = slave->stats();\n\t\t\tresp->push_back(\"replication\");\n\t\t\tresp->push_back(s);\n\t\t}\n\t}\n\t{\n\t\tstd::string val;\n\t\tstd::string s, e;\n\t\tserv->get_kv_range(&s, &e);\n\t\tchar buf[512];\n\t\t{\n\t\t\tsnprintf(buf, sizeof(buf), \"    kv  : \\\"%s\\\" - \\\"%s\\\"\",\n\t\t\t\tstr_escape(s).c_str(),\n\t\t\t\tstr_escape(e).c_str()\n\t\t\t\t);\n\t\t\tval.append(buf);\n\t\t}\n\t\t{\n\t\t\tsnprintf(buf, sizeof(buf), \"\\n    hash: \\\"\\\" - \\\"\\\"\");\n\t\t\tval.append(buf);\n\t\t}\n\t\t{\n\t\t\tsnprintf(buf, sizeof(buf), \"\\n    zset: \\\"\\\" - \\\"\\\"\");\n\t\t\tval.append(buf);\n\t\t}\n\t\t{\n\t\t\tsnprintf(buf, sizeof(buf), \"\\n    list: \\\"\\\" - \\\"\\\"\");\n\t\t\tval.append(buf);\n\t\t}\n\t\tresp->push_back(\"serv_key_range\");\n\t\tresp->push_back(val);\n\t}\n\n\tif(req.size() == 1 || req[1] == \"range\"){\n\t\tstd::string val;\n\t\tstd::vector<std::string> tmp;\n\t\tint ret = serv->ssdb->key_range(&tmp);\n\t\tif(ret == 0){\n\t\t\tchar buf[512];\n\t\t\t\n\t\t\tsnprintf(buf, sizeof(buf), \"    kv  : \\\"%s\\\" - \\\"%s\\\"\",\n\t\t\t\thexmem(tmp[0].data(), tmp[0].size()).c_str(),\n\t\t\t\thexmem(tmp[1].data(), tmp[1].size()).c_str()\n\t\t\t\t);\n\t\t\tval.append(buf);\n\t\t\t\n\t\t\tsnprintf(buf, sizeof(buf), \"\\n    hash: \\\"%s\\\" - \\\"%s\\\"\",\n\t\t\t\thexmem(tmp[2].data(), tmp[2].size()).c_str(),\n\t\t\t\thexmem(tmp[3].data(), tmp[3].size()).c_str()\n\t\t\t\t);\n\t\t\tval.append(buf);\n\t\t\t\n\t\t\tsnprintf(buf, sizeof(buf), \"\\n    zset: \\\"%s\\\" - \\\"%s\\\"\",\n\t\t\t\thexmem(tmp[4].data(), tmp[4].size()).c_str(),\n\t\t\t\thexmem(tmp[5].data(), tmp[5].size()).c_str()\n\t\t\t\t);\n\t\t\tval.append(buf);\n\t\t\t\n\t\t\tsnprintf(buf, sizeof(buf), \"\\n    list: \\\"%s\\\" - \\\"%s\\\"\",\n\t\t\t\thexmem(tmp[6].data(), tmp[6].size()).c_str(),\n\t\t\t\thexmem(tmp[7].data(), tmp[7].size()).c_str()\n\t\t\t\t);\n\t\t\tval.append(buf);\n\t\t}\n\t\tresp->push_back(\"data_key_range\");\n\t\tresp->push_back(val);\n\t}\n\n\tif(req.size() == 1 || req[1] == \"leveldb\"){\n\t\tstd::vector<std::string> tmp = serv->ssdb->info();\n\t\tfor(int i=0; i<(int)tmp.size(); i++){\n\t\t\tstd::string block = tmp[i];\n\t\t\tresp->push_back(block);\n\t\t}\n\t}\n\n\tif(req.size() > 1 && req[1] == \"cmd\"){\n\t\tproc_map_t::iterator it;\n\t\tfor(it=net->proc_map.begin(); it!=net->proc_map.end(); it++){\n\t\t\tCommand *cmd = it->second;\n\t\t\tresp->push_back(\"cmd.\" + cmd->name);\n\t\t\tchar buf[128];\n\t\t\tsnprintf(buf, sizeof(buf), \"calls: %\" PRIu64 \"\\ttime_wait: %.0f\\ttime_proc: %.0f\",\n\t\t\t\tcmd->calls, cmd->time_wait, cmd->time_proc);\n\t\t\tresp->push_back(buf);\n\t\t}\n\t}\n\t\n\treturn 0;\n}\n\nint proc_dump(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tserv->backend_dump->proc(link);\n\treturn PROC_BACKEND;\n}\n\nint proc_sync140(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tserv->backend_sync->proc(link);\n\treturn PROC_BACKEND;\n}\n\n// slaveof id host port [auth last_seq last_key]\nint proc_slaveof(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\t\n\tstd::string id = req[1].String();\n\tstd::string host = req[2].String();\n\tint port = req[3].Int();\n\tstd::string auth;\n\tuint64_t last_seq = 0;\n\tstd::string last_key;\n\tlog_info(\"start slaveof: %s:%d, type: sync\", host.c_str(), port);\n\tif(req.size() > 4 && !req[4].empty()){\n\t\tauth = req[4].String();\n\t\tlog_info(\"    auth: ***\");\n\t}\n\tif(req.size() > 5 && !req[5].empty()){\n\t\tlast_seq = req[5].Uint64();\n\t\tlog_info(\"    last_seq: %\" PRIu64, last_seq);\n\t}\n\tif(req.size() > 6 && !req[6].empty()){\n\t\tlast_key = req[6].String();\n\t\tlog_info(\"    last_key: %s\", hexmem(last_key.data(), last_key.size()).c_str());\n\t}\n\t\n\tserv->slaveof(id, host, port, auth, last_seq, last_key, false, 0);\n\n\tresp->push_back(\"ok\");\n\treturn 0;\n}\n\nint proc_clear_binlog(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tserv->ssdb->binlogs->flush();\n\tresp->push_back(\"ok\");\n\treturn 0;\n}\n"
  },
  {
    "path": "src/proc_sys.h",
    "content": "/*\nCopyright (c) 2012-2018 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n/* system commands */\n#include \"serv.h\"\n#include \"net/proc.h\"\n#include \"net/server.h\"\n\nDEF_PROC(flushdb);\nDEF_PROC(info);\nDEF_PROC(version);\nDEF_PROC(dbsize);\nDEF_PROC(compact);\nDEF_PROC(dump);\nDEF_PROC(sync140);\nDEF_PROC(slaveof);\nDEF_PROC(clear_binlog);\n\nDEF_PROC(get_key_range);\nDEF_PROC(ignore_key_range);\nDEF_PROC(get_kv_range);\nDEF_PROC(set_kv_range);\n"
  },
  {
    "path": "src/proc_zset.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"proc_zset.h\"\n\nint proc_zexists(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\n\tconst Bytes &name = req[1];\n\tconst Bytes &key = req[2];\n\tstd::string val;\n\tint ret = serv->ssdb->zget(name, key, &val);\n\tresp->reply_bool(ret);\n\treturn 0;\n}\n\nint proc_multi_zexists(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\n\tresp->push_back(\"ok\");\n\tconst Bytes &name = req[1];\n\tstd::string val;\n\tfor(Request::const_iterator it=req.begin()+2; it!=req.end(); it++){\n\t\tconst Bytes &key = *it;\n\t\tint64_t ret = serv->ssdb->zget(name, key, &val);\n\t\tresp->push_back(key.String());\n\t\tif(ret > 0){\n\t\t\tresp->push_back(\"1\");\n\t\t}else{\n\t\t\tresp->push_back(\"0\");\n\t\t}\n\t}\n\treturn 0;\n}\n\nint proc_multi_zsize(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\n\tresp->push_back(\"ok\");\n\tfor(Request::const_iterator it=req.begin()+1; it!=req.end(); it++){\n\t\tconst Bytes &key = *it;\n\t\tint64_t ret = serv->ssdb->zsize(key);\n\t\tresp->push_back(key.String());\n\t\tif(ret == -1){\n\t\t\tresp->push_back(\"-1\");\n\t\t}else{\n\t\t\tresp->add(ret);\n\t\t}\n\t}\n\treturn 0;\n}\n\nint proc_multi_zset(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tif(req.size() < 4 || req.size() % 2 != 0){\n\t\tresp->push_back(\"client_error\");\n\t}else{\n\t\tint num = 0;\n\t\tconst Bytes &name = req[1];\n\t\tstd::vector<Bytes>::const_iterator it = req.begin() + 2;\n\t\tfor(; it != req.end(); it += 2){\n\t\t\tconst Bytes &key = *it;\n\t\t\tconst Bytes &val = *(it + 1);\n\t\t\tint ret = serv->ssdb->zset(name, key, val);\n\t\t\tif(ret == -1){\n\t\t\t\tresp->push_back(\"error\");\n\t\t\t\treturn 0;\n\t\t\t}else{\n\t\t\t\tnum += ret;\n\t\t\t}\n\t\t}\n\t\tresp->reply_int(0, num);\n\t}\n\treturn 0;\n}\n\nint proc_multi_zdel(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\n\tint num = 0;\n\tconst Bytes &name = req[1];\n\tstd::vector<Bytes>::const_iterator it = req.begin() + 2;\n\tfor(; it != req.end(); it += 1){\n\t\tconst Bytes &key = *it;\n\t\tint ret = serv->ssdb->zdel(name, key);\n\t\tif(ret == -1){\n\t\t\tresp->push_back(\"error\");\n\t\t\treturn 0;\n\t\t}else{\n\t\t\tnum += ret;\n\t\t}\n\t}\n\tresp->reply_int(0, num);\n\treturn 0;\n}\n\nint proc_multi_zget(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\n\tresp->push_back(\"ok\");\n\tRequest::const_iterator it=req.begin() + 1;\n\tconst Bytes name = *it;\n\tit ++;\n\tfor(; it!=req.end(); it+=1){\n\t\tconst Bytes &key = *it;\n\t\tstd::string score;\n\t\tint ret = serv->ssdb->zget(name, key, &score);\n\t\tif(ret == 1){\n\t\t\tresp->push_back(key.String());\n\t\t\tresp->push_back(score);\n\t\t}\n\t}\n\treturn 0;\n}\n\nint proc_zset(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tint ret = serv->ssdb->zset(req[1], req[2], req[3]);\n\tresp->reply_int(ret, ret);\n\treturn 0;\n}\n\nint proc_zsize(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\n\tint64_t ret = serv->ssdb->zsize(req[1]);\n\tresp->reply_int(ret, ret);\n\treturn 0;\n}\n\nint proc_zget(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\n\tstd::string score;\n\tint ret = serv->ssdb->zget(req[1], req[2], &score);\n\tresp->reply_get(ret, &score);\n\treturn 0;\n}\n\nint proc_zdel(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\n\tint ret = serv->ssdb->zdel(req[1], req[2]);\n\tresp->reply_bool(ret);\n\treturn 0;\n}\n\nint proc_zrank(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\n\tint64_t ret = serv->ssdb->zrank(req[1], req[2]);\n\tif(ret == -1){\n\t\tresp->add(\"not_found\");\n\t}else{\n\t\tresp->reply_int(ret, ret);\n\t}\n\treturn 0;\n}\n\nint proc_zrrank(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\n\tint64_t ret = serv->ssdb->zrrank(req[1], req[2]);\n\tif(ret == -1){\n\t\tresp->add(\"not_found\");\n\t}else{\n\t\tresp->reply_int(ret, ret);\n\t}\n\treturn 0;\n}\n\nint proc_zrange(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tuint64_t offset = req[2].Uint64();\n\tuint64_t limit = req[3].Uint64();\n\tZIterator *it = serv->ssdb->zrange(req[1], offset, limit);\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tresp->push_back(it->key);\n\t\tresp->push_back(it->score);\n\t}\n\tdelete it;\n\treturn 0;\n}\n\nint proc_zrrange(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tuint64_t offset = req[2].Uint64();\n\tuint64_t limit = req[3].Uint64();\n\tZIterator *it = serv->ssdb->zrrange(req[1], offset, limit);\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tresp->push_back(it->key);\n\t\tresp->push_back(it->score);\n\t}\n\tdelete it;\n\treturn 0;\n}\n\nint proc_redis_zrange(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tint64_t start = req[2].Int64();\n\tint64_t end = req[3].Int64();\n\tuint64_t limit;\n\tif(start < 0 || end < 0){\n\t\tint64_t size = serv->ssdb->zsize(req[1]);\n\t\tif(start < 0){\n\t\t\tstart = size + start;\n\t\t\tif(start < 0){\n\t\t\t\tstart = 0;\n\t\t\t}\n\t\t}\n\t\tif(end < 0){\n\t\t\tend = size + end;\n\t\t}\n\t}\n\tif(end < 0 || start > end){\n\t\tresp->push_back(\"ok\");\n\t\treturn 0;\n\t}\n\tlimit = end - start + 1;\n\n\tZIterator *it = serv->ssdb->zrange(req[1], start, limit);\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tresp->push_back(it->key);\n\t\tresp->push_back(it->score);\n\t}\n\tdelete it;\n\treturn 0;\n}\n\nint proc_redis_zrrange(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tint64_t start = req[2].Int64();\n\tint64_t end = req[3].Int64();\n\tuint64_t limit;\n\tif(start < 0 || end < 0){\n\t\tint64_t size = serv->ssdb->zsize(req[1]);\n\t\tif(start < 0){\n\t\t\tstart = size + start;\n\t\t\tif(start < 0){\n\t\t\t\tstart = 0;\n\t\t\t}\n\t\t}\n\t\tif(end < 0){\n\t\t\tend = size + end;\n\t\t}\n\t}\n\tif(end < 0 || start > end){\n\t\tresp->push_back(\"ok\");\n\t\treturn 0;\n\t}\n\tlimit = end - start + 1;\n\n\tZIterator *it = serv->ssdb->zrrange(req[1], start, limit);\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tresp->push_back(it->key);\n\t\tresp->push_back(it->score);\n\t}\n\tdelete it;\n\treturn 0;\n}\n\nint proc_zclear(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\t\n\tconst Bytes &name = req[1];\n\tint64_t count = 0;\n\tstd::string key_start, score_start;\n\twhile(1){\n\t\tZIterator *it = serv->ssdb->zscan(name, key_start, score_start, \"\", 1000);\n\t\tint num = 0;\n\t\twhile(it->next()){\n\t\t\tkey_start = it->key;\n\t\t\tscore_start = it->score;\n\t\t\tint ret = serv->ssdb->zdel(name, key_start);\n\t\t\tif(ret == -1){\n\t\t\t\tresp->push_back(\"error\");\n\t\t\t\tdelete it;\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tnum ++;\n\t\t};\n\t\tdelete it;\n\t\t\n\t\tif(num == 0){\n\t\t\tbreak;\n\t\t}\n\t\tcount += num;\n\t}\n\tresp->reply_int(0, count);\n\n\treturn 0;\n}\n\nint proc_zscan(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(6);\n\n\tuint64_t limit = req[5].Uint64();\n\tuint64_t offset = 0;\n\tif(req.size() > 6){\n\t\toffset = limit;\n\t\tlimit = offset + req[6].Uint64();\n\t}\n\tZIterator *it = serv->ssdb->zscan(req[1], req[2], req[3], req[4], limit);\n\tif(offset > 0){\n\t\tit->skip(offset);\n\t}\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tresp->push_back(it->key);\n\t\tresp->push_back(it->score);\n\t}\n\tdelete it;\n\treturn 0;\n}\n\nint proc_zrscan(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(6);\n\n\tuint64_t limit = req[5].Uint64();\n\tuint64_t offset = 0;\n\tif(req.size() > 6){\n\t\toffset = limit;\n\t\tlimit = offset + req[6].Uint64();\n\t}\n\tZIterator *it = serv->ssdb->zrscan(req[1], req[2], req[3], req[4], limit);\n\tif(offset > 0){\n\t\tit->skip(offset);\n\t}\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tresp->push_back(it->key);\n\t\tresp->push_back(it->score);\n\t}\n\tdelete it;\n\treturn 0;\n}\n\nint proc_zkeys(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(6);\n\n\tuint64_t limit = req[5].Uint64();\n\tZIterator *it = serv->ssdb->zscan(req[1], req[2], req[3], req[4], limit);\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tresp->push_back(it->key);\n\t}\n\tdelete it;\n\treturn 0;\n}\n\nint proc_zlist(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tuint64_t limit = req[3].Uint64();\n\tstd::vector<std::string> list;\n\tint ret = serv->ssdb->zlist(req[1], req[2], limit, &list);\n\tresp->reply_list(ret, list);\n\treturn 0;\n}\n\nint proc_zrlist(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tuint64_t limit = req[3].Uint64();\n\tstd::vector<std::string> list;\n\tint ret = serv->ssdb->zrlist(req[1], req[2], limit, &list);\n\tresp->reply_list(ret, list);\n\treturn 0;\n}\n\n// dir := +1|-1\nstatic int _zincr(SSDB *ssdb, const Request &req, Response *resp, int dir){\n\tCHECK_NUM_PARAMS(3);\n\n\tint64_t by = 1;\n\tif(req.size() > 3){\n\t\tby = req[3].Int64();\n\t}\n\tint64_t new_val;\n\tint ret = ssdb->zincr(req[1], req[2], dir * by, &new_val);\n\tresp->reply_int(ret, new_val);\n\treturn 0;\n}\n\nint proc_zincr(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\treturn _zincr(serv->ssdb, req, resp, 1);\n}\n\nint proc_zdecr(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\treturn _zincr(serv->ssdb, req, resp, -1);\n}\n\nint proc_zcount(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tint64_t count = 0;\n\tZIterator *it = serv->ssdb->zscan(req[1], \"\", req[2], req[3], -1);\n\twhile(it->next()){\n\t\tcount ++;\n\t}\n\tdelete it;\n\t\n\tresp->reply_int(0, count);\n\treturn 0;\n}\n\nint proc_zsum(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tint64_t sum = 0;\n\tZIterator *it = serv->ssdb->zscan(req[1], \"\", req[2], req[3], -1);\n\twhile(it->next()){\n\t\tsum += str_to_int64(it->score);\n\t}\n\tdelete it;\n\t\n\tresp->reply_int(0, sum);\n\treturn 0;\n}\n\nint proc_zavg(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tint64_t sum = 0;\n\tint64_t count = 0;\n\tZIterator *it = serv->ssdb->zscan(req[1], \"\", req[2], req[3], -1);\n\twhile(it->next()){\n\t\tsum += str_to_int64(it->score);\n\t\tcount ++;\n\t}\n\tdelete it;\n\tdouble avg = (double)sum/count;\n\t\n\tresp->push_back(\"ok\");\n\tresp->add(avg);\n\treturn 0;\n}\n\nint proc_zremrangebyscore(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tZIterator *it = serv->ssdb->zscan(req[1], \"\", req[2], req[3], -1);\n\tint64_t count = 0;\n\twhile(it->next()){\n\t\tcount ++;\n\t\tint ret = serv->ssdb->zdel(req[1], it->key);\n\t\tif(ret == -1){\n\t\t\tdelete it;\n\t\t\tresp->push_back(\"error\");\n\t\t\treturn 0;\n\t\t}\n\t}\n\tdelete it;\n\t\n\tresp->reply_int(0, count);\n\treturn 0;\n}\n\nint proc_zremrangebyrank(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(4);\n\n\tint64_t start = req[2].Int64();\n\tint64_t end = req[3].Int64();\n\tif(start < 0 || end < 0){\n\t\tint64_t size = serv->ssdb->zsize(req[1]);\n\t\tif(start < 0){\n\t\t\tstart = size + start;\n\t\t\tif(start < 0){\n\t\t\t\tstart = 0;\n\t\t\t}\n\t\t}\n\t\tif(end < 0){\n\t\t\tend = size + end;\n\t\t}\n\t}\n\tif(end < 0 || start > end){\n\t\tresp->reply_int(0, 0);\n\t\treturn 0;\n\t}\n\t\n\tZIterator *it = serv->ssdb->zrange(req[1], start, end - start + 1);\n\tint64_t count = 0;\n\twhile(it->next()){\n\t\tcount ++;\n\t\tint ret = serv->ssdb->zdel(req[1], it->key);\n\t\tif(ret == -1){\n\t\t\tresp->push_back(\"error\");\n\t\t\tdelete it;\n\t\t\treturn 0;\n\t\t}\n\t}\n\tdelete it;\n\t\n\tresp->reply_int(0, count);\n\treturn 0;\n}\n\n// 因为 writer 线程只有一个, 所以这个操作还是线程安全的\nstatic inline\nvoid zpop(ZIterator *it, SSDBServer *serv, const Bytes &name, Response *resp){\n\tresp->push_back(\"ok\");\n\twhile(it->next()){\n\t\tint ret = serv->ssdb->zdel(name, it->key);\n\t\tif(ret == 1){\n\t\t\tresp->add(it->key);\n\t\t\tresp->add(it->score);\n\t\t}\n\t}\n}\n\nint proc_zpop_front(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\n\tconst Bytes &name = req[1];\n\tuint64_t limit = req[2].Uint64();\n\tZIterator *it = serv->ssdb->zscan(name, \"\", \"\", \"\", limit);\n\tzpop(it, serv, name, resp);\n\tdelete it;\n\treturn 0;\n}\n\nint proc_zpop_back(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(3);\n\n\tconst Bytes &name = req[1];\n\tuint64_t limit = req[2].Uint64();\n\tZIterator *it = serv->ssdb->zrscan(name, \"\", \"\", \"\", limit);\n\tzpop(it, serv, name, resp);\n\tdelete it;\n\treturn 0;\n}\n\nint proc_zfix(NetworkServer *net, Link *link, const Request &req, Response *resp){\n\tSSDBServer *serv = (SSDBServer *)net->data;\n\tCHECK_NUM_PARAMS(2);\n\t\n\tconst Bytes &name = req[1];\n\tint64_t ret = serv->ssdb->zfix(name);\n\tresp->reply_int(ret, ret);\n\treturn 0;\n}\n"
  },
  {
    "path": "src/proc_zset.h",
    "content": "/*\nCopyright (c) 2012-2018 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n/* zset commands */\n#include \"serv.h\"\n#include \"net/proc.h\"\n#include \"net/server.h\"\n\nDEF_PROC(zrank);\nDEF_PROC(zrrank);\nDEF_PROC(zrange);\nDEF_PROC(zrrange);\nDEF_PROC(redis_zrange);\nDEF_PROC(redis_zrrange);\nDEF_PROC(zsize);\nDEF_PROC(zget);\nDEF_PROC(zset);\nDEF_PROC(zdel);\nDEF_PROC(zincr);\nDEF_PROC(zdecr);\nDEF_PROC(zclear);\nDEF_PROC(zfix);\nDEF_PROC(zscan);\nDEF_PROC(zrscan);\nDEF_PROC(zkeys);\nDEF_PROC(zlist);\nDEF_PROC(zrlist);\nDEF_PROC(zcount);\nDEF_PROC(zsum);\nDEF_PROC(zavg);\nDEF_PROC(zexists);\nDEF_PROC(zremrangebyrank);\nDEF_PROC(zremrangebyscore);\nDEF_PROC(multi_zexists);\nDEF_PROC(multi_zsize);\nDEF_PROC(multi_zget);\nDEF_PROC(multi_zset);\nDEF_PROC(multi_zdel);\nDEF_PROC(zpop_front);\nDEF_PROC(zpop_back);\n"
  },
  {
    "path": "src/serv.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"version.h\"\n#include \"util/log.h\"\n#include \"util/string_util.h\"\n#include \"serv.h\"\n#include \"net/proc.h\"\n#include \"net/server.h\"\n#include \"proc_sys.h\"\n#include \"proc_kv.h\"\n#include \"proc_hash.h\"\n#include \"proc_zset.h\"\n#include \"proc_queue.h\"\n\n#define REG_PROC(c, f)     net->proc_map.set_proc(#c, f, proc_##c)\n\nvoid SSDBServer::reg_procs(NetworkServer *net){\n\tREG_PROC(get, \"rt\");\n\tREG_PROC(set, \"wt\");\n\tREG_PROC(del, \"wt\");\n\tREG_PROC(setx, \"wt\");\n\tREG_PROC(setnx, \"wt\");\n\tREG_PROC(getset, \"wt\");\n\tREG_PROC(getbit, \"rt\");\n\tREG_PROC(setbit, \"wt\");\n\tREG_PROC(countbit, \"rt\");\n\tREG_PROC(substr, \"rt\");\n\tREG_PROC(getrange, \"rt\");\n\tREG_PROC(strlen, \"rt\");\n\tREG_PROC(bitcount, \"rt\");\n\tREG_PROC(incr, \"wt\");\n\tREG_PROC(decr, \"wt\");\n\tREG_PROC(scan, \"rt\");\n\tREG_PROC(rscan, \"rt\");\n\tREG_PROC(keys, \"rt\");\n\tREG_PROC(rkeys, \"rt\");\n\tREG_PROC(exists, \"rt\");\n\tREG_PROC(multi_exists, \"rt\");\n\tREG_PROC(multi_get, \"rt\");\n\tREG_PROC(multi_set, \"wt\");\n\tREG_PROC(multi_del, \"wt\");\n\tREG_PROC(ttl, \"rt\");\n\tREG_PROC(expire, \"wt\");\n\n\tREG_PROC(hsize, \"rt\");\n\tREG_PROC(hget, \"rt\");\n\tREG_PROC(hset, \"wt\");\n\tREG_PROC(hdel, \"wt\");\n\tREG_PROC(hincr, \"wt\");\n\tREG_PROC(hdecr, \"wt\");\n\tREG_PROC(hclear, \"wt\");\n\tREG_PROC(hgetall, \"rt\");\n\tREG_PROC(hscan, \"rt\");\n\tREG_PROC(hrscan, \"rt\");\n\tREG_PROC(hkeys, \"rt\");\n\tREG_PROC(hvals, \"rt\");\n\tREG_PROC(hlist, \"rt\");\n\tREG_PROC(hrlist, \"rt\");\n\tREG_PROC(hexists, \"rt\");\n\tREG_PROC(multi_hexists, \"rt\");\n\tREG_PROC(multi_hsize, \"rt\");\n\tREG_PROC(multi_hget, \"rt\");\n\tREG_PROC(multi_hset, \"wt\");\n\tREG_PROC(multi_hdel, \"wt\");\n\tREG_PROC(hfix, \"wt\");\n\n\t// because zrank may be extremly slow, execute in a seperate thread\n\tREG_PROC(zrank, \"rt\");\n\tREG_PROC(zrrank, \"rt\");\n\tREG_PROC(zrange, \"rt\");\n\tREG_PROC(zrrange, \"rt\");\n\tREG_PROC(redis_zrange, \"rt\");\n\tREG_PROC(redis_zrrange, \"rt\");\n\tREG_PROC(zsize, \"rt\");\n\tREG_PROC(zget, \"rt\");\n\tREG_PROC(zset, \"wt\");\n\tREG_PROC(zdel, \"wt\");\n\tREG_PROC(zincr, \"wt\");\n\tREG_PROC(zdecr, \"wt\");\n\tREG_PROC(zclear, \"wt\");\n\tREG_PROC(zfix, \"wt\");\n\tREG_PROC(zscan, \"rt\");\n\tREG_PROC(zrscan, \"rt\");\n\tREG_PROC(zkeys, \"rt\");\n\tREG_PROC(zlist, \"rt\");\n\tREG_PROC(zrlist, \"rt\");\n\tREG_PROC(zcount, \"rt\");\n\tREG_PROC(zsum, \"rt\");\n\tREG_PROC(zavg, \"rt\");\n\tREG_PROC(zremrangebyrank, \"wt\");\n\tREG_PROC(zremrangebyscore, \"wt\");\n\tREG_PROC(zexists, \"rt\");\n\tREG_PROC(multi_zexists, \"rt\");\n\tREG_PROC(multi_zsize, \"rt\");\n\tREG_PROC(multi_zget, \"rt\");\n\tREG_PROC(multi_zset, \"wt\");\n\tREG_PROC(multi_zdel, \"wt\");\n\tREG_PROC(zpop_front, \"wt\");\n\tREG_PROC(zpop_back, \"wt\");\n\n\tREG_PROC(qsize, \"rt\");\n\tREG_PROC(qfront, \"rt\");\n\tREG_PROC(qback, \"rt\");\n\tREG_PROC(qpush, \"wt\");\n\tREG_PROC(qpush_front, \"wt\");\n\tREG_PROC(qpush_back, \"wt\");\n\tREG_PROC(qpop, \"wt\");\n\tREG_PROC(qpop_front, \"wt\");\n\tREG_PROC(qpop_back, \"wt\");\n\tREG_PROC(qtrim_front, \"wt\");\n\tREG_PROC(qtrim_back, \"wt\");\n\tREG_PROC(qfix, \"wt\");\n\tREG_PROC(qclear, \"wt\");\n\tREG_PROC(qlist, \"rt\");\n\tREG_PROC(qrlist, \"rt\");\n\tREG_PROC(qslice, \"rt\");\n\tREG_PROC(qrange, \"rt\");\n\tREG_PROC(qget, \"rt\");\n\tREG_PROC(qset, \"wt\");\n\n\tREG_PROC(clear_binlog, \"wt\");\n\tREG_PROC(flushdb, \"wt\");\n\n\tREG_PROC(dump, \"b\");\n\tREG_PROC(sync140, \"b\");\n\tREG_PROC(slaveof, \"w\");\n\tREG_PROC(info, \"rt\");\n\tREG_PROC(version, \"r\");\n\tREG_PROC(dbsize, \"rt\");\n\t// doing compaction in a reader thread, because we have only one\n\t// writer thread(for performance reason); we don't want to block writes\n\tREG_PROC(compact, \"rt\");\n\n\tREG_PROC(ignore_key_range, \"r\");\n\tREG_PROC(get_key_range, \"r\");\n\tREG_PROC(get_kv_range, \"r\");\n\tREG_PROC(set_kv_range, \"r\");\n}\n\n\nSSDBServer::SSDBServer(SSDB *ssdb, SSDB *meta, const Config &conf, NetworkServer *net){\n\tthis->ssdb = (SSDBImpl *)ssdb;\n\tthis->meta = meta;\n\n\tnet->data = this;\n\tthis->reg_procs(net);\n\n\tint sync_speed = conf.get_num(\"replication.sync_speed\");\n\n\tbackend_dump = new BackendDump(this->ssdb);\n\tbackend_sync = new BackendSync(this->ssdb, sync_speed);\n\texpiration = new ExpirationHandler(this->ssdb);\n\t\n\t{ // slaves\n\t\tconst Config *repl_conf = conf.get(\"replication\");\n\t\tif(repl_conf != NULL){\n\t\t\tstd::vector<Config *> children = repl_conf->children;\n\t\t\tfor(std::vector<Config *>::iterator it = children.begin(); it != children.end(); it++){\n\t\t\t\tConfig *c = *it;\n\t\t\t\tif(c->key != \"slaveof\"){\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tstd::string ip = c->get_str(\"ip\");\n\t\t\t\tint port = c->get_num(\"port\");\n\t\t\t\tif(ip == \"\"){\n\t\t\t\t\tip = c->get_str(\"host\");\n\t\t\t\t}\n\t\t\t\tif(ip == \"\" || port <= 0 || port > 65535){\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tbool is_mirror = false;\n\t\t\t\tstd::string type = c->get_str(\"type\");\n\t\t\t\tif(type == \"mirror\"){\n\t\t\t\t\tis_mirror = true;\n\t\t\t\t}else{\n\t\t\t\t\ttype = \"sync\";\n\t\t\t\t\tis_mirror = false;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tstd::string id = c->get_str(\"id\");\n\t\t\t\tstd::string auth = c->get_str(\"auth\");\n\t\t\t\tint recv_timeout = c->get_num(\"recv_timeout\");\n\t\t\t\t\n\t\t\t\tlog_info(\"slaveof: %s:%d, type: %s\", ip.c_str(), port, type.c_str());\n\t\t\t\tthis->slaveof(id, ip, port, auth, 0, \"\", is_mirror, recv_timeout);\n\t\t\t}\n\t\t}\n\t}\n\n\t// load kv_range\n\tint ret = this->get_kv_range(&this->kv_range_s, &this->kv_range_e);\n\tif(ret == -1){\n\t\tlog_fatal(\"load key_range failed!\");\n\t\texit(1);\n\t}\n\tlog_info(\"key_range.kv: \\\"%s\\\", \\\"%s\\\"\",\n\t\tstr_escape(this->kv_range_s).c_str(),\n\t\tstr_escape(this->kv_range_e).c_str()\n\t\t);\n}\n\nSSDBServer::~SSDBServer(){\n\tstd::vector<Slave *>::iterator it;\n\tfor(it = slaves.begin(); it != slaves.end(); it++){\n\t\tSlave *slave = *it;\n\t\tslave->stop();\n\t\tdelete slave;\n\t}\n\n\tdelete backend_dump;\n\tdelete backend_sync;\n\tdelete expiration;\n\n\tlog_debug(\"SSDBServer finalized\");\n}\n\nint SSDBServer::slaveof(const std::string &id, const std::string &host, int port, const std::string &auth, uint64_t last_seq, const std::string &last_key, bool is_mirror, int recv_timeout){\n\tSlave *slave = new Slave(ssdb, meta, host.c_str(), port, is_mirror);\n\tif(!id.empty()){\n\t\tslave->set_id(id);\n\t}\n\tif(recv_timeout > 0){\n\t\tslave->recv_timeout = recv_timeout;\n\t}\n\tslave->last_seq = last_seq;\n\tslave->last_key = last_key;\n\tslave->auth = auth;\n\tslave->start();\n\tslaves.push_back(slave);\n\treturn 0;\n}\n\nint SSDBServer::set_kv_range(const std::string &start, const std::string &end){\n\tif(meta->hset(\"key_range\", \"kv_s\", start) == -1){\n\t\treturn -1;\n\t}\n\tif(meta->hset(\"key_range\", \"kv_e\", end) == -1){\n\t\treturn -1;\n\t}\n\n\tkv_range_s = start;\n\tkv_range_e = end;\n\treturn 0;\n}\n\nint SSDBServer::get_kv_range(std::string *start, std::string *end){\n\tif(meta->hget(\"key_range\", \"kv_s\", start) == -1){\n\t\treturn -1;\n\t}\n\tif(meta->hget(\"key_range\", \"kv_e\", end) == -1){\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nbool SSDBServer::in_kv_range(const Bytes &key){\n\tif((this->kv_range_s.size() && this->kv_range_s >= key)\n\t\t|| (this->kv_range_e.size() && this->kv_range_e < key))\n\t{\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nbool SSDBServer::in_kv_range(const std::string &key){\n\tif((this->kv_range_s.size() && this->kv_range_s >= key)\n\t\t|| (this->kv_range_e.size() && this->kv_range_e < key))\n\t{\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n"
  },
  {
    "path": "src/serv.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef SSDB_SERVER_H_\n#define SSDB_SERVER_H_\n\n#include \"include.h\"\n#include <map>\n#include <vector>\n#include <string>\n#include \"ssdb/ssdb_impl.h\"\n#include \"ssdb/ttl.h\"\n#include \"backend_dump.h\"\n#include \"backend_sync.h\"\n#include \"slave.h\"\n#include \"net/server.h\"\n\nclass SSDBServer\n{\nprivate:\n\tvoid reg_procs(NetworkServer *net);\n\t\n\tstd::string kv_range_s;\n\tstd::string kv_range_e;\n\t\n\tSSDB *meta;\n\npublic:\n\tSSDBImpl *ssdb;\n\tBackendDump *backend_dump;\n\tBackendSync *backend_sync;\n\tExpirationHandler *expiration;\n\tstd::vector<Slave *> slaves;\n\n\tSSDBServer(SSDB *ssdb, SSDB *meta, const Config &conf, NetworkServer *net);\n\t~SSDBServer();\n\t\n\tint slaveof(const std::string &id, const std::string &host, int port, const std::string &auth, uint64_t last_seq, const std::string &last_key, bool is_mirror, int recv_timeout);\n\n\tint set_kv_range(const std::string &s, const std::string &e);\n\tint get_kv_range(std::string *s, std::string *e);\n\tbool in_kv_range(const std::string &key);\n\tbool in_kv_range(const Bytes &key);\n};\n\n#define CHECK_KV_KEY_RANGE(n) do{ \\\n\t\tif(!link->ignore_key_range && req.size() > n){ \\\n\t\t\tif(!serv->in_kv_range(req[n])){ \\\n\t\t\t\tresp->push_back(\"out_of_range\"); \\\n\t\t\t\treturn 0; \\\n\t\t\t} \\\n\t\t} \\\n\t}while(0)\n\n#define CHECK_NUM_PARAMS(n) do{ \\\n\t\tif(req.size() < n){ \\\n\t\t\tresp->push_back(\"client_error\"); \\\n\t\t\tresp->push_back(\"wrong number of arguments\"); \\\n\t\t\treturn 0; \\\n\t\t} \\\n\t}while(0)\n\n#endif\n"
  },
  {
    "path": "src/slave.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"net/fde.h\"\n#include \"util/log.h\"\n#include \"slave.h\"\n#include \"include.h\"\n\nSlave::Slave(SSDB *ssdb, SSDB *meta, const char *ip, int port, bool is_mirror){\n\tthread_quit = false;\n\tthis->recv_timeout = 30;\n\tthis->ssdb = ssdb;\n\tthis->meta = meta;\n\tthis->status = DISCONNECTED;\n\tthis->master_ip = std::string(ip);\n\tthis->master_port = port;\n\tthis->is_mirror = is_mirror;\n\tif(this->is_mirror){\n\t\tthis->log_type = BinlogType::MIRROR;\n\t}else{\n\t\tthis->log_type = BinlogType::SYNC;\n\t}\n\t\n\t{\n\t\tchar buf[128];\n\t\tsnprintf(buf, sizeof(buf), \"%s|%d\", master_ip.c_str(), master_port);\n\t\tthis->set_id(buf);\n\t}\n\t\n\tthis->link = NULL;\n\tthis->last_seq = 0;\n\tthis->last_key = \"\";\n\tthis->connect_retry = 0;\n\t\n\tthis->copy_count = 0;\n\tthis->sync_count = 0;\n}\n\nSlave::~Slave(){\n\tlog_debug(\"stopping slave thread...\");\n\tif(!thread_quit){\n\t\tstop();\n\t}\n\tif(link){\n\t\tdelete link;\n\t}\n\tlog_debug(\"Slave finalized\");\n}\n\nstd::string Slave::stats() const{\n\tstd::string s;\n\ts.append(\"slaveof \" + master_ip + \":\" + str(master_port) + \"\\n\");\n\ts.append(\"    id         : \" + id_ + \"\\n\");\n\tif(is_mirror){\n\t\ts.append(\"    type       : mirror\\n\");\n\t}else{\n\t\ts.append(\"    type       : sync\\n\");\n\t}\n\n\ts.append(\"    status     : \");\n\tswitch(status){\n\tcase DISCONNECTED:\n\t\ts.append(\"DISCONNECTED\\n\");\n\t\tbreak;\n\tcase INIT:\n\t\ts.append(\"INIT\\n\");\n\t\tbreak;\n\tcase COPY:\n\t\ts.append(\"COPY\\n\");\n\t\tbreak;\n\tcase SYNC:\n\t\ts.append(\"SYNC\\n\");\n\t\tbreak;\n\tcase OUT_OF_SYNC:\n\t\ts.append(\"OUT_OF_SYNC\\n\");\n\t\tbreak;\n\t}\n\n\ts.append(\"    last_seq   : \" + str(last_seq) + \"\\n\");\n\ts.append(\"    copy_count : \" + str(copy_count) + \"\\n\");\n\ts.append(\"    sync_count : \" + str(sync_count) + \"\");\n\treturn s;\n}\n\nvoid Slave::start(){\n\tmigrate_old_status();\n\tif(last_seq != 0 || !last_key.empty()){\n\t\tsave_status();\n\t}else{\n\t\tload_status();\n\t}\n\tlog_debug(\"last_seq: %\" PRIu64 \", last_key: %s\",\n\t\tlast_seq, hexmem(last_key.data(), last_key.size()).c_str());\n\n\tthread_quit = false;\n\tint err = pthread_create(&run_thread_tid, NULL, &Slave::_run_thread, this);\n\tif(err != 0){\n\t\tlog_error(\"can't create thread: %s\", strerror(err));\n\t}\n}\n\nvoid Slave::stop(){\n\tthread_quit = true;\n\tvoid *tret;\n\tint err = pthread_join(run_thread_tid, &tret);\n    if(err != 0){\n\t\tlog_error(\"can't join thread: %s\", strerror(err));\n\t}\n}\n\nvoid Slave::set_id(const std::string &id){\n\tthis->id_ = id;\n}\n\nvoid Slave::migrate_old_status(){\n\tstd::string old_key = \"new.slave.status|\" + this->id_;\n\tstd::string val;\n\tint old_found = meta->raw_get(old_key, &val);\n\tif(!old_found){\n\t\treturn;\n\t}\n\tif(val.size() < sizeof(uint64_t)){\n\t\tlog_error(\"invalid format of status\");\n\t\treturn;\n\t}\n\tlast_seq = *((uint64_t *)(val.data()));\n\tlast_key.assign(val.data() + sizeof(uint64_t), val.size() - sizeof(uint64_t));\n\t// migrate old status\n\tlog_info(\"migrate old version slave status to new format, last_seq: %\" PRIu64 \", last_key: %s\",\n\t\tlast_seq, hexmem(last_key.data(), last_key.size()).c_str());\n\t\n\tsave_status();\n\tif(meta->raw_del(old_key) == -1){\n\t\tlog_fatal(\"meta db error!\");\n\t\texit(1);\n\t}\n}\n\nstd::string Slave::status_key(){\n\tstd::string key;\n\tkey = \"slave.status.\" + this->id_;\n\treturn key;\n}\n\nvoid Slave::load_status(){\n\tstd::string key;\n\tstd::string seq;\n\tmeta->hget(status_key(), \"last_key\", &key);\n\tmeta->hget(status_key(), \"last_seq\", &seq);\n\tif(!key.empty()){\n\t\tthis->last_key = key;\n\t}\n\tif(!seq.empty()){\n\t\tthis->last_seq = str_to_uint64(seq);\n\t}\n}\n\nvoid Slave::save_status(){\n\tstd::string seq = str(this->last_seq);\n\tmeta->hset(status_key(), \"last_key\", this->last_key);\n\tmeta->hset(status_key(), \"last_seq\", seq);\n}\n\nint Slave::connect(){\n\tconst char *ip = this->master_ip.c_str();\n\tint port = this->master_port;\n\t\n\tif(++connect_retry % 50 == 1){\n\t\tlog_info(\"[%s][%d] connecting to master at %s:%d...\", this->id_.c_str(), (connect_retry-1)/50, ip, port);\n\t\tlink = Link::connect(ip, port);\n\t\tif(link == NULL){\n\t\t\tlog_error(\"[%s]failed to connect to master: %s:%d! %s\", this->id_.c_str(), ip, port, strerror(errno));\n\t\t\tgoto err;\n\t\t}else{\n\t\t\tstatus = INIT;\n\t\t\tconnect_retry = 0;\n\t\t\tconst char *type = is_mirror? \"mirror\" : \"sync\";\n\t\t\t\n\t\t\tif(!this->auth.empty()){\n\t\t\t\tconst std::vector<Bytes> *resp;\n\t\t\t\tresp = link->request(\"auth\", this->auth);\n\t\t\t\tif(resp->empty() || resp->at(0) != \"ok\"){\n\t\t\t\t\tlog_error(\"auth error\");\n\t\t\t\t\tdelete link;\n\t\t\t\t\tlink = NULL;\n\t\t\t\t\tsleep(1);\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tlink->send(\"sync140\", str(this->last_seq), this->last_key, type);\n\t\t\tif(link->flush() == -1){\n\t\t\t\tlog_error(\"[%s] network error\", this->id_.c_str());\n\t\t\t\tdelete link;\n\t\t\t\tlink = NULL;\n\t\t\t\tgoto err;\n\t\t\t}\n\t\t\tlog_info(\"[%s] ready to receive binlogs\", this->id_.c_str());\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\nerr:\n\treturn -1;\n}\n\nvoid* Slave::_run_thread(void *arg){\n\tSlave *slave = (Slave *)arg;\n\tconst std::vector<Bytes> *req;\n\tFdevents select;\n\tconst Fdevents::events_t *events;\n\tint idle = 0;\n\tbool reconnect = false;\n\t\n#define RECV_TIMEOUT\t\t200\n\tint max_idle = (slave->recv_timeout * 1000) / RECV_TIMEOUT;\n\n\twhile(!slave->thread_quit){\n\t\tif(reconnect){\n\t\t\tslave->status = DISCONNECTED;\n\t\t\treconnect = false;\n\t\t\tselect.del(slave->link->fd());\n\t\t\tdelete slave->link;\n\t\t\tslave->link = NULL;\n\t\t\tsleep(1);\n\t\t}\n\t\tif(!slave->connected()){\n\t\t\tif(slave->connect() != 1){\n\t\t\t\tusleep(100 * 1000);\n\t\t\t}else{\n\t\t\t\tselect.set(slave->link->fd(), FDEVENT_IN, 0, NULL);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\t\n\t\tevents = select.wait(RECV_TIMEOUT);\n\t\tif(events == NULL){\n\t\t\tlog_error(\"events.wait error: %s\", strerror(errno));\n\t\t\tsleep(1);\n\t\t\tcontinue;\n\t\t}else if(events->empty()){\n\t\t\tif(idle++ >= max_idle){\n\t\t\t\tlog_error(\"the master hasn't responsed for awhile, reconnect...\");\n\t\t\t\tidle = 0;\n\t\t\t\treconnect = true;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tidle = 0;\n\n\t\tif(slave->link->read() <= 0){\n\t\t\tlog_error(\"link.read error: %s, reconnecting to master\", strerror(errno));\n\t\t\treconnect = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\twhile(1){\n\t\t\treq = slave->link->recv();\n\t\t\tif(req == NULL){\n\t\t\t\tlog_error(\"link.recv error: %s, reconnecting to master\", strerror(errno));\n\t\t\t\treconnect = true;\n\t\t\t\tbreak;\n\t\t\t}else if(req->empty()){\n\t\t\t\tbreak;\n\t\t\t}else if(req->at(0) == \"noauth\"){\n\t\t\t\tlog_error(\"authentication required\");\n\t\t\t\treconnect = true;\n\t\t\t\tsleep(1);\n\t\t\t\tbreak;\n\t\t\t}else{\n\t\t\t\tif(slave->proc(*req) == -1){\n\t\t\t\t\tgoto err;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} // end while\n\tlog_info(\"Slave thread quit\");\n\treturn (void *)NULL;\n\nerr:\n\tlog_fatal(\"Slave thread exit unexpectedly\");\n\texit(0);\n\treturn (void *)NULL;;\n}\n\nint Slave::proc(const std::vector<Bytes> &req){\n\tBinlog log;\n\tif(log.load(req[0]) == -1){\n\t\tlog_error(\"invalid binlog!\");\n\t\treturn 0;\n\t}\n\tconst char *sync_type = this->is_mirror? \"mirror\" : \"sync\";\n\tswitch(log.type()){\n\t\tcase BinlogType::NOOP:\n\t\t\treturn this->proc_noop(log, req);\n\t\t\tbreak;\n\t\tcase BinlogType::CTRL:\n\t\t\tif(log.key() == \"OUT_OF_SYNC\"){\n\t\t\t\tstatus = OUT_OF_SYNC;\n\t\t\t\tlog_error(\"OUT_OF_SYNC, you must reset this node manually!\");\n\t\t\t}\n\t\t\tbreak;\n\t\tcase BinlogType::COPY:{\n\t\t\tstatus = COPY;\n\t\t\tif(req.size() >= 2){\n\t\t\t\tlog_debug(\"[%s] %s [%d]\", sync_type, log.dumps().c_str(), req[1].size());\n\t\t\t}else{\n\t\t\t\tlog_debug(\"[%s] %s\", sync_type, log.dumps().c_str());\n\t\t\t}\n\t\t\tthis->proc_copy(log, req);\n\t\t\tbreak;\n\t\t}\n\t\tcase BinlogType::SYNC:\n\t\tcase BinlogType::MIRROR:{\n\t\t\tstatus = SYNC;\n\t\t\tif(++sync_count % 1000 == 1){\n\t\t\t\tlog_info(\"sync_count: %\" PRIu64 \", last_seq: %\" PRIu64 \", seq: %\" PRIu64 \"\",\n\t\t\t\t\tsync_count, this->last_seq, log.seq());\n\t\t\t}\n\t\t\tif(req.size() >= 2){\n\t\t\t\tlog_debug(\"[%s] %s [%d]\", sync_type, log.dumps().c_str(), req[1].size());\n\t\t\t}else{\n\t\t\t\tlog_debug(\"[%s] %s\", sync_type, log.dumps().c_str());\n\t\t\t}\n\t\t\tthis->proc_sync(log, req);\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\treturn 0;\n}\n\nint Slave::proc_noop(const Binlog &log, const std::vector<Bytes> &req){\n\tuint64_t seq = log.seq();\n\tif(this->last_seq != seq){\n\t\tlog_debug(\"noop last_seq: %\" PRIu64 \", seq: %\" PRIu64 \"\", this->last_seq, seq);\n\t\tthis->last_seq = seq;\n\t\tthis->save_status();\n\t}\n\treturn 0;\n}\n\nint Slave::proc_copy(const Binlog &log, const std::vector<Bytes> &req){\n\tswitch(log.cmd()){\n\t\tcase BinlogCommand::BEGIN:\n\t\t\tlog_info(\"copy begin\");\n\t\t\t// log_info(\"start flushdb...\");\n\t\t\t// this->last_seq = 0;\n\t\t\t// this->last_key = \"\";\n\t\t\t// this->save_status();\n\t\t\t// ssdb->flushdb();\n\t\t\t// log_info(\"end flushdb.\");\n\t\t\tbreak;\n\t\tcase BinlogCommand::END:\n\t\t\tlog_info(\"copy end, copy_count: %\" PRIu64 \", last_seq: %\" PRIu64 \", seq: %\" PRIu64,\n\t\t\t\tcopy_count, this->last_seq, log.seq());\n\t\t\tthis->status = SYNC;\n\t\t\tthis->last_key = \"\";\n\t\t\tthis->save_status();\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif(++copy_count % 1000 == 1){\n\t\t\t\tlog_info(\"copy_count: %\" PRIu64 \", last_seq: %\" PRIu64 \", seq: %\" PRIu64 \"\",\n\t\t\t\t\tcopy_count, this->last_seq, log.seq());\n\t\t\t}\n\t\t\treturn proc_sync(log, req);\n\t\t\tbreak;\n\t}\n\treturn 0;\n}\n\nint Slave::proc_sync(const Binlog &log, const std::vector<Bytes> &req){\n\tswitch(log.cmd()){\n\t\tcase BinlogCommand::KSET:\n\t\t\t{\n\t\t\t\tif(req.size() != 2){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tstd::string key;\n\t\t\t\tif(decode_kv_key(log.key(), &key) == -1){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlog_trace(\"set %s\", hexmem(key.data(), key.size()).c_str());\n\t\t\t\tif(ssdb->set(key, req[1], log_type) == -1){\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase BinlogCommand::KDEL:\n\t\t\t{\n\t\t\t\tstd::string key;\n\t\t\t\tif(decode_kv_key(log.key(), &key) == -1){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlog_trace(\"del %s\", hexmem(key.data(), key.size()).c_str());\n\t\t\t\tif(ssdb->del(key, log_type) == -1){\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase BinlogCommand::HSET:\n\t\t\t{\n\t\t\t\tif(req.size() != 2){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tstd::string name, key;\n\t\t\t\tif(decode_hash_key(log.key(), &name, &key) == -1){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlog_trace(\"hset %s %s\",\n\t\t\t\t\thexmem(name.data(), name.size()).c_str(),\n\t\t\t\t\thexmem(key.data(), key.size()).c_str());\n\t\t\t\tif(ssdb->hset(name, key, req[1], log_type) == -1){\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase BinlogCommand::HDEL:\n\t\t\t{\n\t\t\t\tstd::string name, key;\n\t\t\t\tif(decode_hash_key(log.key(), &name, &key) == -1){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlog_trace(\"hdel %s %s\",\n\t\t\t\t\thexmem(name.data(), name.size()).c_str(),\n\t\t\t\t\thexmem(key.data(), key.size()).c_str());\n\t\t\t\tif(ssdb->hdel(name, key, log_type) == -1){\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase BinlogCommand::ZSET:\n\t\t\t{\n\t\t\t\tif(req.size() != 2){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tstd::string name, key;\n\t\t\t\tif(decode_zset_key(log.key(), &name, &key) == -1){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlog_trace(\"zset %s %s\",\n\t\t\t\t\thexmem(name.data(), name.size()).c_str(),\n\t\t\t\t\thexmem(key.data(), key.size()).c_str());\n\t\t\t\tif(ssdb->zset(name, key, req[1], log_type) == -1){\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase BinlogCommand::ZDEL:\n\t\t\t{\n\t\t\t\tstd::string name, key;\n\t\t\t\tif(decode_zset_key(log.key(), &name, &key) == -1){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlog_trace(\"zdel %s %s\",\n\t\t\t\t\thexmem(name.data(), name.size()).c_str(),\n\t\t\t\t\thexmem(key.data(), key.size()).c_str());\n\t\t\t\tif(ssdb->zdel(name, key, log_type) == -1){\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase BinlogCommand::QSET:\n\t\tcase BinlogCommand::QPUSH_BACK:\n\t\tcase BinlogCommand::QPUSH_FRONT:\n\t\t\t{\n\t\t\t\tif(req.size() != 2){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tstd::string name;\n\t\t\t\tuint64_t seq;\n\t\t\t\tif(decode_qitem_key(log.key(), &name, &seq) == -1){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif(seq < QITEM_MIN_SEQ || seq > QITEM_MAX_SEQ){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tint ret;\n\t\t\t\tif(log.cmd() == BinlogCommand::QSET){\n\t\t\t\t\tlog_trace(\"qset %s %\" PRIu64 \"\", hexmem(name.data(), name.size()).c_str(), seq);\n\t\t\t\t\tret = ssdb->qset_by_seq(name, seq, req[1], log_type);\n\t\t\t\t}else if(log.cmd() == BinlogCommand::QPUSH_BACK){\n\t\t\t\t\tlog_trace(\"qpush_back %s\", hexmem(name.data(), name.size()).c_str());\n\t\t\t\t\tret = ssdb->qpush_back(name, req[1], log_type);\n\t\t\t\t}else{\n\t\t\t\t\tlog_trace(\"qpush_front %s\", hexmem(name.data(), name.size()).c_str());\n\t\t\t\t\tret = ssdb->qpush_front(name, req[1], log_type);\n\t\t\t\t}\n\t\t\t\tif(ret == -1){\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase BinlogCommand::QPOP_BACK:\n\t\tcase BinlogCommand::QPOP_FRONT:\n\t\t\t{\n\t\t\t\tint ret;\n\t\t\t\tconst Bytes name = log.key();\n\t\t\t\tstd::string tmp;\n\t\t\t\tif(log.cmd() == BinlogCommand::QPOP_BACK){\n\t\t\t\t\tlog_trace(\"qpop_back %s\", hexmem(name.data(), name.size()).c_str());\n\t\t\t\t\tret = ssdb->qpop_back(name, &tmp, log_type);\n\t\t\t\t}else{\n\t\t\t\t\tlog_trace(\"qpop_front %s\", hexmem(name.data(), name.size()).c_str());\n\t\t\t\t\tret = ssdb->qpop_front(name, &tmp, log_type);\n\t\t\t\t}\n\t\t\t\tif(ret == -1){\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tlog_error(\"unknown binlog, type=%d, cmd=%d\", log.type(), log.cmd());\n\t\t\tbreak;\n\t}\n\tthis->last_seq = log.seq();\n\tif(log.type() == BinlogType::COPY){\n\t\tthis->last_key = log.key().String();\n\t}\n\tthis->save_status();\n\treturn 0;\n}\n\n"
  },
  {
    "path": "src/slave.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef SSDB_SLAVE_H_\n#define SSDB_SLAVE_H_\n\n#include <stdint.h>\n#include <string>\n#include <pthread.h>\n#include <vector>\n#include \"ssdb/ssdb_impl.h\"\n#include \"ssdb/binlog.h\"\n#include \"net/link.h\"\n\nclass Slave{\nprivate:\n\tuint64_t copy_count;\n\tuint64_t sync_count;\n\t\t\n\tstd::string id_;\n\n\tSSDB *ssdb;\n\tSSDB *meta;\n\tLink *link;\n\tstd::string master_ip;\n\tint master_port;\n\tbool is_mirror;\n\tchar log_type;\n\n\tstatic const int DISCONNECTED = 0;\n\tstatic const int INIT = 1;\n\tstatic const int COPY = 2;\n\tstatic const int SYNC = 4;\n\tstatic const int OUT_OF_SYNC = 8;\n\tint status;\n\n\tvoid migrate_old_status();\n\n\tstd::string status_key();\n\tvoid load_status();\n\tvoid save_status();\n\n\tvolatile bool thread_quit;\n\tpthread_t run_thread_tid;\n\tstatic void* _run_thread(void *arg);\n\t\t\n\tint proc(const std::vector<Bytes> &req);\n\tint proc_noop(const Binlog &log, const std::vector<Bytes> &req);\n\tint proc_copy(const Binlog &log, const std::vector<Bytes> &req);\n\tint proc_sync(const Binlog &log, const std::vector<Bytes> &req);\n\n\tunsigned int connect_retry;\n\tint connect();\n\tbool connected(){\n\t\treturn link != NULL;\n\t}\npublic:\n\t// the max time wait for a noop or binlog message from master,\n\t// after this time, the slave will disconnect from master.\n\t// in seconds, default 30\n\tint recv_timeout;\n\tuint64_t last_seq;\n\tstd::string last_key;\n\tstd::string auth;\n\tSlave(SSDB *ssdb, SSDB *meta, const char *ip, int port, bool is_mirror=false);\n\t~Slave();\n\tvoid start();\n\tvoid stop();\n\t\t\n\tvoid set_id(const std::string &id);\n\tstd::string stats() const;\n};\n\n#endif\n"
  },
  {
    "path": "src/ssdb/Makefile",
    "content": "include ../../build_config.mk\n\nOBJS = ssdb_impl.o iterator.o options.o \\\n\tt_kv.o t_hash.o t_zset.o t_queue.o binlog.o ttl.o\nLIBS = ../util/libutil.a\n\n\nall: ssdb.h ${OBJS}\n\tar -cru ./libssdb.a ${OBJS}\n\nssdb_impl.o: ssdb.h ssdb_impl.h ssdb_impl.cpp\n\t${CXX} ${CFLAGS} -c ssdb_impl.cpp\niterator.o: ssdb.h iterator.h iterator.cpp\n\t${CXX} ${CFLAGS} -c iterator.cpp\noptions.o: ssdb.h options.h options.cpp\n\t${CXX} ${CFLAGS} -c options.cpp\nt_kv.o: ssdb.h t_kv.h t_kv.cpp\n\t${CXX} ${CFLAGS} -c t_kv.cpp\nt_hash.o: ssdb.h t_hash.h t_hash.cpp\n\t${CXX} ${CFLAGS} -c t_hash.cpp\nt_zset.o: ssdb.h t_zset.h t_zset.cpp\n\t${CXX} ${CFLAGS} -c t_zset.cpp\nt_queue.o: ssdb.h t_queue.h t_queue.cpp\n\t${CXX} ${CFLAGS} -c t_queue.cpp\nbinlog.o: ssdb.h binlog.h binlog.cpp\n\t${CXX} ${CFLAGS} -c binlog.cpp\nttl.o: ssdb.h ttl.h ttl.cpp\n\t${CXX} ${CFLAGS} -c ttl.cpp\n\ntest:\n\t${CXX} -o test.out test.cpp ${OBJS} ${CFLAGS} ${LIBS} ${CLIBS}\n\nclean:\n\trm -f ${EXES} *.o *.exe *.a\n\n"
  },
  {
    "path": "src/ssdb/Makefile-ios",
    "content": "include ../../build_config.mk\n\nPLATFORMSROOT=/Applications/Xcode.app/Contents/Developer/Platforms\nSIMULATORROOT=$(PLATFORMSROOT)/iPhoneSimulator.platform/Developer\nDEVICEROOT=$(PLATFORMSROOT)/iPhoneOS.platform/Developer\nIOSVERSION=$(shell defaults read $(PLATFORMSROOT)/iPhoneOS.platform/version CFBundleShortVersionString)\nSIMULATOR_SDK=$(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk\nDEVICE_SDK=$(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk\n\nCFLAGS= -miphoneos-version-min=7.0 -stdlib=libc++ -DIOS -I. -O2 -I$(LEVELDB_PATH)/include\nSIMULATOR_CFLAGS=$(CFLAGS) -isysroot $(SIMULATOR_SDK) -arch i386 -arch x86_64\nDEVICE_CFLAGS=$(CFLAGS) -isysroot $(DEVICE_SDK) -arch armv6 -arch armv7 -arch armv7s -arch arm64\n\nOBJS = ssdb_impl.o iterator.o options.o t_kv.o t_hash.o t_zset.o t_queue.o binlog.o ttl.o\nLIB = libssdb-ios.a\nOUTPUT_LIB_DIR = ../../ios\nOUTPUT_HEADER_DIR = ../../ios/include/ssdb\n\nall: $(OBJS)\n\trm -f $(LIB)\n\tar -rs $(LIB) $(OBJS)\n\trm -rf $(OUTPUT_HEADER_DIR) $(OUTPUT_LIB_DIR)/$(LIB)\n\tmkdir -p $(OUTPUT_HEADER_DIR)\n\tcp -f const.h binlog.h iterator.h options.h ssdb.h ttl.h $(OUTPUT_HEADER_DIR)\n\tmv -f $(LIB) $(OUTPUT_LIB_DIR)\n\n.cpp.o:\n\tmkdir -p ios-x86\n\tmkdir -p ios-arm\n\txcrun -sdk iphonesimulator clang++ $(SIMULATOR_CFLAGS) -c $< -o ios-x86/$@\n\txcrun -sdk iphoneos clang++ $(DEVICE_CFLAGS) -c $< -o ios-arm/$@\n\tlipo ios-x86/$@ ios-arm/$@ -create -output $@\n\nclean:\n\trm -f ${EXES} *.o *.exe *.a\n\n"
  },
  {
    "path": "src/ssdb/binlog.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"binlog.h\"\n#include \"const.h\"\n#include \"../include.h\"\n#include \"../util/log.h\"\n#include \"../util/string_util.h\"\n#include <map>\n\n/* Binlog */\n\nBinlog::Binlog(uint64_t seq, char type, char cmd, const leveldb::Slice &key){\n\tbuf.append((char *)(&seq), sizeof(uint64_t));\n\tbuf.push_back(type);\n\tbuf.push_back(cmd);\n\tbuf.append(key.data(), key.size());\n}\n\nuint64_t Binlog::seq() const{\n\treturn *((uint64_t *)(buf.data()));\n}\n\nchar Binlog::type() const{\n\treturn buf[sizeof(uint64_t)];\n}\n\nchar Binlog::cmd() const{\n\treturn buf[sizeof(uint64_t) + 1];\n}\n\nconst Bytes Binlog::key() const{\n\treturn Bytes(buf.data() + HEADER_LEN, buf.size() - HEADER_LEN);\n}\n\nint Binlog::load(const Bytes &s){\n\tif(s.size() < HEADER_LEN){\n\t\treturn -1;\n\t}\n\tbuf.assign(s.data(), s.size());\n\treturn 0;\n}\n\nint Binlog::load(const leveldb::Slice &s){\n\tif(s.size() < HEADER_LEN){\n\t\treturn -1;\n\t}\n\tbuf.assign(s.data(), s.size());\n\treturn 0;\n}\n\nint Binlog::load(const std::string &s){\n\tif(s.size() < HEADER_LEN){\n\t\treturn -1;\n\t}\n\tbuf.assign(s.data(), s.size());\n\treturn 0;\n}\n\nstd::string Binlog::dumps() const{\n\tstd::string str;\n\tif(buf.size() < HEADER_LEN){\n\t\treturn str;\n\t}\n\tstr.reserve(128);\n\n\tchar buf[20];\n\tsnprintf(buf, sizeof(buf), \"%\" PRIu64 \" \", this->seq());\n\tstr.append(buf);\n\n\tswitch(this->type()){\n\t\tcase BinlogType::NOOP:\n\t\t\tstr.append(\"noop \");\n\t\t\tbreak;\n\t\tcase BinlogType::SYNC:\n\t\t\tstr.append(\"sync \");\n\t\t\tbreak;\n\t\tcase BinlogType::MIRROR:\n\t\t\tstr.append(\"mirror \");\n\t\t\tbreak;\n\t\tcase BinlogType::COPY:\n\t\t\tstr.append(\"copy \");\n\t\t\tbreak;\n\t\tcase BinlogType::CTRL:\n\t\t\tstr.append(\"control \");\n\t\t\tbreak;\n\t}\n\tswitch(this->cmd()){\n\t\tcase BinlogCommand::NONE:\n\t\t\tstr.append(\"none \");\n\t\t\tbreak;\n\t\tcase BinlogCommand::KSET:\n\t\t\tstr.append(\"set \");\n\t\t\tbreak;\n\t\tcase BinlogCommand::KDEL:\n\t\t\tstr.append(\"del \");\n\t\t\tbreak;\n\t\tcase BinlogCommand::HSET:\n\t\t\tstr.append(\"hset \");\n\t\t\tbreak;\n\t\tcase BinlogCommand::HDEL:\n\t\t\tstr.append(\"hdel \");\n\t\t\tbreak;\n\t\tcase BinlogCommand::ZSET:\n\t\t\tstr.append(\"zset \");\n\t\t\tbreak;\n\t\tcase BinlogCommand::ZDEL:\n\t\t\tstr.append(\"zdel \");\n\t\t\tbreak;\n\t\tcase BinlogCommand::BEGIN:\n\t\t\tstr.append(\"begin \");\n\t\t\tbreak;\n\t\tcase BinlogCommand::END:\n\t\t\tstr.append(\"end \");\n\t\t\tbreak;\n\t\tcase BinlogCommand::QPUSH_BACK:\n\t\t\tstr.append(\"qpush_back \");\n\t\t\tbreak;\n\t\tcase BinlogCommand::QPUSH_FRONT:\n\t\t\tstr.append(\"qpush_front \");\n\t\t\tbreak;\n\t\tcase BinlogCommand::QPOP_BACK:\n\t\t\tstr.append(\"qpop_back \");\n\t\t\tbreak;\n\t\tcase BinlogCommand::QPOP_FRONT:\n\t\t\tstr.append(\"qpop_front \");\n\t\t\tbreak;\n\t\tcase BinlogCommand::QSET:\n\t\t\tstr.append(\"qset \");\n\t\t\tbreak;\n\t}\n\tBytes b = this->key();\n\tstr.append(hexmem(b.data(), b.size()));\n\treturn str;\n}\n\n\n/* SyncLogQueue */\n\nstatic inline std::string encode_seq_key(uint64_t seq){\n\tseq = big_endian(seq);\n\tstd::string ret;\n\tret.push_back(DataType::SYNCLOG);\n\tret.append((char *)&seq, sizeof(seq));\n\treturn ret;\n}\n\nstatic inline uint64_t decode_seq_key(const leveldb::Slice &key){\n\tuint64_t seq = 0;\n\tif(key.size() == (sizeof(uint64_t) + 1) && key.data()[0] == DataType::SYNCLOG){\n\t\tseq = *((uint64_t *)(key.data() + 1));\n\t\tseq = big_endian(seq);\n\t}\n\treturn seq;\n}\n\nBinlogQueue::BinlogQueue(leveldb::DB *db, bool enabled, int capacity){\n\tthis->db = db;\n\tthis->min_seq_ = 0;\n\tthis->last_seq = 0;\n\tthis->tran_seq = 0;\n\tthis->capacity = capacity;\n\tthis->enabled = enabled;\n\n\tif(!this->enabled){\n\t\treturn;\n\t}\n\t\n\tBinlog log;\n\tif(this->find_last(&log) == 1){\n\t\tthis->last_seq = log.seq();\n\t}\n\tif(this->find_min(&log) == 1){\n\t\tthis->min_seq_ = log.seq();\n\t}\n\tlog_info(\"binlogs capacity: %d, min: %\" PRIu64 \", max: %\" PRIu64 \"\",\n\t\tthis->capacity, this->min_seq_, this->last_seq);\n\t// 这个方法有性能问题\n\t// 但是, 如果不执行清理, 如果将 capacity 修改大, 可能会导致主从同步问题\n\t//this->clean_obsolete_binlogs();\n\n\t// start cleaning thread\n\tthread_quit = false;\n\tpthread_t tid;\n\tint err = pthread_create(&tid, NULL, &BinlogQueue::log_clean_thread_func, this);\n\tif(err != 0){\n\t\tlog_fatal(\"can't create thread: %s\", strerror(err));\n\t\texit(0);\n\t}\n}\n\nBinlogQueue::~BinlogQueue(){\n\tif(this->enabled){\n\t\tthread_quit = true;\n\t\tfor(int i=0; i<100; i++){\n\t\t\tif(thread_quit == false){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tusleep(10 * 1000);\n\t\t}\n\t}\n\tLocking l(&this->mutex);\n\tdb = NULL;\n}\n\nstd::string BinlogQueue::stats() const{\n\tstd::string s;\n\ts.append(\"    capacity : \" + str(capacity) + \"\\n\");\n\ts.append(\"    min_seq  : \" + str(min_seq_) + \"\\n\");\n\ts.append(\"    max_seq  : \" + str(last_seq) + \"\");\n\treturn s;\n}\n\nvoid BinlogQueue::begin(){\n\ttran_seq = last_seq;\n\tbatch.Clear();\n}\n\nvoid BinlogQueue::rollback(){\n\ttran_seq = 0;\n}\n\nleveldb::Status BinlogQueue::commit(){\n\tleveldb::WriteOptions write_opts;\n\tleveldb::Status s = db->Write(write_opts, &batch);\n\tif(s.ok()){\n\t\tlast_seq = tran_seq;\n\t\ttran_seq = 0;\n\t}\n\treturn s;\n}\n\nvoid BinlogQueue::add_log(char type, char cmd, const leveldb::Slice &key){\n\tif(!enabled){\n\t\treturn;\n\t}\n\ttran_seq ++;\n\tBinlog log(tran_seq, type, cmd, key);\n\tbatch.Put(encode_seq_key(tran_seq), log.repr());\n}\n\nvoid BinlogQueue::add_log(char type, char cmd, const std::string &key){\n\tif(!enabled){\n\t\treturn;\n\t}\n\tleveldb::Slice s(key);\n\tthis->add_log(type, cmd, s);\n}\n\n// leveldb put\nvoid BinlogQueue::Put(const leveldb::Slice& key, const leveldb::Slice& value){\n\tbatch.Put(key, value);\n}\n\n// leveldb delete\nvoid BinlogQueue::Delete(const leveldb::Slice& key){\n\tbatch.Delete(key);\n}\n\t\nint BinlogQueue::find_next(uint64_t next_seq, Binlog *log) const{\n\tif(this->get(next_seq, log) == 1){\n\t\treturn 1;\n\t}\n\tuint64_t ret = 0;\n\tstd::string key_str = encode_seq_key(next_seq);\n\tleveldb::ReadOptions iterate_options;\n\tleveldb::Iterator *it = db->NewIterator(iterate_options);\n\tit->Seek(key_str);\n\tif(it->Valid()){\n\t\tleveldb::Slice key = it->key();\n\t\tif(decode_seq_key(key) != 0){\n\t\t\tleveldb::Slice val = it->value();\n\t\t\tif(log->load(val) == -1){\n\t\t\t\tret = -1;\n\t\t\t}else{\n\t\t\t\tret = 1;\n\t\t\t}\n\t\t}\n\t}\n\tdelete it;\n\treturn ret;\n}\n\nint BinlogQueue::find_min(Binlog *log) const{\n\tint ret = 0;\n\tstd::string key_str = encode_seq_key(0);\n\tleveldb::ReadOptions iterate_options;\n\tleveldb::Iterator *it = db->NewIterator(iterate_options);\n\tit->Seek(key_str);\n\tif(it->Valid()){\n\t\tleveldb::Slice key = it->key();\n\t\tif(decode_seq_key(key) != 0){\n\t\t\tleveldb::Slice val = it->value();\n\t\t\tif(log->load(val) == -1){\n\t\t\t\tret = -1;\n\t\t\t}else{\n\t\t\t\tret = 1;\n\t\t\t}\n\t\t}\n\t}\n\tdelete it;\n\treturn ret;\n}\n\nint BinlogQueue::find_last(Binlog *log) const{\n\t// 二分查找比 Iterator 快！\n\t{\n\t\tif(this->find_min(log) != 1){\n\t\t\treturn 0;\n\t\t}\n\t\t// log_debug(\"min = %\" PRIu64 \"\", log->seq());\n\n\t\tuint64_t begin = log->seq();\n\t\tuint64_t end = UINT64_MAX;\n\t\twhile(begin != end){\n\t\t\tuint64_t curr = begin + (end - begin)/2;\n\t\t\tif(this->get(curr, log) == 0){\n\t\t\t\t// log_debug(\"[%\" PRIu64 \", %\" PRIu64 \"] %\" PRIu64 \" not found\", begin, end, curr);\n\t\t\t\tend = curr;\n\t\t\t}else{\n\t\t\t\t// log_debug(\"[%\" PRIu64 \", %\" PRIu64 \"] %\" PRIu64 \" found\", begin, end, curr);\n\t\t\t\tbegin = curr + 1;\n\t\t\t}\n\t\t}\n\t\t\n\t\tend -= 1; // end 总是指向找不到的元素\n\t\tthis->get(end, log);\n\t\t// log_debug(\"max = %\" PRIu64 \"\", end);\n\t\treturn 1;\n\t}\n\t\n\t// int ret = 0;\n\t// std::string key_str = encode_seq_key(UINT64_MAX);\n\t// leveldb::ReadOptions iterate_options;\n\t// leveldb::Iterator *it = db->NewIterator(iterate_options);\n\t// it->Seek(key_str);\n\t// if(!it->Valid()){\n\t// \t// Iterator::prev requires Valid, so we seek to last\n\t// \tit->SeekToLast();\n\t// }else{\n\t// \t// UINT64_MAX is not used\n\t// \tit->Prev();\n\t// }\n\t// if(it->Valid()){\n\t// \tleveldb::Slice key = it->key();\n\t// \tif(decode_seq_key(key) != 0){\n\t// \t\tleveldb::Slice val = it->value();\n\t// \t\tif(log->load(val) == -1){\n\t// \t\t\tret = -1;\n\t// \t\t}else{\n\t// \t\t\tret = 1;\n\t// \t\t}\n\t// \t}\n\t// }\n\t// delete it;\n\t// return ret;\n}\n\nint BinlogQueue::get(uint64_t seq, Binlog *log) const{\n\tstd::string val;\n\tleveldb::Status s = db->Get(leveldb::ReadOptions(), encode_seq_key(seq), &val);\n\tif(s.ok()){\n\t\tif(log->load(val) != -1){\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n}\n\nint BinlogQueue::update(uint64_t seq, char type, char cmd, const std::string &key){\n\tBinlog log(seq, type, cmd, key);\n\tleveldb::Status s = db->Put(leveldb::WriteOptions(), encode_seq_key(seq), log.repr());\n\tif(s.ok()){\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nint BinlogQueue::del(uint64_t seq){\n\tleveldb::Status s = db->Delete(leveldb::WriteOptions(), encode_seq_key(seq));\n\tif(!s.ok()){\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nvoid BinlogQueue::flush(){\n\tdel_range(this->min_seq_, this->last_seq);\n}\n\nint BinlogQueue::del_range(uint64_t start, uint64_t end){\n\twhile(start <= end){\n\t\tleveldb::WriteBatch batch;\n\t\tfor(int count = 0; start <= end && count < 1000; start++, count++){\n\t\t\tbatch.Delete(encode_seq_key(start));\n\t\t}\n\t\t\n\t\tLocking l(&this->mutex);\n\t\tif(!this->db){\n\t\t\treturn -1;\n\t\t}\n\t\tleveldb::Status s = this->db->Write(leveldb::WriteOptions(), &batch);\n\t\tif(!s.ok()){\n\t\t\treturn -1;\n\t\t}\n\t}\n\treturn 0;\n}\n\nvoid* BinlogQueue::log_clean_thread_func(void *arg){\n\tBinlogQueue *logs = (BinlogQueue *)arg;\n\t\n\twhile(!logs->thread_quit){\n\t\tif(!logs->db){\n\t\t\tbreak;\n\t\t}\n\t\tassert(logs->last_seq >= logs->min_seq_);\n\n\t\tif(logs->last_seq - logs->min_seq_ < logs->capacity + 10000){\n\t\t\tusleep(50 * 1000);\n\t\t\tcontinue;\n\t\t}\n\t\t\n\t\tuint64_t start = logs->min_seq_;\n\t\tuint64_t end = logs->last_seq - logs->capacity;\n\t\tlogs->del_range(start, end);\n\t\tlogs->min_seq_ = end + 1;\n\t\tlog_info(\"clean %d logs[%\" PRIu64 \" ~ %\" PRIu64 \"], %d left, max: %\" PRIu64 \"\",\n\t\t\tend-start+1, start, end, logs->last_seq - logs->min_seq_ + 1, logs->last_seq);\n\t}\n\tlog_debug(\"binlog clean_thread quit\");\n\t\n\tlogs->thread_quit = false;\n\treturn (void *)NULL;\n}\n\n// 因为老版本可能产生了断续的binlog\n// 例如, binlog-1 存在, 但后面的被删除了, 然后到 binlog-100000 时又开始存在.\nvoid BinlogQueue::clean_obsolete_binlogs(){\n\tstd::string key_str = encode_seq_key(this->min_seq_);\n\tleveldb::ReadOptions iterate_options;\n\tleveldb::Iterator *it = db->NewIterator(iterate_options);\n\tit->Seek(key_str);\n\tif(it->Valid()){\n\t\tit->Prev();\n\t}\n\tuint64_t count = 0;\n\twhile(it->Valid()){\n\t\tleveldb::Slice key = it->key();\n\t\tuint64_t seq = decode_seq_key(key);\n\t\tif(seq == 0){\n\t\t\tbreak;\n\t\t}\n\t\tthis->del(seq);\n\t\t\n\t\tit->Prev();\n\t\tcount ++;\n\t}\n\tdelete it;\n\tif(count > 0){\n\t\tlog_info(\"clean_obsolete_binlogs: %\" PRIu64, count);\n\t}\n}\n\n// TESTING, slow, so not used\nvoid BinlogQueue::merge(){\n\tstd::map<std::string, uint64_t> key_map;\n\tuint64_t start = min_seq_;\n\tuint64_t end = last_seq;\n\tint reduce_count = 0;\n\tint total = 0;\n\ttotal = end - start + 1;\n\t(void)total; // suppresses warning\n\tlog_trace(\"merge begin\");\n\tfor(; start <= end; start++){\n\t\tBinlog log;\n\t\tif(this->get(start, &log) == 1){\n\t\t\tif(log.type() == BinlogType::NOOP){\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tstd::string key = log.key().String();\n\t\t\tstd::map<std::string, uint64_t>::iterator it = key_map.find(key);\n\t\t\tif(it != key_map.end()){\n\t\t\t\tuint64_t seq = it->second;\n\t\t\t\tthis->update(seq, BinlogType::NOOP, BinlogCommand::NONE, \"\");\n\t\t\t\t//log_trace(\"merge update %\" PRIu64 \" to NOOP\", seq);\n\t\t\t\treduce_count ++;\n\t\t\t}\n\t\t\tkey_map[key] = log.seq();\n\t\t}\n\t}\n\tlog_trace(\"merge reduce %d of %d binlogs\", reduce_count, total);\n}\n"
  },
  {
    "path": "src/ssdb/binlog.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef SSDB_BINLOG_H_\n#define SSDB_BINLOG_H_\n\n#include <string>\n#include \"leveldb/db.h\"\n#include \"leveldb/options.h\"\n#include \"leveldb/slice.h\"\n#include \"leveldb/status.h\"\n#include \"leveldb/write_batch.h\"\n#include \"../util/thread.h\"\n#include \"../util/bytes.h\"\n\n\nclass Binlog{\nprivate:\n\tstd::string buf;\n\tstatic const unsigned int HEADER_LEN = sizeof(uint64_t) + 2;\npublic:\n\tBinlog(){}\n\tBinlog(uint64_t seq, char type, char cmd, const leveldb::Slice &key);\n\t\t\n\tint load(const Bytes &s);\n\tint load(const leveldb::Slice &s);\n\tint load(const std::string &s);\n\n\tuint64_t seq() const;\n\tchar type() const;\n\tchar cmd() const;\n\tconst Bytes key() const;\n\n\tconst char* data() const{\n\t\treturn buf.data();\n\t}\n\tint size() const{\n\t\treturn (int)buf.size();\n\t}\n\tconst std::string repr() const{\n\t\treturn this->buf;\n\t}\n\tstd::string dumps() const;\n};\n\n// circular queue\nclass BinlogQueue{\nprivate:\n\tleveldb::DB *db;\n\tuint64_t min_seq_;\n\tuint64_t last_seq;\n\tuint64_t tran_seq;\n\tint capacity;\n\tleveldb::WriteBatch batch;\n\n\tvolatile bool thread_quit;\n\tstatic void* log_clean_thread_func(void *arg);\n\tint del(uint64_t seq);\n\t// [start, end] includesive\n\tint del_range(uint64_t start, uint64_t end);\n\t\n\tvoid clean_obsolete_binlogs();\n\tvoid merge();\n\tbool enabled;\npublic:\n\tMutex mutex;\n\n\tBinlogQueue(leveldb::DB *db, bool enabled=true, int capacity=20000000);\n\t~BinlogQueue();\n\tvoid begin();\n\tvoid rollback();\n\tleveldb::Status commit();\n\t// leveldb put\n\tvoid Put(const leveldb::Slice& key, const leveldb::Slice& value);\n\t// leveldb delete\n\tvoid Delete(const leveldb::Slice& key);\n\tvoid add_log(char type, char cmd, const leveldb::Slice &key);\n\tvoid add_log(char type, char cmd, const std::string &key);\n\t\t\n\tint get(uint64_t seq, Binlog *log) const;\n\tint update(uint64_t seq, char type, char cmd, const std::string &key);\n\t\t\n\tvoid flush();\n\t\t\n\t/** @returns\n\t 1 : log.seq greater than or equal to seq\n\t 0 : not found\n\t -1: error\n\t */\n\tint find_next(uint64_t seq, Binlog *log) const;\n\tint find_min(Binlog *log) const;\n\tint find_last(Binlog *log) const;\n\t\n\tuint64_t min_seq() const{\n\t\treturn min_seq_;\n\t}\n\tuint64_t max_seq() const{\n\t\treturn last_seq;\n\t}\n\t\t\n\tstd::string stats() const;\n};\n\nclass Transaction{\nprivate:\n\tBinlogQueue *logs;\npublic:\n\tTransaction(BinlogQueue *logs){\n\t\tthis->logs = logs;\n\t\tlogs->mutex.lock();\n\t\tlogs->begin();\n\t}\n\t\n\t~Transaction(){\n\t\t// it is safe to call rollback after commit\n\t\tlogs->rollback();\n\t\tlogs->mutex.unlock();\n\t}\n};\n\n\n#endif\n"
  },
  {
    "path": "src/ssdb/const.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef SSDB_CONST_H_\n#define SSDB_CONST_H_\n\nstatic const int SSDB_SCORE_WIDTH\t\t= 9;\nstatic const int SSDB_KEY_LEN_MAX\t\t= 255;\n\nclass DataType{\npublic:\n\tstatic const char SYNCLOG\t= 1;\n\tstatic const char KV\t\t= 'k';\n\tstatic const char HASH\t\t= 'h'; // hashmap(sorted by key)\n\tstatic const char HSIZE\t\t= 'H';\n\tstatic const char ZSET\t\t= 's'; // key => score\n\tstatic const char ZSCORE\t= 'z'; // key|score => \"\"\n\tstatic const char ZSIZE\t\t= 'Z';\n\tstatic const char QUEUE\t\t= 'q';\n\tstatic const char QSIZE\t\t= 'Q';\n\tstatic const char MIN_PREFIX = HASH;\n\tstatic const char MAX_PREFIX = ZSET;\n};\n\nclass BinlogType{\npublic:\n\tstatic const char NOOP\t\t= 0;\n\tstatic const char SYNC\t\t= 1;\n\tstatic const char MIRROR\t= 2;\n\tstatic const char COPY\t\t= 3;\n\tstatic const char CTRL\t\t= 4;\n};\n\nclass BinlogCommand{\npublic:\n\tstatic const char NONE  = 0;\n\tstatic const char KSET  = 1;\n\tstatic const char KDEL  = 2;\n\tstatic const char HSET  = 3;\n\tstatic const char HDEL  = 4;\n\tstatic const char ZSET  = 5;\n\tstatic const char ZDEL  = 6;\n\n\tstatic const char QPUSH_BACK\t= 10;\n\tstatic const char QPUSH_FRONT\t= 11;\n\tstatic const char QPOP_BACK\t\t= 12;\n\tstatic const char QPOP_FRONT\t= 13;\n\tstatic const char QSET\t\t\t= 14;\n\t\n\tstatic const char BEGIN  = 7;\n\tstatic const char END    = 8;\n};\n\n#endif\n"
  },
  {
    "path": "src/ssdb/iterator.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"iterator.h\"\n#include \"t_kv.h\"\n#include \"t_hash.h\"\n#include \"t_zset.h\"\n#include \"t_queue.h\"\n#include \"../util/log.h\"\n#include \"../util/config.h\"\n#include \"leveldb/iterator.h\"\n\nIterator::Iterator(leveldb::Iterator *it,\n\t\tconst std::string &end,\n\t\tuint64_t limit,\n\t\tDirection direction)\n{\n\tthis->it = it;\n\tthis->end = end;\n\tthis->limit = limit;\n\tthis->is_first = true;\n\tthis->direction = direction;\n}\n\nIterator::~Iterator(){\n\tdelete it;\n}\n\nBytes Iterator::key(){\n\tleveldb::Slice s = it->key();\n\treturn Bytes(s.data(), s.size());\n}\n\nBytes Iterator::val(){\n\tleveldb::Slice s = it->value();\n\treturn Bytes(s.data(), s.size());\n}\n\nbool Iterator::skip(uint64_t offset){\n\twhile(offset-- > 0){\n\t\tif(this->next() == false){\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nbool Iterator::next(){\n\tif(limit == 0){\n\t\treturn false;\n\t}\n\tif(is_first){\n\t\tis_first = false;\n\t}else{\n\t\tif(direction == FORWARD){\n\t\t\tit->Next();\n\t\t}else{\n\t\t\tit->Prev();\n\t\t}\n\t}\n\n\tif(!it->Valid()){\n\t\t// make next() safe to be called after previous return false.\n\t\tlimit = 0;\n\t\treturn false;\n\t}\n\tif(direction == FORWARD){\n\t\tif(!end.empty() && it->key().compare(end) > 0){\n\t\t\tlimit = 0;\n\t\t\treturn false;\n\t\t}\n\t}else{\n\t\tif(!end.empty() && it->key().compare(end) < 0){\n\t\t\tlimit = 0;\n\t\t\treturn false;\n\t\t}\n\t}\n\tlimit --;\n\treturn true;\n}\n\n\n/* KV */\n\nKIterator::KIterator(Iterator *it){\n\tthis->it = it;\n\tthis->return_val_ = true;\n}\n\nKIterator::~KIterator(){\n\tdelete it;\n}\n\nvoid KIterator::return_val(bool onoff){\n\tthis->return_val_ = onoff;\n}\n\nbool KIterator::next(){\n\twhile(it->next()){\n\t\tBytes ks = it->key();\n\t\tBytes vs = it->val();\n\t\t//dump(ks.data(), ks.size(), \"z.next\");\n\t\t//dump(vs.data(), vs.size(), \"z.next\");\n\t\tif(ks.data()[0] != DataType::KV){\n\t\t\treturn false;\n\t\t}\n\t\tif(decode_kv_key(ks, &this->key) == -1){\n\t\t\tcontinue;\n\t\t}\n\t\tif(return_val_){\n\t\t\tthis->val.assign(vs.data(), vs.size());\n\t\t}\n\t\treturn true;\n\t}\n\treturn  false;\n}\n\n/* HASH */\n\nHIterator::HIterator(Iterator *it, const Bytes &name){\n\tthis->it = it;\n\tthis->name.assign(name.data(), name.size());\n\tthis->return_val_ = true;\n}\n\nHIterator::~HIterator(){\n\tdelete it;\n}\n\nvoid HIterator::return_val(bool onoff){\n\tthis->return_val_ = onoff;\n}\n\nbool HIterator::next(){\n\twhile(it->next()){\n\t\tBytes ks = it->key();\n\t\tBytes vs = it->val();\n\t\t//dump(ks.data(), ks.size(), \"z.next\");\n\t\t//dump(vs.data(), vs.size(), \"z.next\");\n\t\tif(ks.data()[0] != DataType::HASH){\n\t\t\treturn false;\n\t\t}\n\t\tstd::string n;\n\t\tif(decode_hash_key(ks, &n, &key) == -1){\n\t\t\tcontinue;\n\t\t}\n\t\tif(n != this->name){\n\t\t\treturn false;\n\t\t}\n\t\tif(return_val_){\n\t\t\tthis->val.assign(vs.data(), vs.size());\n\t\t}\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/* ZSET */\n\nZIterator::ZIterator(Iterator *it, const Bytes &name){\n\tthis->it = it;\n\tthis->name.assign(name.data(), name.size());\n}\n\nZIterator::~ZIterator(){\n\tdelete it;\n}\n\t\t\nbool ZIterator::skip(uint64_t offset){\n\twhile(offset-- > 0){\n\t\tif(this->next() == false){\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nbool ZIterator::next(){\n\twhile(it->next()){\n\t\tBytes ks = it->key();\n\t\t//Bytes vs = it->val();\n\t\t//dump(ks.data(), ks.size(), \"z.next\");\n\t\t//dump(vs.data(), vs.size(), \"z.next\");\n\t\tif(ks.data()[0] != DataType::ZSCORE){\n\t\t\treturn false;\n\t\t}\n\t\tif(decode_zscore_key(ks, NULL, &key, &score) == -1){\n\t\t\tcontinue;\n\t\t}\n\t\treturn true;\n\t}\n\treturn false;\n}\n"
  },
  {
    "path": "src/ssdb/iterator.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef SSDB_ITERATOR_H_\n#define SSDB_ITERATOR_H_\n\n#include <inttypes.h>\n#include <string>\n#include \"../util/bytes.h\"\n\nnamespace leveldb{\n\tclass Iterator;\n}\n\nclass Iterator{\npublic:\n\tenum Direction{\n\t\tFORWARD, BACKWARD\n\t};\n\tIterator(leveldb::Iterator *it,\n\t\t\tconst std::string &end,\n\t\t\tuint64_t limit,\n\t\t\tDirection direction=Iterator::FORWARD);\n\t~Iterator();\n\tbool skip(uint64_t offset);\n\tbool next();\n\tBytes key();\n\tBytes val();\nprivate:\n\tleveldb::Iterator *it;\n\tstd::string end;\n\tuint64_t limit;\n\tbool is_first;\n\tint direction;\n};\n\n\nclass KIterator{\npublic:\n\tstd::string key;\n\tstd::string val;\n\n\tKIterator(Iterator *it);\n\t~KIterator();\n\tvoid return_val(bool onoff);\n\tbool next();\nprivate:\n\tIterator *it;\n\tbool return_val_;\n};\n\n\nclass HIterator{\npublic:\n\tstd::string name;\n\tstd::string key;\n\tstd::string val;\n\n\tHIterator(Iterator *it, const Bytes &name);\n\t~HIterator();\n\tvoid return_val(bool onoff);\n\tbool next();\nprivate:\n\tIterator *it;\n\tbool return_val_;\n};\n\n\nclass ZIterator{\npublic:\n\tstd::string name;\n\tstd::string key;\n\tstd::string score;\n\n\tZIterator(Iterator *it, const Bytes &name);\n\t~ZIterator();\n\tbool skip(uint64_t offset);\n\tbool next();\nprivate:\n\tIterator *it;\n};\n\n\n#endif\n"
  },
  {
    "path": "src/ssdb/options.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"options.h\"\n#include \"../util/string_util.h\"\n\n#ifdef NDEBUG\n\tstatic const int LOG_QUEUE_SIZE  = 20 * 1000 * 1000;\n#else\n\tstatic const int LOG_QUEUE_SIZE  = 10000;\n#endif\n\nOptions::Options(){\n\tConfig c;\n\tthis->load(c);\n}\n\nvoid Options::load(const Config &conf){\n\tcache_size = (size_t)conf.get_num(\"leveldb.cache_size\");\n\tmax_open_files = (size_t)conf.get_num(\"leveldb.max_open_files\");\n\twrite_buffer_size = (size_t)conf.get_num(\"leveldb.write_buffer_size\");\n\tblock_size = (size_t)conf.get_num(\"leveldb.block_size\");\n\tcompaction_speed = conf.get_num(\"leveldb.compaction_speed\");\n\tcompression = conf.get_str(\"leveldb.compression\");\n\tstd::string binlog = conf.get_str(\"replication.binlog\");\n\tbinlog_capacity = (size_t)conf.get_num(\"replication.binlog.capacity\");\n\n\tstrtolower(&compression);\n\tif(compression != \"no\"){\n\t\tcompression = \"yes\";\n\t}\n\tstrtolower(&binlog);\n\tif(binlog != \"yes\"){\n\t\tthis->binlog = false;\n\t}else{\n\t\tthis->binlog = true;\n\t}\n\tif(binlog_capacity <= 0){\n\t\tbinlog_capacity = LOG_QUEUE_SIZE;\n\t}\n\n\tif(cache_size <= 0){\n\t\tcache_size = 16;\n\t}\n\tif(write_buffer_size <= 0){\n\t\twrite_buffer_size = 16;\n\t}\n\tif(block_size <= 0){\n\t\tblock_size = 32;\n\t}\n\tif(max_open_files <= 0){\n\t\tmax_open_files = cache_size / 1024 * 300;\n\t\tif(max_open_files < 500){\n\t\t\tmax_open_files = 500;\n\t\t}\n\t\tif(max_open_files > 1000){\n\t\t\tmax_open_files = 1000;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/ssdb/options.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef SSDB_OPTION_H_\n#define SSDB_OPTION_H_\n\n#include \"../util/config.h\"\n\nclass Options\n{\npublic:\n\tOptions();\n\t~Options(){}\n\t\n\tvoid load(const Config &conf);\n\n\tsize_t cache_size;\n\tsize_t max_open_files;\n\tsize_t write_buffer_size;\n\tsize_t block_size;\n\tint compaction_speed;\n\tstd::string compression;\n\tbool binlog;\n\tsize_t binlog_capacity;\n};\n\n#endif\n"
  },
  {
    "path": "src/ssdb/ssdb.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef SSDB_H_\n#define SSDB_H_\n\n#include <vector>\n#include <string>\n#include \"const.h\"\n#include \"options.h\"\n#include \"iterator.h\"\n\nclass Bytes;\nclass Config;\n\nclass SSDB{\npublic:\n\tSSDB(){}\n\tvirtual ~SSDB(){};\n\tstatic SSDB* open(const Options &opt, const std::string &base_dir);\n\t\n\tvirtual int flushdb() = 0;\n\n\t// return (start, end], not include start\n\tvirtual Iterator* iterator(const std::string &start, const std::string &end, uint64_t limit) = 0;\n\tvirtual Iterator* rev_iterator(const std::string &start, const std::string &end, uint64_t limit) = 0;\n\n\t//void flushdb();\n\tvirtual uint64_t size() = 0;\n\tvirtual std::vector<std::string> info() = 0;\n\tvirtual void compact() = 0;\n\tvirtual int key_range(std::vector<std::string> *keys) = 0;\n\n\t/* raw operates */\n\n\t// repl: whether to sync this operation to slaves\n\tvirtual int raw_set(const Bytes &key, const Bytes &val) = 0;\n\tvirtual int raw_del(const Bytes &key) = 0;\n\tvirtual int raw_get(const Bytes &key, std::string *val) = 0;\n\n\t/* key value */\n\n\tvirtual int set(const Bytes &key, const Bytes &val, char log_type=BinlogType::SYNC) = 0;\n\tvirtual int setnx(const Bytes &key, const Bytes &val, char log_type=BinlogType::SYNC) = 0;\n\tvirtual int del(const Bytes &key, char log_type=BinlogType::SYNC) = 0;\n\t// -1: error, 1: ok, 0: value is not an integer or out of range\n\tvirtual int incr(const Bytes &key, int64_t by, int64_t *new_val, char log_type=BinlogType::SYNC) = 0;\n\tvirtual int multi_set(const std::vector<Bytes> &kvs, int offset=0, char log_type=BinlogType::SYNC) = 0;\n\tvirtual int multi_del(const std::vector<Bytes> &keys, int offset=0, char log_type=BinlogType::SYNC) = 0;\n\t// fix iOS 11 issue\n#ifdef setbit\n#define setbit_ setbit\n#undef setbit\n\tvirtual int setbit(const Bytes &key, int bitoffset, int on, char log_type=BinlogType::SYNC) = 0;\n#define setbit setbit_\n#endif\n\tvirtual int getbit(const Bytes &key, int bitoffset) = 0;\n\t\n\tvirtual int get(const Bytes &key, std::string *val) = 0;\n\tvirtual int getset(const Bytes &key, std::string *val, const Bytes &newval, char log_type=BinlogType::SYNC) = 0;\n\t// return (start, end]\n\tvirtual KIterator* scan(const Bytes &start, const Bytes &end, uint64_t limit) = 0;\n\tvirtual KIterator* rscan(const Bytes &start, const Bytes &end, uint64_t limit) = 0;\n\n\t/* hash */\n\n\tvirtual int hset(const Bytes &name, const Bytes &key, const Bytes &val, char log_type=BinlogType::SYNC) = 0;\n\tvirtual int hdel(const Bytes &name, const Bytes &key, char log_type=BinlogType::SYNC) = 0;\n\t// -1: error, 1: ok, 0: value is not an integer or out of range\n\tvirtual int hincr(const Bytes &name, const Bytes &key, int64_t by, int64_t *new_val, char log_type=BinlogType::SYNC) = 0;\n\n\tvirtual int64_t hsize(const Bytes &name) = 0;\n\tvirtual int64_t hclear(const Bytes &name) = 0;\n\tvirtual int hget(const Bytes &name, const Bytes &key, std::string *val) = 0;\n\tvirtual int hlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\t\tstd::vector<std::string> *list) = 0;\n\tvirtual int hrlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\t\tstd::vector<std::string> *list) = 0;\n\tvirtual HIterator* hscan(const Bytes &name, const Bytes &start, const Bytes &end, uint64_t limit) = 0;\n\tvirtual HIterator* hrscan(const Bytes &name, const Bytes &start, const Bytes &end, uint64_t limit) = 0;\n\tvirtual int64_t hfix(const Bytes &name) = 0;\n\n\t/* zset */\n\n\tvirtual int zset(const Bytes &name, const Bytes &key, const Bytes &score, char log_type=BinlogType::SYNC) = 0;\n\tvirtual int zdel(const Bytes &name, const Bytes &key, char log_type=BinlogType::SYNC) = 0;\n\t// -1: error, 1: ok, 0: value is not an integer or out of range\n\tvirtual int zincr(const Bytes &name, const Bytes &key, int64_t by, int64_t *new_val, char log_type=BinlogType::SYNC) = 0;\n\t\n\tvirtual int64_t zsize(const Bytes &name) = 0;\n\t/**\n\t * @return -1: error; 0: not found; 1: found\n\t */\n\tvirtual int zget(const Bytes &name, const Bytes &key, std::string *score) = 0;\n\tvirtual int64_t zrank(const Bytes &name, const Bytes &key) = 0;\n\tvirtual int64_t zrrank(const Bytes &name, const Bytes &key) = 0;\n\tvirtual ZIterator* zrange(const Bytes &name, uint64_t offset, uint64_t limit) = 0;\n\tvirtual ZIterator* zrrange(const Bytes &name, uint64_t offset, uint64_t limit) = 0;\n\t/**\n\t * scan by score, but won't return @key if key.score=score_start.\n\t * return (score_start, score_end]\n\t */\n\tvirtual ZIterator* zscan(const Bytes &name, const Bytes &key,\n\t\t\tconst Bytes &score_start, const Bytes &score_end, uint64_t limit) = 0;\n\tvirtual ZIterator* zrscan(const Bytes &name, const Bytes &key,\n\t\t\tconst Bytes &score_start, const Bytes &score_end, uint64_t limit) = 0;\n\tvirtual int zlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\t\tstd::vector<std::string> *list) = 0;\n\tvirtual int zrlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\t\tstd::vector<std::string> *list) = 0;\n\tvirtual int64_t zfix(const Bytes &name) = 0;\n\t\n\tvirtual int64_t qsize(const Bytes &name) = 0;\n\t// @return 0: empty queue, 1: item peeked, -1: error\n\tvirtual int qfront(const Bytes &name, std::string *item) = 0;\n\t// @return 0: empty queue, 1: item peeked, -1: error\n\tvirtual int qback(const Bytes &name, std::string *item) = 0;\n\t// @return -1: error, other: the new length of the queue\n\tvirtual int64_t qpush_front(const Bytes &name, const Bytes &item, char log_type=BinlogType::SYNC) = 0;\n\tvirtual int64_t qpush_back(const Bytes &name, const Bytes &item, char log_type=BinlogType::SYNC) = 0;\n\t// @return 0: empty queue, 1: item popped, -1: error\n\tvirtual int qpop_front(const Bytes &name, std::string *item, char log_type=BinlogType::SYNC) = 0;\n\tvirtual int qpop_back(const Bytes &name, std::string *item, char log_type=BinlogType::SYNC) = 0;\n\tvirtual int qfix(const Bytes &name) = 0;\n\tvirtual int qlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\t\tstd::vector<std::string> *list) = 0;\n\tvirtual int qrlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\t\tstd::vector<std::string> *list) = 0;\n\tvirtual int qslice(const Bytes &name, int64_t offset, int64_t limit,\n\t\t\tstd::vector<std::string> *list) = 0;\n\tvirtual int qget(const Bytes &name, int64_t index, std::string *item) = 0;\n\tvirtual int qset(const Bytes &name, int64_t index, const Bytes &item, char log_type=BinlogType::SYNC) = 0;\n\tvirtual int qset_by_seq(const Bytes &name, uint64_t seq, const Bytes &item, char log_type=BinlogType::SYNC) = 0;\n};\n\n\n#endif\n"
  },
  {
    "path": "src/ssdb/ssdb_impl.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"ssdb_impl.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/iterator.h\"\n#include \"leveldb/cache.h\"\n#include \"leveldb/filter_policy.h\"\n\n#include \"iterator.h\"\n#include \"t_kv.h\"\n#include \"t_hash.h\"\n#include \"t_zset.h\"\n#include \"t_queue.h\"\n\nSSDBImpl::SSDBImpl(){\n\tldb = NULL;\n\tbinlogs = NULL;\n}\n\nSSDBImpl::~SSDBImpl(){\n\tif(binlogs){\n\t\tdelete binlogs;\n\t}\n\tif(ldb){\n\t\tdelete ldb;\n\t}\n\tif(options.block_cache){\n\t\tdelete options.block_cache;\n\t}\n\tif(options.filter_policy){\n\t\tdelete options.filter_policy;\n\t}\n}\n\nSSDB* SSDB::open(const Options &opt, const std::string &dir){\n\tSSDBImpl *ssdb = new SSDBImpl();\n\tssdb->options.max_file_size = 32 * 1048576; // leveldb 1.20\n\tssdb->options.create_if_missing = true;\n\tssdb->options.max_open_files = opt.max_open_files;\n\tssdb->options.filter_policy = leveldb::NewBloomFilterPolicy(10);\n\tssdb->options.block_cache = leveldb::NewLRUCache(opt.cache_size * 1048576);\n\tssdb->options.block_size = opt.block_size * 1024;\n\tssdb->options.write_buffer_size = opt.write_buffer_size * 1024 * 1024;\n\tssdb->options.compaction_speed = opt.compaction_speed;\n\tif(opt.compression == \"yes\"){\n\t\tssdb->options.compression = leveldb::kSnappyCompression;\n\t}else{\n\t\tssdb->options.compression = leveldb::kNoCompression;\n\t}\n\n\tleveldb::Status status;\n\n\tstatus = leveldb::DB::Open(ssdb->options, dir, &ssdb->ldb);\n\tif(!status.ok()){\n\t\tlog_error(\"open db failed: %s\", status.ToString().c_str());\n\t\tgoto err;\n\t}\n\tssdb->binlogs = new BinlogQueue(ssdb->ldb, opt.binlog, opt.binlog_capacity);\n\n\treturn ssdb;\nerr:\n\tif(ssdb){\n\t\tdelete ssdb;\n\t}\n\treturn NULL;\n}\n\nint SSDBImpl::flushdb(){\n\tint ret = 0;\n\tbool stop = false;\n\t{\n\t\tTransaction trans(binlogs);\n\t\twhile(!stop){\n\t\t\tleveldb::Iterator *it;\n\t\t\tleveldb::ReadOptions iterate_options;\n\t\t\titerate_options.fill_cache = false;\n\t\t\tleveldb::WriteOptions write_opts;\n\n\t\t\tit = ldb->NewIterator(iterate_options);\n\t\t\tit->SeekToFirst();\n\t\t\tfor(int i=0; i<10000; i++){\n\t\t\t\tif(!it->Valid()){\n\t\t\t\t\tstop = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t//log_debug(\"%s\", hexmem(it->key().data(), it->key().size()).c_str());\n\t\t\t\tleveldb::Status s = ldb->Delete(write_opts, it->key());\n\t\t\t\tif(!s.ok()){\n\t\t\t\t\tlog_error(\"del error: %s\", s.ToString().c_str());\n\t\t\t\t\tstop = true;\n\t\t\t\t\tret = -1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tit->Next();\n\t\t\t}\n\t\t\tdelete it;\n\t\t}\n\t}\n\tbinlogs->flush();\n\treturn ret;\n}\n\nIterator* SSDBImpl::iterator(const std::string &start, const std::string &end, uint64_t limit){\n\tleveldb::Iterator *it;\n\tleveldb::ReadOptions iterate_options;\n\titerate_options.fill_cache = false;\n\tit = ldb->NewIterator(iterate_options);\n\tit->Seek(start);\n\tif(it->Valid() && it->key() == start){\n\t\tit->Next();\n\t}\n\treturn new Iterator(it, end, limit);\n}\n\nIterator* SSDBImpl::rev_iterator(const std::string &start, const std::string &end, uint64_t limit){\n\tleveldb::Iterator *it;\n\tleveldb::ReadOptions iterate_options;\n\titerate_options.fill_cache = false;\n\tit = ldb->NewIterator(iterate_options);\n\tit->Seek(start);\n\tif(!it->Valid()){\n\t\tit->SeekToLast();\n\t}else{\n\t\tit->Prev();\n\t}\n\treturn new Iterator(it, end, limit, Iterator::BACKWARD);\n}\n\n/* raw operates */\n\nint SSDBImpl::raw_set(const Bytes &key, const Bytes &val){\n\tleveldb::WriteOptions write_opts;\n\tleveldb::Status s = ldb->Put(write_opts, slice(key), slice(val));\n\tif(!s.ok()){\n\t\tlog_error(\"set error: %s\", s.ToString().c_str());\n\t\treturn -1;\n\t}\n\treturn 1;\n}\n\nint SSDBImpl::raw_del(const Bytes &key){\n\tleveldb::WriteOptions write_opts;\n\tleveldb::Status s = ldb->Delete(write_opts, slice(key));\n\tif(!s.ok()){\n\t\tlog_error(\"del error: %s\", s.ToString().c_str());\n\t\treturn -1;\n\t}\n\treturn 1;\n}\n\nint SSDBImpl::raw_get(const Bytes &key, std::string *val){\n\tleveldb::ReadOptions opts;\n\topts.fill_cache = false;\n\tleveldb::Status s = ldb->Get(opts, slice(key), val);\n\tif(s.IsNotFound()){\n\t\treturn 0;\n\t}\n\tif(!s.ok()){\n\t\tlog_error(\"get error: %s\", s.ToString().c_str());\n\t\treturn -1;\n\t}\n\treturn 1;\n}\n\nuint64_t SSDBImpl::size(){\n\tstd::string s = \"A\";\n\tstd::string e(1, 'z' + 1);\n\tleveldb::Range ranges[1];\n\tranges[0] = leveldb::Range(s, e);\n\tuint64_t sizes[1];\n\tldb->GetApproximateSizes(ranges, 1, sizes);\n\treturn sizes[0];\n}\n\nstd::vector<std::string> SSDBImpl::info(){\n\t//  \"leveldb.num-files-at-level<N>\" - return the number of files at level <N>,\n\t//     where <N> is an ASCII representation of a level number (e.g. \"0\").\n\t//  \"leveldb.stats\" - returns a multi-line string that describes statistics\n\t//     about the internal operation of the DB.\n\t//  \"leveldb.sstables\" - returns a multi-line string that describes all\n\t//     of the sstables that make up the db contents.\n\tstd::vector<std::string> info;\n\tstd::vector<std::string> keys;\n\t/*\n\tfor(int i=0; i<7; i++){\n\t\tchar buf[128];\n\t\tsnprintf(buf, sizeof(buf), \"leveldb.num-files-at-level%d\", i);\n\t\tkeys.push_back(buf);\n\t}\n\t*/\n\tkeys.push_back(\"leveldb.stats\");\n\t//keys.push_back(\"leveldb.sstables\");\n\n\tfor(size_t i=0; i<keys.size(); i++){\n\t\tstd::string key = keys[i];\n\t\tstd::string val;\n\t\tif(ldb->GetProperty(key, &val)){\n\t\t\tinfo.push_back(key);\n\t\t\tinfo.push_back(val);\n\t\t}\n\t}\n\n\treturn info;\n}\n\nvoid SSDBImpl::compact(){\n\tldb->CompactRange(NULL, NULL);\n}\n\nint SSDBImpl::key_range(std::vector<std::string> *keys){\n\tint ret = 0;\n\tstd::string kstart, kend;\n\tstd::string hstart, hend;\n\tstd::string zstart, zend;\n\tstd::string qstart, qend;\n\t\n\tIterator *it;\n\t\n\tit = this->iterator(encode_kv_key(\"\"), \"\", 1);\n\tif(it->next()){\n\t\tBytes ks = it->key();\n\t\tif(ks.data()[0] == DataType::KV){\n\t\t\tstd::string n;\n\t\t\tif(decode_kv_key(ks, &n) == -1){\n\t\t\t\tret = -1;\n\t\t\t}else{\n\t\t\t\tkstart = n;\n\t\t\t}\n\t\t}\n\t}\n\tdelete it;\n\t\n\tit = this->rev_iterator(encode_kv_key(\"\\xff\"), \"\", 1);\n\tif(it->next()){\n\t\tBytes ks = it->key();\n\t\tif(ks.data()[0] == DataType::KV){\n\t\t\tstd::string n;\n\t\t\tif(decode_kv_key(ks, &n) == -1){\n\t\t\t\tret = -1;\n\t\t\t}else{\n\t\t\t\tkend = n;\n\t\t\t}\n\t\t}\n\t}\n\tdelete it;\n\t\n\tit = this->iterator(encode_hsize_key(\"\"), \"\", 1);\n\tif(it->next()){\n\t\tBytes ks = it->key();\n\t\tif(ks.data()[0] == DataType::HSIZE){\n\t\t\tstd::string n;\n\t\t\tif(decode_hsize_key(ks, &n) == -1){\n\t\t\t\tret = -1;\n\t\t\t}else{\n\t\t\t\thstart = n;\n\t\t\t}\n\t\t}\n\t}\n\tdelete it;\n\t\n\tit = this->rev_iterator(encode_hsize_key(\"\\xff\"), \"\", 1);\n\tif(it->next()){\n\t\tBytes ks = it->key();\n\t\tif(ks.data()[0] == DataType::HSIZE){\n\t\t\tstd::string n;\n\t\t\tif(decode_hsize_key(ks, &n) == -1){\n\t\t\t\tret = -1;\n\t\t\t}else{\n\t\t\t\thend = n;\n\t\t\t}\n\t\t}\n\t}\n\tdelete it;\n\t\n\tit = this->iterator(encode_zsize_key(\"\"), \"\", 1);\n\tif(it->next()){\n\t\tBytes ks = it->key();\n\t\tif(ks.data()[0] == DataType::ZSIZE){\n\t\t\tstd::string n;\n\t\t\tif(decode_zsize_key(ks, &n) == -1){\n\t\t\t\tret = -1;\n\t\t\t}else{\n\t\t\t\tzstart = n;\n\t\t\t}\n\t\t}\n\t}\n\tdelete it;\n\t\n\tit = this->rev_iterator(encode_zsize_key(\"\\xff\"), \"\", 1);\n\tif(it->next()){\n\t\tBytes ks = it->key();\n\t\tif(ks.data()[0] == DataType::ZSIZE){\n\t\t\tstd::string n;\n\t\t\tif(decode_zsize_key(ks, &n) == -1){\n\t\t\t\tret = -1;\n\t\t\t}else{\n\t\t\t\tzend = n;\n\t\t\t}\n\t\t}\n\t}\n\tdelete it;\n\t\n\tit = this->iterator(encode_qsize_key(\"\"), \"\", 1);\n\tif(it->next()){\n\t\tBytes ks = it->key();\n\t\tif(ks.data()[0] == DataType::QSIZE){\n\t\t\tstd::string n;\n\t\t\tif(decode_qsize_key(ks, &n) == -1){\n\t\t\t\tret = -1;\n\t\t\t}else{\n\t\t\t\tqstart = n;\n\t\t\t}\n\t\t}\n\t}\n\tdelete it;\n\t\n\tit = this->rev_iterator(encode_qsize_key(\"\\xff\"), \"\", 1);\n\tif(it->next()){\n\t\tBytes ks = it->key();\n\t\tif(ks.data()[0] == DataType::QSIZE){\n\t\t\tstd::string n;\n\t\t\tif(decode_qsize_key(ks, &n) == -1){\n\t\t\t\tret = -1;\n\t\t\t}else{\n\t\t\t\tqend = n;\n\t\t\t}\n\t\t}\n\t}\n\tdelete it;\n\n\tkeys->push_back(kstart);\n\tkeys->push_back(kend);\n\tkeys->push_back(hstart);\n\tkeys->push_back(hend);\n\tkeys->push_back(zstart);\n\tkeys->push_back(zend);\n\tkeys->push_back(qstart);\n\tkeys->push_back(qend);\n\t\n\treturn ret;\n}\n"
  },
  {
    "path": "src/ssdb/ssdb_impl.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef SSDB_IMPL_H_\n#define SSDB_IMPL_H_\n\n#include \"leveldb/db.h\"\n#include \"leveldb/slice.h\"\n#include \"../include.h\"\n#include \"../util/log.h\"\n#include \"../util/config.h\"\n\n#include \"ssdb.h\"\n#include \"binlog.h\"\n#include \"iterator.h\"\n#include \"t_kv.h\"\n#include \"t_hash.h\"\n#include \"t_zset.h\"\n#include \"t_queue.h\"\n\ninline\nstatic leveldb::Slice slice(const Bytes &b){\n\treturn leveldb::Slice(b.data(), b.size());\n}\n\nclass SSDBImpl : public SSDB\n{\nprivate:\n\tfriend class SSDB;\n\tleveldb::DB* ldb;\n\tleveldb::Options options;\n\t\n\tSSDBImpl();\npublic:\n\tBinlogQueue *binlogs;\n\t\n\tvirtual ~SSDBImpl();\n\n\tvirtual int flushdb();\n\n\t// return (start, end], not include start\n\tvirtual Iterator* iterator(const std::string &start, const std::string &end, uint64_t limit);\n\tvirtual Iterator* rev_iterator(const std::string &start, const std::string &end, uint64_t limit);\n\n\t//void flushdb();\n\tvirtual uint64_t size();\n\tvirtual std::vector<std::string> info();\n\tvirtual void compact();\n\tvirtual int key_range(std::vector<std::string> *keys);\n\t\n\t/* raw operates */\n\n\t// repl: whether to sync this operation to slaves\n\tvirtual int raw_set(const Bytes &key, const Bytes &val);\n\tvirtual int raw_del(const Bytes &key);\n\tvirtual int raw_get(const Bytes &key, std::string *val);\n\n\t/* key value */\n\n\tvirtual int set(const Bytes &key, const Bytes &val, char log_type=BinlogType::SYNC);\n\tvirtual int setnx(const Bytes &key, const Bytes &val, char log_type=BinlogType::SYNC);\n\tvirtual int del(const Bytes &key, char log_type=BinlogType::SYNC);\n\t// -1: error, 1: ok, 0: value is not an integer or out of range\n\tvirtual int incr(const Bytes &key, int64_t by, int64_t *new_val, char log_type=BinlogType::SYNC);\n\tvirtual int multi_set(const std::vector<Bytes> &kvs, int offset=0, char log_type=BinlogType::SYNC);\n\tvirtual int multi_del(const std::vector<Bytes> &keys, int offset=0, char log_type=BinlogType::SYNC);\n\tvirtual int setbit(const Bytes &key, int bitoffset, int on, char log_type=BinlogType::SYNC);\n\tvirtual int getbit(const Bytes &key, int bitoffset);\n\t\n\tvirtual int get(const Bytes &key, std::string *val);\n\tvirtual int getset(const Bytes &key, std::string *val, const Bytes &newval, char log_type=BinlogType::SYNC);\n\t// return (start, end]\n\tvirtual KIterator* scan(const Bytes &start, const Bytes &end, uint64_t limit);\n\tvirtual KIterator* rscan(const Bytes &start, const Bytes &end, uint64_t limit);\n\n\t/* hash */\n\n\tvirtual int hset(const Bytes &name, const Bytes &key, const Bytes &val, char log_type=BinlogType::SYNC);\n\tvirtual int hdel(const Bytes &name, const Bytes &key, char log_type=BinlogType::SYNC);\n\t// -1: error, 1: ok, 0: value is not an integer or out of range\n\tvirtual int hincr(const Bytes &name, const Bytes &key, int64_t by, int64_t *new_val, char log_type=BinlogType::SYNC);\n\t//int multi_hset(const Bytes &name, const std::vector<Bytes> &kvs, int offset=0, char log_type=BinlogType::SYNC);\n\t//int multi_hdel(const Bytes &name, const std::vector<Bytes> &keys, int offset=0, char log_type=BinlogType::SYNC);\n\n\tvirtual int64_t hsize(const Bytes &name);\n\tvirtual int64_t hclear(const Bytes &name);\n\tvirtual int hget(const Bytes &name, const Bytes &key, std::string *val);\n\tvirtual int hlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\t\tstd::vector<std::string> *list);\n\tvirtual int hrlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\t\tstd::vector<std::string> *list);\n\tvirtual HIterator* hscan(const Bytes &name, const Bytes &start, const Bytes &end, uint64_t limit);\n\tvirtual HIterator* hrscan(const Bytes &name, const Bytes &start, const Bytes &end, uint64_t limit);\n\tvirtual int64_t hfix(const Bytes &name);\n\n\t/* zset */\n\n\tvirtual int zset(const Bytes &name, const Bytes &key, const Bytes &score, char log_type=BinlogType::SYNC);\n\tvirtual int zdel(const Bytes &name, const Bytes &key, char log_type=BinlogType::SYNC);\n\t// -1: error, 1: ok, 0: value is not an integer or out of range\n\tvirtual int zincr(const Bytes &name, const Bytes &key, int64_t by, int64_t *new_val, char log_type=BinlogType::SYNC);\n\t//int multi_zset(const Bytes &name, const std::vector<Bytes> &kvs, int offset=0, char log_type=BinlogType::SYNC);\n\t//int multi_zdel(const Bytes &name, const std::vector<Bytes> &keys, int offset=0, char log_type=BinlogType::SYNC);\n\t\n\tvirtual int64_t zsize(const Bytes &name);\n\t/**\n\t * @return -1: error; 0: not found; 1: found\n\t */\n\tvirtual int zget(const Bytes &name, const Bytes &key, std::string *score);\n\tvirtual int64_t zrank(const Bytes &name, const Bytes &key);\n\tvirtual int64_t zrrank(const Bytes &name, const Bytes &key);\n\tvirtual ZIterator* zrange(const Bytes &name, uint64_t offset, uint64_t limit);\n\tvirtual ZIterator* zrrange(const Bytes &name, uint64_t offset, uint64_t limit);\n\t/**\n\t * scan by score, but won't return @key if key.score=score_start.\n\t * return (score_start, score_end]\n\t */\n\tvirtual ZIterator* zscan(const Bytes &name, const Bytes &key,\n\t\t\tconst Bytes &score_start, const Bytes &score_end, uint64_t limit);\n\tvirtual ZIterator* zrscan(const Bytes &name, const Bytes &key,\n\t\t\tconst Bytes &score_start, const Bytes &score_end, uint64_t limit);\n\tvirtual int zlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\t\tstd::vector<std::string> *list);\n\tvirtual int zrlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\t\tstd::vector<std::string> *list);\n\tvirtual int64_t zfix(const Bytes &name);\n\t\n\tvirtual int64_t qsize(const Bytes &name);\n\t// @return 0: empty queue, 1: item peeked, -1: error\n\tvirtual int qfront(const Bytes &name, std::string *item);\n\t// @return 0: empty queue, 1: item peeked, -1: error\n\tvirtual int qback(const Bytes &name, std::string *item);\n\t// @return -1: error, other: the new length of the queue\n\tvirtual int64_t qpush_front(const Bytes &name, const Bytes &item, char log_type=BinlogType::SYNC);\n\tvirtual int64_t qpush_back(const Bytes &name, const Bytes &item, char log_type=BinlogType::SYNC);\n\t// @return 0: empty queue, 1: item popped, -1: error\n\tvirtual int qpop_front(const Bytes &name, std::string *item, char log_type=BinlogType::SYNC);\n\tvirtual int qpop_back(const Bytes &name, std::string *item, char log_type=BinlogType::SYNC);\n\tvirtual int qfix(const Bytes &name);\n\tvirtual int qlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\t\tstd::vector<std::string> *list);\n\tvirtual int qrlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\t\tstd::vector<std::string> *list);\n\tvirtual int qslice(const Bytes &name, int64_t offset, int64_t limit,\n\t\t\tstd::vector<std::string> *list);\n\tvirtual int qget(const Bytes &name, int64_t index, std::string *item);\n\tvirtual int qset(const Bytes &name, int64_t index, const Bytes &item, char log_type=BinlogType::SYNC);\n\tvirtual int qset_by_seq(const Bytes &name, uint64_t seq, const Bytes &item, char log_type=BinlogType::SYNC);\n\nprivate:\n\tint64_t _qpush(const Bytes &name, const Bytes &item, uint64_t front_or_back_seq, char log_type=BinlogType::SYNC);\n\tint _qpop(const Bytes &name, std::string *item, uint64_t front_or_back_seq, char log_type=BinlogType::SYNC);\n};\n\n#endif\n"
  },
  {
    "path": "src/ssdb/t_hash.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"t_hash.h\"\n\nstatic int hset_one(SSDBImpl *ssdb, const Bytes &name, const Bytes &key, const Bytes &val, char log_type);\nstatic int hdel_one(SSDBImpl *ssdb, const Bytes &name, const Bytes &key, char log_type);\nstatic int incr_hsize(SSDBImpl *ssdb, const Bytes &name, int64_t incr);\n\n/**\n * @return -1: error, 0: item updated, 1: new item inserted\n */\nint SSDBImpl::hset(const Bytes &name, const Bytes &key, const Bytes &val, char log_type){\n\tTransaction trans(binlogs);\n\n\tint ret = hset_one(this, name, key, val, log_type);\n\tif(ret >= 0){\n\t\tif(ret > 0){\n\t\t\tif(incr_hsize(this, name, ret) == -1){\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t\tleveldb::Status s = binlogs->commit();\n\t\tif(!s.ok()){\n\t\t\treturn -1;\n\t\t}\n\t}\n\treturn ret;\n}\n\nint SSDBImpl::hdel(const Bytes &name, const Bytes &key, char log_type){\n\tTransaction trans(binlogs);\n\n\tint ret = hdel_one(this, name, key, log_type);\n\tif(ret >= 0){\n\t\tif(ret > 0){\n\t\t\tif(incr_hsize(this, name, -ret) == -1){\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t\tleveldb::Status s = binlogs->commit();\n\t\tif(!s.ok()){\n\t\t\treturn -1;\n\t\t}\n\t}\n\treturn ret;\n}\n\nint SSDBImpl::hincr(const Bytes &name, const Bytes &key, int64_t by, int64_t *new_val, char log_type){\n\tTransaction trans(binlogs);\n\n\tstd::string old;\n\tint ret = this->hget(name, key, &old);\n\tif(ret == -1){\n\t\treturn -1;\n\t}else if(ret == 0){\n\t\t*new_val = by;\n\t}else{\n\t\t*new_val = str_to_int64(old) + by;\n\t\tif(errno != 0){\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tret = hset_one(this, name, key, str(*new_val), log_type);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\tif(ret >= 0){\n\t\tif(ret > 0){\n\t\t\tif(incr_hsize(this, name, ret) == -1){\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t\tleveldb::Status s = binlogs->commit();\n\t\tif(!s.ok()){\n\t\t\treturn -1;\n\t\t}\n\t}\n\treturn 1;\n}\n\nint64_t SSDBImpl::hsize(const Bytes &name){\n\tstd::string size_key = encode_hsize_key(name);\n\tstd::string val;\n\tleveldb::Status s;\n\n\ts = ldb->Get(leveldb::ReadOptions(), size_key, &val);\n\tif(s.IsNotFound()){\n\t\treturn 0;\n\t}else if(!s.ok()){\n\t\treturn -1;\n\t}else{\n\t\tif(val.size() != sizeof(uint64_t)){\n\t\t\treturn 0;\n\t\t}\n\t\tint64_t ret; \n\t\tmemcpy(&ret, val.data(), sizeof(int64_t));\n\t\treturn ret < 0? 0 : ret;\n\t}\n}\n\nint64_t SSDBImpl::hclear(const Bytes &name){\n\tint64_t count = 0;\n\tstd::string start;\n\twhile(1){\n\t\tHIterator *it = this->hscan(name, start, \"\", 10000);\n\t\tint num = 0;\n\t\twhile(it->next()){\n\t\t\tstart = it->key;\n\t\t\tint ret = this->hdel(name, it->key);\n\t\t\tif(ret == -1){\n\t\t\t\tdelete it;\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tnum ++;\n\t\t};\n\t\tdelete it;\n\n\t\tif(num == 0){\n\t\t\tbreak;\n\t\t}\n\t\tcount += num;\n\t}\n\treturn count;\n}\n\nint SSDBImpl::hget(const Bytes &name, const Bytes &key, std::string *val){\n\tstd::string dbkey = encode_hash_key(name, key);\n\tleveldb::Status s = ldb->Get(leveldb::ReadOptions(), dbkey, val);\n\tif(s.IsNotFound()){\n\t\treturn 0;\n\t}\n\tif(!s.ok()){\n\t\tlog_error(\"%s\", s.ToString().c_str());\n\t\treturn -1;\n\t}\n\treturn 1;\n}\n\nHIterator* SSDBImpl::hscan(const Bytes &name, const Bytes &start, const Bytes &end, uint64_t limit){\n\tstd::string key_start, key_end;\n\n\tkey_start = encode_hash_key(name, start);\n\tif(!end.empty()){\n\t\tkey_end = encode_hash_key(name, end);\n\t}\n\t//dump(key_start.data(), key_start.size(), \"scan.start\");\n\t//dump(key_end.data(), key_end.size(), \"scan.end\");\n\n\treturn new HIterator(this->iterator(key_start, key_end, limit), name);\n}\n\nHIterator* SSDBImpl::hrscan(const Bytes &name, const Bytes &start, const Bytes &end, uint64_t limit){\n\tstd::string key_start, key_end;\n\n\tkey_start = encode_hash_key(name, start);\n\tif(start.empty()){\n\t\tkey_start.append(1, 255);\n\t}\n\tif(!end.empty()){\n\t\tkey_end = encode_hash_key(name, end);\n\t}\n\t//dump(key_start.data(), key_start.size(), \"scan.start\");\n\t//dump(key_end.data(), key_end.size(), \"scan.end\");\n\n\treturn new HIterator(this->rev_iterator(key_start, key_end, limit), name);\n}\n\nstatic void get_hnames(Iterator *it, std::vector<std::string> *list){\n\twhile(it->next()){\n\t\tBytes ks = it->key();\n\t\tif(ks.data()[0] != DataType::HSIZE){\n\t\t\tbreak;\n\t\t}\n\t\tstd::string n;\n\t\tif(decode_hsize_key(ks, &n) == -1){\n\t\t\tcontinue;\n\t\t}\n\t\tlist->push_back(n);\n\t}\n}\n\nint SSDBImpl::hlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\tstd::vector<std::string> *list){\n\tstd::string start;\n\tstd::string end;\n\t\n\tstart = encode_hsize_key(name_s);\n\tif(!name_e.empty()){\n\t\tend = encode_hsize_key(name_e);\n\t}\n\t\n\tIterator *it = this->iterator(start, end, limit);\n\tget_hnames(it, list);\n\tdelete it;\n\treturn 0;\n}\n\nint SSDBImpl::hrlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\tstd::vector<std::string> *list){\n\tstd::string start;\n\tstd::string end;\n\t\n\tstart = encode_hsize_key(name_s);\n\tif(name_s.empty()){\n\t\tstart.append(1, 255);\n\t}\n\tif(!name_e.empty()){\n\t\tend = encode_hsize_key(name_e);\n\t}\n\t\n\tIterator *it = this->rev_iterator(start, end, limit);\n\tget_hnames(it, list);\n\tdelete it;\n\treturn 0;\n}\n\n// returns the number of newly added items\nstatic int hset_one(SSDBImpl *ssdb, const Bytes &name, const Bytes &key, const Bytes &val, char log_type){\n\tif(name.empty() || key.empty()){\n\t\tlog_error(\"empty name or key!\");\n\t\treturn -1;\n\t}\n\tif(name.size() > SSDB_KEY_LEN_MAX ){\n\t\tlog_error(\"name too long! %s\", hexmem(name.data(), name.size()).c_str());\n\t\treturn -1;\n\t}\n\tif(key.size() > SSDB_KEY_LEN_MAX){\n\t\tlog_error(\"key too long! %s\", hexmem(key.data(), key.size()).c_str());\n\t\treturn -1;\n\t}\n\tint ret = 0;\n\tstd::string dbval;\n\tif(ssdb->hget(name, key, &dbval) == 0){ // not found\n\t\tstd::string hkey = encode_hash_key(name, key);\n\t\tssdb->binlogs->Put(hkey, slice(val));\n\t\tssdb->binlogs->add_log(log_type, BinlogCommand::HSET, hkey);\n\t\tret = 1;\n\t}else{\n\t\tif(dbval != val){\n\t\t\tstd::string hkey = encode_hash_key(name, key);\n\t\t\tssdb->binlogs->Put(hkey, slice(val));\n\t\t\tssdb->binlogs->add_log(log_type, BinlogCommand::HSET, hkey);\n\t\t}\n\t\tret = 0;\n\t}\n\treturn ret;\n}\n\nstatic int hdel_one(SSDBImpl *ssdb, const Bytes &name, const Bytes &key, char log_type){\n\tif(name.size() > SSDB_KEY_LEN_MAX ){\n\t\tlog_error(\"name too long! %s\", hexmem(name.data(), name.size()).c_str());\n\t\treturn -1;\n\t}\n\tif(key.size() > SSDB_KEY_LEN_MAX){\n\t\tlog_error(\"key too long! %s\", hexmem(key.data(), key.size()).c_str());\n\t\treturn -1;\n\t}\n\tstd::string dbval;\n\tif(ssdb->hget(name, key, &dbval) == 0){\n\t\treturn 0;\n\t}\n\n\tstd::string hkey = encode_hash_key(name, key);\n\tssdb->binlogs->Delete(hkey);\n\tssdb->binlogs->add_log(log_type, BinlogCommand::HDEL, hkey);\n\t\n\treturn 1;\n}\n\nstatic int incr_hsize(SSDBImpl *ssdb, const Bytes &name, int64_t incr){\n\tint64_t size = ssdb->hsize(name);\n\tsize += incr;\n\tstd::string size_key = encode_hsize_key(name);\n\tif(size == 0){\n\t\tssdb->binlogs->Delete(size_key);\n\t}else{\n\t\tssdb->binlogs->Put(size_key, leveldb::Slice((char *)&size, sizeof(int64_t)));\n\t}\n\treturn 0;\n}\n\nint64_t SSDBImpl::hfix(const Bytes &name){\n\tTransaction trans(binlogs);\n\n\tuint64_t size = 0;\n\tHIterator *it = this->hscan(name, \"\", \"\", UINT64_MAX);\n\twhile(it->next()){\n\t\tsize ++;\n\t}\n\tdelete it;\n\n\tstd::string size_key = encode_hsize_key(name);\n\tif(size == 0){\n\t\tldb->Delete(leveldb::WriteOptions(), size_key);\n\t}else{\n\t\tldb->Put(leveldb::WriteOptions(), size_key, leveldb::Slice((char *)&size, sizeof(int64_t)));\n\t}\n\t\n\treturn size;\n}\n"
  },
  {
    "path": "src/ssdb/t_hash.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef SSDB_HASH_H_\n#define SSDB_HASH_H_\n\n#include \"ssdb_impl.h\"\n\ninline static\nstd::string encode_hsize_key(const Bytes &name){\n\tstd::string buf;\n\tbuf.reserve(name.size() + 1);\n\tbuf.append(1, DataType::HSIZE);\n\tbuf.append(name.data(), name.size());\n\treturn buf;\n}\n\ninline static\nint decode_hsize_key(const Bytes &slice, std::string *name){\n\tDecoder decoder(slice.data(), slice.size());\n\tif(decoder.skip(1) == -1){\n\t\treturn -1;\n\t}\n\tif(decoder.read_data(name) == -1){\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\ninline static\nstd::string encode_hash_key(const Bytes &name, const Bytes &key){\n\tstd::string buf;\n\tbuf.reserve(128);\n\tbuf.append(1, DataType::HASH);\n\tbuf.append(1, (uint8_t)name.size());\n\tbuf.append(name.data(), name.size());\n\tbuf.append(1, '=');\n\tbuf.append(key.data(), key.size());\n\treturn buf;\n}\n\ninline static\nint decode_hash_key(const Bytes &slice, std::string *name, std::string *key){\n\tDecoder decoder(slice.data(), slice.size());\n\tif(decoder.skip(1) == -1){\n\t\treturn -1;\n\t}\n\tif(decoder.read_8_data(name) == -1){\n\t\treturn -1;\n\t}\n\tif(decoder.skip(1) == -1){\n\t\treturn -1;\n\t}\n\tif(decoder.read_data(key) == -1){\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\n#endif\n"
  },
  {
    "path": "src/ssdb/t_kv.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"t_kv.h\"\n\nint SSDBImpl::multi_set(const std::vector<Bytes> &kvs, int offset, char log_type){\n\tTransaction trans(binlogs);\n\n\tstd::vector<Bytes>::const_iterator it;\n\tit = kvs.begin() + offset;\n\tfor(; it != kvs.end(); it += 2){\n\t\tconst Bytes &key = *it;\n\t\tif(key.empty()){\n\t\t\tlog_error(\"empty key!\");\n\t\t\treturn 0;\n\t\t\t//return -1;\n\t\t}\n\t\tif(key.size() > SSDB_KEY_LEN_MAX ){\n\t\t\tlog_error(\"name too long! %s\", hexmem(key.data(), key.size()).c_str());\n\t\t\treturn 0;\n\t\t}\n\t\tconst Bytes &val = *(it + 1);\n\t\tstd::string buf = encode_kv_key(key);\n\t\tbinlogs->Put(buf, slice(val));\n\t\tbinlogs->add_log(log_type, BinlogCommand::KSET, buf);\n\t}\n\tleveldb::Status s = binlogs->commit();\n\tif(!s.ok()){\n\t\tlog_error(\"multi_set error: %s\", s.ToString().c_str());\n\t\treturn -1;\n\t}\n\treturn (kvs.size() - offset)/2;\n}\n\nint SSDBImpl::multi_del(const std::vector<Bytes> &keys, int offset, char log_type){\n\tTransaction trans(binlogs);\n\n\tstd::vector<Bytes>::const_iterator it;\n\tit = keys.begin() + offset;\n\tfor(; it != keys.end(); it++){\n\t\tconst Bytes &key = *it;\n\t\tstd::string buf = encode_kv_key(key);\n\t\tbinlogs->Delete(buf);\n\t\tbinlogs->add_log(log_type, BinlogCommand::KDEL, buf);\n\t}\n\tleveldb::Status s = binlogs->commit();\n\tif(!s.ok()){\n\t\tlog_error(\"multi_del error: %s\", s.ToString().c_str());\n\t\treturn -1;\n\t}\n\treturn keys.size() - offset;\n}\n\nint SSDBImpl::set(const Bytes &key, const Bytes &val, char log_type){\n\tif(key.empty()){\n\t\tlog_error(\"empty key!\");\n\t\t//return -1;\n\t\treturn 0;\n\t}\n\tif(key.size() > SSDB_KEY_LEN_MAX ){\n\t\tlog_error(\"name too long! %s\", hexmem(key.data(), key.size()).c_str());\n\t\treturn -1;\n\t}\n\n\tTransaction trans(binlogs);\n\n\tstd::string buf = encode_kv_key(key);\n\tbinlogs->Put(buf, slice(val));\n\tbinlogs->add_log(log_type, BinlogCommand::KSET, buf);\n\tleveldb::Status s = binlogs->commit();\n\tif(!s.ok()){\n\t\tlog_error(\"set error: %s\", s.ToString().c_str());\n\t\treturn -1;\n\t}\n\treturn 1;\n}\n\nint SSDBImpl::setnx(const Bytes &key, const Bytes &val, char log_type){\n\tif(key.empty()){\n\t\tlog_error(\"empty key!\");\n\t\t//return -1;\n\t\treturn 0;\n\t}\n\tif(key.size() > SSDB_KEY_LEN_MAX ){\n\t\tlog_error(\"name too long! %s\", hexmem(key.data(), key.size()).c_str());\n\t\treturn -1;\n\t}\n\tTransaction trans(binlogs);\n\n\tstd::string tmp;\n\tint found = this->get(key, &tmp);\n\tif(found != 0){\n\t\treturn 0;\n\t}\n\tstd::string buf = encode_kv_key(key);\n\tbinlogs->Put(buf, slice(val));\n\tbinlogs->add_log(log_type, BinlogCommand::KSET, buf);\n\tleveldb::Status s = binlogs->commit();\n\tif(!s.ok()){\n\t\tlog_error(\"set error: %s\", s.ToString().c_str());\n\t\treturn -1;\n\t}\n\treturn 1;\n}\n\nint SSDBImpl::getset(const Bytes &key, std::string *val, const Bytes &newval, char log_type){\n\tif(key.empty()){\n\t\tlog_error(\"empty key!\");\n\t\t//return -1;\n\t\treturn 0;\n\t}\n\tif(key.size() > SSDB_KEY_LEN_MAX ){\n\t\tlog_error(\"name too long! %s\", hexmem(key.data(), key.size()).c_str());\n\t\treturn -1;\n\t}\n\tTransaction trans(binlogs);\n\n\tint found = this->get(key, val);\n\tstd::string buf = encode_kv_key(key);\n\tbinlogs->Put(buf, slice(newval));\n\tbinlogs->add_log(log_type, BinlogCommand::KSET, buf);\n\tleveldb::Status s = binlogs->commit();\n\tif(!s.ok()){\n\t\tlog_error(\"set error: %s\", s.ToString().c_str());\n\t\treturn -1;\n\t}\n\treturn found;\n}\n\n\nint SSDBImpl::del(const Bytes &key, char log_type){\n\tif(key.size() > SSDB_KEY_LEN_MAX ){\n\t\tlog_error(\"name too long! %s\", hexmem(key.data(), key.size()).c_str());\n\t\treturn -1;\n\t}\n\tTransaction trans(binlogs);\n\n\tstd::string buf = encode_kv_key(key);\n\tbinlogs->Delete(buf);\n\tbinlogs->add_log(log_type, BinlogCommand::KDEL, buf);\n\tleveldb::Status s = binlogs->commit();\n\tif(!s.ok()){\n\t\tlog_error(\"del error: %s\", s.ToString().c_str());\n\t\treturn -1;\n\t}\n\treturn 1;\n}\n\nint SSDBImpl::incr(const Bytes &key, int64_t by, int64_t *new_val, char log_type){\n\tif(key.size() > SSDB_KEY_LEN_MAX ){\n\t\tlog_error(\"name too long! %s\", hexmem(key.data(), key.size()).c_str());\n\t\treturn -1;\n\t}\n\tTransaction trans(binlogs);\n\n\tstd::string old;\n\tint ret = this->get(key, &old);\n\tif(ret == -1){\n\t\treturn -1;\n\t}else if(ret == 0){\n\t\t*new_val = by;\n\t}else{\n\t\t*new_val = str_to_int64(old) + by;\n\t\tif(errno != 0){\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tstd::string buf = encode_kv_key(key);\n\tbinlogs->Put(buf, str(*new_val));\n\tbinlogs->add_log(log_type, BinlogCommand::KSET, buf);\n\n\tleveldb::Status s = binlogs->commit();\n\tif(!s.ok()){\n\t\tlog_error(\"del error: %s\", s.ToString().c_str());\n\t\treturn -1;\n\t}\n\treturn 1;\n}\n\nint SSDBImpl::get(const Bytes &key, std::string *val){\n\tstd::string buf = encode_kv_key(key);\n\n\tleveldb::Status s = ldb->Get(leveldb::ReadOptions(), buf, val);\n\tif(s.IsNotFound()){\n\t\treturn 0;\n\t}\n\tif(!s.ok()){\n\t\tlog_error(\"get error: %s\", s.ToString().c_str());\n\t\treturn -1;\n\t}\n\treturn 1;\n}\n\nKIterator* SSDBImpl::scan(const Bytes &start, const Bytes &end, uint64_t limit){\n\tstd::string key_start, key_end;\n\tkey_start = encode_kv_key(start);\n\tif(end.empty()){\n\t\tkey_end = \"\";\n\t}else{\n\t\tkey_end = encode_kv_key(end);\n\t}\n\t//dump(key_start.data(), key_start.size(), \"scan.start\");\n\t//dump(key_end.data(), key_end.size(), \"scan.end\");\n\n\treturn new KIterator(this->iterator(key_start, key_end, limit));\n}\n\nKIterator* SSDBImpl::rscan(const Bytes &start, const Bytes &end, uint64_t limit){\n\tstd::string key_start, key_end;\n\n\tkey_start = encode_kv_key(start);\n\tif(start.empty()){\n\t\tkey_start.append(1, 255);\n\t}\n\tif(!end.empty()){\n\t\tkey_end = encode_kv_key(end);\n\t}\n\t//dump(key_start.data(), key_start.size(), \"scan.start\");\n\t//dump(key_end.data(), key_end.size(), \"scan.end\");\n\n\treturn new KIterator(this->rev_iterator(key_start, key_end, limit));\n}\n\nint SSDBImpl::setbit(const Bytes &key, int bitoffset, int on, char log_type){\n\tif(key.empty()){\n\t\tlog_error(\"empty key!\");\n\t\treturn 0;\n\t}\n\tif(key.size() > SSDB_KEY_LEN_MAX ){\n\t\tlog_error(\"name too long! %s\", hexmem(key.data(), key.size()).c_str());\n\t\treturn -1;\n\t}\n\tTransaction trans(binlogs);\n\t\n\tstd::string val;\n\tint ret = this->get(key, &val);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\t\n\tint len = bitoffset / 8;\n\t// Bit Numbering: MSB 0\n\tint bit = 7 - bitoffset % 8;\n\tif(len >= val.size()){\n\t\tval.resize(len + 1, 0);\n\t}\n\tint orig = val[len] & (1 << bit);\n\tif(on == 1){\n\t\tval[len] |= (1 << bit);\n\t}else{\n\t\tval[len] &= ~(1 << bit);\n\t}\n\n\tstd::string buf = encode_kv_key(key);\n\tbinlogs->Put(buf, val);\n\tbinlogs->add_log(log_type, BinlogCommand::KSET, buf);\n\tleveldb::Status s = binlogs->commit();\n\tif(!s.ok()){\n\t\tlog_error(\"set error: %s\", s.ToString().c_str());\n\t\treturn -1;\n\t}\n\treturn orig;\n}\n\nint SSDBImpl::getbit(const Bytes &key, int bitoffset){\n\tstd::string val;\n\tint ret = this->get(key, &val);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\t\n\tint len = bitoffset / 8;\n\t// Bit Numbering: MSB 0\n\tint bit = 7 - bitoffset % 8;\n\tif(len >= val.size()){\n\t\treturn 0;\n\t}\n\treturn (val[len] & (1 << bit)) == 0? 0 : 1;\n}\n\n\n"
  },
  {
    "path": "src/ssdb/t_kv.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef SSDB_KV_H_\n#define SSDB_KV_H_\n\n#include \"ssdb_impl.h\"\n\nstatic inline\nstd::string encode_kv_key(const Bytes &key){\n\tstd::string buf;\n\tbuf.reserve(key.size() + 1);\n\tbuf.append(1, DataType::KV);\n\tbuf.append(key.data(), key.size());\n\treturn buf;\n}\n\nstatic inline\nint decode_kv_key(const Bytes &slice, std::string *key){\n\tDecoder decoder(slice.data(), slice.size());\n\tif(decoder.skip(1) == -1){\n\t\treturn -1;\n\t}\n\tif(decoder.read_data(key) == -1){\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\n#endif\n"
  },
  {
    "path": "src/ssdb/t_queue.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"t_queue.h\"\n\nstatic int qget_by_seq(leveldb::DB* db, const Bytes &name, uint64_t seq, std::string *val){\n\tstd::string key = encode_qitem_key(name, seq);\n\tleveldb::Status s;\n\n\ts = db->Get(leveldb::ReadOptions(), key, val);\n\tif(s.IsNotFound()){\n\t\treturn 0;\n\t}else if(!s.ok()){\n\t\tlog_error(\"Get() error!\");\n\t\treturn -1;\n\t}else{\n\t\treturn 1;\n\t}\n}\n\nstatic int qget_uint64(leveldb::DB* db, const Bytes &name, uint64_t seq, uint64_t *ret){\n\tstd::string val;\n\t*ret = 0;\n\tint s = qget_by_seq(db, name, seq, &val);\n\tif(s == 1){\n\t\tif(val.size() != sizeof(uint64_t)){\n\t\t\treturn -1;\n\t\t}\n\t\tmemcpy(ret, val.data(), sizeof(uint64_t));\n\t}\n\treturn s;\n}\n\nstatic int qdel_one(SSDBImpl *ssdb, const Bytes &name, uint64_t seq){\n\tstd::string key = encode_qitem_key(name, seq);\n\tleveldb::Status s;\n\n\tssdb->binlogs->Delete(key);\n\treturn 0;\n}\n\nstatic int qset_one(SSDBImpl *ssdb, const Bytes &name, uint64_t seq, const Bytes &item){\n\tif(name.size() > SSDB_KEY_LEN_MAX ){\n\t\tlog_error(\"name too long! %s\", hexmem(name.data(), name.size()).c_str());\n\t\treturn -1;\n\t}\n\n\tstd::string key = encode_qitem_key(name, seq);\n\tleveldb::Status s;\n\n\tssdb->binlogs->Put(key, slice(item));\n\treturn 0;\n}\n\nstatic int64_t incr_qsize(SSDBImpl *ssdb, const Bytes &name, int64_t incr){\n\tint64_t size = ssdb->qsize(name);\n\tif(size == -1){\n\t\treturn -1;\n\t}\n\tsize += incr;\n\tif(size <= 0){\n\t\tssdb->binlogs->Delete(encode_qsize_key(name));\n\t\tqdel_one(ssdb, name, QFRONT_SEQ);\n\t\tqdel_one(ssdb, name, QBACK_SEQ);\n\t}else{\n\t\tssdb->binlogs->Put(encode_qsize_key(name), leveldb::Slice((char *)&size, sizeof(size)));\n\t}\n\treturn size;\n}\n\n/****************/\n\nint64_t SSDBImpl::qsize(const Bytes &name){\n\tstd::string key = encode_qsize_key(name);\n\tstd::string val;\n\n\tleveldb::Status s;\n\ts = ldb->Get(leveldb::ReadOptions(), key, &val);\n\tif(s.IsNotFound()){\n\t\treturn 0;\n\t}else if(!s.ok()){\n\t\tlog_error(\"Get() error!\");\n\t\treturn -1;\n\t}else{\n\t\tif(val.size() != sizeof(uint64_t)){\n\t\t\treturn -1;\n\t\t}\n\t\tint64_t ret; \n\t\tmemcpy(&ret, val.data(), sizeof(int64_t));\n\t\treturn ret;\n\t}\n}\n\n// @return 0: empty queue, 1: item peeked, -1: error\nint SSDBImpl::qfront(const Bytes &name, std::string *item){\n\tint ret = 0;\n\tuint64_t seq;\n\tret = qget_uint64(this->ldb, name, QFRONT_SEQ, &seq);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\tif(ret == 0){\n\t\treturn 0;\n\t}\n\tret = qget_by_seq(this->ldb, name, seq, item);\n\treturn ret;\n}\n\n// @return 0: empty queue, 1: item peeked, -1: error\nint SSDBImpl::qback(const Bytes &name, std::string *item){\n\tint ret = 0;\n\tuint64_t seq;\n\tret = qget_uint64(this->ldb, name, QBACK_SEQ, &seq);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\tif(ret == 0){\n\t\treturn 0;\n\t}\n\tret = qget_by_seq(this->ldb, name, seq, item);\n\treturn ret;\n}\n\nint SSDBImpl::qset_by_seq(const Bytes &name, uint64_t seq, const Bytes &item, char log_type){\n\tTransaction trans(binlogs);\n\tuint64_t min_seq, max_seq;\n\tint ret;\n\tint64_t size = this->qsize(name);\n\tif(size == -1){\n\t\treturn -1;\n\t}\n\tret = qget_uint64(this->ldb, name, QFRONT_SEQ, &min_seq);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\tmax_seq = min_seq + size;\n\tif(seq < min_seq || seq > max_seq){\n\t\treturn 0;\n\t}\n\n\tret = qset_one(this, name, seq, item);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\n\tstd::string buf = encode_qitem_key(name, seq);\n\tbinlogs->add_log(log_type, BinlogCommand::QSET, buf);\n\n\tleveldb::Status s = binlogs->commit();\n\tif(!s.ok()){\n\t\tlog_error(\"Write error!\");\n\t\treturn -1;\n\t}\n\treturn 1;\n}\n\n// return: 0: index out of range, -1: error, 1: ok\nint SSDBImpl::qset(const Bytes &name, int64_t index, const Bytes &item, char log_type){\n\tTransaction trans(binlogs);\n\tint64_t size = this->qsize(name);\n\tif(size == -1){\n\t\treturn -1;\n\t}\n\tif(index >= size || index < -size){\n\t\treturn 0;\n\t}\n\t\n\tint ret;\n\tuint64_t seq;\n\tif(index >= 0){\n\t\tret = qget_uint64(this->ldb, name, QFRONT_SEQ, &seq);\n\t\tseq += index;\n\t}else{\n\t\tret = qget_uint64(this->ldb, name, QBACK_SEQ, &seq);\n\t\tseq += index + 1;\n\t}\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\tif(ret == 0){\n\t\treturn 0;\n\t}\n\n\tret = qset_one(this, name, seq, item);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\n\t//log_info(\"qset %s %\" PRIu64 \"\", hexmem(name.data(), name.size()).c_str(), seq);\n\tstd::string buf = encode_qitem_key(name, seq);\n\tbinlogs->add_log(log_type, BinlogCommand::QSET, buf);\n\t\n\tleveldb::Status s = binlogs->commit();\n\tif(!s.ok()){\n\t\tlog_error(\"Write error!\");\n\t\treturn -1;\n\t}\n\treturn 1;\n}\n\nint64_t SSDBImpl::_qpush(const Bytes &name, const Bytes &item, uint64_t front_or_back_seq, char log_type){\n\tTransaction trans(binlogs);\n\n\tint ret;\n\t// generate seq\n\tuint64_t seq;\n\tret = qget_uint64(this->ldb, name, front_or_back_seq, &seq);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\t// update front and/or back\n\tif(ret == 0){\n\t\tseq = QITEM_SEQ_INIT;\n\t\tret = qset_one(this, name, QFRONT_SEQ, Bytes(&seq, sizeof(seq)));\n\t\tif(ret == -1){\n\t\t\treturn -1;\n\t\t}\n\t\tret = qset_one(this, name, QBACK_SEQ, Bytes(&seq, sizeof(seq)));\n\t}else{\n\t\tseq += (front_or_back_seq == QFRONT_SEQ)? -1 : +1;\n\t\tret = qset_one(this, name, front_or_back_seq, Bytes(&seq, sizeof(seq)));\n\t}\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\tif(seq <= QITEM_MIN_SEQ || seq >= QITEM_MAX_SEQ){\n\t\tlog_info(\"queue is full, seq: %\" PRIu64 \" out of range\", seq);\n\t\treturn -1;\n\t}\n\t\n\t// prepend/append item\n\tret = qset_one(this, name, seq, item);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\n\tstd::string buf = encode_qitem_key(name, seq);\n\tif(front_or_back_seq == QFRONT_SEQ){\n\t\tbinlogs->add_log(log_type, BinlogCommand::QPUSH_FRONT, buf);\n\t}else{\n\t\tbinlogs->add_log(log_type, BinlogCommand::QPUSH_BACK, buf);\n\t}\n\t\n\t// update size\n\tint64_t size = incr_qsize(this, name, +1);\n\tif(size == -1){\n\t\treturn -1;\n\t}\n\n\tleveldb::Status s = binlogs->commit();\n\tif(!s.ok()){\n\t\tlog_error(\"Write error! %s\", s.ToString().c_str());\n\t\treturn -1;\n\t}\n\treturn size;\n}\n\nint64_t SSDBImpl::qpush_front(const Bytes &name, const Bytes &item, char log_type){\n\treturn _qpush(name, item, QFRONT_SEQ, log_type);\n}\n\nint64_t SSDBImpl::qpush_back(const Bytes &name, const Bytes &item, char log_type){\n\treturn _qpush(name, item, QBACK_SEQ, log_type);\n}\n\nint SSDBImpl::_qpop(const Bytes &name, std::string *item, uint64_t front_or_back_seq, char log_type){\n\tTransaction trans(binlogs);\n\t\n\tint ret;\n\tuint64_t seq;\n\tret = qget_uint64(this->ldb, name, front_or_back_seq, &seq);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\tif(ret == 0){\n\t\treturn 0;\n\t}\n\t\n\tret = qget_by_seq(this->ldb, name, seq, item);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\tif(ret == 0){\n\t\treturn 0;\n\t}\n\n\t// delete item\n\tret = qdel_one(this, name, seq);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\n\tif(front_or_back_seq == QFRONT_SEQ){\n\t\tbinlogs->add_log(log_type, BinlogCommand::QPOP_FRONT, name.String());\n\t}else{\n\t\tbinlogs->add_log(log_type, BinlogCommand::QPOP_BACK, name.String());\n\t}\n\n\t// update size\n\tint64_t size = incr_qsize(this, name, -1);\n\tif(size == -1){\n\t\treturn -1;\n\t}\n\t\t\n\t// update front\n\tif(size > 0){\n\t\tseq += (front_or_back_seq == QFRONT_SEQ)? +1 : -1;\n\t\t//log_debug(\"seq: %\" PRIu64 \", ret: %d\", seq, ret);\n\t\tret = qset_one(this, name, front_or_back_seq, Bytes(&seq, sizeof(seq)));\n\t\tif(ret == -1){\n\t\t\treturn -1;\n\t\t}\n\t}\n\t\t\n\tleveldb::Status s = binlogs->commit();\n\tif(!s.ok()){\n\t\tlog_error(\"Write error! %s\", s.ToString().c_str());\n\t\treturn -1;\n\t}\n\treturn 1;\n}\n\n// @return 0: empty queue, 1: item popped, -1: error\nint SSDBImpl::qpop_front(const Bytes &name, std::string *item, char log_type){\n\treturn _qpop(name, item, QFRONT_SEQ, log_type);\n}\n\nint SSDBImpl::qpop_back(const Bytes &name, std::string *item, char log_type){\n\treturn _qpop(name, item, QBACK_SEQ, log_type);\n}\n\nstatic void get_qnames(Iterator *it, std::vector<std::string> *list){\n\twhile(it->next()){\n\t\tBytes ks = it->key();\n\t\t//dump(ks.data(), ks.size());\n\t\tif(ks.data()[0] != DataType::QSIZE){\n\t\t\tbreak;\n\t\t}\n\t\tstd::string n;\n\t\tif(decode_qsize_key(ks, &n) == -1){\n\t\t\tcontinue;\n\t\t}\n\t\tlist->push_back(n);\n\t}\n}\n\nint SSDBImpl::qlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\tstd::vector<std::string> *list){\n\tstd::string start;\n\tstd::string end;\n\t\n\tstart = encode_qsize_key(name_s);\n\tif(!name_e.empty()){\n\t\tend = encode_qsize_key(name_e);\n\t}\n\t\n\tIterator *it = this->iterator(start, end, limit);\n\tget_qnames(it, list);\n\tdelete it;\n\treturn 0;\n}\n\nint SSDBImpl::qrlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\tstd::vector<std::string> *list){\n\tstd::string start;\n\tstd::string end;\n\t\n\tstart = encode_qsize_key(name_s);\n\tif(name_s.empty()){\n\t\tstart.append(1, 255);\n\t}\n\tif(!name_e.empty()){\n\t\tend = encode_qsize_key(name_e);\n\t}\n\t\n\tIterator *it = this->rev_iterator(start, end, limit);\n\tget_qnames(it, list);\n\tdelete it;\n\treturn 0;\n}\n\nint SSDBImpl::qfix(const Bytes &name){\n\tTransaction trans(binlogs);\n\tstd::string key_s = encode_qitem_key(name, QITEM_MIN_SEQ - 1);\n\tstd::string key_e = encode_qitem_key(name, QITEM_MAX_SEQ);\n\n\tbool error = false;\n\tuint64_t seq_min = 0;\n\tuint64_t seq_max = 0;\n\tuint64_t count = 0;\n\tIterator *it = this->iterator(key_s, key_e, QITEM_MAX_SEQ);\n\twhile(it->next()){\n\t\t//dump(it->key().data(), it->key().size());\n\t\tif(seq_min == 0){\n\t\t\tif(decode_qitem_key(it->key(), NULL, &seq_min) == -1){\n\t\t\t\t// or just delete it?\n\t\t\t\terror = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif(decode_qitem_key(it->key(), NULL, &seq_max) == -1){\n\t\t\terror = true;\n\t\t\tbreak;\n\t\t}\n\t\tcount ++;\n\t}\n\tdelete it;\n\tif(error){\n\t\treturn -1;\n\t}\n\t\n\tif(count == 0){\n\t\tthis->binlogs->Delete(encode_qsize_key(name));\n\t\tqdel_one(this, name, QFRONT_SEQ);\n\t\tqdel_one(this, name, QBACK_SEQ);\n\t}else{\n\t\tthis->binlogs->Put(encode_qsize_key(name), leveldb::Slice((char *)&count, sizeof(count)));\n\t\tqset_one(this, name, QFRONT_SEQ, Bytes(&seq_min, sizeof(seq_min)));\n\t\tqset_one(this, name, QBACK_SEQ, Bytes(&seq_max, sizeof(seq_max)));\n\t}\n\t\t\n\tleveldb::Status s = binlogs->commit();\n\tif(!s.ok()){\n\t\tlog_error(\"Write error!\");\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nint SSDBImpl::qslice(const Bytes &name, int64_t begin, int64_t end,\n\t\tstd::vector<std::string> *list)\n{\n\tint ret;\n\tuint64_t seq_begin, seq_end;\n\tif(begin >= 0 && end >= 0){\n\t\tuint64_t tmp_seq;\n\t\tret = qget_uint64(this->ldb, name, QFRONT_SEQ, &tmp_seq);\n\t\tif(ret != 1){\n\t\t\treturn ret;\n\t\t}\n\t\tseq_begin = tmp_seq + begin;\n\t\tseq_end = tmp_seq + end;\n\t}else if(begin < 0 && end < 0){\n\t\tuint64_t tmp_seq;\n\t\tret = qget_uint64(this->ldb, name, QBACK_SEQ, &tmp_seq);\n\t\tif(ret != 1){\n\t\t\treturn ret;\n\t\t}\n\t\tseq_begin = tmp_seq + begin + 1;\n\t\tseq_end = tmp_seq + end + 1;\n\t}else{\n\t\tuint64_t f_seq, b_seq;\n\t\tret = qget_uint64(this->ldb, name, QFRONT_SEQ, &f_seq);\n\t\tif(ret != 1){\n\t\t\treturn ret;\n\t\t}\n\t\tret = qget_uint64(this->ldb, name, QBACK_SEQ, &b_seq);\n\t\tif(ret != 1){\n\t\t\treturn ret;\n\t\t}\n\t\tif(begin >= 0){\n\t\t\tseq_begin = f_seq + begin;\n\t\t}else{\n\t\t\tseq_begin = b_seq + begin + 1;\n\t\t}\n\t\tif(end >= 0){\n\t\t\tseq_end = f_seq + end;\n\t\t}else{\n\t\t\tseq_end = b_seq + end + 1;\n\t\t}\n\t}\n\t\n\tfor(; seq_begin <= seq_end; seq_begin++){\n\t\tstd::string item;\n\t\tret = qget_by_seq(this->ldb, name, seq_begin, &item);\n\t\tif(ret == -1){\n\t\t\treturn -1;\n\t\t}\n\t\tif(ret == 0){\n\t\t\treturn 0;\n\t\t}\n\t\tlist->push_back(item);\n\t}\n\treturn 0;\n}\n\nint SSDBImpl::qget(const Bytes &name, int64_t index, std::string *item){\n\tint ret;\n\tuint64_t seq;\n\tif(index >= 0){\n\t\tret = qget_uint64(this->ldb, name, QFRONT_SEQ, &seq);\n\t\tseq += index;\n\t}else{\n\t\tret = qget_uint64(this->ldb, name, QBACK_SEQ, &seq);\n\t\tseq += index + 1;\n\t}\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\tif(ret == 0){\n\t\treturn 0;\n\t}\n\t\n\tret = qget_by_seq(this->ldb, name, seq, item);\n\treturn ret;\n}\n"
  },
  {
    "path": "src/ssdb/t_queue.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef SSDB_QUEUE_H_\n#define SSDB_QUEUE_H_\n\n#include \"ssdb_impl.h\"\n\nconst uint64_t QFRONT_SEQ = 2;\nconst uint64_t QBACK_SEQ  = 3;\nconst uint64_t QITEM_MIN_SEQ = 10000;\nconst uint64_t QITEM_MAX_SEQ = 9223372036854775807ULL;\nconst uint64_t QITEM_SEQ_INIT = QITEM_MAX_SEQ/2;\n\ninline static\nstd::string encode_qsize_key(const Bytes &name){\n\tstd::string buf;\n\tbuf.reserve(name.size() + 1);\n\tbuf.append(1, DataType::QSIZE);\n\tbuf.append(name.data(), name.size());\n\treturn buf;\n}\n\ninline static\nint decode_qsize_key(const Bytes &slice, std::string *name){\n\tDecoder decoder(slice.data(), slice.size());\n\tif(decoder.skip(1) == -1){\n\t\treturn -1;\n\t}\n\tif(decoder.read_data(name) == -1){\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\ninline static\nstd::string encode_qitem_key(const Bytes &name, uint64_t seq){\n\tstd::string buf;\n\tbuf.reserve(128);\n\tbuf.append(1, DataType::QUEUE);\n\tbuf.append(1, (uint8_t)name.size());\n\tbuf.append(name.data(), name.size());\n\tseq = big_endian(seq);\n\tbuf.append((char *)&seq, sizeof(uint64_t));\n\treturn buf;\n}\n\ninline static\nint decode_qitem_key(const Bytes &slice, std::string *name, uint64_t *seq){\n\tDecoder decoder(slice.data(), slice.size());\n\tif(decoder.skip(1) == -1){\n\t\treturn -1;\n\t}\n\tif(decoder.read_8_data(name) == -1){\n\t\treturn -1;\n\t}\n\tif(decoder.read_uint64(seq) == -1){\n\t\treturn -1;\n\t}\n\t*seq = big_endian(*seq);\n\treturn 0;\n}\n\n#endif\n"
  },
  {
    "path": "src/ssdb/t_zset.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include <limits.h>\n#include \"t_zset.h\"\n\nstatic const char *SSDB_SCORE_MIN\t\t= \"-9223372036854775808\";\nstatic const char *SSDB_SCORE_MAX\t\t= \"+9223372036854775807\";\n\nstatic int zset_one(SSDBImpl *ssdb, const Bytes &name, const Bytes &key, const Bytes &score, char log_type);\nstatic int zdel_one(SSDBImpl *ssdb, const Bytes &name, const Bytes &key, char log_type);\nstatic int incr_zsize(SSDBImpl *ssdb, const Bytes &name, int64_t incr);\n\n/**\n * @return -1: error, 0: item updated, 1: new item inserted\n */\nint SSDBImpl::zset(const Bytes &name, const Bytes &key, const Bytes &score, char log_type){\n\tTransaction trans(binlogs);\n\n\tint ret = zset_one(this, name, key, score, log_type);\n\tif(ret >= 0){\n\t\tif(ret > 0){\n\t\t\tif(incr_zsize(this, name, ret) == -1){\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t\tleveldb::Status s = binlogs->commit();\n\t\tif(!s.ok()){\n\t\t\tlog_error(\"zset error: %s\", s.ToString().c_str());\n\t\t\treturn -1;\n\t\t}\n\t}\n\treturn ret;\n}\n\nint SSDBImpl::zdel(const Bytes &name, const Bytes &key, char log_type){\n\tTransaction trans(binlogs);\n\n\tint ret = zdel_one(this, name, key, log_type);\n\tif(ret >= 0){\n\t\tif(ret > 0){\n\t\t\tif(incr_zsize(this, name, -ret) == -1){\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t\tleveldb::Status s = binlogs->commit();\n\t\tif(!s.ok()){\n\t\t\tlog_error(\"zdel error: %s\", s.ToString().c_str());\n\t\t\treturn -1;\n\t\t}\n\t}\n\treturn ret;\n}\n\nint SSDBImpl::zincr(const Bytes &name, const Bytes &key, int64_t by, int64_t *new_val, char log_type){\n\tTransaction trans(binlogs);\n\n\tstd::string old;\n\tint ret = this->zget(name, key, &old);\n\tif(ret == -1){\n\t\treturn -1;\n\t}else if(ret == 0){\n\t\t*new_val = by;\n\t}else{\n\t\t*new_val = str_to_int64(old) + by;\n\t}\n\n\tret = zset_one(this, name, key, str(*new_val), log_type);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\tif(ret >= 0){\n\t\tif(ret > 0){\n\t\t\tif(incr_zsize(this, name, ret) == -1){\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t\tleveldb::Status s = binlogs->commit();\n\t\tif(!s.ok()){\n\t\t\tlog_error(\"zset error: %s\", s.ToString().c_str());\n\t\t\treturn -1;\n\t\t}\n\t}\n\treturn 1;\n}\n\nint64_t SSDBImpl::zsize(const Bytes &name){\n\tstd::string size_key = encode_zsize_key(name);\n\tstd::string val;\n\tleveldb::Status s;\n\n\ts = ldb->Get(leveldb::ReadOptions(), size_key, &val);\n\tif(s.IsNotFound()){\n\t\treturn 0;\n\t}else if(!s.ok()){\n\t\treturn -1;\n\t}else{\n\t\tif(val.size() != sizeof(uint64_t)){\n\t\t\treturn 0;\n\t\t}\n\t\tint64_t ret; \n\t\tmemcpy(&ret, val.data(), sizeof(int64_t));\n\t\treturn ret < 0? 0 : ret;\n\t}\n}\n\nint SSDBImpl::zget(const Bytes &name, const Bytes &key, std::string *score){\n\tstd::string buf = encode_zset_key(name, key);\n\tleveldb::Status s = ldb->Get(leveldb::ReadOptions(), buf, score);\n\tif(s.IsNotFound()){\n\t\treturn 0;\n\t}\n\tif(!s.ok()){\n\t\tlog_error(\"zget error: %s\", s.ToString().c_str());\n\t\treturn -1;\n\t}\n\treturn 1;\n}\n\nstatic ZIterator* ziterator(\n\tSSDBImpl *ssdb,\n\tconst Bytes &name, const Bytes &key_start,\n\tconst Bytes &score_start, const Bytes &score_end,\n\tuint64_t limit, Iterator::Direction direction)\n{\n\tif(direction == Iterator::FORWARD){\n\t\tstd::string start, end;\n\t\tif(score_start.empty()){\n\t\t\tstart = encode_zscore_key(name, key_start, SSDB_SCORE_MIN);\n\t\t}else{\n\t\t\tstart = encode_zscore_key(name, key_start, score_start);\n\t\t}\n\t\tif(score_end.empty()){\n\t\t\tend = encode_zscore_key(name, \"\\xff\", SSDB_SCORE_MAX);\n\t\t}else{\n\t\t\tend = encode_zscore_key(name, \"\\xff\", score_end);\n\t\t}\n\t\treturn new ZIterator(ssdb->iterator(start, end, limit), name);\n\t}else{\n\t\tstd::string start, end;\n\t\tif(score_start.empty()){\n\t\t\tstart = encode_zscore_key(name, key_start, SSDB_SCORE_MAX);\n\t\t}else{\n\t\t\tif(key_start.empty()){\n\t\t\t\tstart = encode_zscore_key(name, \"\\xff\", score_start);\n\t\t\t}else{\n\t\t\t\tstart = encode_zscore_key(name, key_start, score_start);\n\t\t\t}\n\t\t}\n\t\tif(score_end.empty()){\n\t\t\tend = encode_zscore_key(name, \"\", SSDB_SCORE_MIN);\n\t\t}else{\n\t\t\tend = encode_zscore_key(name, \"\", score_end);\n\t\t}\n\t\treturn new ZIterator(ssdb->rev_iterator(start, end, limit), name);\n\t}\n}\n\nint64_t SSDBImpl::zrank(const Bytes &name, const Bytes &key){\n\tZIterator *it = ziterator(this, name, \"\", \"\", \"\", INT_MAX, Iterator::FORWARD);\n\tuint64_t ret = 0;\n\twhile(true){\n\t\tif(it->next() == false){\n\t\t\tret = -1;\n\t\t\tbreak;\n\t\t}\n\t\tif(key == it->key){\n\t\t\tbreak;\n\t\t}\n\t\tret ++;\n\t}\n\tdelete it;\n\treturn ret;\n}\n\nint64_t SSDBImpl::zrrank(const Bytes &name, const Bytes &key){\n\tZIterator *it = ziterator(this, name, \"\", \"\", \"\", INT_MAX, Iterator::BACKWARD);\n\tuint64_t ret = 0;\n\twhile(true){\n\t\tif(it->next() == false){\n\t\t\tret = -1;\n\t\t\tbreak;\n\t\t}\n\t\tif(key == it->key){\n\t\t\tbreak;\n\t\t}\n\t\tret ++;\n\t}\n\tdelete it;\n\treturn ret;\n}\n\nZIterator* SSDBImpl::zrange(const Bytes &name, uint64_t offset, uint64_t limit){\n\tif(offset + limit > limit){\n\t\tlimit = offset + limit;\n\t}\n\tZIterator *it = ziterator(this, name, \"\", \"\", \"\", limit, Iterator::FORWARD);\n\tit->skip(offset);\n\treturn it;\n}\n\nZIterator* SSDBImpl::zrrange(const Bytes &name, uint64_t offset, uint64_t limit){\n\tif(offset + limit > limit){\n\t\tlimit = offset + limit;\n\t}\n\tZIterator *it = ziterator(this, name, \"\", \"\", \"\", limit, Iterator::BACKWARD);\n\tit->skip(offset);\n\treturn it;\n}\n\nZIterator* SSDBImpl::zscan(const Bytes &name, const Bytes &key,\n\t\tconst Bytes &score_start, const Bytes &score_end, uint64_t limit)\n{\n\tstd::string score;\n\t// if only key is specified, load its value\n\tif(!key.empty() && score_start.empty()){\n\t\tthis->zget(name, key, &score);\n\t}else{\n\t\tscore = score_start.String();\n\t}\n\treturn ziterator(this, name, key, score, score_end, limit, Iterator::FORWARD);\n}\n\nZIterator* SSDBImpl::zrscan(const Bytes &name, const Bytes &key,\n\t\tconst Bytes &score_start, const Bytes &score_end, uint64_t limit)\n{\n\tstd::string score;\n\t// if only key is specified, load its value\n\tif(!key.empty() && score_start.empty()){\n\t\tthis->zget(name, key, &score);\n\t}else{\n\t\tscore = score_start.String();\n\t}\n\treturn ziterator(this, name, key, score, score_end, limit, Iterator::BACKWARD);\n}\n\nstatic void get_znames(Iterator *it, std::vector<std::string> *list){\n\twhile(it->next()){\n\t\tBytes ks = it->key();\n\t\t//dump(ks.data(), ks.size());\n\t\tif(ks.data()[0] != DataType::ZSIZE){\n\t\t\tbreak;\n\t\t}\n\t\tstd::string n;\n\t\tif(decode_zsize_key(ks, &n) == -1){\n\t\t\tcontinue;\n\t\t}\n\t\tlist->push_back(n);\n\t}\n}\n\nint SSDBImpl::zlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\tstd::vector<std::string> *list){\n\tstd::string start;\n\tstd::string end;\n\t\n\tstart = encode_zsize_key(name_s);\n\tif(!name_e.empty()){\n\t\tend = encode_zsize_key(name_e);\n\t}\n\t\n\tIterator *it = this->iterator(start, end, limit);\n\tget_znames(it, list);\n\tdelete it;\n\treturn 0;\n}\n\nint SSDBImpl::zrlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit,\n\t\tstd::vector<std::string> *list){\n\tstd::string start;\n\tstd::string end;\n\n\tstart = encode_zsize_key(name_s);\n\tif(name_s.empty()){\n\t\tstart.append(1, 255);\n\t}\n\tif(!name_e.empty()){\n\t\tend = encode_zsize_key(name_e);\n\t}\n\n\tIterator *it = this->rev_iterator(start, end, limit);\n\tget_znames(it, list);\n\tdelete it;\n\treturn 0;\n}\n\nstatic std::string filter_score(const Bytes &score){\n\tint64_t s = score.Int64();\n\treturn str(s);\n}\n\n// returns the number of newly added items\nstatic int zset_one(SSDBImpl *ssdb, const Bytes &name, const Bytes &key, const Bytes &score, char log_type){\n\tif(name.empty() || key.empty()){\n\t\tlog_error(\"empty name or key!\");\n\t\treturn 0;\n\t\t//return -1;\n\t}\n\tif(name.size() > SSDB_KEY_LEN_MAX ){\n\t\tlog_error(\"name too long!\");\n\t\treturn -1;\n\t}\n\tif(key.size() > SSDB_KEY_LEN_MAX){\n\t\tlog_error(\"key too long!\");\n\t\treturn -1;\n\t}\n\tstd::string new_score = filter_score(score);\n\tstd::string old_score;\n\tint found = ssdb->zget(name, key, &old_score);\n\tif(found == 0 || old_score != new_score){\n\t\tstd::string k0, k1, k2;\n\n\t\tif(found){\n\t\t\t// delete zscore key\n\t\t\tk1 = encode_zscore_key(name, key, old_score);\n\t\t\tssdb->binlogs->Delete(k1);\n\t\t}\n\n\t\t// add zscore key\n\t\tk2 = encode_zscore_key(name, key, new_score);\n\t\tssdb->binlogs->Put(k2, \"\");\n\n\t\t// update zset\n\t\tk0 = encode_zset_key(name, key);\n\t\tssdb->binlogs->Put(k0, new_score);\n\t\tssdb->binlogs->add_log(log_type, BinlogCommand::ZSET, k0);\n\n\t\treturn found? 0 : 1;\n\t}\n\treturn 0;\n}\n\nstatic int zdel_one(SSDBImpl *ssdb, const Bytes &name, const Bytes &key, char log_type){\n\tif(name.size() > SSDB_KEY_LEN_MAX ){\n\t\tlog_error(\"name too long!\");\n\t\treturn -1;\n\t}\n\tif(key.size() > SSDB_KEY_LEN_MAX){\n\t\tlog_error(\"key too long!\");\n\t\treturn -1;\n\t}\n\tstd::string old_score;\n\tint found = ssdb->zget(name, key, &old_score);\n\tif(found != 1){\n\t\treturn 0;\n\t}\n\n\tstd::string k0, k1;\n\t// delete zscore key\n\tk1 = encode_zscore_key(name, key, old_score);\n\tssdb->binlogs->Delete(k1);\n\n\t// delete zset\n\tk0 = encode_zset_key(name, key);\n\tssdb->binlogs->Delete(k0);\n\tssdb->binlogs->add_log(log_type, BinlogCommand::ZDEL, k0);\n\n\treturn 1;\n}\n\nstatic int incr_zsize(SSDBImpl *ssdb, const Bytes &name, int64_t incr){\n\tint64_t size = ssdb->zsize(name);\n\tsize += incr;\n\tstd::string size_key = encode_zsize_key(name);\n\tif(size == 0){\n\t\tssdb->binlogs->Delete(size_key);\n\t}else{\n\t\tssdb->binlogs->Put(size_key, leveldb::Slice((char *)&size, sizeof(int64_t)));\n\t}\n\treturn 0;\n}\n\nint64_t SSDBImpl::zfix(const Bytes &name){\n\tTransaction trans(binlogs);\n\tstd::string it_start, it_end;\n\tIterator *it;\n\tleveldb::Status s;\n\tint64_t size = 0;\n\tint64_t old_size;\n\n\tit_start = encode_zscore_key(name, \"\", SSDB_SCORE_MIN);\n\tit_end = encode_zscore_key(name, \"\\xff\", SSDB_SCORE_MAX);\n\tit = this->iterator(it_start, it_end, UINT64_MAX);\n\tsize = 0;\n\twhile(it->next()){\n\t\tBytes ks = it->key();\n\t\t//Bytes vs = it->val();\n\t\t//dump(ks.data(), ks.size(), \"z.next\");\n\t\t//dump(vs.data(), vs.size(), \"z.next\");\n\t\tif(ks.data()[0] != DataType::ZSCORE){\n\t\t\tbreak;\n\t\t}\n\t\tstd::string name2, key, score;\n\t\tif(decode_zscore_key(ks, &name2, &key, &score) == -1){\n\t\t\tsize = -1;\n\t\t\tbreak;\n\t\t}\n\t\tif(name != name2){\n\t\t\tbreak;\n\t\t}\n\t\tsize ++;\n\t\t\n\t\tstd::string buf = encode_zset_key(name, key);\n\t\tstd::string score2;\n\t\ts = ldb->Get(leveldb::ReadOptions(), buf, &score2);\n\t\tif(!s.ok() && !s.IsNotFound()){\n\t\t\tlog_error(\"zget error: %s\", s.ToString().c_str());\n\t\t\tsize = -1;\n\t\t\tbreak;\n\t\t}\n\t\tif(s.IsNotFound() || score != score2){\n\t\t\tlog_info(\"fix incorrect zset item, name: %s, key: %s, score: %s\",\n\t\t\t\thexmem(name.data(), name.size()).c_str(),\n\t\t\t\thexmem(key.data(), key.size()).c_str(),\n\t\t\t\thexmem(score.data(), score.size()).c_str()\n\t\t\t\t);\n\t\t\ts = ldb->Put(leveldb::WriteOptions(), buf, score);\n\t\t\tif(!s.ok()){\n\t\t\t\tlog_error(\"db error! %s\", s.ToString().c_str());\n\t\t\t\tsize = -1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tdelete it;\n\tif(size == -1){\n\t\treturn -1;\n\t}\n\n\told_size = this->zsize(name);\n\tif(old_size == -1){\n\t\treturn -1;\n\t}\n\tif(old_size != size){\n\t\tlog_info(\"fix zsize, name: %s, size: %\" PRId64 \" => %\" PRId64,\n\t\t\thexmem(name.data(), name.size()).c_str(), old_size, size);\n\t\tstd::string size_key = encode_zsize_key(name);\n\t\tif(size == 0){\n\t\t\ts = ldb->Delete(leveldb::WriteOptions(), size_key);\n\t\t}else{\n\t\t\ts = ldb->Put(leveldb::WriteOptions(), size_key, leveldb::Slice((char *)&size, sizeof(int64_t)));\n\t\t}\n\t}\n\t\n\t//////////////////////////////////////////\n\n\tit_start = encode_zset_key(name, \"\");\n\tit_end = encode_zset_key(name.String() + \"\\xff\", \"\");\n\tit = this->iterator(it_start, it_end, UINT64_MAX);\n\tsize = 0;\n\twhile(it->next()){\n\t\tBytes ks = it->key();\n\t\t//Bytes vs = it->val();\n\t\t//dump(ks.data(), ks.size(), \"z.next\");\n\t\t//dump(vs.data(), vs.size(), \"z.next\");\n\t\tif(ks.data()[0] != DataType::ZSET){\n\t\t\tbreak;\n\t\t}\n\t\tstd::string name2, key;\n\t\tif(decode_zset_key(ks, &name2, &key) == -1){\n\t\t\tsize = -1;\n\t\t\tbreak;\n\t\t}\n\t\tif(name != name2){\n\t\t\tbreak;\n\t\t}\n\t\tsize ++;\n\t\tBytes score = it->val();\n\t\t\n\t\tstd::string buf = encode_zscore_key(name, key, score);\n\t\tstd::string score2;\n\t\ts = ldb->Get(leveldb::ReadOptions(), buf, &score2);\n\t\tif(!s.ok() && !s.IsNotFound()){\n\t\t\tlog_error(\"zget error: %s\", s.ToString().c_str());\n\t\t\tsize = -1;\n\t\t\tbreak;\n\t\t}\n\t\tif(s.IsNotFound()){\n\t\t\tlog_info(\"fix incorrect zset score, name: %s, key: %s, score: %s\",\n\t\t\t\thexmem(name.data(), name.size()).c_str(),\n\t\t\t\thexmem(key.data(), key.size()).c_str(),\n\t\t\t\thexmem(score.data(), score.size()).c_str()\n\t\t\t\t);\n\t\t\ts = ldb->Put(leveldb::WriteOptions(), buf, \"\");\n\t\t\tif(!s.ok()){\n\t\t\t\tlog_error(\"db error! %s\", s.ToString().c_str());\n\t\t\t\tsize = -1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tdelete it;\n\tif(size == -1){\n\t\treturn -1;\n\t}\n\n\told_size = this->zsize(name);\n\tif(old_size == -1){\n\t\treturn -1;\n\t}\n\tif(old_size != size){\n\t\tlog_info(\"fix zsize, name: %s, size: %\" PRId64 \" => %\" PRId64,\n\t\t\thexmem(name.data(), name.size()).c_str(), old_size, size);\n\t\tstd::string size_key = encode_zsize_key(name);\n\t\tif(size == 0){\n\t\t\ts = ldb->Delete(leveldb::WriteOptions(), size_key);\n\t\t}else{\n\t\t\ts = ldb->Put(leveldb::WriteOptions(), size_key, leveldb::Slice((char *)&size, sizeof(int64_t)));\n\t\t}\n\t}\n\t\n\t//////////////////////////////////////////\n\t\n\treturn size;\n}\n"
  },
  {
    "path": "src/ssdb/t_zset.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef SSDB_ZSET_H_\n#define SSDB_ZSET_H_\n\n#include \"ssdb_impl.h\"\n\n#define encode_score(s) big_endian((uint64_t)(s))\n#define decode_score(s) big_endian((uint64_t)(s))\n\nstatic inline\nstd::string encode_zsize_key(const Bytes &name){\n\tstd::string buf;\n\tbuf.reserve(name.size() + 1);\n\tbuf.append(1, DataType::ZSIZE);\n\tbuf.append(name.data(), name.size());\n\treturn buf;\n}\n\ninline static\nint decode_zsize_key(const Bytes &slice, std::string *name){\n\tDecoder decoder(slice.data(), slice.size());\n\tif(decoder.skip(1) == -1){\n\t\treturn -1;\n\t}\n\tif(decoder.read_data(name) == -1){\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nstatic inline\nstd::string encode_zset_key(const Bytes &name, const Bytes &key){\n\tstd::string buf;\n\tbuf.reserve(128);\n\tbuf.append(1, DataType::ZSET);\n\tbuf.append(1, (uint8_t)name.size());\n\tbuf.append(name.data(), name.size());\n\tbuf.append(1, (uint8_t)key.size());\n\tbuf.append(key.data(), key.size());\n\treturn buf;\n}\n\nstatic inline\nint decode_zset_key(const Bytes &slice, std::string *name, std::string *key){\n\tDecoder decoder(slice.data(), slice.size());\n\tif(decoder.skip(1) == -1){\n\t\treturn -1;\n\t}\n\tif(decoder.read_8_data(name) == -1){\n\t\treturn -1;\n\t}\n\tif(decoder.read_8_data(key) == -1){\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\n// type, len, key, score, =, val\nstatic inline\nstd::string encode_zscore_key(const Bytes &key, const Bytes &val, const Bytes &score){\n\tstd::string buf;\n\tbuf.reserve(128);\n\tbuf.append(1, DataType::ZSCORE);\n\tbuf.append(1, (uint8_t)key.size());\n\tbuf.append(key.data(), key.size());\n\n\tint64_t s = score.Int64();\n\tif(s < 0){\n\t\tbuf.append(1, '-');\n\t}else{\n\t\tbuf.append(1, '=');\n\t}\n\ts = encode_score(s);\n\n\tbuf.append((char *)&s, sizeof(int64_t));\n\tbuf.append(1, '=');\n\tbuf.append(val.data(), val.size());\n\treturn buf;\n}\n\nstatic inline\nint decode_zscore_key(const Bytes &slice, std::string *name, std::string *key, std::string *score){\n\tDecoder decoder(slice.data(), slice.size());\n\tif(decoder.skip(1) == -1){\n\t\treturn -1;\n\t}\n\tif(decoder.read_8_data(name) == -1){\n\t\treturn -1;\n\t}\n\tif(decoder.skip(1) == -1){\n\t\treturn -1;\n\t}\n\tint64_t s;\n\tif(decoder.read_int64(&s) == -1){\n\t\treturn -1;\n\t}else{\n\t\tif(score != NULL){\n\t\t\ts = decode_score(s);\n\t\t\tscore->assign(str(s));\n\t\t}\n\t}\n\tif(decoder.skip(1) == -1){\n\t\treturn -1;\n\t}\n\tif(decoder.read_data(key) == -1){\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\n#endif\n"
  },
  {
    "path": "src/ssdb/test.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include <string>\n#include \"ssdb.h\"\n#include \"../util/log.h\"\n#include \"../util/config.h\"\n\nint main(int argc, char **argv){\n\tset_log_level(Logger::LEVEL_TRACE);\n\tstd::string work_dir = \"./tmp/a\";\n\tOptions opt;\n\topt.compression = \"no\";\n\n\tSSDB *ssdb = NULL;\n\tssdb = SSDB::open(opt, work_dir);\n\tif(!ssdb){\n\t\tlog_fatal(\"could not open work_dir: %s\", work_dir.c_str());\n\t\tfprintf(stderr, \"could not open work_dir: %s\\n\", work_dir.c_str());\n\t\texit(1);\n\t}\n\tstd::string key, val;\n\tkey = \"a\";\n\t\n\tval.append(1024 * 1024, 'a');\n\tssdb->raw_set(\"tmp\", val);\n\tssdb->compact();\n\n\tuint64_t size;\n\tsize = ssdb->size();\n\tlog_debug(\"dbsize: %d\", size);\n\n\n\tssdb->get(key, &val);\n\tint num = str_to_int(val) + 1;\n\tssdb->set(key, str(num));\n\tssdb->get(key, &val);\n\t\n\tlog_debug(\"%s\", val.c_str());\n\tdelete ssdb;\n}\n"
  },
  {
    "path": "src/ssdb/ttl.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include <pthread.h>\n#include <time.h>\n#include \"../include.h\"\n#include \"../util/log.h\"\n#include \"ttl.h\"\n\n#define EXPIRATION_LIST_KEY \"\\xff\\xff\\xff\\xff\\xff|EXPIRE_LIST|KV\"\n#define BATCH_SIZE    1000\n\nExpirationHandler::ExpirationHandler(SSDB *ssdb){\n\tthis->ssdb = ssdb;\n\tthis->thread_quit = false;\n\tthis->list_name = EXPIRATION_LIST_KEY;\n\tthis->first_timeout = 0;\n\tthis->start();\n}\n\nExpirationHandler::~ExpirationHandler(){\n\tLocking l(&this->mutex);\n\tthis->stop();\n\tssdb = NULL;\n}\n\nvoid ExpirationHandler::start(){\n\tthread_quit = false;\n\tpthread_t tid;\n\tint err = pthread_create(&tid, NULL, &ExpirationHandler::thread_func, this);\n\tif(err != 0){\n\t\tlog_fatal(\"can't create thread: %s\", strerror(err));\n\t\texit(0);\n\t}\n}\n\nvoid ExpirationHandler::stop(){\n\tthread_quit = true;\n\tfor(int i=0; i<100; i++){\n\t\tif(!thread_quit){\n\t\t\tbreak;\n\t\t}\n\t\tusleep(10 * 1000);\n\t}\n}\n\nint ExpirationHandler::set_ttl(const Bytes &key, int64_t ttl){\n\tint64_t expired = time_ms() + ttl * 1000;\n\tstd::string expire_str = str(expired);\n\tint ret = ssdb->zset(this->list_name, key, expire_str);\n\tif(ret == -1){\n\t\treturn -1;\n\t}\n\tif(expired < first_timeout){\n\t\tfirst_timeout = expired;\n\t}\n\tstd::string s_key = key.String();\n\tif(!fast_keys.empty() && expired <= fast_keys.max_score()){\n\t\tfast_keys.add(s_key, expired);\n\t\tif(fast_keys.size() > BATCH_SIZE){\n\t\t\tfast_keys.pop_back();\n\t\t}\n\t}else{\n\t\tfast_keys.del(s_key);\n\t\t//log_debug(\"don't put in fast_keys\");\n\t}\n\t\n\treturn 0;\n}\n\nint ExpirationHandler::del_ttl(const Bytes &key){\n\t// 这样用是有 bug 的, 虽然 fast_keys 为空, 不代表整个 ttl 队列为空\n\t// if(!this->fast_keys.empty()){\n\tif(first_timeout != INT64_MAX){\n\t\tfast_keys.del(key.String());\n\t\tssdb->zdel(this->list_name, key);\n\t}\n\treturn 0;\n}\n\nint64_t ExpirationHandler::get_ttl(const Bytes &key){\n\tstd::string score;\n\tif(ssdb->zget(this->list_name, key, &score) == 1){\n\t\tint64_t ex = str_to_int64(score);\n\t\treturn (ex - time_ms())/1000;\n\t}\n\treturn -1;\n}\n\nvoid ExpirationHandler::load_expiration_keys_from_db(int num){\n\tZIterator *it;\n\tit = ssdb->zscan(this->list_name, \"\", \"\", \"\", num);\n\tint n = 0;\n\twhile(it->next()){\n\t\tn ++;\n\t\tstd::string &key = it->key;\n\t\tint64_t score = str_to_int64(it->score);\n\t\tif(score < 2000000000){\n\t\t\t// older version compatible\n\t\t\tscore *= 1000;\n\t\t}\n\t\tLocking l(&this->mutex);\n\t\tfast_keys.add(key, score);\n\t}\n\tdelete it;\n\tlog_debug(\"load %d keys into fast_keys\", n);\n}\n\nvoid ExpirationHandler::expire_loop(){\n\tif(!this->ssdb){\n\t\treturn;\n\t}\n\n\tbool need_load = false;\n\t{\n\t\tLocking l(&this->mutex);\n\t\tif(this->fast_keys.empty()){\n\t\t\tneed_load = true;\n\t\t}\n\t\t// 释放锁\n\t}\n\tif(need_load){\n\t\tthis->load_expiration_keys_from_db(BATCH_SIZE);\n\t}\n\n\tLocking l(&this->mutex);\n\tif(this->fast_keys.empty()){\n\t\tthis->first_timeout = INT64_MAX;\n\t\treturn;\n\t}\n\tint64_t score;\n\tstd::string key;\n\tif(this->fast_keys.front(&key, &score)){\n\t\tthis->first_timeout = score;\n\t\t\n\t\tif(score <= time_ms()){\n\t\t\tlog_debug(\"expired %s\", key.c_str());\n\t\t\tssdb->del(key);\n\t\t\tssdb->zdel(this->list_name, key);\n\t\t\tthis->fast_keys.pop_front();\n\t\t}\n\t}\n}\n\nvoid* ExpirationHandler::thread_func(void *arg){\n\tExpirationHandler *handler = (ExpirationHandler *)arg;\n\t\n\twhile(!handler->thread_quit){\n\t\tbool need_sleep = false;\n\t\t{\n\t\t\tLocking l(&handler->mutex);\n\t\t\t// fast_keys and expire_list_in_db empty\n\t\t\tif(handler->first_timeout > time_ms()){\n\t\t\t\tneed_sleep = true;\n\t\t\t}\n\t\t}\n\t\tif(need_sleep){\n\t\t\tusleep(10 * 1000);\n\t\t\tcontinue;\n\t\t}\n\t\t\n\t\thandler->expire_loop();\n\t}\n\t\n\tlog_debug(\"ExpirationHandler thread quit\");\n\thandler->thread_quit = false;\n\treturn (void *)NULL;\n}\n"
  },
  {
    "path": "src/ssdb/ttl.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef SSDB_TTL_H_\n#define SSDB_TTL_H_\n\n#include \"ssdb.h\"\n#include \"../util/thread.h\"\n#include \"../util/sorted_set.h\"\n#include <string>\n\nclass ExpirationHandler\n{\npublic:\n\tMutex mutex;\n\n\tExpirationHandler(SSDB *ssdb);\n\t~ExpirationHandler();\n\n\t// \"In Redis 2.6 or older the command returns -1 if the key does not exist\n\t// or if the key exist but has no associated expire. Starting with Redis 2.8..\"\n\t// I stick to Redis 2.6\n\tint64_t get_ttl(const Bytes &key);\n\t// The caller must hold mutex before calling set/del functions\n\tint del_ttl(const Bytes &key);\n\tint set_ttl(const Bytes &key, int64_t ttl);\n\nprivate:\n\tSSDB *ssdb;\n\tvolatile bool thread_quit;\n\tstd::string list_name;\n\tint64_t first_timeout;\n\tSortedSet fast_keys;\n\n\tvoid start();\n\tvoid stop();\n\tvoid expire_loop();\n\tstatic void* thread_func(void *arg);\n\tvoid load_expiration_keys_from_db(int num);\n};\n\n#endif\n"
  },
  {
    "path": "src/util/Makefile",
    "content": "include ../../build_config.mk\n\nOBJS = log.o config.o bytes.o sorted_set.o app.o\nEXES = \n\nall: ${OBJS}\n\tar -cru ./libutil.a ${OBJS}\n\napp.o: app.h app.cpp\n\t${CXX} ${CFLAGS} -c app.cpp\n\nlog.o: log.h log.cpp\n\t${CXX} ${CFLAGS} -c log.cpp\n\nconfig.o: config.h config.cpp\n\t${CXX} ${CFLAGS} -c config.cpp\n\nbytes.o: bytes.h bytes.cpp\n\t${CXX} ${CFLAGS} -c bytes.cpp\n\nsorted_set.o: sorted_set.h sorted_set.cpp\n\t${CXX} ${CFLAGS} -c sorted_set.cpp\n\ntest:\n\t$(CXX) ${CFLAGS} test_sorted_set.cpp $(OBJS)\n\nclean:\n\trm -f ${EXES} ${OBJS} *.o *.exe *.a\n\n"
  },
  {
    "path": "src/util/Makefile-ios",
    "content": "include ../../build_config.mk\n\nPLATFORMSROOT=/Applications/Xcode.app/Contents/Developer/Platforms\nSIMULATORROOT=$(PLATFORMSROOT)/iPhoneSimulator.platform/Developer\nDEVICEROOT=$(PLATFORMSROOT)/iPhoneOS.platform/Developer\nIOSVERSION=$(shell defaults read $(PLATFORMSROOT)/iPhoneOS.platform/version CFBundleShortVersionString)\nSIMULATOR_SDK=$(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk\nDEVICE_SDK=$(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk\n\nCFLAGS= -miphoneos-version-min=7.0 -stdlib=libc++ -DIOS -I. -O2 -I$(LEVELDB_PATH)/include\nSIMULATOR_CFLAGS=$(CFLAGS) -isysroot $(SIMULATOR_SDK) -arch i386 -arch x86_64\nDEVICE_CFLAGS=$(CFLAGS) -isysroot $(DEVICE_SDK) -arch armv6 -arch armv7 -arch armv7s -arch arm64\n\nOBJS = config.o bytes.o sorted_set.o\nLIB = libutil-ios.a\nOUTPUT_LIB_DIR = ../../ios\nOUTPUT_HEADER_DIR = ../../ios/include/util\n\nall: $(OBJS)\n\trm -f $(LIB)\n\tar -rs $(LIB) $(OBJS)\n\trm -rf $(OUTPUT_HEADER_DIR) $(OUTPUT_LIB_DIR)/$(LIB)\n\tmkdir -p $(OUTPUT_HEADER_DIR)\n\tcp -f config.h bytes.h string_util.h $(OUTPUT_HEADER_DIR)\n\tmv -f $(LIB) $(OUTPUT_LIB_DIR)\n\n.cpp.o:\n\tmkdir -p ios-x86\n\tmkdir -p ios-arm\n\txcrun -sdk iphonesimulator clang++ $(SIMULATOR_CFLAGS) -c $< -o ios-x86/$@\n\txcrun -sdk iphoneos clang++ $(DEVICE_CFLAGS) -c $< -o ios-arm/$@\n\tlipo ios-x86/$@ ios-arm/$@ -create -output $@\n\nclean:\n\trm -f ${EXES} *.o *.exe *.a\n\n"
  },
  {
    "path": "src/util/app.cpp",
    "content": "#include \"app.h\"\n#include \"log.h\"\n#include \"file.h\"\n#include \"config.h\"\n#include \"daemon.h\"\n#include \"string_util.h\"\n#include <stdio.h>\n\nint Application::main(int argc, char **argv){\n\tconf = NULL;\n\n\twelcome();\n\tparse_args(argc, argv);\n\tinit();\n\n\twrite_pid();\n\trun();\n\tremove_pidfile();\n\t\n\tdelete conf;\n\treturn 0;\n}\n\nvoid Application::usage(int argc, char **argv){\n\tprintf(\"Usage:\\n\");\n\tprintf(\"    %s [-d] /path/to/app.conf [-s start|stop|restart]\\n\", argv[0]);\n\tprintf(\"Options:\\n\");\n\tprintf(\"    -d    run as daemon\\n\");\n\tprintf(\"    -s    option to start|stop|restart the server\\n\");\n\tprintf(\"    -h    show this message\\n\");\n}\n\nvoid Application::parse_args(int argc, char **argv){\n\tfor(int i=1; i<argc; i++){\n\t\tstd::string arg = argv[i];\n\t\tif(arg == \"-d\"){\n\t\t\tapp_args.is_daemon = true;\n\t\t}else if(arg == \"-v\"){\n\t\t\texit(0);\n\t\t}else if(arg == \"-h\"){\n\t\t\tusage(argc, argv);\n\t\t\texit(0);\n\t\t}else if(arg == \"-s\"){\n\t\t\tif(argc > i + 1){\n\t\t\t\ti ++;\n\t\t\t\tapp_args.start_opt = argv[i];\n\t\t\t}else{\n\t\t\t\tusage(argc, argv);\n\t\t\t\texit(1);\n\t\t\t}\n\t\t\tif(app_args.start_opt != \"start\" && app_args.start_opt != \"stop\" && app_args.start_opt != \"restart\"){\n\t\t\t\tusage(argc, argv);\n\t\t\t\tfprintf(stderr, \"Error: bad argument: '%s'\\n\", app_args.start_opt.c_str());\n\t\t\t\texit(1);\n\t\t\t}\n\t\t}else{\n\t\t\tapp_args.conf_file = argv[i];\n\t\t}\n\t}\n\n\tif(app_args.conf_file.empty()){\n\t\tusage(argc, argv);\n\t\texit(1);\n\t}\n}\n\nvoid Application::init(){\n\tif(!is_file(app_args.conf_file.c_str())){\n\t\tfprintf(stderr, \"'%s' is not a file or not exists!\\n\", app_args.conf_file.c_str());\n\t\texit(1);\n\t}\n\tconf = Config::load(app_args.conf_file.c_str());\n\tif(!conf){\n\t\tfprintf(stderr, \"error loading conf file: '%s'\\n\", app_args.conf_file.c_str());\n\t\texit(1);\n\t}\n\t{\n\t\tstd::string conf_dir = real_dirname(app_args.conf_file.c_str());\n\t\tif(chdir(conf_dir.c_str()) == -1){\n\t\t\tfprintf(stderr, \"error chdir: %s\\n\", conf_dir.c_str());\n\t\t\texit(1);\n\t\t}\n\t}\n\n\tapp_args.pidfile = conf->get_str(\"pidfile\");\n\n\tif(app_args.start_opt == \"stop\"){\n\t\tkill_process();\n\t\texit(0);\n\t}\n\tif(app_args.start_opt == \"restart\"){\n\t\tif(file_exists(app_args.pidfile)){\n\t\t\tkill_process();\n\t\t}\n\t}\n\t\n\tcheck_pidfile();\n\t\n\t{ // logger\n\t\tstd::string log_output;\n\t\tstd::string log_level_;\n\t\tint64_t log_rotate_size;\n\n\t\tlog_level_ = conf->get_str(\"logger.level\");\n\t\tstrtolower(&log_level_);\n\t\tif(log_level_.empty()){\n\t\t\tlog_level_ = \"debug\";\n\t\t}\n\t\tint level = Logger::get_level(log_level_.c_str());\n\t\tlog_rotate_size = conf->get_int64(\"logger.rotate.size\");\n\t\tlog_output = conf->get_str(\"logger.output\");\n\t\tif(log_output == \"\"){\n\t\t\tlog_output = \"stdout\";\n\t\t}\n\t\tif(log_open(log_output.c_str(), level, true, log_rotate_size) == -1){\n\t\t\tfprintf(stderr, \"error opening log file: %s\\n\", log_output.c_str());\n\t\t\texit(1);\n\t\t}\n\t}\n\n\tapp_args.work_dir = conf->get_str(\"work_dir\");\n\tif(app_args.work_dir.empty()){\n\t\tapp_args.work_dir = \".\";\n\t}\n\tif(!is_dir(app_args.work_dir.c_str())){\n\t\tfprintf(stderr, \"'%s' is not a directory or not exists!\\n\", app_args.work_dir.c_str());\n\t\texit(1);\n\t}\n\n\t// WARN!!!\n\t// deamonize() MUST be called before any thread is created!\n\tif(app_args.is_daemon){\n\t\tdaemonize();\n\t}\n}\n\nint Application::read_pid(){\n\tif(app_args.pidfile.empty()){\n\t\treturn -1;\n\t}\n\tstd::string s;\n\tfile_get_contents(app_args.pidfile, &s);\n\tif(s.empty()){\n\t\treturn -1;\n\t}\n\treturn str_to_int(s);\n}\n\nvoid Application::write_pid(){\n\tif(app_args.pidfile.empty()){\n\t\treturn;\n\t}\n\tint pid = (int)getpid();\n\tstd::string s = str(pid);\n\tint ret = file_put_contents(app_args.pidfile, s);\n\tif(ret == -1){\n\t\tlog_error(\"Failed to write pidfile '%s'(%s)\", app_args.pidfile.c_str(), strerror(errno));\n\t\texit(1);\n\t}\n}\n\nvoid Application::check_pidfile(){\n\tif(app_args.pidfile.size()){\n\t\tif(access(app_args.pidfile.c_str(), F_OK) == 0){\n\t\t\tfprintf(stderr, \"Fatal error!\\nPidfile %s already exists!\\n\"\n\t\t\t\t\"Kill the running process before you run this command,\\n\"\n\t\t\t\t\"or use '-s restart' option to restart the server.\\n\",\n\t\t\t\tapp_args.pidfile.c_str());\n\t\t\texit(1);\n\t\t}\n\t}\n}\n\nvoid Application::remove_pidfile(){\n\tif(app_args.pidfile.size()){\n\t\tremove(app_args.pidfile.c_str());\n\t}\n}\n\nvoid Application::kill_process(){\n\tint pid = read_pid();\n\tif(pid == -1){\n\t\tfprintf(stderr, \"could not read pidfile: %s(%s)\\n\", app_args.pidfile.c_str(), strerror(errno));\n\t\texit(1);\n\t}\n\tif(kill(pid, 0) == -1 && errno == ESRCH){\n\t\tfprintf(stderr, \"process: %d not running\\n\", pid);\n\t\tremove_pidfile();\n\t\treturn;\n\t}\n\tint ret = kill(pid, SIGTERM);\n\tif(ret == -1){\n\t\tfprintf(stderr, \"could not kill process: %d(%s)\\n\", pid, strerror(errno));\n\t\texit(1);\n\t}\n\t\n\twhile(file_exists(app_args.pidfile)){\n\t\tusleep(100 * 1000);\n\t}\n}\n\n"
  },
  {
    "path": "src/util/app.h",
    "content": "#ifndef UTIL_APP_H\n#define UTIL_APP_H\n\n#include <string>\n\nclass Config;\n\nclass Application{\npublic:\n\tApplication(){};\n\tvirtual ~Application(){};\n\n\tint main(int argc, char **argv);\n\t\n\tvirtual void usage(int argc, char **argv);\n\tvirtual void welcome() = 0;\n\tvirtual void run() = 0;\n\nprotected:\n\tstruct AppArgs{\n\t\tbool is_daemon;\n\t\tstd::string pidfile;\n\t\tstd::string conf_file;\n\t\tstd::string work_dir;\n\t\tstd::string start_opt;\n\n\t\tAppArgs(){\n\t\t\tis_daemon = false;\n\t\t\tstart_opt = \"start\";\n\t\t}\n\t};\n\n\tConfig *conf;\n\tAppArgs app_args;\n\t\nprivate:\n\tvoid parse_args(int argc, char **argv);\n\tvoid init();\n\n\tint read_pid();\n\tvoid write_pid();\n\tvoid check_pidfile();\n\tvoid remove_pidfile();\n\tvoid kill_process();\n};\n\n#endif\n"
  },
  {
    "path": "src/util/bytes.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"bytes.h\"\n\nBuffer::Buffer(int total){\n\tsize_ = 0;\n\ttotal_ = total;\n\tbuf = (char *)malloc(total);\n\tdata_ = buf;\n}\n\nBuffer::~Buffer(){\n\tfree(buf);\n}\n\nvoid Buffer::nice(){\n\t// 保证不改变后半段的数据, 以便使已生成的 Bytes 不失效.\n\tif(size_ == 0 || data_ - buf > total_/2){\n\t\tif(size_ > 0){\n\t\t\tmemcpy(buf, data_, size_);\n\t\t}\n\t\tdata_ = buf;\n\t}\n}\n\nvoid Buffer::shrink(int total){\n\tif(total <= 0){\n\t\ttotal = 8 * 1024;\n\t}\n\tint offset = data_ - buf;\n\tif(offset + size_ > total){ // 要求的空间太小, 停止\n\t\treturn;\n\t}\n\t\n\ttotal_ = total;\n\tbuf = (char *)realloc(buf, total);\n\tdata_ = buf + offset;\n}\n\nint Buffer::grow(){ // 扩大缓冲区\n\tint n;\n\tif(total_ < 8 * 1024){\n\t\tn = 8 * 1024;\n\t}else if(total_ < 512 * 1024){\n\t\tn = 8 * total_;\n\t}else{\n\t\tn = 2 * total_;\n\t}\n\t//log_debug(\"Buffer resize %d => %d\", total_, n);\n\tchar *p = (char *)realloc(buf, n);\n\tif(p == NULL){\n\t\treturn -1;\n\t}\n\tdata_ = p + (data_ - buf);\n\tbuf = p;\n\ttotal_ = n;\n\treturn total_;\n}\n\nstd::string Buffer::stats() const{\n\tchar str[1024 * 32];\n\tstr[0] = '\\n';\n\tsprintf(str, \"total: %d, data: %d, size: %d, slot: %d\",\n\t\ttotal_, (int)(data_ - buf), size_, (int)(slot() - buf));\n\treturn std::string(str);\n}\n\nint Buffer::read_record(Bytes *s){\n\tchar *head = this->data();\n\tchar *body = (char *)memchr(head, '\\n', this->size_);\n\tif(body == NULL){\n\t\treturn 0;\n\t}\n\tbody ++;\n\n\tint head_len = body - head;\n\tif(head[0] < '0' || head[0] > '9'){\n\t\treturn -1;\n\t}\n\n\tchar head_str[20];\n\tif(head_len + 1 > (int)sizeof(head_str)){\n\t\treturn -1;\n\t}\n\tmemcpy(head_str, head, head_len - 1); // no '\\n'\n\thead_str[head_len - 1] = '\\0';\n\n\tint body_len = atoi(head_str);\n\tif(body_len < 0){\n\t\treturn -1;\n\t}\n\n\tchar *p = body + body_len;\n\tif(this->size_ >= head_len + body_len + 1){\n\t\tif(p[0] == '\\n'){\n\t\t\tthis->decr(head_len + body_len + 1);\n\t\t\t*s = Bytes(body, body_len);\n\t\t\treturn 1;\n\t\t}else if(p[0] == '\\r'){\n\t\t\tif(this->size_ >= head_len + body_len + 2){\n\t\t\t\tif(p[1] == '\\n'){\n\t\t\t\t\tthis->decr(head_len + body_len + 2);\n\t\t\t\t\t*s = Bytes(body, body_len);\n\t\t\t\t\treturn 1;\n\t\t\t\t}else{\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t}\n\t\t}else{\n\t\t\treturn -1;\n\t\t}\n\t}\n\treturn 0;\n}\n\nint Buffer::append_record(const Bytes &s){\n\t// 16 is the maximum length of literal string of s.size()\n\tint size = 16 + s.size() + 1;\n\twhile(size > this->space()){\n\t\tif(this->grow() == -1){\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\tchar len[16];\n\tint num = snprintf(len, sizeof(len), \"%d\\n\", (int)s.size());\n\n\tchar *p = this->slot();\n\tmemcpy(p, len, num);\n\tp += num;\n\n\tmemcpy(p, s.data(), s.size());\n\tp += s.size();\n\n\t*p = '\\n';\n\tp += 1;\n\tthis->size_ += (num + s.size() + 1);\n\treturn (num + s.size() + 1);\n}\n\nint Buffer::append(char c){\n\twhile(1 > this->space()){\n\t\tif(this->grow() == -1){\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\t*(this->slot()) = c;\n\tsize_ += 1;\n\treturn 1;\n}\n\nint Buffer::append(const void *p, int size){\n\twhile(size > this->space()){\n\t\tif(this->grow() == -1){\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\tmemcpy(this->slot(), p, size);\n\tsize_ += size;\n\treturn size;\n}\n\nint Buffer::append(const char *p){\n\treturn this->append(p, strlen(p));\n}\n\nint Buffer::append(const Bytes &s){\n\treturn this->append(s.data(), s.size());\n}\n"
  },
  {
    "path": "src/util/bytes.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef UTIL_BYTES_H_\n#define UTIL_BYTES_H_\n\n#include \"string_util.h\"\n\n// readonly\n// to replace std::string\nclass Bytes{\n\tprivate:\n\t\tconst char *data_;\n\t\tint size_;\n\tpublic:\n\t\tBytes(){\n\t\t\tdata_ = \"\";\n\t\t\tsize_ = 0;\n\t\t}\n\n\t\tBytes(void *data, int size){\n\t\t\tdata_ = (char *)data;\n\t\t\tsize_ = size;\n\t\t}\n\n\t\tBytes(const char *data, int size){\n\t\t\tdata_ = data;\n\t\t\tsize_ = size;\n\t\t}\n\n\t\tBytes(const std::string &str){\n\t\t\tdata_ = str.data();\n\t\t\tsize_ = (int)str.size();\n\t\t}\n\n\t\tBytes(const char *str){\n\t\t\tdata_ = str;\n\t\t\tsize_ = (int)strlen(str);\n\t\t}\n\n\t\tconst char* data() const{\n\t\t\treturn data_;\n\t\t}\n\n\t\tbool empty() const{\n\t\t\treturn size_ == 0;\n\t\t}\n\n\t\tint size() const{\n\t\t\treturn size_;\n\t\t}\n\n\t\tint compare(const Bytes &b) const{\n\t\t\tconst int min_len = (size_ < b.size_) ? size_ : b.size_;\n\t\t\tint r = memcmp(data_, b.data_, min_len);\n\t\t\tif(r == 0){\n\t\t\t\tif (size_ < b.size_) r = -1;\n\t\t\t\telse if (size_ > b.size_) r = +1;\n\t\t\t}\n\t\t\treturn r;\n\t\t}\n\n\t\tstd::string String() const{\n\t\t\treturn std::string(data_, size_);\n\t\t}\n\n\t\tint Int() const{\n\t\t\treturn str_to_int(data_, size_);\n\t\t}\n\n\t\tint64_t Int64() const{\n\t\t\treturn str_to_int64(data_, size_);\n\t\t}\n\n\t\tuint64_t Uint64() const{\n\t\t\treturn str_to_uint64(data_, size_);\n\t\t}\n\n\t\tdouble Double() const{\n\t\t\treturn str_to_double(data_, size_);\n\t\t}\n};\n\ninline\nbool operator==(const Bytes &x, const Bytes &y){\n\treturn ((x.size() == y.size()) &&\n\t\t\t(memcmp(x.data(), y.data(), x.size()) == 0));\n}\n\ninline\nbool operator!=(const Bytes &x, const Bytes &y){\n\treturn !(x == y);\n}\n\ninline\nbool operator>(const Bytes &x, const Bytes &y){\n\treturn x.compare(y) > 0;\n}\n\ninline\nbool operator>=(const Bytes &x, const Bytes &y){\n\treturn x.compare(y) >= 0;\n}\n\ninline\nbool operator<(const Bytes &x, const Bytes &y){\n\treturn x.compare(y) < 0;\n}\n\ninline\nbool operator<=(const Bytes &x, const Bytes &y){\n\treturn x.compare(y) <= 0;\n}\n\n\n\nclass Buffer{\n\tprivate:\n\t\tchar *buf;\n\t\tchar *data_;\n\t\tint size_;\n\t\tint total_;\n\tpublic:\n\t\tBuffer(int total);\n\t\t~Buffer();\n\n\t\t// 缓冲区大小\n\t\tint total() const{\n\t\t\treturn total_;\n\t\t}\n\n\t\tbool empty() const{\n\t\t\treturn size_ == 0;\n\t\t}\n\n\t\t// 数据\n\t\tchar* data() const{\n\t\t\treturn data_;\n\t\t}\n\n\t\t// 数据大小\n\t\tint size() const{\n\t\t\treturn size_;\n\t\t}\n\n\t\t// 指向空闲处\n\t\tchar* slot() const{\n\t\t\treturn data_ + size_;\n\t\t}\n\n\t\tint space() const{\n\t\t\treturn total_ - (int)(data_ - buf) - size_;\n\t\t}\n\n\t\tvoid incr(int num){\n\t\t\tsize_ += num;\n\t\t}\n\n\t\tvoid decr(int num){\n\t\t\tsize_ -= num;\n\t\t\tdata_ += num;\n\t\t}\n\n\t\t// 保证不改变后半段的数据, 以便使已生成的 Bytes 不失效.\n\t\tvoid nice();\n\t\t// 扩大缓冲区\n\t\tint grow();\n\t\t// 缩小缓冲区, 如果指定的 total 太小超过数据范围, 或者不合理, 则不会缩小\n\t\tvoid shrink(int total=0);\n\n\t\tstd::string stats() const;\n\t\tint read_record(Bytes *s);\n\n\t\tint append(char c);\n\t\tint append(const char *p);\n\t\tint append(const void *p, int size);\n\t\tint append(const Bytes &s);\n\n\t\tint append_record(const Bytes &s);\n};\n\n\nclass Decoder{\nprivate:\n\tconst char *p;\n\tint size;\n\tDecoder(){}\npublic:\n\tDecoder(const char *p, int size){\n\t\tthis->p = p;\n\t\tthis->size = size;\n\t}\n\tint skip(int n){\n\t\tif(size < n){\n\t\t\treturn -1;\n\t\t}\n\t\tp += n;\n\t\tsize -= n;\n\t\treturn n;\n\t}\n\tint read_int64(int64_t *ret){\n\t\tif(size_t(size) < sizeof(int64_t)){\n\t\t\treturn -1;\n\t\t}\n\t\tif(ret){\n\t\t\tmemcpy(ret, p, sizeof(int64_t));\n\t\t}\n\t\tp += sizeof(int64_t);\n\t\tsize -= sizeof(int64_t);\n\t\treturn sizeof(int64_t);\n\t}\n\tint read_uint64(uint64_t *ret){\n\t\tif(size_t(size) < sizeof(uint64_t)){\n\t\t\treturn -1;\n\t\t}\n\t\tif(ret){\n\t\t\tmemcpy(ret, p, sizeof(uint64_t));\n\t\t}\n\t\tp += sizeof(uint64_t);\n\t\tsize -= sizeof(uint64_t);\n\t\treturn sizeof(uint64_t);\n\t}\n\tint read_data(std::string *ret){\n\t\tint n = size;\n\t\tif(ret){\n\t\t\tret->assign(p, size);\n\t\t}\n\t\tp += size;\n\t\tsize = 0;\n\t\treturn n;\n\t}\n\tint read_8_data(std::string *ret=NULL){\n\t\tif(size < 1){\n\t\t\treturn -1;\n\t\t}\n\t\tint len = (uint8_t)p[0];\n\t\tp += 1;\n\t\tsize -= 1;\n\t\tif(size < len){\n\t\t\treturn -1;\n\t\t}\n\t\tif(ret){\n\t\t\tret->assign(p, len);\n\t\t}\n\t\tp += len;\n\t\tsize -= len;\n\t\treturn 1 + len;\n\t}\n};\n\n#endif\n\n"
  },
  {
    "path": "src/util/config.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"log.h\"\n#include \"config.h\"\n#include \"string_util.h\"\n\ninline static\nint is_kv_seperator(int ch){\n\treturn (ch == '=') || (ch == ':');\n}\n\nConfig* Config::load(const char *filename){\n\tFILE *fp = NULL;\n\tint lineno = 0;\n\n\tif(strcmp(filename, \"stdin\") == 0){\n\t\tfp = stdin;\n\t}else{\n\t\tfp = fopen(filename, \"r\");\n\t\tif(!fp){\n\t\t\tlog_error(\"error opening file '%s': %s\", filename, strerror(errno));\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\tConfig *root = new Config(\"root\", \"\");\n\tConfig *cfg = root;\n\tint last_indent = 0;\n\tchar buf[CONFIG_MAX_LINE];\n\twhile(fgets(buf, sizeof(buf), fp)){\n\t\tlineno++;\n\n\t\tbuf[strlen(buf) - 1] = '\\0'; /* 去除 '\\n' */\n\t\tif(is_empty_str(buf)){\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* 有效行以 \\t* 开头 */\n\t\tint indent = strspn(buf, \"\\t\");\n\t\tchar *key = buf + indent;\n\n\t\tif(*key == '#'){\n\t\t\tcfg->add_child(\"#\", key + 1, lineno);\n\t\t\tcontinue;\n\t\t}\n\t\tif(indent <= last_indent){\n\t\t\tfor(int i = indent; i <= last_indent; i++){\n\t\t\t\t/* 第一个配置时, 此条件为真 */\n\t\t\t\tif(cfg != root){\n\t\t\t\t\tcfg = cfg->parent;\n\t\t\t\t}\n\t\t\t}\n\t\t}else if(indent > last_indent + 1){\n\t\t\tlog_error(\"invalid indent line(%d)\", lineno);\n\t\t\tgoto err;\n\t\t}\n\t\t\n\t\tif(isspace(*key)){\n\t\t\tlog_error(\"invalid line(%d): unexpected whitespace char '%c'\", lineno, *key);\n\t\t\tgoto err;\n\t\t}\n\n\t\tchar *val = key;\n\t\t/* 跳过键名 */\n\t\twhile(*val && !is_kv_seperator(*val)){\n\t\t\tval++;\n\t\t}\n\t\tif(*val == '\\0'){\n\t\t\tlog_error(\"invalid line(%d): %s, expecting ':' or '='\", lineno, *val);\n\t\t\tgoto err;\n\t\t}else if(!is_kv_seperator(*val)){\n\t\t\tlog_error(\"invalid line(%d): unexpected char '%c', expecting ':' or '='\", lineno, *val);\n\t\t\tgoto err;\n\t\t}\n\t\t*val++ = '\\0';\n\n\t\t/* key 或者 value 的前后空白字符会被过滤 */\n\t\tkey = trim(key);\n\t\tval = trim(val);\n\n\t\tcfg = cfg->add_child(key, val, lineno);\n\t\tif(cfg == NULL){\n\t\t\tgoto err;\n\t\t}\n\n\t\tlast_indent = indent;\n\t}\n\tif(ferror(fp)){\n\t\tlog_error(\"error while reading file %s\", filename);\n\t\tgoto err;\n\t}\n\tfclose(fp);\n\treturn root;\nerr:\n\tif(root){\n\t\tdelete root;\n\t}\n\tif(fp && fp != stdin){\n\t\tfclose(fp);\n\t}\n\treturn NULL;\n}\n\nConfig::Config(const char *key, const char *val){\n\tthis->parent = NULL;\n\tthis->depth = 0;\n\tif(key){\n\t\tthis->key = key;\n\t}\n\tif(val){\n\t\tthis->val = val;\n\t}\n};\n\nConfig::~Config(){\n\t//log_trace(\"%*sfree %s(%d)\", depth*4, \"\", this->key.c_str(), this->children.size());\n\tfor(int i = 0; i < (int)children.size(); i++){\n\t\tdelete children[i];\n\t}\n}\n\nConfig* Config::build_key_path(const char *key){\n\tchar path[CONFIG_MAX_LINE];\n\tConfig *conf = this;\n\tConfig *c;\n\n\tsnprintf(path, CONFIG_MAX_LINE, \"%s\", key);\n\n\tchar *f, *fs; /* field, field seperator */\n\tf = fs = path;\n\twhile(1){\n\t\tswitch(*fs++){\n\t\t\tcase '.':\n\t\t\tcase '/':\n\t\t\t\t*(fs - 1) = '\\0';\n\t\t\t\tc = (Config *)conf->find_child(f);\n\t\t\t\tif(c == NULL){\n\t\t\t\t\tc = conf->add_child(f);\n\t\t\t\t}\n\t\t\t\tconf = c;\n\t\t\t\tf = fs;\n\t\t\t\tbreak;\n\t\t\tcase '\\0':\n\t\t\t\tc = (Config *)conf->find_child(f);\n\t\t\t\tif(c == NULL){\n\t\t\t\t\tc = conf->add_child(f);\n\t\t\t\t}\n\t\t\t\treturn c;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\nConfig* Config::set(const char *key, const char *val){\n\tConfig *c = this->build_key_path(key);\n\tc->val = val;\n\tlog_trace(\"%*s'%s' : '%s'\", depth*4, \"\", this->key.c_str(), key);\n\treturn c;\n}\n\nConfig* Config::add_child(const char *key, const char *val, int lineno){\n\tlog_trace(\"add_child: %s\", key);\n\tConfig *c = new Config(key, val);\n\tc->parent = this;\n\tc->depth  = this->depth + 1;\n\tchildren.push_back(c);\n\treturn c;\n}\n\nconst Config* Config::find_child(const char *key) const{\n\tint i = (int)children.size()-1;\n\tfor(; i >= 0; i--){\n\t\tif(children[i]->key == key){\n\t\t\treturn children[i];\n\t\t}\n\t}\n\treturn NULL;\n}\n\nconst Config* Config::get(const char *key) const{\n\tchar path[CONFIG_MAX_LINE];\n\tconst Config *conf = this;\n\n\tsnprintf(path, CONFIG_MAX_LINE, \"%s\", key);\n\n\tchar *f, *fs; /* field, field seperator */\n\tf = fs = path;\n\twhile(conf){\n\t\tswitch(*fs++){\n\t\t\tcase '.':\n\t\t\tcase '/':\n\t\t\t\t*(fs - 1) = '\\0';\n\t\t\t\tconf = conf->find_child(f);\n\t\t\t\tf = fs;\n\t\t\t\tbreak;\n\t\t\tcase '\\0':\n\t\t\t\tconf = conf->find_child(f);\n\t\t\t\treturn conf;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\treturn conf;\n}\n\nint Config::num() const{\n\treturn atoi(this->val.c_str());\n}\n\nconst char* Config::str() const{\n\treturn this->val.c_str();\n}\n\nint Config::get_num(const char *key) const{\n\tconst Config *c = this->get(key);\n\tif(!c){\n\t\treturn 0;\n\t}\n\treturn c->num();\n}\n\nint64_t Config::get_int64(const char *key) const{\n\tconst Config *c = this->get(key);\n\tif(!c){\n\t\treturn 0;\n\t}\n\treturn str_to_int64(c->val);\n}\n\nconst char* Config::get_str(const char *key) const{\n\tconst Config *c = this->get(key);\n\tif(!c){\n\t\treturn \"\";\n\t}\n\treturn c->str();\n}\n\nint Config::save(FILE *fp) const{\n\tfor(int i = 0; i < (int)children.size(); i++){\n\t\tConfig *c = children[i];\n\t\tfor(int j=0; j<this->depth; j++){\n\t\t\tfputc('\\t', fp);\n\t\t}\n\n\t\tif(c->is_comment()){\n\t\t\tfprintf(fp, \"#%s\\n\", c->val.c_str());\n\t\t}else{\n\t\t\tfprintf(fp, \"%s: %s\\n\", c->key.c_str(), c->val.c_str());\n\t\t}\n\t\tc->save(fp);\n\t}\n\treturn 0;\n}\n\nint Config::save(const char *filename) const{\n\tFILE *fp;\n\n\tif(strcmp(filename, \"stdout\") == 0){\n\t\tfp = stdout;\n\t}else if(strcmp(filename, \"stderr\") == 0){\n\t\tfp = stderr;\n\t}else{\n\t\tfp = fopen(filename, \"w\");\n\t\tif(!fp){\n\t\t\tlog_error(\"error opening file '%s': %s\", filename, strerror(errno));\n\t\t\treturn -1;\n\t\t}\n\t}\n\tthis->save(fp);\n\tif(fp && fp != stdout && fp != stderr){\n\t\tfclose(fp);\n\t}\n\treturn 0;\n}\n\n"
  },
  {
    "path": "src/util/config.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef UTIL__CONFIG_H\n#define UTIL__CONFIG_H\n\n/*\n语法定义:\n\t空白字符为 '\\t \\r\\n'(制表符, 空格, 回车, 换行)\n\t忽略只包含空白字符的行\n\t有效行以 '\\t*' 开头\n\t注释行以 '\\t*#' 开头\n\tkey 和 value 之间可以用等号'='或者冒号':'分隔\n\tkey 不包含任何空白字符, 两端的空白字符被忽略\n\tvalue 两端的空白字符被忽略\n\t配置项可以有包含关系, 用一个 TAB 缩进表示父子关系\n\n配置读取:\n\t用键名获取子配置项\n\t用斜杠'/'或者句号'.'分隔的配置项路径获取配置项\n\t把配置项的值作为整形(int)返回\n\t把配置项的值作为字符串(char *)返回\n*/\n\n#include <string>\n#include <vector>\n#include <stdint.h>\n#include <stdio.h>\n\n#define CONFIG_MAX_LINE\t\t4096\n\n/* special filenames: stdin, stdout, stderr */\nclass Config{\n\tprivate:\n\t\tConfig *parent;\n\t\tint depth;\n\n\t\tConfig* build_key_path(const char *key);\n\t\tConfig* add_child(const char *key, const char *val=\"\", int lineno=0);\n\t\tconst Config* find_child(const char *key) const;\n\tpublic:\n\t\tConfig(const char *key=NULL, const char *val=NULL);\n\t\t~Config();\n\n\t\tstatic Config* load(const char *filename);\n\t\tint save(FILE *fp) const;\n\t\tint save(const char *filename) const;\n\n\t\tstd::vector<Config *> children;\n\t\tstd::string key;\n\t\tstd::string val;\n\n\t\tConfig* set(const char *key, const char *val);\n\t\tconst Config* get(const char *key) const;\n\t\tint num() const;\n\t\tint get_num(const char *key) const;\n\t\tint64_t get_int64(const char *key) const;\n\t\tconst char* str() const;\n\t\tconst char* get_str(const char *key) const;\n\n\t\tbool is_comment() const{\n\t\t\treturn key[0] == '#';\n\t\t}\n\t\tstd::string ToString() const{\n\t\t\treturn key + \": \" + val;\n\t\t}\n};\n\n#endif\n\n/*\n配置文件示例:\n\n# this is a comment\n\nauthor : ideawu\n\turl: http://www.ideawu.net\n\nproxy :\n\tphp =\n\t\thost = 127.0.0.1\n\t\tport = 8088\n\tpy :\n\t\thost = 127.0.0.1\n\t\tport = 8080\n\ncgi =\n\tpl = /usr/bin/perl\n\n应用程序示例:\n\n#include <stdio.h>\n#include \"config.h\"\n\nint main(int argc, char **argv){\n\tstruct config *cfg, *c;\n\n\tcfg = cfg_load_file(\"cfg_test.conf\");\n\tif(!cfg){\n\t\treturn 0;\n\t}\n\n\tprintf(\"\\n\");\n\tprintf(\"proxy.php.host = %s\\n\", cfg_getstr(cfg, \"proxy.php.host\"));\n\tprintf(\"proxy.php.port = %d\\n\", cfg_getnum(cfg, \"proxy.php.port\"));\n\tprintf(\"cgi.pl = %s\\n\", cfg_getstr(cfg, \"cgi.pl\"));\n\tprintf(\"\\n\");\n\n\tc = cfg_get(cfg, \"author\");\n\tprintf(\"author: %s\\n\", cfg_str(c));\n\tprintf(\"url: %s\\n\", cfg_getstr(c, \"url\"));\n\tprintf(\"\\n\");\n\n\tcfg_free(cfg);\n\treturn 0;\n}\n\n*/\n"
  },
  {
    "path": "src/util/daemon.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef UTIL_DAEMON_H\n#define UTIL_DAEMON_H\n\nint daemonize(const char *dir=NULL){\n\tswitch(fork()){\n\t\tcase -1:\n\t\t\treturn -1;\n\t\tcase 0:\n\t\t\tbreak;\n\t\tdefault:\n\t\t\texit(0);\n\t}\n\tif(setsid() == -1){\n\t\texit(0);\n\t}\n\tif(dir != NULL){\n\t\tif(chdir(dir) == -1){\n\t\t\texit(0);\n\t\t}\n\t}\n\n\tif(close(STDIN_FILENO) == -1){\n\t\texit(0);\n\t}\n\tif(close(STDOUT_FILENO) == -1){\n\t\texit(0);\n\t}\n\tif(close(STDERR_FILENO) == -1){\n\t\texit(0);\n\t}\n\n\tint fd = open(\"/dev/null\", O_RDWR, 0);\n\tif(fd == -1){\n\t\texit(0);\n\t}\n\tif(dup2(fd, STDIN_FILENO) == -1){\n\t\texit(0);\n\t}\n\tif(dup2(fd, STDOUT_FILENO) == -1){\n\t\texit(0);\n\t}\n\tif(dup2(fd, STDERR_FILENO) == -1){\n\t\texit(0);\n\t}\n\n\treturn 0;\n}\n\n#endif\n"
  },
  {
    "path": "src/util/file.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef UTIL_FILE_H_\n#define UTIL_FILE_H_\n\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <unistd.h>\n#include <string>\n\nstatic inline\nbool file_exists(const std::string &filename){\n\tstruct stat st;\n\treturn stat(filename.c_str(), &st) == 0;\n}\n\nstatic inline\nbool is_dir(const std::string &filename){\n\tstruct stat st;\n\tif(stat(filename.c_str(), &st) == -1){\n\t\treturn false;\n\t}\n\treturn (bool)S_ISDIR(st.st_mode);\n}\n\nstatic inline\nbool is_file(const std::string &filename){\n\tstruct stat st;\n\tif(stat(filename.c_str(), &st) == -1){\n\t\treturn false;\n\t}\n\treturn (bool)S_ISREG(st.st_mode);\n}\n\n// return number of bytes read\nstatic inline\nint file_get_contents(const std::string &filename, std::string *content){\n\tchar buf[8192];\n\tFILE *fp = fopen(filename.c_str(), \"rb\");\n\tif(!fp){\n\t\treturn -1;\n\t}\n\tint ret = 0;\n\twhile(!feof(fp) && !ferror(fp)){\n\t\tint n = fread(buf, 1, sizeof(buf), fp);\n\t\tif(n > 0){\n\t\t\tret += n;\n\t\t\tcontent->append(buf, n);\n\t\t}\n\t}\n\tfclose(fp);\n\treturn ret;\n}\n\n// return number of bytes written\nstatic inline\nint file_put_contents(const std::string &filename, const std::string &content){\n\tFILE *fp = fopen(filename.c_str(), \"wb\");\n\tif(!fp){\n\t\treturn -1;\n\t}\n\tint ret = fwrite(content.data(), 1, content.size(), fp);\n\tfclose(fp);\n\treturn ret == (int)content.size()? ret : -1;\n}\n\n#endif\n"
  },
  {
    "path": "src/util/ip_filter.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef ICOMET_IPFILTER_H\n#define ICOMET_IPFILTER_H\n\n#include <string>\n#include <set>\n\n// filter ip address\nclass IpFilter{\nprivate:\n\t\n\tbool check_hit(const std::set<std::string> &m, const std::string &ip){\n\t\tif(m.empty()){\n\t\t\treturn false;\n\t\t}\n\t\tstd::set<std::string>::const_iterator it;\n\t\tit = m.upper_bound(ip);\n\t\tif(it == m.end()){\n\t\t\treturn false;\n\t\t}\n\t\tconst std::string &prefix = *it;\n\n\t\tint len = prefix.size() - 1;\n\t\tif(prefix[len] == '='){\n\t\t\treturn prefix.compare(0, len, ip) == 0;\n\t\t}else if(ip.size() >= len){\n\t\t\treturn ip.compare(0, len, prefix, 0, len) == 0;\n\t\t}\n\t\treturn false;\n\t}\n\t\n\tbool is_full_ip(const std::string &ip_prefix){\n\t\tint n = 0;\n\t\tfor(int i=0; i<(int)ip_prefix.size(); i++){\n\t\t\tif(ip_prefix[i] == '.'){\n\t\t\t\tn ++;\n\t\t\t}\n\t\t}\n\t\treturn n == 3;\n\t}\n\npublic:\n\tbool allow_all;\n\tbool deny_all;\n\tstd::set<std::string> deny;\n\tstd::set<std::string> allow;\n\n\tIpFilter(){\n\t\tallow_all = true;\n\t\tdeny_all = false;\n\t}\n\t\n\tvoid add_allow(const std::string &ip_prefix){\n\t\tif(ip_prefix == \"all\" || ip_prefix == \"*\"){\n\t\t\tallow_all = true;\n\t\t}else{\n\t\t\tallow_all = false;\n\t\t\t// '@' and '=' is greater than any char in ip\n\t\t\tstd::string prefix = ip_prefix + (is_full_ip(ip_prefix)? \"=\" : \"@\");\n\t\t\tallow.insert(prefix);\n\t\t}\n\t}\n\n\tvoid del_allow(const std::string &ip_prefix){\n\t\tif(ip_prefix == \"all\" || ip_prefix == \"*\"){\n\t\t\tallow_all = false;\n\t\t}else{\n\t\t\tstd::string prefix = ip_prefix + (is_full_ip(ip_prefix)? \"=\" : \"@\");\n\t\t\tallow.erase(prefix);\n\t\t}\n\t}\n\t\n\tvoid add_deny(const std::string &ip_prefix){\n\t\tif(ip_prefix == \"all\" || ip_prefix == \"*\"){\n\t\t\tdeny_all = true;\n\t\t}else{\n\t\t\t// deny_all is always true\n\t\t\t// '@' and '=' is greater than any char in ip\n\t\t\tstd::string prefix = ip_prefix + (is_full_ip(ip_prefix)? \"=\" : \"@\");\n\t\t\tdeny.insert(prefix);\n\t\t}\n\t}\n\n\tvoid del_deny(const std::string &ip_prefix){\n\t\tif(ip_prefix == \"all\" || ip_prefix == \"*\"){\n\t\t\tdeny_all = false;\n\t\t}else{\n\t\t\tstd::string prefix = ip_prefix + (is_full_ip(ip_prefix)? \"=\" : \"@\");\n\t\t\tdeny.erase(prefix);\n\t\t}\n\t}\n\t\n\tbool check_pass(const std::string &ip){\n\t\t// check specified allow/deny\n\t\tif(check_hit(deny, ip)){\n\t\t\treturn false;\n\t\t}\n\t\tif(check_hit(allow, ip)){\n\t\t\treturn true;\n\t\t}\n\t\tif(deny_all){\n\t\t\treturn false;\n\t\t}\n\t\tif(allow_all){\n\t\t\treturn true;\n\t\t}else{\n\t\t\treturn false;\n\t\t}\n\t}\n};\n\n#endif\n"
  },
  {
    "path": "src/util/line.h",
    "content": "#ifndef UTIL_LINE_H\n#define UTIL_LINE_H\n\n#include <inttypes.h>\n#include <string>\n#include \"string_util.h\"\n\nclass LineEncoder{\npublic:\n\tint write(const std::string &data){\n\t\tval.append(str_escape(data));\n\t\tval.append(\"\\n\");\n\t\treturn 0;\n\t}\n\t\n\tint write(int data){\n\t\treturn this->write(::str(data));\n\t}\n\t\n\tint write(int64_t data){\n\t\treturn this->write(::str(data));\n\t}\n\t\n\tstd::string str(){\n\t\treturn val;\n\t}\nprivate:\n\tstd::string val;\n};\n\nclass LineDecoder{\npublic:\n\tLineDecoder(const std::string &s){\n\t\tspos = 0;\n\t\tepos = 0;\n\t\tbuf = s.data();\n\t\tlen = (int)s.size();\n\t}\n\t\n\tint readline(std::string *ret){\n\t\treturn this->read(ret);\n\t}\n\t\n\tint read(std::string *ret){\n\t\twhile(epos < len && buf[epos] != '\\n'){\n\t\t\tepos ++;\n\t\t}\n\t\tif(epos >= len || buf[epos] != '\\n'){\n\t\t\treturn -1;\n\t\t}\n\t\tstd::string line(&buf[spos], epos - spos);\n\t\tspos = epos + 1;\n\t\tepos = spos;\n\t\t*ret = str_unescape(line);\n\t\treturn (int)ret->size();\n\t}\n\t\n\tint read(int *ret){\n\t\tstd::string line;\n\t\tif(this->read(&line) == -1){\n\t\t\treturn -1;\n\t\t}\n\t\t*ret = str_to_int(line);\n\t\treturn 0;\n\t}\n\t\t\n\tint read(int64_t *ret){\n\t\tstd::string line;\n\t\tif(this->read(&line) == -1){\n\t\t\treturn -1;\n\t\t}\n\t\t*ret = str_to_int64(line);\n\t\treturn 0;\n\t}\n\t\npublic:\n\tconst char *buf;\n\tint len;\n\tint spos;\n\tint epos;\n};\n\n#endif\n"
  },
  {
    "path": "src/util/list.h",
    "content": "/*\nCopyright (c) 2012-2014 The icomet Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef UTIL_LIST_H\n#define UTIL_LIST_H\n\ntemplate <class T>\nclass LinkedList{\npublic:\n\tclass Iterator{\n\tprivate:\n\t\tT p;\n\tpublic:\n\t\tfriend class LinkedList;\n\t\t\n\t\tT next(){\n\t\t\tT ret = p;\n\t\t\tif(p){\n\t\t\t\tp = p->next;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n\tfriend class Iterator;\npublic:\n\tint size;\n\tT head;\n\tT tail;\n\t\n\tLinkedList(){\n\t\tsize = 0;\n\t\thead = NULL;\n\t\ttail = NULL;\n\t}\n\t\n\tIterator iterator(){\n\t\tIterator it;\n\t\tit.p = this->head;\n\t\treturn it;\n\t}\n\t\n\tbool empty() const{\n\t\treturn size == 0;\n\t}\n\t\n\tvoid remove(T t){\n\t\tthis->size --;\n\t\tif(t->prev){\n\t\t\tt->prev->next = t->next;\n\t\t}\n\t\tif(t->next){\n\t\t\tt->next->prev = t->prev;\n\t\t}\n\t\tif(this->head == t){\n\t\t\tthis->head = t->next;\n\t\t}\n\t\tif(this->tail == t){\n\t\t\tthis->tail = t->prev;\n\t\t}\n\t}\n\t\n\tT pop_front(){\n\t\tT t = this->head;\n\t\tthis->remove(t);\n\t\treturn t;\n\t}\n\n\tvoid push_back(T t){\n\t\tthis->size ++;\n\t\tt->prev = this->tail;\n\t\tt->next = NULL;\n\t\tif(this->tail){\n\t\t\tthis->tail->next = t;\n\t\t}else{ // both head and tail is empty\n\t\t\tthis->head = t;\n\t\t}\n\t\tthis->tail = t;\n\t}\n};\n\n\n#endif\n"
  },
  {
    "path": "src/util/log.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"log.h\"\n#include <algorithm>\n\nstatic Logger logger;\n\nint log_open(const char *filename, int level, bool is_threadsafe, uint64_t rotate_size){\n\treturn logger.open(filename, level, is_threadsafe, rotate_size);\n}\n\nint log_level(){\n\treturn logger.level();\n}\n\nvoid set_log_level(int level){\n\tlogger.set_level(level);\n}\n\nvoid set_log_level(const char *s){\n\tstd::string ss(s);\n\tstd::transform(ss.begin(), ss.end(), ss.begin(), ::tolower);\n\tint level = Logger::LEVEL_DEBUG;\n\tif(ss == \"fatal\"){\n\t\tlevel = Logger::LEVEL_FATAL;\n\t}else if(ss == \"error\"){\n\t\tlevel = Logger::LEVEL_ERROR;\n\t}else if(ss == \"warn\"){\n\t\tlevel = Logger::LEVEL_WARN;\n\t}else if(ss == \"info\"){\n\t\tlevel = Logger::LEVEL_INFO;\n\t}else if(ss == \"debug\"){\n\t\tlevel = Logger::LEVEL_DEBUG;\n\t}else if(ss == \"trace\"){\n\t\tlevel = Logger::LEVEL_TRACE;\n\t}\n\tlogger.set_level(level);\n}\n\nint log_write(int level, const char *fmt, ...){\n\tva_list ap;\n\tva_start(ap, fmt);\n\tint ret = logger.logv(level, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\n/*****/\n\nLogger* Logger::shared(){\n\treturn &logger;\n}\n\nLogger::Logger(){\n\tfd = STDOUT_FILENO;\n\tlevel_ = LEVEL_DEBUG;\n\tmutex = NULL;\n\n\tfilename[0] = '\\0';\n\trotate_size_ = 0;\n\tstats.w_curr = 0;\n\tstats.w_total = 0;\n}\n\nLogger::~Logger(){\n\tif(mutex){\n\t\tpthread_mutex_destroy(mutex);\n\t\tfree(mutex);\n\t}\n\tthis->close();\n}\n\nstd::string Logger::level_name(){\n\tswitch(level_){\n\t\tcase Logger::LEVEL_FATAL:\n\t\t\treturn \"fatal\";\n\t\tcase Logger::LEVEL_ERROR:\n\t\t\treturn \"error\";\n\t\tcase Logger::LEVEL_WARN:\n\t\t\treturn \"warn\";\n\t\tcase Logger::LEVEL_INFO:\n\t\t\treturn \"info\";\n\t\tcase Logger::LEVEL_DEBUG:\n\t\t\treturn \"debug\";\n\t\tcase Logger::LEVEL_TRACE:\n\t\t\treturn \"trace\";\n\t}\n\treturn \"\";\n}\n\nstd::string Logger::output_name(){\n\treturn filename;\n}\n\nuint64_t Logger::rotate_size(){\n\treturn rotate_size_;\n}\n\nvoid Logger::threadsafe(){\n\tif(mutex){\n\t\tpthread_mutex_destroy(mutex);\n\t\tfree(mutex);\n\t\tmutex = NULL;\n\t}\n\tmutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));\n\tpthread_mutex_init(mutex, NULL);\n}\n\nint Logger::open(const char *filename, int level, bool is_threadsafe, uint64_t rotate_size){\n\tif(strlen(filename) > PATH_MAX - 20){\n\t\tfprintf(stderr, \"log filename too long!\");\n\t\treturn -1;\n\t}\n\tthis->level_ = level;\n\tthis->rotate_size_ = rotate_size;\n\tif(is_threadsafe){\n\t\tthis->threadsafe();\n\t}\n\tstrcpy(this->filename, filename);\n\n\tif(strcmp(filename, \"stdout\") == 0){\n\t\tthis->fd = STDOUT_FILENO;\n\t}else if(strcmp(filename, \"stderr\") == 0){\n\t\tthis->fd = STDERR_FILENO;\n\t}else{\n\t\tthis->fd = ::open(filename, O_CREAT | O_WRONLY | O_APPEND, 0644);\n\t\tif(this->fd == -1){\n\t\t\tfprintf(stderr, \"open log file %s error - %s\\n\", filename, strerror(errno));\n\t\t\treturn -1;\n\t\t}\n\n\t\tstruct stat st;\n\t\tint ret = fstat(this->fd, &st);\n\t\tif(ret == -1){\n\t\t\tfprintf(stderr, \"fstat log file %s error!\\n\", filename);\n\t\t\treturn -1;\n\t\t}else{\n\t\t\tstats.w_curr = st.st_size;\n\t\t}\n\t}\n\treturn 0;\n}\n\nvoid Logger::close(){\n\tif(this->fd != STDOUT_FILENO && this->fd != STDERR_FILENO){\n\t\t::close(this->fd);\n\t}\n}\n\nvoid Logger::rotate(){\n\t::close(this->fd);\n\t\n\tchar newpath[PATH_MAX];\n\ttime_t time;\n\tstruct timeval tv;\n\tstruct tm *tm, tm_tmp;\n\tgettimeofday(&tv, NULL);\n\ttime = tv.tv_sec;\n\ttm = localtime_r(&time, &tm_tmp);\n\tsprintf(newpath, \"%s.%04d%02d%02d-%02d%02d%02d\",\n\t\tthis->filename,\n\t\ttm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,\n\t\ttm->tm_hour, tm->tm_min, tm->tm_sec);\n\n\t//printf(\"rename %s => %s\\n\", this->filename, newpath);\n\tint ret = rename(this->filename, newpath);\n\tif(ret == -1){\n\t\treturn;\n\t}\n\tthis->fd = ::open(filename, O_CREAT | O_WRONLY | O_APPEND, 0644);\n\tif(this->fd == -1){\n\t\tfprintf(stderr, \"open log file %s error - %s\\n\", filename, strerror(errno));\n\t\treturn;\n\t}\n\tstats.w_curr = 0;\n}\n\nint Logger::get_level(const char *levelname){\n\tif(strcmp(\"trace\", levelname) == 0){\n\t\treturn LEVEL_TRACE;\n\t}\n\tif(strcmp(\"debug\", levelname) == 0){\n\t\treturn LEVEL_DEBUG;\n\t}\n\tif(strcmp(\"info\", levelname) == 0){\n\t\treturn LEVEL_INFO;\n\t}\n\tif(strcmp(\"warn\", levelname) == 0){\n\t\treturn LEVEL_WARN;\n\t}\n\tif(strcmp(\"error\", levelname) == 0){\n\t\treturn LEVEL_ERROR;\n\t}\n\tif(strcmp(\"fatal\", levelname) == 0){\n\t\treturn LEVEL_FATAL;\n\t}\n\tif(strcmp(\"none\", levelname) == 0){\n\t\treturn LEVEL_NONE;\n\t}\n\treturn LEVEL_DEBUG;\n}\n\ninline static const char* get_level_name(int level){\n\tswitch(level){\n\t\tcase Logger::LEVEL_FATAL:\n\t\t\treturn \"[FATAL] \";\n\t\tcase Logger::LEVEL_ERROR:\n\t\t\treturn \"[ERROR] \";\n\t\tcase Logger::LEVEL_WARN:\n\t\t\treturn \"[WARN ] \";\n\t\tcase Logger::LEVEL_INFO:\n\t\t\treturn \"[INFO ] \";\n\t\tcase Logger::LEVEL_DEBUG:\n\t\t\treturn \"[DEBUG] \";\n\t\tcase Logger::LEVEL_TRACE:\n\t\t\treturn \"[TRACE] \";\n\t}\n\treturn \"\";\n}\n\n#define LEVEL_NAME_LEN\t8\n#define LOG_BUF_LEN\t\t4096\n\nint Logger::logv(int level, const char *fmt, va_list ap){\n\tif(logger.level_ < level){\n\t\treturn 0;\n\t}\n\n\tchar buf[LOG_BUF_LEN];\n\tint len;\n\tchar *ptr = buf;\n\n\ttime_t time;\n\tstruct timeval tv;\n\tstruct tm *tm, tm_tmp;\n\tgettimeofday(&tv, NULL);\n\ttime = tv.tv_sec;\n\ttm = localtime_r(&time, &tm_tmp);\n\t/* %3ld 在数值位数超过3位的时候不起作用, 所以这里转成int */\n\tlen = sprintf(ptr, \"%04d-%02d-%02d %02d:%02d:%02d.%03d \",\n\t\ttm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,\n\t\ttm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec/1000));\n\tif(len < 0){\n\t\treturn -1;\n\t}\n\tptr += len;\n\n\tmemcpy(ptr, get_level_name(level), LEVEL_NAME_LEN);\n\tptr += LEVEL_NAME_LEN;\n\n\tint space = sizeof(buf) - (ptr - buf) - 10;\n\tlen = vsnprintf(ptr, space, fmt, ap);\n\tif(len < 0){\n\t\treturn -1;\n\t}\n\tptr += len > space? space : len;\n\t*ptr++ = '\\n';\n\t*ptr = '\\0';\n\n\tlen = ptr - buf;\n\tif(this->mutex){\n\t\tpthread_mutex_lock(this->mutex);\n\t}\n\twrite(this->fd, buf, len);\n\n\tif(this->fd != STDOUT_FILENO && this->fd != STDERR_FILENO){\n\t\tstats.w_curr += len;\n\t\tstats.w_total += len;\n\t\tif(rotate_size_ > 0 && stats.w_curr > rotate_size_){\n\t\t\tthis->rotate();\n\t\t}\n\t}\n\tif(this->mutex){\n\t\tpthread_mutex_unlock(this->mutex);\n\t}\n\n\treturn len;\n}\n\nint Logger::trace(const char *fmt, ...){\n\tva_list ap;\n\tva_start(ap, fmt);\n\tint ret = logger.logv(Logger::LEVEL_TRACE, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\nint Logger::debug(const char *fmt, ...){\n\tva_list ap;\n\tva_start(ap, fmt);\n\tint ret = logger.logv(Logger::LEVEL_DEBUG, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\nint Logger::info(const char *fmt, ...){\n\tva_list ap;\n\tva_start(ap, fmt);\n\tint ret = logger.logv(Logger::LEVEL_INFO, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\nint Logger::warn(const char *fmt, ...){\n\tva_list ap;\n\tva_start(ap, fmt);\n\tint ret = logger.logv(Logger::LEVEL_WARN, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\nint Logger::error(const char *fmt, ...){\n\tva_list ap;\n\tva_start(ap, fmt);\n\tint ret = logger.logv(Logger::LEVEL_ERROR, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\nint Logger::fatal(const char *fmt, ...){\n\tva_list ap;\n\tva_start(ap, fmt);\n\tint ret = logger.logv(Logger::LEVEL_FATAL, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n"
  },
  {
    "path": "src/util/log.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef UTIL_LOG_H\n#define UTIL_LOG_H\n\n#include <inttypes.h>\n#include <unistd.h>\n#include <stdarg.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <limits.h>\n#include <errno.h>\n#include <string.h>\n#include <math.h>\n#include <fcntl.h>\n#include <assert.h>\n#include <signal.h>\n#include <time.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <pthread.h>\n#include <string>\n\nclass Logger{\n\tpublic:\n\t\tstatic const int LEVEL_NONE\t\t= (-1);\n\t\tstatic const int LEVEL_MIN\t\t= 0;\n\t\tstatic const int LEVEL_FATAL\t= 0;\n\t\tstatic const int LEVEL_ERROR\t= 1;\n\t\tstatic const int LEVEL_WARN\t\t= 2;\n\t\tstatic const int LEVEL_INFO\t\t= 3;\n\t\tstatic const int LEVEL_DEBUG\t= 4;\n\t\tstatic const int LEVEL_TRACE\t= 5;\n\t\tstatic const int LEVEL_MAX\t\t= 5;\n\n\t\tstatic int get_level(const char *levelname);\n\t\t\n\t\tstatic Logger* shared();\n\t\t\n\t\tstd::string level_name();\n\t\tstd::string output_name();\n\t\tuint64_t rotate_size();\n\tprivate:\n\t\tint fd;\n\t\tchar filename[PATH_MAX];\n\t\tint level_;\n\t\tpthread_mutex_t *mutex;\n\n\t\tuint64_t rotate_size_;\n\t\tstruct{\n\t\t\tuint64_t w_curr;\n\t\t\tuint64_t w_total;\n\t\t}stats;\n\n\t\tvoid rotate();\n\t\tvoid threadsafe();\n\tpublic:\n\t\tLogger();\n\t\t~Logger();\n\n\t\tint level(){\n\t\t\treturn level_;\n\t\t}\n\n\t\tvoid set_level(int level){\n\t\t\tthis->level_ = level;\n\t\t}\n\n\t\tint open(const char *filename, int level=LEVEL_DEBUG,\n\t\t\tbool is_threadsafe=false, uint64_t rotate_size=0);\n\t\tvoid close();\n\n\t\tint logv(int level, const char *fmt, va_list ap);\n\n\t\tint trace(const char *fmt, ...);\n\t\tint debug(const char *fmt, ...);\n\t\tint info(const char *fmt, ...);\n\t\tint warn(const char *fmt, ...);\n\t\tint error(const char *fmt, ...);\n\t\tint fatal(const char *fmt, ...);\n};\n\n\nint log_open(const char *filename, int level=Logger::LEVEL_DEBUG,\n\tbool is_threadsafe=false, uint64_t rotate_size=0);\nint log_level();\nvoid set_log_level(int level);\nvoid set_log_level(const char *s);\nint log_write(int level, const char *fmt, ...);\n\n\n#ifndef IOS\n\t#ifdef NDEBUG\n\t\t#define log_trace(fmt, args...) do{}while(0)\n\t#else\n\t\t#define log_trace(fmt, args...)\t\\\n\t\t\tlog_write(Logger::LEVEL_TRACE, \"%s(%d): \" fmt, __FILE__, __LINE__, ##args)\n\t#endif\n\n\t#define log_debug(fmt, args...)\t\\\n\t\tlog_write(Logger::LEVEL_DEBUG, \"%s(%d): \" fmt, __FILE__, __LINE__, ##args)\n\t#define log_info(fmt, args...)\t\\\n\t\tlog_write(Logger::LEVEL_INFO,  \"%s(%d): \" fmt, __FILE__, __LINE__, ##args)\n\t#define log_warn(fmt, args...)\t\\\n\t\tlog_write(Logger::LEVEL_WARN,  \"%s(%d): \" fmt, __FILE__, __LINE__, ##args)\n\t#define log_error(fmt, args...)\t\\\n\t\tlog_write(Logger::LEVEL_ERROR, \"%s(%d): \" fmt, __FILE__, __LINE__, ##args)\n\t#define log_fatal(fmt, args...)\t\\\n\t\tlog_write(Logger::LEVEL_FATAL, \"%s(%d): \" fmt, __FILE__, __LINE__, ##args)\n#else\n\t#define log_trace(fmt, args...) do{}while(0)\n\t#define log_debug(fmt, args...) do{}while(0)\n\t#define log_info(fmt, args...) do{}while(0)\n\t#define log_warn(fmt, args...) do{}while(0)\n\t#define log_error(fmt, args...) do{}while(0)\n\t#define log_fatal(fmt, args...) do{}while(0)\n#endif\n\n#endif\n"
  },
  {
    "path": "src/util/sorted_set.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"sorted_set.h\"\n\nint SortedSet::size() const{\n\treturn (int)sorted_set.size();\n}\n\nint SortedSet::add(const std::string &key, int64_t score){\n\tint ret;\n\tstd::map<std::string, std::set<Item>::iterator>::iterator it;\n\t\n\tit = existed.find(key);\n\tif(it == existed.end()){\n\t\t// new item\n\t\tret = 1;\n\t}else{\n\t\tret = 0;\n\t\tstd::set<Item>::iterator it2 = it->second;\n\t\tconst Item &item = *it2;\n\t\tif(item.score == score){\n\t\t\t// not updated\n\t\t\treturn 0;\n\t\t}\n\t\t// remove existing item\n\t\tsorted_set.erase(it2);\n\t}\n\t\n\tItem item;\n\titem.key = key;\n\titem.score = score;\n\t\n\tstd::pair<std::set<Item>::iterator, bool> p = sorted_set.insert(item);\n\texisted[key] = p.first;\n\t\n\treturn ret;\n}\n\nint SortedSet::del(const std::string &key){\n\tint ret;\n\tstd::map<std::string, std::set<Item>::iterator>::iterator it;\n\t\n\tit = existed.find(key);\n\tif(it == existed.end()){\n\t\t// new item\n\t\tret = 0;\n\t}else{\n\t\tret = 1;\n\t\tsorted_set.erase(it->second);\n\t\texisted.erase(it);\n\t}\n\treturn ret;\n}\n\nint SortedSet::front(std::string *key, int64_t *score) const{\n\tstd::set<Item>::iterator it2 = sorted_set.begin();\n\tif(it2 == sorted_set.end()){\n\t\treturn 0;\n\t}\n\tconst Item &item = *it2;\n\t*key = item.key;\n\tif(score){\n\t\t*score = item.score;\n\t}\n\treturn 1;\n}\n\nint SortedSet::back(std::string *key, int64_t *score) const{\n\tstd::set<Item>::reverse_iterator it2 = sorted_set.rbegin();\n\tif(it2 == sorted_set.rend()){\n\t\treturn 0;\n\t}\n\tconst Item &item = *it2;\n\t*key = item.key;\n\tif(score){\n\t\t*score = item.score;\n\t}\n\treturn 1;\n}\n\nint64_t SortedSet::max_score() const{\n\tint64_t score = 0;\n\tstd::string key;\n\tthis->back(&key, &score);\n\treturn score;\n}\n\n\nint SortedSet::pop_front(){\n\tif(sorted_set.empty()){\n\t\treturn 0;\n\t}\n\tstd::set<Item>::iterator it = sorted_set.begin();\n\tconst Item &item = *it;\n\texisted.erase(item.key);\n\tsorted_set.erase(it);\n\treturn 1;\n}\n\nint SortedSet::pop_back(){\n\tif(sorted_set.empty()){\n\t\treturn 0;\n\t}\n\tstd::set<Item>::iterator it = sorted_set.end();\n\tit --;\n\tconst Item &item = *it;\n\texisted.erase(item.key);\n\tsorted_set.erase(it);\n\treturn 1;\n}\n"
  },
  {
    "path": "src/util/sorted_set.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef UTIL_SORTED_SET_H\n#define UTIL_SORTED_SET_H\n\n#include <inttypes.h>\n#include <string>\n#include <map>\n#include <set>\n\nclass SortedSet\n{\npublic:\n\tbool empty() const{\n\t\treturn size() == 0;\n\t}\n\tint size() const;\n\tint add(const std::string &key, int64_t score);\n\t// 0: not found, 1: found and deleted\n\tint del(const std::string &key);\n\t// the first item is copied into key if SortedSet not empty\n\tint front(std::string *key, int64_t *score=NULL) const;\n\tint back(std::string *key, int64_t *score=NULL) const;\n\tint64_t max_score() const;\n\tint pop_front();\n\tint pop_back();\n\t\n\t/*\n\tclass Iterator\n\t{\n\tpublic:\n\t\tbool next();\n\t\tconst std::string& key();\n\t\tint64_t score();\n\t};\n\t\n\tIterator begin();\n\t*/\n\nprivate:\n\tstruct Item\n\t{\n\t\tstd::string key;\n\t\tint64_t score;\n\t\t\n\t\tbool operator<(const Item& b) const{\n\t\t\treturn this->score < b.score\n\t\t\t\t|| (this->score == b.score && this->key < b.key);\n\t\t}\n\t};\n\t\n\tstd::map<std::string, std::set<Item>::iterator> existed;\n\tstd::set<Item> sorted_set;\n};\n\n\n/*\nTODO: HashedWheel\nEach item is linked in two list, one is slot list, the other\none is total list.\n*/\n/*\ntemplate <class T>\nclass SortedList\n{\npublic:\n\tvoid add(const T data, int64_t score);\n\tT front();\n\tvoid pop_front();\n\n\tclass Item\n\t{\n\tpublic:\n\t\tint64_t score;\n\t\tItem *prev;\n\t\tItem *next;\n\t\t//Item *slot_prev;\n\t\t//Item *slot_next;\n\t\tT data;\n\t};\n};\n*/\n\n#endif\n"
  },
  {
    "path": "src/util/string_util.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef UTIL_STRING_H\n#define UTIL_STRING_H\n\n#include <unistd.h>\n#include <string.h>\n#include <errno.h>\n#include <math.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <inttypes.h>\n#include <string>\n#include <algorithm>\n\n\ninline static\nint is_empty_str(const char *str){\n\tconst char *p = str;\n\twhile(*p && isspace(*p)){\n\t\tp++;\n\t}\n\treturn *p == '\\0';\n}\n\n/* 返回左边不包含空白字符的字符串的指针 */\ninline static\nchar *ltrim(const char *str){\n\tconst char *p = str;\n\twhile(*p && isspace(*p)){\n\t\tp++;\n\t}\n\treturn (char *)p;\n}\n\n/* 返回指向字符串结尾的指针, 会修改字符串内容 */\ninline static\nchar *rtrim(char *str){\n\tchar *p;\n\tp = str + strlen(str) - 1;\n\twhile(p >= str && isspace(*p)){\n\t\tp--;\n\t}\n\t*(++p) = '\\0';\n\treturn p;\n}\n\n/* 返回左边不包含空白字符的字符串的指针 */\ninline static\nchar *trim(char *str){\n\tchar *p;\n\tp = ltrim(str);\n\trtrim(p);\n\treturn p;\n}\n\ninline static\nvoid strtolower(std::string *str){\n\tstd::transform(str->begin(), str->end(), str->begin(), ::tolower);\n}\n\ninline static\nvoid strtoupper(std::string *str){\n\tstd::transform(str->begin(), str->end(), str->begin(), ::toupper);\n}\n\ninline static\nstd::string real_dirname(const char *filepath){\n\tstd::string dir;\n\tif(filepath[0] != '/'){\n\t\tchar buf[1024];\n\t\tchar *p = getcwd(buf, sizeof(buf));\n\t\tif(p != NULL){\n\t\t\tdir.append(p);\n\t\t}\n\t\tdir.append(\"/\");\n\t}\n\n\tconst char *p = strrchr(filepath, '/');\n\tif(p != NULL){\n\t\tdir.append(filepath, p - filepath);\n\t}\n\treturn dir;\n}\n\ninline static\nvoid str_escape(const char *s, int size, std::string *ret){\n\tstatic const char *hex = \"0123456789abcdef\";\n\tfor(int i=0; i<size; i++){\n\t\tchar c = s[i];\n\t\tswitch(c){\n\t\t\tcase '\\r':\n\t\t\t\tret->append(\"\\\\r\");\n\t\t\t\tbreak;\n\t\t\tcase '\\n':\n\t\t\t\tret->append(\"\\\\n\");\n\t\t\t\tbreak;\n\t\t\tcase '\\t':\n\t\t\t\tret->append(\"\\\\t\");\n\t\t\t\tbreak;\n\t\t\tcase '\\\\':\n\t\t\t\tret->append(\"\\\\\\\\\");\n\t\t\t\tbreak;\n\t\t\tcase ' ':\n\t\t\t\tret->push_back(c);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif(c >= '!' && c <= '~'){\n\t\t\t\t\tret->push_back(c);\n\t\t\t\t}else{\n\t\t\t\t\tret->append(\"\\\\x\");\n\t\t\t\t\tunsigned char d = c;\n\t\t\t\t\tret->push_back(hex[d >> 4]);\n\t\t\t\t\tret->push_back(hex[d & 0x0f]);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\ninline static\nstd::string str_escape(const char *s, int size){\n\tstd::string ret;\n\tint capacity = (size < 20)? 32 : (size * 1.2);\n\tret.reserve(capacity);\n\tstr_escape(s, size, &ret);\n\treturn ret;\n}\n\ninline static\nstd::string str_escape(const std::string &s){\n\treturn str_escape(s.data(), (int)s.size());\n}\n\ninline static\nint hex_int(char c){\n\tif(c >= '0' && c <= '9'){\n\t\treturn c - '0';\n\t}else{\n\t\treturn c - 'a' + 10;\n\t}\n}\n\ninline static\nvoid str_unescape(const char *s, int size, std::string *ret){\n\tfor(int i=0; i<size; i++){\n\t\tchar c = s[i];\n\t\tif(c != '\\\\'){\n\t\t\tret->push_back(c);\n\t\t}else{\n\t\t\tif(i >= size - 1){\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tchar c2 = s[++i];\n\t\t\tswitch(c2){\n\t\t\t\tcase 'a':\n\t\t\t\t\tret->push_back('\\a');\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'b':\n\t\t\t\t\tret->push_back('\\b');\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'f':\n\t\t\t\t\tret->push_back('\\f');\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'v':\n\t\t\t\t\tret->push_back('\\v');\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'r':\n\t\t\t\t\tret->push_back('\\r');\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'n':\n\t\t\t\t\tret->push_back('\\n');\n\t\t\t\t\tbreak;\n\t\t\t\tcase 't':\n\t\t\t\t\tret->push_back('\\t');\n\t\t\t\t\tbreak;\n\t\t\t\tcase '\\\\':\n\t\t\t\t\tret->push_back('\\\\');\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'x':\n\t\t\t\t\tif(i < size - 2){\n\t\t\t\t\t\tchar c3 = s[++i];\n\t\t\t\t\t\tchar c4 = s[++i];\n\t\t\t\t\t\tret->push_back((char)((hex_int(c3) << 4) + hex_int(c4)));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tret->push_back(c2);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\ninline static\nstd::string str_unescape(const char *s, int size){\n\tstd::string ret;\n\tret.reserve(size);\n\tstr_unescape(s, size, &ret);\n\treturn ret;\n}\n\ninline static\nstd::string str_unescape(const std::string &s){\n\treturn str_unescape(s.data(), (int)s.size());\n}\n\ninline static\nstd::string hexmem(const void *p, int size){\n\treturn str_escape((char *)p, size);\n\t/*\n\tstd::string ret;\n\tchar buf[4];\n\tfor(int i=0; i<size; i++){\n\t\tchar c = ((char *)p)[i];\n\t\tif(isalnum(c) || isprint(c)){\n\t\t\tret.append(1, c);\n\t\t}else{\n\t\t\tswitch(c){\n\t\t\t\tcase '\\r':\n\t\t\t\t\tret.append(\"\\\\r\", 2);\n\t\t\t\t\tbreak;\n\t\t\t\tcase '\\n':\n\t\t\t\t\tret.append(\"\\\\n\", 2);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tsprintf(buf, \"\\\\%02x\", (unsigned char)c);\n\t\t\t\t\tret.append(buf, 3);\n\t\t\t}\n\t\t}\n\t}\n\treturn ret;\n\t*/\n}\n\n// TODO: mem_printf(\"%5c%d%s\", p, size);\nstatic inline\nvoid dump(const void *p, int size, const char *msg = NULL){\n\tif(msg == NULL){\n\t\tprintf(\"dump <\");\n\t}else{\n\t\tprintf(\"%s <\", msg);\n\t}\n\tstd::string s = hexmem(p, size);\n\tprintf(\"%s>\\n\", s.c_str());\n}\n\n\nstatic inline\nstd::string str(const char *s){\n\treturn std::string(s);\n}\n\nstatic inline\nstd::string str(int v){\n\tchar buf[21] = {0};\n\tsnprintf(buf, sizeof(buf), \"%d\", v);\n\treturn std::string(buf);\n}\n\nstatic inline\nstd::string str(int64_t v){\n\tchar buf[21] = {0};\n\tsnprintf(buf, sizeof(buf), \"%\" PRId64 \"\", v);\n\treturn std::string(buf);\n}\n\nstatic inline\nstd::string str(uint64_t v){\n\tchar buf[21] = {0};\n\tsnprintf(buf, sizeof(buf), \"%\" PRIu64 \"\", v);\n\treturn std::string(buf);\n}\n\nstatic inline\nstd::string str(double v){\n\tchar buf[21] = {0};\n\tif(v - floor(v) == 0){\n\t\tsnprintf(buf, sizeof(buf), \"%.0f\", v);\n\t}else{\n\t\tsnprintf(buf, sizeof(buf), \"%f\", v);\n\t}\n\treturn std::string(buf);\n}\n\nstatic inline\nstd::string str(float v){\n\treturn str((double)v);\n}\n\n// all str_to_xx methods set errno on error\n\nstatic inline\nint str_to_int(const std::string &str){\n\tconst char *start = str.c_str();\n\tchar *end;\n\tint ret = (int)strtol(start, &end, 10);\n\t// the WHOLE string must be string represented integer\n\tif(*end == '\\0' && size_t(end - start) == str.size()){\n\t\terrno = 0;\n\t}else{\n\t\t// strtoxx do not set errno all the time!\n\t\tif(errno == 0){\n\t\t\terrno = EINVAL;\n\t\t}\n\t}\n\treturn ret;\n}\n\nstatic inline\nint str_to_int(const char *p, int size){\n\treturn str_to_int(std::string(p, size));\n}\n\nstatic inline\nint64_t str_to_int64(const std::string &str){\n\tconst char *start = str.c_str();\n\tchar *end;\n\tint64_t ret = (int64_t)strtoll(start, &end, 10);\n\t// the WHOLE string must be string represented integer\n\tif(*end == '\\0' && size_t(end - start) == str.size()){\n\t\terrno = 0;\n\t}else{\n\t\t// strtoxx do not set errno all the time!\n\t\tif(errno == 0){\n\t\t\terrno = EINVAL;\n\t\t}\n\t}\n\treturn ret;\n}\n\nstatic inline\nint64_t str_to_int64(const char *p, int size){\n\treturn str_to_int64(std::string(p, size));\n}\n\nstatic inline\nuint64_t str_to_uint64(const std::string &str){\n\tconst char *start = str.c_str();\n\tchar *end;\n\tuint64_t ret = (uint64_t)strtoull(start, &end, 10);\n\t// the WHOLE string must be string represented integer\n\tif(*end == '\\0' && size_t(end - start) == str.size()){\n\t\terrno = 0;\n\t}else{\n\t\t// strtoxx do not set errno all the time!\n\t\tif(errno == 0){\n\t\t\terrno = EINVAL;\n\t\t}\n\t}\n\treturn ret;\n}\n\nstatic inline\nuint64_t str_to_uint64(const char *p, int size){\n\treturn str_to_uint64(std::string(p, size));\n}\n\nstatic inline\ndouble str_to_double(const char *p, int size){\n\treturn atof(std::string(p, size).c_str());\n}\n\nstatic inline\nstd::string substr(const std::string &str, int start, int size){\n\tif(start < 0){\n\t\tstart = (int)str.size() + start;\n\t}\n\tif(size < 0){\n\t\t// 忽略掉 abs(size) 个字节\n\t\tsize = ((int)str.size() + size) - start;\n\t}\n\tif(start < 0 || size_t(start) >= str.size() || size < 0){\n\t\treturn \"\";\n\t}\n\treturn str.substr(start, size);\n}\n\nstatic inline\nstd::string str_slice(const std::string &str, int start, int end){\n\tif(start < 0){\n\t\tstart = (int)str.size() + start;\n\t}\n\tint size;\n\tif(end < 0){\n\t\tsize = ((int)str.size() + end + 1) - start;\n\t}else{\n\t\tsize = end - start + 1;\n\t}\n\tif(start < 0 || size_t(start) >= str.size() || size < 0){\n\t\treturn \"\";\n\t}\n\treturn str.substr(start, size);\n}\n\nstatic inline\nint bitcount(const char *p, int size){\n\tint n = 0;\n\tfor(int i=0; i<size; i++){\n\t\tunsigned char c = (unsigned char)p[i];\n\t\twhile(c){\n\t\t\tn += c & 1;\n\t\t\tc = c >> 1;\n\t\t}\n\t}\n\treturn n;\n}\n\n// is big endia. TODO: auto detect\n#if 0\n\t#define big_endian(v) (v)\n#else\n\tstatic inline\n\tuint16_t big_endian(uint16_t v){\n\t\treturn (v>>8) | (v<<8);\n\t}\n\n\tstatic inline\n\tuint32_t big_endian(uint32_t v){\n\t\treturn (v >> 24) | ((v >> 8) & 0xff00) | ((v << 8) & 0xff0000) | (v << 24);\n\t}\n\n\tstatic inline\n\tuint64_t big_endian(uint64_t v){\n\t\tuint32_t h = v >> 32;\n\t\tuint32_t l = v & 0xffffffffull;\n\t\treturn big_endian(h) | ((uint64_t)big_endian(l) << 32);\n\t}\n#endif\n\n\n#endif\n"
  },
  {
    "path": "src/util/test_sorted_set.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include <stdio.h>\n#include <stdlib.h>\n#include <time.h>\n#include <vector>\n#include \"log.h\"\n#include \"sorted_set.h\"\n#include \"bytes.h\"\n\nint main(int argc, char **argv){\t\n\tSortedSet zset;\n\n\tstd::vector<std::string> keys;\n\tfor(int i='a'; i<='z'; i++){\n\t\tchar buf[10];\n\t\tsnprintf(buf, sizeof(buf), \"%c\", i);\n\t\tkeys.push_back(buf);\n\t}\n\t\n\tlog_debug(\"\");\n\tsrand(time(NULL));\n\tfor(int i=0; i<1000 * 1000; i++){\n\t\tstd::string &key = keys[rand() % keys.size()];\n\t\tzset.add(key, rand()%30 - 15);\n\t}\n\tlog_debug(\"\");\n\t\n\tstd::string key;\n\tint64_t score;\n\tint n = 0;\n\twhile(zset.front(&key, &score)){\n\t\tprintf(\"%s : %4lld\\n\", key.c_str(), score);\n\t\tzset.pop_front();\n\t\tn ++;\n\t}\n\tlog_debug(\"%d\", n);\n\t\n\t{\n\t\tBuffer bs(8192);\n\t\tbs.append_record(\"a\");\n\t\tbs.append_record(\"bs\");\n\t\tdump(bs.data(), bs.size());\n\t\n\t\tBytes s;\n\t\tbs.read_record(&s);\n\t\tdump(s.data(), s.size());\n\t\tbs.read_record(&s);\n\t\tdump(s.data(), s.size());\n\t}\n\t\n\treturn 0;\n}\n"
  },
  {
    "path": "src/util/test_thread.cpp",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include <stdio.h>\n#include <stdlib.h>\n#include <time.h>\n#include <vector>\n#include \"log.h\"\n#include \"thread.h\"\n\n// g++ log.o a.cpp\n\nclass MyWorker : public WorkerPool<MyWorker, int*>::Worker{\npublic:\n\tMyWorker(const std::string &name){\n\t}\n\t\n\tint proc(int *job){\n\t\tusleep(200 * 1000);\n\t\t*job = 100000 + *job;\n\t\treturn 0;\n\t}\n};\n\n#define NUM_JOBS 10\n\nint main(){\n\tint jobs[NUM_JOBS];\n\tWorkerPool<MyWorker, int*> tp(\"test\");\n\ttp.start(3);\n\t\n\tlog_debug(\"add begin\");\n\tfor(int i=0; i<NUM_JOBS; i++){\n\t\t//usleep(200 * 1000);\n\t\tlog_debug(\"    add job: %d\", i);\n\t\tjobs[i] = i;\n\t\ttp.push(&jobs[i]);\n\t}\n\tlog_debug(\"add end\");\n\t\n\tlog_debug(\"pop begin\");\n\tfor(int i=0; i<NUM_JOBS-1; i++){\n\t\tint *job;\n\t\ttp.pop(&job);\n\t\tlog_debug(\"    result: %d, %d\", i, *job);\n\t}\n\tlog_debug(\"pop end\");\n\t\n\tlog_debug(\"stopping...\");\n\ttp.stop();\n\tlog_debug(\"stopped\");\n\n\treturn 0;\n}\n"
  },
  {
    "path": "src/util/thread.h",
    "content": "/*\nCopyright (c) 2012-2014 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#ifndef UTIL_THREAD_H_\n#define UTIL_THREAD_H_\n\n#include <unistd.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n#include <pthread.h>\n#include <queue>\n#include <vector>\n\nclass Mutex{\n\tprivate:\n\t\tpthread_mutex_t mutex;\n\tpublic:\n\t\tMutex(){\n\t\t\tpthread_mutex_init(&mutex, NULL);\n\t\t}\n\t\t~Mutex(){\n\t\t\tpthread_mutex_destroy(&mutex);\n\t\t}\n\t\tvoid lock(){\n\t\t\tpthread_mutex_lock(&mutex);\n\t\t}\n\t\tvoid unlock(){\n\t\t\tpthread_mutex_unlock(&mutex);\n\t\t}\n};\n\nclass Locking{\n\tprivate:\n\t\tMutex *mutex;\n\t\t// No copying allowed\n\t\tLocking(const Locking&);\n\t\tvoid operator=(const Locking&);\n\tpublic:\n\t\tLocking(Mutex *mutex){\n\t\t\tthis->mutex = mutex;\n\t\t\tthis->mutex->lock();\n\t\t}\n\t\t~Locking(){\n\t\t\tthis->mutex->unlock();\n\t\t}\n\n};\n\n/*\nclass Semaphore {\n\tprivate:\n\t\tpthread_cond_t cond;\n\t\tpthread_mutex_t mutex;\n\tpublic:\n\t\tSemaphore(Mutex* mu){\n\t\t\tpthread_cond_init(&cond, NULL);\n\t\t\tpthread_mutex_init(&mutex, NULL);\n\t\t}\n\t\t~CondVar(){\n\t\t\tpthread_cond_destroy(&cond);\n\t\t\tpthread_mutex_destroy(&mutex);\n\t\t}\n\t\tvoid wait();\n\t\tvoid signal();\n};\n*/\n\n\n// Thread safe queue\ntemplate <class T>\nclass Queue{\n\tprivate:\n\t\tpthread_cond_t cond;\n\t\tpthread_mutex_t mutex;\n\t\tstd::queue<T> items;\n\tpublic:\n\t\tQueue();\n\t\t~Queue();\n\n\t\tbool empty();\n\t\tint size();\n\t\tint push(const T item);\n\t\t// TODO: with timeout\n\t\tint pop(T *data);\n};\n\n\n// Selectable queue, multi writers, single reader\ntemplate <class T>\nclass SelectableQueue{\n\tprivate:\n\t\tint fds[2];\n\t\tpthread_mutex_t mutex;\n\t\tstd::queue<T> items;\n\tpublic:\n\t\tSelectableQueue();\n\t\t~SelectableQueue();\n\t\tint fd(){\n\t\t\treturn fds[0];\n\t\t}\n\t\tint size();\n\t\t// multi writer\n\t\tint push(const T item);\n\t\t// single reader\n\t\tint pop(T *data);\n};\n\ntemplate<class W, class JOB>\nclass WorkerPool{\n\tpublic:\n\t\tclass Worker{\n\t\t\tpublic:\n\t\t\t\tWorker(){};\n\t\t\t\tWorker(const std::string &name);\n\t\t\t\tvirtual ~Worker(){}\n\t\t\t\tint id;\n\t\t\t\tvirtual void init(){}\n\t\t\t\tvirtual void destroy(){}\n\t\t\t\tvirtual int proc(JOB job) = 0;\n\t\t\tprivate:\n\t\t\tprotected:\n\t\t\t\tstd::string name;\n\t\t};\n\tprivate:\n\t\tstd::string name;\n\t\tQueue<JOB> jobs;\n\t\tSelectableQueue<JOB> results;\n\n\t\tint num_workers;\n\t\tstd::vector<pthread_t> tids;\n\t\tbool started;\n\n\t\tstruct run_arg{\n\t\t\tint id;\n\t\t\tWorkerPool *tp;\n\t\t};\n\t\tstatic void* _run_worker(void *arg);\n\tpublic:\n\t\tWorkerPool(const char *name=\"\");\n\t\t~WorkerPool();\n\n\t\tint fd(){\n\t\t\treturn results.fd();\n\t\t}\n\t\t\n\t\tint start(int num_workers);\n\t\tint stop();\n\t\t\n\t\tint push(JOB job);\n\t\tint pop(JOB *job);\n};\n\n\n\n\n\ntemplate <class T>\nQueue<T>::Queue(){\n\tpthread_cond_init(&cond, NULL);\n\tpthread_mutex_init(&mutex, NULL);\n}\n\ntemplate <class T>\nQueue<T>::~Queue(){\n\tpthread_cond_destroy(&cond);\n\tpthread_mutex_destroy(&mutex);\n}\n\ntemplate <class T>\nbool Queue<T>::empty(){\n\tbool ret = false;\n\tif(pthread_mutex_lock(&mutex) != 0){\n\t\treturn -1;\n\t}\n\tret = items.empty();\n\tpthread_mutex_unlock(&mutex);\n\treturn ret;\n}\n\ntemplate <class T>\nint Queue<T>::size(){\n\tint ret = -1;\n\tif(pthread_mutex_lock(&mutex) != 0){\n\t\treturn -1;\n\t}\n\tret = items.size();\n\tpthread_mutex_unlock(&mutex);\n\treturn ret;\n}\n\ntemplate <class T>\nint Queue<T>::push(const T item){\n\tif(pthread_mutex_lock(&mutex) != 0){\n\t\treturn -1;\n\t}\n\t{\n\t\titems.push(item);\n\t}\n\tpthread_mutex_unlock(&mutex);\n\tpthread_cond_signal(&cond);\n\treturn 1;\n}\n\ntemplate <class T>\nint Queue<T>::pop(T *data){\n\tif(pthread_mutex_lock(&mutex) != 0){\n\t\treturn -1;\n\t}\n\t{\n\t\t// 必须放在循环中, 因为多个线程 pthread_cond_wait 可能同时返回(看具体实现策略)\n\t\twhile(items.empty()){\n\t\t\t//fprintf(stderr, \"%d wait\\n\", pthread_self());\n\t\t\tif(pthread_cond_wait(&cond, &mutex) != 0){\n\t\t\t\t//fprintf(stderr, \"%s %d -1!\\n\", __FILE__, __LINE__);\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\t//fprintf(stderr, \"%d wait 2\\n\", pthread_self());\n\t\t}\n\t\t*data = items.front();\n\t\t//fprintf(stderr, \"%d job: %d\\n\", pthread_self(), (int)*data);\n\t\titems.pop();\n\t}\n\tif(pthread_mutex_unlock(&mutex) != 0){\n\t\t//fprintf(stderr, \"error!\\n\");\n\t\treturn -1;\n\t}\n\t\t//fprintf(stderr, \"%d wait end 2, job: %d\\n\", pthread_self(), (int)*data);\n\treturn 1;\n}\n\n\ntemplate <class T>\nSelectableQueue<T>::SelectableQueue(){\n\tif(pipe(fds) == -1){\n\t\tfprintf(stderr, \"create pipe error\\n\");\n\t\texit(0);\n\t}\n\tpthread_mutex_init(&mutex, NULL);\n}\n\ntemplate <class T>\nSelectableQueue<T>::~SelectableQueue(){\n\tpthread_mutex_destroy(&mutex);\n\tclose(fds[0]);\n\tclose(fds[1]);\n}\n\ntemplate <class T>\nint SelectableQueue<T>::push(const T item){\n\tif(pthread_mutex_lock(&mutex) != 0){\n\t\treturn -1;\n\t}\n\t{\n\t\titems.push(item);\n\t}\n\tif(::write(fds[1], \"1\", 1) == -1){\n\t\tfprintf(stderr, \"write fds error\\n\");\n\t\texit(0);\n\t}\n\tpthread_mutex_unlock(&mutex);\n\treturn 1;\n}\n\ntemplate <class T>\nint SelectableQueue<T>::size(){\n\tint ret = 0;\n\tpthread_mutex_lock(&mutex);\n\tret = items.size();\n\tpthread_mutex_unlock(&mutex);\n\treturn ret;\n}\n\ntemplate <class T>\nint SelectableQueue<T>::pop(T *data){\n\tint n, ret = 1;\n\tchar buf[1];\n\n\twhile(1){\n\t\tn = ::read(fds[0], buf, 1);\n\t\tif(n < 0){\n\t\t\tif(errno == EINTR){\n\t\t\t\tcontinue;\n\t\t\t}else{\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}else if(n == 0){\n\t\t\tret = -1;\n\t\t}else{\n\t\t\tif(pthread_mutex_lock(&mutex) != 0){\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\t{\n\t\t\t\tif(items.empty()){\n\t\t\t\t\tfprintf(stderr, \"%s %d error!\\n\", __FILE__, __LINE__);\n\t\t\t\t\tpthread_mutex_unlock(&mutex);\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t\t*data = items.front();\n\t\t\t\titems.pop();\n\t\t\t}\n\t\t\tpthread_mutex_unlock(&mutex);\n\t\t}\n\t\tbreak;\n\t}\n\treturn ret;\n}\n\n\n\ntemplate<class W, class JOB>\nWorkerPool<W, JOB>::WorkerPool(const char *name){\n\tthis->name = name;\n\tthis->started = false;\n}\n\ntemplate<class W, class JOB>\nWorkerPool<W, JOB>::~WorkerPool(){\n\tif(started){\n\t\tstop();\n\t}\n}\n\ntemplate<class W, class JOB>\nint WorkerPool<W, JOB>::push(JOB job){\n\treturn this->jobs.push(job);\n}\n\ntemplate<class W, class JOB>\nint WorkerPool<W, JOB>::pop(JOB *job){\n\treturn this->results.pop(job);\n}\n\ntemplate<class W, class JOB>\nvoid* WorkerPool<W, JOB>::_run_worker(void *arg){\n\tstruct run_arg *p = (struct run_arg*)arg;\n\tint id = p->id;\n\tWorkerPool *tp = p->tp;\n\tdelete p;\n\n\tW w(tp->name);\n\tWorker *worker = (Worker *)&w;\n\tworker->id = id;\n\tworker->init();\n\twhile(1){\n\t\tJOB job;\n\t\tif(tp->jobs.pop(&job) == -1){\n\t\t\tfprintf(stderr, \"jobs.pop error\\n\");\n\t\t\t::exit(0);\n\t\t\tbreak;\n\t\t}\n\t\tif(!tp->started){\n\t\t\tbreak;\n\t\t}\n\t\tworker->proc(job);\n\t\tif(tp->results.push(job) == -1){\n\t\t\tfprintf(stderr, \"results.push error\\n\");\n\t\t\t::exit(0);\n\t\t\tbreak;\n\t\t}\n\t}\n\tworker->destroy();\n\t// fprintf(stderr, \"  %d stopped\\n\", id);\n\treturn (void *)NULL;\n}\n\ntemplate<class W, class JOB>\nint WorkerPool<W, JOB>::start(int num_workers){\n\tthis->num_workers = num_workers;\n\tif(started){\n\t\treturn 0;\n\t}\n\tint err;\n\tpthread_t tid;\n\tfor(int i=0; i<num_workers; i++){\n\t\tstruct run_arg *arg = new run_arg();\n\t\targ->id = i;\n\t\targ->tp = this;\n\n\t\terr = pthread_create(&tid, NULL, &WorkerPool::_run_worker, arg);\n\t\tif(err != 0){\n\t\t\tfprintf(stderr, \"can't create thread: %s\\n\", strerror(err));\n\t\t}else{\n\t\t\ttids.push_back(tid);\n\t\t}\n\t}\n\tstarted = true;\n\treturn 0;\n}\n\ntemplate<class W, class JOB>\nint WorkerPool<W, JOB>::stop(){\n\t// notify and wait workers quit\n\tstarted = false;\n\t// notify\n\tfor(int i=0; i<tids.size(); i++){\n\t\tJOB j = NULL;\n\t\tthis->push(j);\n\t}\n\t// wait\n\tfor(int i=0; i<tids.size(); i++){\n#ifdef OS_ANDROID\n\t\t// TODO:\n#else\n\t\tvoid *ret;\n\t\tpthread_join(tids[i], &ret);\n#endif\n\t}\n\treturn 0;\n}\n\n\n\n#if 0\n// g++ log.o a.cpp\n\nclass MyWorker : public WorkerPool<MyWorker, int*>::Worker{\npublic:\n\tMyWorker(const std::string &name){\n\t}\n\t\n\tint proc(int *job){\n\t\tusleep(200 * 1000);\n\t\t*job = 100000 + *job;\n\t\treturn 0;\n\t}\n};\n\n#define NUM_JOBS 10\n\nint main(){\n\tint jobs[NUM_JOBS];\n\tWorkerPool<MyWorker, int*> tp(\"test\");\n\ttp.start(3);\n\t\n\tlog_debug(\"add begin\");\n\tfor(int i=0; i<NUM_JOBS; i++){\n\t\t//usleep(200 * 1000);\n\t\tlog_debug(\"    add job: %d\", i);\n\t\tjobs[i] = i;\n\t\ttp.push(&jobs[i]);\n\t}\n\tlog_debug(\"add end\");\n\t\n\tlog_debug(\"pop begin\");\n\tfor(int i=0; i<NUM_JOBS-1; i++){\n\t\tint *job;\n\t\ttp.pop(&job);\n\t\tlog_debug(\"    result: %d, %d\", i, *job);\n\t}\n\tlog_debug(\"pop end\");\n\t\n\tlog_debug(\"stopping...\");\n\ttp.stop();\n\tlog_debug(\"stopped\");\n\n\treturn 0;\n}\n#endif\n\n#endif\n\n\n"
  },
  {
    "path": "src/version.h",
    "content": "#ifndef SSDB_DEPS_H\n#ifndef SSDB_VERSION\n#define SSDB_VERSION \"1.9.8\"\n#endif\n#endif\n#ifndef IOS\n#include <stdlib.h>\n#include <jemalloc/jemalloc.h>\n#endif\n"
  },
  {
    "path": "ssdb.conf",
    "content": "# ssdb-server config\n# MUST indent by TAB!\n\n# absolute path, or relative to path of this file, directory must exists\nwork_dir = ./var\npidfile = ./var/ssdb.pid\n\nserver:\n\t# specify an ipv6 address to enable ipv6 support\n\t# ip: ::1\n\tip: 127.0.0.1\n\tport: 8888\n\t# bind to public ip\n\t#ip: 0.0.0.0\n\t# format: allow|deny: all|ip_prefix\n\t# multiple allows or denys is supported\n\t#deny: all\n\t#allow: 127.0.0.1\n\t#allow: 192.168\n\t# auth password must be at least 32 characters\n\t#auth: very-strong-password\n\t#readonly: yes\n\t# in ms, to log slowlog with WARN level\n\t#slowlog_timeout: 5\n\nreplication:\n\tbinlog: yes\n\t# Limit sync speed to *MB/s, -1: no limit\n\tsync_speed: -1\n\tslaveof:\n\t\t# to identify a master even if it moved(ip, port changed)\n\t\t# if set to empty or not defined, ip:port will be used.\n\t\t#id: svc_2\n\t\t# sync|mirror, default is sync\n\t\t#type: sync\n\t\t#host: localhost\n\t\t#port: 8889\n\nlogger:\n\tlevel: debug\n\toutput: log.txt\n\trotate:\n\t\tsize: 1000000000\n\nleveldb:\n\t# in MB\n\tcache_size: 500\n\t# in MB\n\twrite_buffer_size: 64\n\t# in MB/s\n\tcompaction_speed: 1000\n\t# yes|no\n\tcompression: yes\n\n\n"
  },
  {
    "path": "ssdb_slave.conf",
    "content": "# ssdb-server config for slave\n# MUST indent by TAB!\n\n# relative to path of this file, directory must exists\nwork_dir = ./var_slave\npidfile = ./var_slave/ssdb.pid\n\nserver:\n\tip: 127.0.0.1\n\tport: 8889\n\t#readonly: yes\n\nreplication:\n\tbinlog: yes\n\t# Limit sync speed to *MB/s, -1: no limit\n\tsync_speed: -1\n\tslaveof:\n\t\t# to identify a master even if it moved(ip, port changed)\n\t\t# if set to empty or not defined, \"ip|port\" will be used (e.g. \"10.0.0.1|8888\").\n\t\tid: svc_1\n\t\t# sync|mirror, default is sync\n\t\ttype: sync\n\t\thost: localhost\n\t\tport: 8888\n\t\t#auth: password\n\nlogger:\n\tlevel: debug\n\toutput: log_slave.txt\n\trotate:\n\t\tsize: 1000000000\n\nleveldb:\n\t# in MB\n\tcache_size: 500\n\t# in MB\n\twrite_buffer_size: 64\n\t# in MB/s\n\tcompaction_speed: 1000\n\t# yes|no\n\tcompression: yes\n\n\n"
  },
  {
    "path": "tools/Makefile",
    "content": "include ../build_config.mk\n\nOBJS += ../src/net/link.o ../src/net/link_addr.o ../src/net/fde.o \\\n\t../src/util/log.o ../src/util/bytes.o\nCFLAGS += -I../src\nEXES = ssdb-bench ssdb-dump ssdb-repair leveldb-import\n\nall: ssdb-bench.o ssdb-dump.o ssdb-repair.o leveldb-import.o ssdb-migrate.o\n\t${CXX} -o ssdb-bench ssdb-bench.o ${OBJS} ${UTIL_OBJS} ${CLIBS}\n\t${CXX} -o ssdb-dump ssdb-dump.o ${OBJS} ${UTIL_OBJS} ${CLIBS}\n\t${CXX} -o ssdb-repair ssdb-repair.o ${OBJS} ${UTIL_OBJS} ${CLIBS}\n\t${CXX} -o leveldb-import leveldb-import.o ${OBJS} ${UTIL_OBJS} ${CLIBS}\n\t${CXX} -o ssdb-migrate ssdb-migrate.o ../api/cpp/libssdb-client.a ../src/util/libutil.a\n\nssdb-migrate.o: ssdb-migrate.cpp\n\t${CXX} ${CFLAGS} -I../api/cpp -c ssdb-migrate.cpp\nssdb-bench.o: ssdb-bench.cpp\n\t${CXX} ${CFLAGS} -c ssdb-bench.cpp\nssdb-dump.o: ssdb-dump.cpp\n\t${CXX} ${CFLAGS} -c ssdb-dump.cpp\nssdb-repair.o: ssdb-repair.cpp\n\t${CXX} ${CFLAGS} -c ssdb-repair.cpp\nleveldb-import.o: leveldb-import.cpp\n\t${CXX} ${CFLAGS} -c leveldb-import.cpp\n\nclean:\n\trm -f *.exe *.exe.stackdump *.o ${EXES}\n\trm -rf _cpy_\n\n"
  },
  {
    "path": "tools/leveldb-import.cpp",
    "content": "/*\nCopyright (c) 2012-2015 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"include.h\"\n\n#include <string>\n#include <vector>\n\n#include \"leveldb/db.h\"\n#include \"leveldb/options.h\"\n#include \"leveldb/slice.h\"\n#include \"leveldb/iterator.h\"\n\n#include \"net/link.h\"\n#include \"util/log.h\"\n#include \"util/file.h\"\n#include \"util/string_util.h\"\n\nvoid welcome(){\n\tprintf(\"leveldb-import - Import existing leveldb into ssdb\\n\");\n\tprintf(\"Copyright (c) 2013-2015 ssdb.io\\n\");\n\tprintf(\"\\n\");\n}\n\nvoid usage(int argc, char **argv){\n\tprintf(\"Usage:\\n\");\n\tprintf(\"    %s ip port input_folder\\n\", argv[0]);\n\tprintf(\"\\n\");\n\tprintf(\"Options:\\n\");\n\tprintf(\"    ip - ssdb server ip address\\n\");\n\tprintf(\"    port - ssdb server port number\\n\");\n\tprintf(\"    input_folder - local leveldb folder\\n\");\n}\n\nint main(int argc, char **argv){\n\twelcome();\n\n\tset_log_level(Logger::LEVEL_MIN);\n\n\tif(argc <= 3){\n\t\tusage(argc, argv);\n\t\treturn 0;\n\t}\n\tchar *ip = argv[1];\n\tint port = atoi(argv[2]);\n\tchar *input_folder = argv[3];\n\n\tif(!file_exists(input_folder)){\n\t\tprintf(\"input_folder[%s] not exists!\\n\", input_folder);\n\t\treturn 0;\n\t}\n\n\tstd::string data_dir = \"\";\n\tdata_dir.append(input_folder);\n\n\t// connect to server\n\tLink *link = Link::connect(ip, port);\n\tif(link == NULL){\n\t\tprintf(\"error connecting to server!\\n\");\n\t\treturn 0;\n\t}\n\n\tleveldb::DB* db;\n\tleveldb::Options options;\n\tleveldb::Status status;\n\t//options.create_if_missing = true;\n\tstatus = leveldb::DB::Open(options, data_dir.c_str(), &db);\n\tif(!status.ok()){\n\t\tprintf(\"open leveldb: %s error!\\n\", input_folder);\n\t\treturn 0;\n\t}\n\n\tprintf(\"importing data...\\n\");\n\tleveldb::Iterator *it;\n\tit = db->NewIterator(leveldb::ReadOptions());\n\tint save_count = 0;\n\tfor(it->SeekToFirst(); it->Valid(); it->Next()){\n\t\tstd::string key = it->key().ToString();\n\t\tstd::string val = it->value().ToString();\n\t\t\n\t\tconst std::vector<Bytes> *req = link->request(\"set\", key, val);\n\t\tif(req == NULL){\n\t\t\tprintf(\"error\\n\");\n\t\t\texit(0);\n\t\t}else{\n\t\t\tif(req->at(0) != \"ok\"){\n\t\t\t\tprintf(\"server response error: %s\\n\", req->at(0).String().c_str());\n\t\t\t\texit(0);\n\t\t\t}\n\t\t}\n\t\tsave_count ++;\n\t}\n\tprintf(\"importing done.\\n\");\n\tprintf(\"\\n\");\n\tprintf(\"total %d item(s) imported.\\n\", save_count);\n\n\tdelete link;\n\tdelete db;\n\treturn 0;\n}\n"
  },
  {
    "path": "tools/redis-import.php",
    "content": "<?php\n/**\n * Copyright (c) 2014, ideawu\n * All rights reserved.\n * @author: ideawu\n * @link: http://www.ideawu.com/\n *\n * PHP script for importing Redis data into SSDB.\n */\n\nfunction usage(){\n\tglobal $argv;\n\techo \"Usage:\\n\";\n\techo \"    php {$argv[0]} redis_host redis_port redis_db ssdb_host ssdb_port\\n\";\n\techo \"\\n\";\n}\n\nif(count($argv) != 6){\n\tusage();\n\tdie();\n}\n\necho \"This script will only copy entries with types in (STRING, HASH, ZSET, LIST)\\n\";\necho \"ZSET scores are converted to intergers from floating numbers.\\n\";\necho \"Do you want to continue? [y/n](y) \";\n$line = fgets(STDIN);\n$line = trim($line);\nif($line == 'n' || $line == 'N'){\n\techo \"Operation cancelled\\n\";\n\tdie();\n}\n\n$r_host = $argv[1];\n$r_port = $argv[2];\n$r_db   = $argv[3];\n$s_host = $argv[4];\n$s_port = $argv[5];\n\n$redis = new Redis();\n$ret = $redis->connect($r_host, $r_port);\nif($ret === false){\n\techo \"ERROR: could not connect to Redis server!\\n\";\n\tdie();\n}\n// $redis->auth('password');\n$redis->select($r_db);\n\n$ssdb = new Redis();\n$ret = $ssdb->connect($s_host, $s_port);\nif($ret === false){\n\techo \"ERROR: could not connect to SSDB server!\\n\";\n\tdie();\n}\n\n\necho \"\\nCopying data from Redis($r_host:{$r_port}[$r_db]) to SSDB($s_host, $s_port)...\\n\";\nif(scan_command_available()){\n\techo \"Using SCAN.\\n\";\n}else{\n\techo \"Using KEYS.\\n\";\n}\n\n\n$count = 0;\n$total = 0;\n$entries = 0;\n\necho \"==============\\n\";\n// check if phpredis and redis-server supports SCAN\nif(scan_command_available()){\n\t$total = $redis->dbsize();\n\t$it = NULL;\n\t$redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);\n\twhile($keys = $redis->scan($it)){\n\t\tcopy_keys($keys);\n\t}\n}else{\n\t$keys = $redis->keys('*');\n\t$total = count($keys);\n\tcopy_keys($keys);\n}\necho date('Y-m-d H:i:s') . \" $total keys, $entries entries copied.\\n\";\necho \"==============\\n\";\necho \"Done.\\n\";\necho \"\\n\";\n\n\nfunction copy_keys($keys){\n\tglobal $redis, $ssdb, $count, $total, $entries;\n\n\tforeach($keys as $key){\n\t\tcopy_key($key);\n\t\tif(++$count % 100 == 1){\n\t\t\techo date('Y-m-d H:i:s') . \" $count/$total entries: $entries\\n\";\n\t\t}\n\t}\n}\n\nfunction copy_key($key){\n\tglobal $redis, $ssdb, $count, $total, $entries;\n\n\t$type = $redis->type($key);\n\tswitch($type){\n\t\tcase Redis::REDIS_STRING:\n\t\t\t$val = $redis->get($key);\n\t\t\t$ssdb->set($key, $val);\n\t\t\t$entries ++;\n\t\t\tbreak;\n\t\tcase Redis::REDIS_LIST:\n\t\t\t$list = $redis->lRange($key, 0, -1);\n\t\t\tforeach($list as $val){\n\t\t\t\t$ssdb->rPush($key, $val);\n\t\t\t\t$entries ++;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase Redis::REDIS_HASH:\n\t\t\t$hash = $redis->hGetAll($key);\n\t\t\tforeach($hash as $k=>$v){\n\t\t\t\t$ssdb->hset($key, $k, $v);\n\t\t\t\t$entries ++;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase Redis::REDIS_ZSET:\n\t\t\t$zset = $redis->zRange($key, 0, -1, true);\n\t\t\tforeach($zset as $val=>$score){\n\t\t\t\t$ssdb->zAdd($key, $score, $val);\n\t\t\t\t$entries ++;\n\t\t\t}\n\t\t\tbreak;\n\t}\n}\n\nfunction scan_command_available(){\n\tglobal $redis;\n\n\tif(method_exists($redis, 'scan')){\n\t\t$info = $redis->info();\n\t\t$redis_version = $info['redis_version'];\n\t\t$ps = explode('.', $redis_version);\n\t\tif(count($ps) > 2){\n\t\t\t$n = $ps[0] * 10 + $ps[1];\n\t\t\tif($n >= 28){\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n\n"
  },
  {
    "path": "tools/ssdb-bench.cpp",
    "content": "/*\nCopyright (c) 2012-2015 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <errno.h>\n#include <string>\n#include <vector>\n#include <map>\n#include \"net/link.h\"\n#include \"net/fde.h\"\n#include \"util/log.h\"\n#include \"version.h\"\n\n#include \"../src/include.h\"\n\nstruct Data\n{\n\tstd::string key;\n\tstd::string val;\n\tstd::string num;\n};\n\nstd::map<std::string, Data *> *ds;\nFdevents *fdes;\nstd::vector<Link *> *free_links;\n\n\nvoid welcome(){\n\tprintf(\"ssdb-bench - SSDB benchmark tool, %s\\n\", SSDB_VERSION);\n\tprintf(\"Copyright (c) 2013-2015 ssdb.io\\n\");\n\tprintf(\"\\n\");\n}\n\nvoid usage(int argc, char **argv){\n\tprintf(\"Usage:\\n\");\n\tprintf(\"    %s [ip] [port] [requests] [clients]\\n\", argv[0]);\n\tprintf(\"\\n\");\n\tprintf(\"Options:\\n\");\n\tprintf(\"    ip          server ip (default 127.0.0.1)\\n\");\n\tprintf(\"    port        server port (default 8888)\\n\");\n\tprintf(\"    requests    Total number of requests (default 10000)\\n\");\n\tprintf(\"    clients     Number of parallel connections (default 50)\\n\");\n\tprintf(\"\\n\");\n}\n\nvoid init_data(int num){\n\tsrand(time(NULL));\n\tds = new std::map<std::string, Data *>();\n\twhile(ds->size() < num){\n\t\tData *d = new Data();\n\t\tchar buf[1024];\n\n\t\tint n = rand();\n\t\tsnprintf(buf, sizeof(buf), \"%d\", n);\n\t\td->num = buf;\n\t\tsnprintf(buf, sizeof(buf), \"k%010d\", n);\n\t\td->key = buf;\n\t\tsnprintf(buf, sizeof(buf), \"v%0100d\", n);\n\t\td->val = buf;\n\t\tds->insert(make_pair(d->key, d));\n\t}\n}\n\nvoid init_links(int num, const char *ip, int port){\n\tfdes = new Fdevents();\n\tfree_links = new std::vector<Link *>();\n\n\tfor(int i=0; i<num; i++){\n\t\tLink *link = Link::connect(ip, port);\n\t\tif(!link){\n\t\t\tfprintf(stderr, \"connect error! %s\\n\", strerror(errno));\n\t\t\texit(0);\n\t\t}\n\t\tfdes->set(link->fd(), FDEVENT_IN, 0, link);\n\t\tfree_links->push_back(link);\n\t}\n}\n\nvoid send_req(Link *link, const std::string &cmd, const Data *d){\n\tif(cmd == \"set\"){\n\t\tlink->send(cmd, d->key, d->val);\n\t}else if(cmd == \"get\"){\n\t\tlink->send(cmd, d->key);\n\t}else if(cmd == \"del\"){\n\t\tlink->send(cmd, d->key);\n\t}else if(cmd == \"hset\"){\n\t\tlink->send(cmd, \"TEST\", d->key, d->val);\n\t}else if(cmd == \"hget\"){\n\t\tlink->send(cmd, \"TEST\", d->key);\n\t}else if(cmd == \"hdel\"){\n\t\tlink->send(cmd, \"TEST\", d->key);\n\t}else if(cmd == \"zset\"){\n\t\tlink->send(cmd, \"TEST\", d->key, d->num);\n\t}else if(cmd == \"zget\"){\n\t\tlink->send(cmd, \"TEST\", d->key);\n\t}else if(cmd == \"zdel\"){\n\t\tlink->send(cmd, \"TEST\", d->key);\n\t}else if(cmd == \"qpush\"){\n\t\tlink->send(cmd, \"TEST\", d->key);\n\t}else if(cmd == \"qpop\"){\n\t\tlink->send(cmd, \"TEST\");\n\t}else{\n\t\tlog_error(\"bad command!\");\n\t\texit(0);\n\t}\n\tlink->flush();\n}\n\nvoid bench(std::string cmd){\n\tint total = (int)ds->size();\n\tint finished = 0;\n\tint num_sent = 0;\n\t\n\tprintf(\"========== %s ==========\\n\", cmd.c_str());\n\n\tstd::map<std::string, Data *>::iterator it;\n\tit = ds->begin();\n\t\n\tdouble stime = microtime();\n\twhile(1){\n\t\twhile(!free_links->empty()){\n\t\t\tif(num_sent == total){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tnum_sent ++;\n\n\t\t\tLink *link = free_links->back();\n\t\t\tfree_links->pop_back();\n\t\t\t\n\t\t\tsend_req(link, cmd, it->second);\n\t\t\tit ++;\n\t\t}\n\n\t\tconst Fdevents::events_t *events;\n\t\tevents = fdes->wait(50);\n\t\tif(events == NULL){\n\t\t\tlog_error(\"events.wait error: %s\", strerror(errno));\n\t\t\tbreak;\n\t\t}\n\n\t\tfor(int i=0; i<(int)events->size(); i++){\n\t\t\tconst Fdevent *fde = events->at(i);\n\t\t\tLink *link = (Link *)fde->data.ptr;\n\n\t\t\tint len = link->read();\n\t\t\tif(len <= 0){\n\t\t\t\tlog_error(\"fd: %d, read: %d, delete link\", link->fd(), len);\n\t\t\t\texit(0);\n\t\t\t}\n\n\t\t\tconst std::vector<Bytes> *resp = link->recv();\n\t\t\tif(resp == NULL){\n\t\t\t\tlog_error(\"error\");\n\t\t\t\tbreak;\n\t\t\t}else if(resp->empty()){\n\t\t\t\tcontinue;\n\t\t\t}else{\n\t\t\t\tif(resp->at(0) != \"ok\"){\n\t\t\t\t\tlog_error(\"bad response: %s\", resp->at(0).String().c_str());\n\t\t\t\t\texit(0);\n\t\t\t\t}\n\t\t\t\tfree_links->push_back(link);\n\t\t\t\tfinished ++;\n\t\t\t\tif(finished == total){\n\t\t\t\t\tdouble etime = microtime();\n\t\t\t\t\tdouble ts = (stime == etime)? 1 : (etime - stime);\n\t\t\t\t\tdouble speed = total / ts;\n\t\t\t\t\tprintf(\"qps: %d, time: %.3f s\\n\", (int)speed, ts);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nint main(int argc, char **argv){\n\tconst char *ip = \"127.0.0.1\";\n\tint port = 8888;\n\tint requests = 10000;\n\tint clients = 50;\n\n\twelcome();\n\tusage(argc, argv);\n\tfor(int i=1; i<argc; i++){\n\t\tif(strcmp(\"-v\", argv[i]) == 0){\n\t\t\texit(0);\n\t\t}\n\t}\n\tif(argc > 1){\n\t\tip = argv[1];\n\t}\n\tif(argc > 2){\n\t\tport = atoi(argv[2]);\n\t}\n\tif(argc > 3){\n\t\trequests = atoi(argv[3]);\n\t}\n\tif(argc > 4){\n\t\tclients = atoi(argv[4]);\n\t}\n\n\t//printf(\"preparing data...\\n\");\n\tinit_data(requests);\n\t//printf(\"preparing links...\\n\");\n\tinit_links(clients, ip, port);\n\n\tbench(\"set\");\n\tbench(\"get\");\n\tbench(\"del\");\n\n\tbench(\"hset\");\n\tbench(\"hget\");\n\tbench(\"hdel\");\n\n\tbench(\"zset\");\n\tbench(\"zget\");\n\tbench(\"zdel\");\n\n\tbench(\"qpush\");\n\tbench(\"qpop\");\n\t\n\tprintf(\"\\n\");\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "tools/ssdb-cli",
    "content": "#!/bin/sh\nDIR=`S=\\`readlink \"$0\"\\`; [ -z \"$S\" ] && S=$0; dirname $S`\n\nif [ -e $DIR/../deps/cpy/cpy ]; then\n\tCPY=$DIR/../deps/cpy/cpy\nelse\n\tCPY=$DIR/deps/cpy/cpy\nfi\n\n$CPY $DIR/ssdb-cli.cpy $@\n"
  },
  {
    "path": "tools/ssdb-cli.bat",
    "content": "@echo off\n%~dp0..\\deps\\cpy\\cpy.bat %~dp0\\ssdb-cli.cpy %1 %2 %3 %4 %5 %6 %7 %8 %9\n"
  },
  {
    "path": "tools/ssdb-cli.cpy",
    "content": "import thread, re, time, socket;\nimport getopt, shlex;\nimport datetime;\nimport ssdb_cli.*;\nsys.path.append('./api/python');\nsys.path.append('../api/python');\nsys.path.append('/usr/local/ssdb/api/python');\nimport SSDB.*;\n\nfunction save_cli_history(histfile){\n\treadline.set_history_length(1000);\n\treadline.write_history_file(histfile);\n\tsys.stderr.write('\\n');\n}\n\ntry{\n\timport readline;\n\timport atexit;\n\thistfile = os.path.expanduser('~/.ssdb-cli_history');\n\tif(os.path.isfile(histfile)){\n\t\treadline.read_history_file(histfile);\n\t}\n\tatexit.register(save_cli_history, histfile);\n}catch(Exception e){\n\tsys.stderr.write('readline: ' + str(e) + '\\n');\n}\n\nescape_data = false;\n\nfunction welcome(){\n\tsys.stderr.write('ssdb (cli) - ssdb command line tool.\\n');\n\tsys.stderr.write('Copyright (c) 2012-2016 ssdb.io\\n');\n\tsys.stderr.write('\\n');\n\tsys.stderr.write(\"'h' or 'help' for help, 'q' to quit.\\n\");\n\tsys.stderr.write('\\n');\n}\n\nfunction show_command_help(){\n\tprint '';\n\tprint '# display ssdb-server status';\n\tprint '\tinfo';\n\tprint '# escape/do not escape response data';\n\tprint '\t: escape yes|no';\n\tprint '# export/import';\n\tprint '\texport [-i] out_file';\n\tprint '\t\t-i\tinteractive mode';\n\tprint '\timport in_file';\n\tprint '';\n\tprint 'see http://ssdb.io/docs/php/ for commands details';\n\tprint '';\n\tprint 'press \\'q\\' and Enter to quit.';\n\tprint '';\n}\n\nfunction usage(){\n\tprint 'Usage:';\n\tprint '        ssdb-cli [-h] <host> [-p] <port>';\n\tprint '';\n\tprint 'Options:';\n\tprint '  -h <host>      ssdb server hostname/ip address (default: 127.0.0.1)';\n\tprint '  -p <port>      ssdb server port (default: 8888)';\n\tprint '  -a <password>  Password to use when connecting to the server';\n\tprint '  -v             Show this message';\n\tprint '  --help         Show this message';\n\tprint '';\n\tprint '  -n <opt>       Choose nagios probe';\n\tprint '                 opt: info, dbsize, replication, write_read';\n\tprint '  -w <INT>       Set nagios WARN level';\n\tprint '  -c <INT>       Set nagios CRITICAL level';\n\tprint '';\n\tprint 'Examples:';\n\tprint '  ssdb-cli';\n\tprint '  ssdb-cli 8888';\n\tprint '  ssdb-cli 127.0.0.1 8888';\n\tprint '  ssdb-cli -h 127.0.0.1 -p 8888';\n\tprint '  ssdb-cli -h 127.0.0.1 -p 8888 -a xxxpasswordxxx';\n}\n\nfunction repr_data(s){\n\ts = str(s);\n\tgs = globals();\n\tif(gs['escape_data'] == false){\n\t\treturn s;\n\t}\n\tret = s.encode('string-escape');\n\treturn ret;\n}\n\nfunction timespan(stime){\n\tetime = datetime.datetime.now();\n\tts = etime - stime;\n\ttime_consume = ts.seconds + ts.microseconds/1000000.;\n\treturn time_consume;\n}\n\nhost = '';\nport = '';\nopt = '';\nargs = [];\nrun_nagios = false;\npassword = false;\n\nforeach(sys.argv[1 ..] as arg){\n\tif(opt == '' && arg.startswith('-')){\n\t\topt = arg;\n\t\tif(arg == '--help' || arg == '--h' || arg == '-v'){\n\t\t\tusage();\n\t\t\texit(0);\n\t\t}\n\t}else{\n\t\tswitch(opt){\n\t\t\tcase '-h':\n\t\t\t\thost = arg;\n\t\t\t\topt = '';\n\t\t\t\tbreak;\n\t\t\tcase '-p':\n\t\t\t\tport = arg;\n\t\t\t\topt = '';\n\t\t\t\tbreak;\n\t\t\tcase '-a':\n\t\t\t\tpassword = arg;\n\t\t\t\topt = '';\n\t\t\t\tbreak;\n\t\t\t// nagios\n\t\t\tcase '-n':\n\t\t\tcase '-w':\n\t\t\tcase '-c':\n\t\t\t\trun_nagios = true;\n\t\t\t\topt = '';\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\targs.append(arg);\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\nif(host == ''){\n\thost = '127.0.0.1';\n\tforeach(args as arg){\n\t\tif(!re.match('^[0-9]+$', arg)){\n\t\t\thost = arg;\n\t\t\tbreak;\n\t\t}\n\t}\n}\nif(port == ''){\n\tport = '8888';\n\tforeach(args as arg){\n\t\tif(re.match('^[0-9]+$', arg)){\n\t\t\tport = arg;\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\ntry{\n\tport = int(port);\n}catch(Exception e){\n\tsys.stderr.write(sprintf('Invalid argument port: ', port));\n\tusage();\n\tsys.exit(0);\n}\n\ntry{\n\tlink = new SSDB(host, port);\n}catch(socket.error e){\n\tsys.stderr.write(sprintf('Failed to connect to: %s:%d\\n', host, port));\n\tsys.stderr.write(sprintf('Connection error: %s\\n', str(e)));\n\tif(run_nagios){\n\t\tsys.stdout.write(sprintf('CRITICAL: Failed to connect\\n'));\n\t\tsys.exit(2);\n\t} else {\n\t\tsys.exit(0);\n\t}\n}\n\nif(run_nagios){\n\tnagios.run(link, sys.argv[1 ..]);\n\texit(0);\n}\nif(password){\n\tresp = link.request('auth', [password]);\t\n}\n\nwelcome();\nif(sys.stdin.isatty()){\n\tutil.show_version(link);\n}\n\n\nfunction request_with_retry(cmd, args=null){\n\tgs = globals();\n\tlink = gs['link'];\n\tpassword = gs['password'];\n\t\n\tif(!args){\n\t\targs = [];\n\t}\n\t\n\tretry = 0;\n\tmax_retry = 5;\n\twhile(true){\n\t\tresp = link.request(cmd, args);\n\t\tif(resp.code == 'disconnected'){\n\t\t\tlink.close();\n\t\t\tsleep = retry;\n\t\t\tif(sleep > 3){\n\t\t\t\tsleep = 3;\n\t\t\t}\n\t\t\ttime.sleep(sleep);\n\t\t\tretry ++;\n\t\t\tif(retry > max_retry){\n\t\t\t\tsys.stderr.write('cannot connect to server, give up...\\n');\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tsys.stderr.write(sprintf('[%d/%d] reconnecting to server... ', retry, max_retry));\n\t\t\ttry{\n\t\t\t\tlink = new SSDB(host, port);\n\t\t\t\tgs['link'] = link;\n\t\t\t\tsys.stderr.write('done.\\n');\n\t\t\t}catch(socket.error e){\n\t\t\t\tsys.stderr.write(sprintf('Connect error: %s\\n', str(e)));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif(password){\n\t\t\t\tret = link.request('auth', [password]);\n\t\t\t}\n\t\t}else{\n\t\t\treturn resp;\n\t\t}\n\t}\n\treturn null;\n}\n\nwhile(true){\n\tline = '';\n\tc = sprintf('ssdb %s:%s> ', host, str(port));\n\tb = sys.stdout;\n\tsys.stdout = sys.stderr;\n\ttry{\n\t\tline = raw_input(c);\n\t}catch(Exception e){\n\t\tbreak;\n\t}\n\tsys.stdout = b;\n\t\n\tif(line == ''){\n\t\tcontinue;\n\t}\n\tline = line.strip();\n\tif(line == 'q' || line == 'quit'){\n\t\tsys.stderr.write('bye.\\n');\n\t\tbreak;\n\t}\n\tif(line == 'h' || line == 'help'){\n\t\tshow_command_help();\n\t\tcontinue;\n\t}\n\n\ttry{\n\t\tps = shlex.split(line);\n\t}catch(Exception e){\n\t\tsys.stderr.write(sprintf('error: %s\\n', str(e)));\n\t\tcontinue;\n\t}\n\tif(len(ps) == 0){\n\t\tcontinue;\n\t}\n\n\tfor(i=0; i<len(ps); i++){\n\t\tps[i] = ps[i].decode('string-escape');\n\t}\n\t\n\tcmd = ps[0].lower();\n\tif(cmd.startswith(':')){\n\t\tps[0] = cmd[1 ..];\n\t\tcmd = ':';\n\t\targs = ps;\n\t}else{\n\t\targs = ps[1 .. ];\n\t}\n\tif(cmd == ':'){\n\t\top = '';\n\t\tif(len(args) > 0){\n\t\t\top = args[0];\n\t\t}\n\t\tif(op != 'escape'){\n\t\t\tsys.stderr.write(\"Bad setting!\\n\");\n\t\t\tcontinue;\n\t\t}\n\t\tyn = 'yes';\n\t\tif(len(args) > 1){\n\t\t\tyn = args[1];\n\t\t}\n\t\tgs = globals();\n\t\tif(yn == 'yes'){\n\t\t\tgs['escape_data'] = true;\n\t\t\tsys.stderr.write(\"  Escape response\\n\");\n\t\t}else if(yn == 'no' || yn == 'none'){\n\t\t\tgs['escape_data'] = false;\n\t\t\tsys.stderr.write(\"  No escape response\\n\");\n\t\t}else{\n\t\t\tsys.stderr.write(\"  Usage: escape yes|no\\n\");\n\t\t}\n\t\tcontinue;\n\t}\n\tif(cmd == 'v'){\n\t\tutil.show_version(link);\n\t\tcontinue;\n\t}\n\tif(cmd == 'auth'){\n\t\tif(len(args) == 0){\n\t\t\tsys.stderr.write('Usage: auth password\\n');\n\t\t\tcontinue;\n\t\t}\n\t\tpassword = args[0];\n\t}\n\tif(cmd == 'export'){\n\t\texporter.run(link, args);\n\t\tcontinue;\n\t}\n\tif(cmd == 'import'){\n\t\tif(len(args) < 1){\n\t\t\tsys.stderr.write('Usage: import in_file\\n');\n\t\t\tcontinue;\n\t\t}\n\t\tfilename = args[0];\n\t\timporter.run(link, filename);\n\t\tcontinue;\n\t}\n\t\n\ttry{\n\t\tif(cmd == 'flushdb'){\n\t\t\tresp = request_with_retry('ping');\n\t\t\tif(!resp){\n\t\t\t\tthrow new Exception('error');\n\t\t\t}\n\t\t\tif(resp.code != 'ok'){\n\t\t\t\tthrow new Exception(resp.message);\n\t\t\t}\n\t\t\t\n\t\t\tstime = datetime.datetime.now();\n\t\t\tif(len(args) == 0){\n\t\t\t\tflushdb.flushdb(link, '');\n\t\t\t}else{\n\t\t\t\tflushdb.flushdb(link, args[0]);\n\t\t\t}\n\t\t\tsys.stderr.write(sprintf('(%.3f sec)\\n', timespan(stime)));\n\t\t\tcontinue;\n\t\t}\n\t}catch(Exception e){\n\t\tsys.stderr.write(\"error! - \" + str(e) + \"\\n\");\n\t\tcontinue;\n\t}\n\n\tstime = datetime.datetime.now();\n\tresp = request_with_retry(cmd, args);\n\tif(resp == null){\n\t\tsys.stderr.write(\"error!\\n\");\n\t\tcontinue;\n\t}\n\n\ttime_consume = timespan(stime);\n\n\tif(!resp.ok()){\n\t\tif(resp.not_found()){\n\t\t\tsys.stderr.write('not_found\\n');\n\t\t}else{\n\t\t\ts = resp.code;\n\t\t\tif(resp.message){\n\t\t\t\ts += ': ' + str(resp.message);\n\t\t\t}\n\t\t\tsys.stderr.write(str(s) + '\\n');\n\t\t}\n\t\tsys.stderr.write(sprintf('(%.3f sec)\\n', time_consume));\n\t}else{\n\t\tskip = false;\n\t\tswitch(cmd){\n\t\t\tcase 'ping':\n\t\t\tcase 'qset':\n\t\t\tcase 'compact':\n\t\t\tcase 'auth':\n\t\t\tcase 'set':\n\t\t\tcase 'setx':\n\t\t\tcase 'zset':\n\t\t\tcase 'hset':\n\t\t\tcase 'del':\n\t\t\tcase 'zdel':\n\t\t\tcase 'add_allow_ip':\n\t\t\tcase 'del_allow_ip':\n\t\t\tcase 'add_deny_ip':\n\t\t\tcase 'del_deny_ip':\n\t\t\t\tskip = true;\n\t\t\t\tprintf(str(resp.code) + '\\n');\n\t\t\t\tbreak;\n\t\t\tcase 'info':\n\t\t\t\tskip = true;\n\t\t\t\tis_val = false;\n\t\t\t\tfor(i=1; i<len(resp.data); i++){\n\t\t\t\t\ts = resp.data[i];\n\t\t\t\t\tif(is_val){\n\t\t\t\t\t\ts = '\t' + s.replace('\\n', '\\n\t');\n\t\t\t\t\t}\n\t\t\t\t\tprint s;\n\t\t\t\t\tis_val = !is_val;\n\t\t\t\t}\n\t\t\t\tsys.stderr.write(sprintf('%d result(s) (%.3f sec)\\n', len(resp.data), time_consume));\n\t\t\t\tbreak;\n\t\t}\n\t\tif(skip){\n\t\t\tsys.stderr.write(sprintf('(%.3f sec)\\n', time_consume));\n\t\t\tcontinue;\n\t\t}\n\n\t\tswitch(resp.type){\n\t\t\tcase 'none':\n\t\t\t\tprintf(repr_data(resp.data) + '\\n');\n\t\t\t\tbreak;\n\t\t\tcase 'val':\n\t\t\t\tif(resp.code == 'ok'){\n\t\t\t\t\tprintf(repr_data(resp.data) + '\\n');\n\t\t\t\t}else{\n\t\t\t\t\tif(resp.data){\n\t\t\t\t\t\tprint repr_data(resp.code), repr_data(resp.data);\n\t\t\t\t\t}else{\n\t\t\t\t\t\tprint repr_data(resp.code);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'list':\n\t\t\t\tsys.stderr.write(sprintf('  %15s\\n', 'key'));\n\t\t\t\tsys.stderr.write('-' * 17 + '\\n');\n\t\t\t\tforeach(resp.data as k){\n\t\t\t\t\tprintf('  %15s\\n', repr_data(k));\n\t\t\t\t}\n\t\t\t\tsys.stderr.write(sprintf('%d result(s) (%.3f sec)\\n', len(resp.data), time_consume));\n\t\t\t\tbreak;\n\t\t\tcase 'map':\n\t\t\t\tsys.stderr.write(sprintf('%-15s %s\\n', 'key', 'value'));\n\t\t\t\tsys.stderr.write('-' * 25 + '\\n');\n\t\t\t\tforeach(resp.data['index'] as k){\n\t\t\t\t\tv = resp.data['items'][k];\n\t\t\t\t\tprintf('  %-15s: %s\\n', repr_data(k), repr_data(v));\n\t\t\t\t}\n\t\t\t\tsys.stderr.write(sprintf('%d result(s) (%.3f sec)\\n', len(resp.data['index']), time_consume));\n\t\t\t\tbreak;\n\t\t}\n\t\tsys.stderr.write(sprintf('(%.3f sec)\\n', time_consume));\n\t}\n}\n\n"
  },
  {
    "path": "tools/ssdb-dump.cpp",
    "content": "/*\nCopyright (c) 2012-2015 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"include.h\"\n#include <sys/types.h>\n#include <sys/stat.h>\n\n#include <string>\n#include <vector>\n\n#include \"leveldb/db.h\"\n#include \"leveldb/options.h\"\n#include \"leveldb/slice.h\"\n#include \"leveldb/iterator.h\"\n\n#include \"include.h\"\n#include \"ssdb/const.h\"\n#include \"net/link.h\"\n#include \"util/log.h\"\n#include \"util/file.h\"\n#include \"util/string_util.h\"\n\nstruct Config {\n\tstd::string ip;\n\tint port;\n\tbool hasauth;\n\tstd::string auth;\n\tstd::string output_folder;\n};\n\ntemplate<class T>\nstatic std::string serialize_req(T &req){\n\tstd::string ret;\n\tchar buf[50];\n\tfor(int i=0; i<req.size(); i++){\n\t\tif(i >= 5 && i < req.size() - 1){\n\t\t\tsprintf(buf, \"[%d more...]\", (int)req.size() - i - 1);\n\t\t\tret.append(buf);\n\t\t\tbreak;\n\t\t}\n\t\tif(((req[0] == \"get\" || req[0] == \"set\") && i == 1) || req[i].size() < 30){\n\t\t\tstd::string h = hexmem(req[i].data(), req[i].size());\n\t\t\tret.append(h);\n\t\t}else{\n\t\t\tsprintf(buf, \"[%d bytes]\", (int)req[i].size());\n\t\t\tret.append(buf);\n\t\t}\n\t\tif(i < req.size() - 1){\n\t\t\tret.append(\" \");\n\t\t}\n\t}\n\treturn ret;\n}\n\nvoid welcome(){\n\tprintf(\"ssdb-dump - SSDB backup command\\n\");\n\tprintf(\"Copyright (c) 2012-2015 ssdb.io\\n\");\n\tprintf(\"\\n\");\n}\n\nvoid usage(int argc, char **argv){\n\tprintf(\"Usage:\\n\"\n\t\t\"\\n\"\n\t\t\"    %s -o output_folder\\n\"\n\t\t\"    %s ip port output_folder\\n\"\n\t\t\"\\n\"\n\t\t\"Options:\\n\"\n\t\t\"    -h <ip/hostname>   Server IP address/hostname (default: 127.0.0.1).\\n\"\n\t\t\"    -p <port>          Server port (default: 8888).\\n\"\n\t\t\"    -a <password>      Password to use when connecting to the server.\\n\"\n\t\t\"    -o <output_folder> local backup folder that will be created.\\n\"\n\t\t\"\\n\",\n\t\targv[0], argv[0]);\n\texit(1);   \n}\n\nint parse_options(Config *config, int argc, char **argv){\n\tint i;\n\tfor(i = 1; i < argc; i++) {\n\t\tbool lastarg = i==argc-1;\n\t\tif(!strcmp(argv[i],\"-h\") && !lastarg){\n\t\t\tconfig->ip = argv[++i];\n\t\t}else if(!strcmp(argv[i], \"-h\") && lastarg){\n\t\t\tusage(argc, argv);\n\t\t}else if(!strcmp(argv[i], \"-p\") && !lastarg){\n\t\t\tconfig->port = atoi(argv[++i]);\n\t\t}else if(!strcmp(argv[i], \"-a\") && !lastarg){\n\t\t\tconfig->hasauth = true;\n\t\t\tconfig->auth = argv[++i];\n\t\t}else if(!strcmp(argv[i], \"-o\") && !lastarg){\n\t\t\tconfig->output_folder = argv[++i];\n\t\t}else{\n\t\t\tif(argv[i][0] == '-'){\n\t\t\t\tfprintf(stderr,\n\t\t\t\t\t\"Unrecognized option or bad number of args for: '%s'\\n\",\n\t\t\t\t\targv[i]);\n\t\t\t\t\texit(1);\n\t\t\t}else{\n\t\t\t\t/* Likely the command name, stop here. */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn i;\n}\n\nint main(int argc, char **argv){\n\twelcome();\n\tset_log_level(Logger::LEVEL_MIN);\n\n\tConfig config;\n\tconfig.ip = \"127.0.0.1\";\n\tconfig.port = 8888;\n\tconfig.hasauth = false;\n    \n\tint firstarg = parse_options(&config, argc, argv);\n\tif(firstarg == 1 && firstarg + 3 <= argc){\n\t\t// compatibale with old style arguments\n\t\tconfig.ip = argv[firstarg + 0];\n\t\tconfig.port = atoi(argv[firstarg + 1]);\n\t\tconfig.output_folder = argv[firstarg + 2];\n\t}\n\n\tif(config.output_folder.empty()){\n\t\tfprintf(stderr, \"ERROR: -o <output_folder> is required!\\n\");\n\t\tusage(argc, argv);\n\t\texit(1);\n\t}\n    \n\tif(file_exists(config.output_folder.c_str())){\n\t\tfprintf(stderr, \"ERROR: output_folder[%s] exists!\\n\", config.output_folder.c_str());\n\t\texit(1);\n\t}\n\tif(mkdir(config.output_folder.c_str(), 0777) == -1){\n\t\tfprintf(stderr, \"ERROR: error create backup directory!\\n\");\n\t\texit(1);\n\t}\n\n\tstd::string data_dir = \"\";\n\tdata_dir.append(config.output_folder);\n\tdata_dir.append(\"/data\");\n\t\n\t{\n\t\tstd::string meta_dir = \"\";\n\t\tmeta_dir.append(config.output_folder);\n\t\tmeta_dir.append(\"/meta\");\n\n\t\tint ret;\n\t\tret = mkdir(meta_dir.c_str(), 0755);\n\t\tif(ret == -1){\n\t\t\tfprintf(stderr, \"ERROR: error creating meta dir\\n\");\n\t\t\texit(1);\n\t\t}\n\t}\n\n\t// connect to server\n\tLink *link = Link::connect(config.ip.c_str(), config.port);\n\tif(link == NULL){\n\t\tfprintf(stderr, \"ERROR: error connecting to server: %s:%d!\\n\", config.ip.c_str(), config.port);\n\t\texit(1);\n\t}\n\tif(config.hasauth){\n\t\tconst std::vector<Bytes> *resp = link->request(\"auth\", config.auth.c_str());\n\t\tif(resp == NULL || resp->at(0) != \"ok\"){\n\t\t\tfprintf(stderr, \"ERROR: auth error!\\n\");\n\t\t\texit(1);\n\t\t}\n\t}\n\tlink->send(\"dump\", \"A\", \"\", \"-1\");\n\tlink->flush();\n\n\tleveldb::DB* db;\n\tleveldb::Options options;\n\tleveldb::Status status;\n\toptions.create_if_missing = true;\n\toptions.write_buffer_size = 32 * 1024 * 1024;\n\toptions.max_file_size = 32 * 1048576; // leveldb 1.20\n\toptions.compression = leveldb::kSnappyCompression;\n\n\tstatus = leveldb::DB::Open(options, data_dir.c_str(), &db);\n\tif(!status.ok()){\n\t\tfprintf(stderr, \"ERROR: open leveldb: %s error!\\n\", config.output_folder.c_str());\n\t\texit(1);\n\t}\n\n\tint64_t dump_count = 0;\n\twhile(1){\n\t\tconst std::vector<Bytes> *req = link->recv();\n\t\tif(req == NULL){\n\t\t\tfprintf(stderr, \"recv error\\n\");\n\t\t\tfprintf(stderr, \"ERROR: failed to dump data!\\n\");\n\t\t\texit(1);\n\t\t}else if(req->empty()){\n\t\t\tint len = link->read();\n\t\t\tif(len <= 0){\n\t\t\t\tfprintf(stderr, \"read error: %s\\n\", strerror(errno));\n\t\t\t\tfprintf(stderr, \"ERROR: failed to dump data!\\n\");\n\t\t\t\texit(1);\n\t\t\t}\n\t\t}else{\n\t\t\tBytes cmd = req->at(0);\n\t\t\tif(cmd == \"begin\"){\n\t\t\t\tprintf(\"recv begin...\\n\");\n\t\t\t}else if(cmd == \"end\"){\n\t\t\t\tprintf(\"received %\" PRId64 \" entry(s)\\n\", dump_count);\n\t\t\t\tprintf(\"recv end\\n\\n\");\n\t\t\t\tbreak;\n\t\t\t}else if(cmd == \"set\"){\n\t\t\t\t/*\n\t\t\t\tstd::string s = serialize_req(*req);\n\t\t\t\tprintf(\"%s\\n\", s.c_str());\n\t\t\t\t*/\n\n\t\t\t\tif(req->size() != 3){\n\t\t\t\t\tfprintf(stderr, \"invalid set params!\\n\");\n\t\t\t\t\tfprintf(stderr, \"ERROR: failed to dump data!\\n\");\n\t\t\t\t\texit(1);\n\t\t\t\t}\n\t\t\t\tBytes key = req->at(1);\n\t\t\t\tBytes val = req->at(2);\n\t\t\t\tif(key.size() == 0 || key.data()[0] == DataType::SYNCLOG){\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tleveldb::Slice k(key.data(), key.size());\n\t\t\t\tleveldb::Slice v(val.data(), val.size());\n\t\t\t\tstatus = db->Put(leveldb::WriteOptions(), k, v);\n\t\t\t\t//printf(\"set %s %s\\n\", str_escape(key.data(), key.size()).c_str(), str_escape(val.data(), val.size()).c_str());\n\t\t\t\tif(!status.ok()){\n\t\t\t\t\tfprintf(stderr, \"put leveldb error!\\n\");\n\t\t\t\t\tfprintf(stderr, \"ERROR: failed to dump data!\\n\");\n\t\t\t\t\texit(1);\n\t\t\t\t}\n\n\t\t\t\tdump_count ++;\n\t\t\t\tif((int)log10(dump_count - 1) != (int)log10(dump_count) || (dump_count > 0 && dump_count % 100000 == 0)){\n\t\t\t\t\tprintf(\"received %\" PRId64 \" entry(s)\\n\", dump_count);\n\t\t\t\t}\n\t\t\t}else{\n\t\t\t\tfprintf(stderr, \"error: unknown command %s\\n\", std::string(cmd.data(), cmd.size()).c_str());\n\t\t\t\tfprintf(stderr, \"ERROR: failed to dump data!\\n\");\n\t\t\t\texit(1);\n\t\t\t}\n\t\t}\n\t}\n\tprintf(\"total dumped %\" PRId64 \" entry(s)\\n\", dump_count);\n\n\t{\n\t\tstd::string val;\n\t\tif(db->GetProperty(\"leveldb.stats\", &val)){\n\t\t\tprintf(\"%s\\n\", val.c_str());\n\t\t}\n\t}\n\n\tprintf(\"compacting data...\\n\");\n\tdb->CompactRange(NULL, NULL);\n\t\n\t{\n\t\tstd::string val;\n\t\tif(db->GetProperty(\"leveldb.stats\", &val)){\n\t\t\tprintf(\"%s\\n\", val.c_str());\n\t\t}\n\t}\n\n\tprintf(\"backup has been made to folder: %s\\n\", config.output_folder.c_str());\n\t\n\tdelete link;\n\tdelete db;\n\treturn 0;\n}\n"
  },
  {
    "path": "tools/ssdb-iterate.php",
    "content": "<?php\n/**\n * Copyright (c) 2017, ideawu\n * All rights reserved.\n * @author: ideawu\n * @link: http://www.ideawu.com/\n *\n * Demonstrate how to iterate over the whole db.\n */\n\ninclude(dirname(__FILE__) . '/../api/php/SSDB.php');\n\n$host = '127.0.0.1';\n$port = 8888;\n$ssdb = new SimpleSSDB($host, $port);\n\n// to copy data from one ssdb to another\n// $dst = new SimpleSSDB($host2, $port2);\n\n$size = 1000;\n\n// KV\n$s_key = ''; // the lower bound of key range to iterate over(exclusive)\n$e_key = ''; // the upper bound of key range to iterate over(inclusive)\nwhile(1){\n\t$kvs = $ssdb->scan($s_key, $e_key, $size);\n\tif(!$kvs){\n\t\tbreak;\n\t}\n\tforeach($kvs as $k=>$v){\n\t\t$s_key = $k;\n\t\t// do your stuff\n\t\t// to copy data\n\t\t// $dst->set($k, $v);\n\t\techo \"KV: $k\\n\";\n\t}\n}\n\n\n// HASH\n$s_key = ''; // the lower bound of key range to iterate over(exclusive)\n$e_key = ''; // the upper bound of key range to iterate over(inclusive)\nwhile(1){\n\t$names = $ssdb->hlist($s_key, $e_key, $size);\n\tif(!$names){\n\t\tbreak;\n\t}\n\tforeach($names as $name){\n\t\t$s_key = $name;\n\n\t\t$s_item = '';\n\t\twhile(1){\n\t\t\t$kvs = $ssdb->hscan($name, $s_item, '', $size);\n\t\t\tif(!$kvs){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tforeach($kvs as $k=>$v){\n\t\t\t\t$s_item = $k;\n\t\t\t\t// do your stuff\n\t\t\t\t// to copy data\n\t\t\t\t// $dst->hset($name, $k, $v);\n\t\t\t\techo \"HASH: $name - $k\\n\";\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n// ZSET\n$s_key = ''; // the lower bound of key range to iterate over(exclusive)\n$e_key = ''; // the upper bound of key range to iterate over(inclusive)\nwhile(1){\n\t$names = $ssdb->zlist($s_key, $e_key, $size);\n\tif(!$names){\n\t\tbreak;\n\t}\n\tforeach($names as $name){\n\t\t$s_name = $name;\n\n\t\t$s_item = '';\n\t\t$s_score = '';\n\t\twhile(1){\n\t\t\t$kvs = $ssdb->zscan($name, $s_item, $s_score, '', $size);\n\t\t\tif(!$kvs){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tforeach($kvs as $k=>$v){\n\t\t\t\t$s_item = $k;\n\t\t\t\t$s_score = $v;\n\t\t\t\t// do your stuff\n\t\t\t\t// to copy data\n\t\t\t\t// $dst->zset($name, $k, $v);\n\t\t\t\techo \"ZSET: $name - $k : $v\\n\";\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n// QUEUE/LIST\n$s_key = ''; // the lower bound of key range to iterate over(exclusive)\n$e_key = ''; // the upper bound of key range to iterate over(inclusive)\nwhile(1){\n\t$names = $ssdb->qlist($s_key, $e_key, $size);\n\tif(!$names){\n\t\tbreak;\n\t}\n\tforeach($names as $name){\n\t\t$s_key = $name;\n\n\t\t$start = 0;\n\t\twhile(1){\n\t\t\t$kvs = $ssdb->qrange($name, $start, $size);\n\t\t\tif(!$kvs){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tforeach($kvs as $k=>$v){\n\t\t\t\t$start ++;\n\t\t\t\t$index = $start - 1;\n\t\t\t\t// do your stuff\n\t\t\t\t// to copy data\n\t\t\t\t// $dst->qpush($name, $v);\n\t\t\t\techo \"LIST: $name - [$index]\\n\";\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tools/ssdb-migrate.cpp",
    "content": "// this is only a demo, DO NOT use\n#include <stdio.h>\n#include <stdlib.h>\n#include <string>\n#include <vector>\n#include \"util/log.h\"\n#include \"util/string_util.h\"\n#include \"SSDB_client.h\"\n\n#define BATCH_SIZE 100\n\nssdb::Client *src = NULL;\nssdb::Client *dst = NULL;\n\nvoid welcome(){\n\tprintf(\"ssdb-migrate - SSDB server migration tool\\n\");\n\tprintf(\"Copyright (c) 2012-2015 ssdb.io\\n\");\n\tprintf(\"\\n\");\n}\n\nvoid usage(int argc, char **argv){\n\tprintf(\"Usage:\\n\"\n\t\t\"    %s type src_ip src_port dst_ip dst_port limit\\n\"\n\t\t\"\\n\"\n\t\t\"Options:\\n\"\n\t\t\"    type      Supported values: KV\\n\"\n\t\t\"    src_ip    IP addr of the SSDB server to move data from, example: 127.0.0.1\\n\"\n\t\t\"    src_port  Port number of source SSDB server\\n\"\n\t\t\"    src_ip    IP addr of the SSDB server to move data to, example: 127.0.0.1\\n\"\n\t\t\"    dst_port  Port number of destination SSDB server\\n\"\n\t\t\"    limit     Approximated number of keys to be moved, example: 1000\\n\"\n\t\t\"    -h        Show this message\"\n\t\t\"\\n\"\n\t\t\"Example:\\n\"\n\t\t\"    %s KV 127.0.0.1 8887 127.0.0.1 8889 13\\n\"\n\t\t\"\\n\",\n\t\targv[0], argv[0]);\n\texit(1);   \n}\n\nstruct AppArgs{\n\tstd::string type;\n\tstd::string src_ip;\n\tint src_port;\n\tstd::string dst_ip;\n\tint dst_port;\n\tint limit;\n};\n\nvoid parse_args(AppArgs *args, int argc, char **argv){\n\tif(argc < 7){\n\t\tusage(argc, argv);\n\t}\n\tfor(int i=1; i<argc; i++){\n\t\tif(std::string(\"-h\") == argv[i]){\n\t\t\tusage(argc, argv);\n\t\t}\n\t\tif(argv[i][0] == '-'){\n\t\t\tfprintf(stderr, \"ERROR: Invalid argument: %s!\\n\", argv[i]);\n\t\t\texit(1);   \n\t\t}\n\t}\n\targs->type = argv[1];\n\targs->src_ip = argv[2];\n\targs->src_port = str_to_int(argv[3]);\n\targs->dst_ip = argv[4];\n\targs->dst_port = str_to_int(argv[5]);\n\targs->limit = str_to_int(argv[6]);\n\tif(args->type != \"KV\"){\n\t\tfprintf(stderr, \"ERROR: only type of KV is supported!\\n\");\n\t\texit(1);   \n\t}\n\tif(args->limit <= 0){\n\t\tfprintf(stderr, \"ERROR: invalid limit option!\\n\");\n\t\texit(1);   \n\t}\n}\n\nstruct KeyRange{\n\tstd::string start;\n\tstd::string end;\n\t\n\tKeyRange(){\n\t}\n\t\n\tKeyRange(const std::string &start, const std::string &end){\n\t\tthis->start = start;\n\t\tthis->end = end;\n\t}\n\t\n\tstd::string str(){\n\t\tchar buf[1024];\n\t\tsnprintf(buf, sizeof(buf), \"(\\\"%s\\\", \\\"%s\\\"]\", str_escape(start).c_str(), str_escape(end).c_str());\n\t\treturn std::string(buf);\n\t}\n};\n\nint move_key(const std::string &key){\n\tstd::string val;\n\tssdb::Status s;\n\ts = src->get(key, &val);\n\tif(s.not_found()){\n\t\treturn 0;\n\t}\n\tif(!s.ok()){\n\t\tlog_error(\"src server error! %s\", s.code().c_str());\n\t\treturn -1;\n\t}\n\ts = dst->set(key, val);\n\tif(!s.ok()){\n\t\tlog_error(\"dst server error! %s\", s.code().c_str());\n\t\treturn -1;\n\t}\n\ts = src->del(key);\n\tif(!s.ok()){\n\t\tlog_error(\"src server error! %s\", s.code().c_str());\n\t\treturn -1;\n\t}\n\treturn 1;\n}\n\nint move_range(const std::string &min_key, const std::string &max_key, int limit, std::string *moved_max_key){\n\t// get key range\n\tstd::vector<std::string> keys;\n\tssdb::Status s;\n\ts = src->keys(min_key, max_key, limit, &keys);\n\tif(!s.ok()){\n\t\tlog_error(\"response error: %s\", s.code().c_str());\n\t\treturn -1;\n\t}\n\tif(keys.empty()){\n\t\treturn 0;\n\t}\n\tif(moved_max_key){\n\t\t*moved_max_key = keys[keys.size() - 1];\n\n\t\t// lock key range\n\t\tlog_info(\"lock range %s\", KeyRange(min_key, *moved_max_key).str().c_str());\n\t\tconst std::vector<std::string>* resp;\n\t\tresp = src->request(\"set_kv_range\", *moved_max_key, max_key);\n\t\tif(!resp || resp->empty() || resp->at(0) != \"ok\"){\n\t\t\tlog_error(\"src server set_kv_range error!\");\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\t// move key range\n\tfor(int i=0; i<(int)keys.size(); i++){\n\t\tconst std::string &key = keys[i];\n\t\tif(move_key(key) == -1){\n\t\t\tlog_fatal(\"move key %s error! %s\", key.c_str(), s.code().c_str());\n\t\t\texit(1);   \n\t\t}\n\t}\n\t\n\treturn (int)keys.size();\n}\n\nssdb::Client* init_client(const std::string &ip, int port){\n\tssdb::Client *client = ssdb::Client::connect(ip, port);\n\tif(client == NULL){\n\t\tlog_error(\"fail to connect to server!\");\n\t\treturn NULL;\n\t}\n\n\tconst std::vector<std::string>* resp;\n\tresp = client->request(\"ignore_key_range\");\n\tif(!resp || resp->empty() || resp->at(0) != \"ok\"){\n\t\tlog_error(\"src server ignore_key_range error!\");\n\t\tdelete client;\n\t\treturn NULL;\n\t}\n\treturn client;\n}\n\nint get_key_range(ssdb::Client *client, KeyRange *range){\n\tconst std::vector<std::string>* resp;\n\tresp = client->request(\"get_kv_range\");\n\tif(!resp || resp->size() < 3 || resp->at(0) != \"ok\"){\n\t\tlog_error(\"get_kv_range error!\");\n\t\treturn -1;\n\t}\n\trange->start = resp->at(1);\n\trange->end = resp->at(2);\n\treturn 0;\n}\n\nint set_key_range(ssdb::Client *client, const KeyRange &range){\n\tconst std::vector<std::string>* resp;\n\tresp = client->request(\"set_kv_range\", range.start, range.end);\n\tif(!resp || resp->empty() || resp->at(0) != \"ok\"){\n\t\tlog_error(\"server set_kv_range error!\");\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nvoid check_version(ssdb::Client *client){\n\tconst std::vector<std::string>* resp;\n\tresp = client->request(\"version\");\n\tif(!resp || resp->size() < 2 || resp->at(0) != \"ok\"){\n\t\tfprintf(stderr, \"ERROR: ssdb-server 1.9.0 or higher is required!\\n\");\n\t\texit(1);\n\t}\n}\n\nint main(int argc, char **argv){\n\twelcome();\n\tAppArgs args;\n\tparse_args(&args, argc, argv);\n\n\tsrc = init_client(args.src_ip, args.src_port);\n\tif(src == NULL){\n\t\tlog_error(\"fail to connect to server!\");\n\t\treturn 0;\n\t}\n\tdst = init_client(args.dst_ip, args.dst_port);\n\tif(dst == NULL){\n\t\tlog_error(\"fail to connect to server!\");\n\t\treturn 0;\n\t}\n\tcheck_version(src);\n\tcheck_version(dst);\n\t\n\tKeyRange src_range;\n\tif(get_key_range(src, &src_range) == -1){\n\t\treturn -1;\n\t}\n\tlog_info(\"old src %s\", src_range.str().c_str());\n\t\n\tKeyRange dst_range;\n\tif(get_key_range(dst, &dst_range) == -1){\n\t\treturn -1;\n\t}\n\tlog_info(\"old dst %s\", dst_range.str().c_str());\n\n\tfor(int i=0; i<args.limit; i+=BATCH_SIZE){\n\t\tint num = BATCH_SIZE;\n\t\tif(args.limit - i < BATCH_SIZE){\n\t\t\tnum = args.limit - i;\n\t\t}\n\t\t\n\t\t// move data\n\t\tint ret;\n\t\tstd::string moved_max_key;\n\t\tret = move_range(src_range.start, src_range.end, num, &moved_max_key);\n\t\tif(ret == -1){\n\t\t\tlog_fatal(\"move_range error!\");\n\t\t\texit(1);   \n\t\t}\n\t\tif(ret == 0){\n\t\t\tcontinue;\n\t\t}\n\t\tlog_debug(\"moved %d key(s)\", ret);\n\t\twhile(ret == num){\n\t\t\t// check again, make sure there is not key inserted before we lock range\n\t\t\tret = move_range(src_range.start, moved_max_key, num, NULL);\n\t\t\tif(ret == -1){\n\t\t\t\tlog_fatal(\"move_range error!\");\n\t\t\t\texit(1);   \n\t\t\t}\n\t\t}\n\t\n\t\tKeyRange new_src_range(moved_max_key, src_range.end);\n\t\tKeyRange new_dst_range(dst_range.start, moved_max_key);\n\t\n\t\tlog_info(\"src %s => %s\", src_range.str().c_str(), new_src_range.str().c_str());\n\t\tlog_info(\"dst %s => %s\", dst_range.str().c_str(), new_dst_range.str().c_str());\n\t\n\t\t// update key range\n\t\tif(set_key_range(src, new_src_range) == -1){\n\t\t\tlog_fatal(\"src server set_kv_range error!\");\n\t\t\texit(1);   \n\t\t}\n\t\tif(set_key_range(dst, new_dst_range) == -1){\n\t\t\tlog_fatal(\"dst server set_kv_range error!\");\n\t\t\texit(1);   \n\t\t}\n\t}\n\t\n\tdelete src;\n\tdelete dst;\n\treturn 0;\n}\n"
  },
  {
    "path": "tools/ssdb-repair.cpp",
    "content": "/*\nCopyright (c) 2012-2015 The SSDB Authors. All rights reserved.\nUse of this source code is governed by a BSD-style license that can be\nfound in the LICENSE file.\n*/\n#include \"include.h\"\n\n#include <string>\n#include <vector>\n\n#include \"leveldb/db.h\"\n#include \"leveldb/env.h\"\n#include \"leveldb/options.h\"\n#include \"leveldb/slice.h\"\n#include \"leveldb/iterator.h\"\n\n#include \"util/log.h\"\n#include \"util/file.h\"\n#include \"util/string_util.h\"\n\nvoid welcome(){\n\tprintf(\"ssdb-repair - SSDB repair tool\\n\");\n\tprintf(\"Copyright (c) 2013-2015 ssdb.io\\n\");\n\tprintf(\"\\n\");\n}\n\nvoid usage(int argc, char **argv){\n\tprintf(\"Usage:\\n\");\n\tprintf(\"    %s leveldb_folder\\n\", argv[0]);\n\tprintf(\"\\n\");\n}\n\nint main(int argc, char **argv){\n\twelcome();\n\n\tset_log_level(Logger::LEVEL_MIN);\n\n\tif(argc <= 1){\n\t\tusage(argc, argv);\n\t\treturn 0;\n\t}\n\tstd::string leveldb_folder(argv[1]);\n\n\tif(!file_exists(leveldb_folder.c_str())){\n\t\tprintf(\"leveldb_folder[%s] not exists!\\n\", leveldb_folder.c_str());\n\t\treturn 0;\n\t}\n\t\n\tleveldb::Status status;\n\t\n\tleveldb::Logger *logger;\n\tstatus = leveldb::Env::Default()->NewLogger(\"repair.log\", &logger);\n\tif(!status.ok()){\n\t\tprintf(\"logger error!\\n\");\n\t\treturn 0;\n\t}\n\tprintf(\"writing repair log into: repair.log\\n\");\n\n\tleveldb::Options options;\n\toptions.max_file_size = 32 * 1048576; // leveldb 1.20\n\toptions.info_log = logger;\n\tstatus = leveldb::RepairDB(leveldb_folder.c_str(), options);\n\tif(!status.ok()){\n\t\tprintf(\"repair leveldb: %s error!\\n\", leveldb_folder.c_str());\n\t\treturn 0;\n\t}\n\t\n\tprintf(\"leveldb repaired.\\n\");\n\t\n\t{\n\t\tleveldb::DB* db;\n\t\tleveldb::Options options;\n\t\tleveldb::Status status;\n\t\toptions.create_if_missing = true;\n    \toptions.max_file_size = 32 * 1048576; // leveldb 1.20\n\t\toptions.write_buffer_size = 32 * 1024 * 1024;\n\t\toptions.compression = leveldb::kSnappyCompression;\n\n\t\tstatus = leveldb::DB::Open(options, leveldb_folder.c_str(), &db);\n\t\tif(!status.ok()){\n\t\t\tfprintf(stderr, \"ERROR: open leveldb: %s error!\\n\", leveldb_folder.c_str());\n\t\t\texit(1);\n\t\t}\n\t\tprintf(\"compacting data...\\n\");\n\t\tdb->CompactRange(NULL, NULL);\n\t\n\t\t{\n\t\t\tstd::string val;\n\t\t\tif(db->GetProperty(\"leveldb.stats\", &val)){\n\t\t\t\tprintf(\"%s\\n\", val.c_str());\n\t\t\t}\n\t\t}\n\n\t\tdelete db;\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "tools/ssdb.sh",
    "content": "#!/bin/sh\n#\n# chkconfig: 2345 64 36\n# description: SSDB startup scripts\n#\nssdb_root=/usr/local/ssdb\nssdb_bin=$ssdb_root/ssdb-server\n# each config file for one instance\n# configs=\"/data/ssdb_data/test/ssdb.conf /data/ssdb_data/test2/ssdb.conf\"\nconfigs=\"/data/ssdb_data/test/ssdb.conf\"\n\n \nif [ -f /etc/rc.d/init.d/functions ]; then\n\t. /etc/rc.d/init.d/functions\nfi\n \nstart() {\n\tfor conf in $configs; do\n\t\t$ssdb_bin $conf -s restart -d\n\tdone\n}\n \nstop() {\n\tfor conf in $configs; do\n\t\t$ssdb_bin $conf -s stop -d\n\tdone\n}\n \n# See how we were called.\ncase \"$1\" in\n    start)\n        start\n        ;;\n    stop)\n        stop\n        ;;\n    restart)\n        stop\n        start\n        ;;\n    *)\n        echo $\"Usage: $0 {start|stop|restart}\"\n        ;;\nesac\nexit $RETVAL\n"
  },
  {
    "path": "tools/ssdb_cli/cluster.cpy",
    "content": "import util.*;\n\nfunction kv_node_list(resp, time_consume){\n\tlen_index = 0;\n\tcount = 0;\n\twhile(len(resp.data) > len_index){\n\t\tkv_len = int(resp.data[len_index]);\n\t\tif(kv_len < 6){\n\t\t\tprintf('bad response!\\n');\n\t\t\tbreak;\n\t\t}\n\t\tif(len(resp.data) >= len_index + kv_len){\n\t\t\tcount += 1;\n\t\t\tid      = resp.data[len_index + 1];\n\t\t\tstatus  = resp.data[len_index + 2];\n\t\t\trange_s = resp.data[len_index + 3];\n\t\t\trange_e = resp.data[len_index + 4];\n\t\t\tip      = resp.data[len_index + 5];\n\t\t\tport    = resp.data[len_index + 6];\n\t\t\t\n\t\t\tstatus_text = 'UNKNOWN';\n\t\t\tif(status == '0'){\n\t\t\t\tstatus_text = 'INIT';\n\t\t\t}else if(status == '1'){\n\t\t\t\tstatus_text = 'SERVING';\n\t\t\t}\n\t\t\t\n\t\t\tprintf('id: %s\\n', id);\n\t\t\tprintf('    status: %s\\n', status_text);\n\t\t\tprintf('    range:  (\\\"%s\\\", \\\"%s\\\"]\\n', range_s.encode('string-escape'), range_e.encode('string-escape'));\n\t\t\tprintf('    ip:     %s\\n', ip);\n\t\t\tprintf('    port:   %s\\n', port);\n\t\t}\n\t\tlen_index += 6 + 1;\n\t}\n\tsys.stderr.write(sprintf('%d result(s) (%.3f sec)\\n', count, time_consume));\n}\n"
  },
  {
    "path": "tools/ssdb_cli/exporter.cpy",
    "content": "import util.*;\n\nfp = null;\nprogress = 0;\nread_size = 0;\ntotal_size = 0;\n\nfunction write_line(params){\n\tgs = globals();\n\tforeach(params as k=>v){\n\t\tparams[k] = str(v).encode('string-escape');\n\t}\n\tline = str('\\t').join(params) + '\\n';\n\tgs['read_size'] += len(line);\n\tgs['fp'].write(line);\n}\n\nfunction show_progress(){\n\tgs = globals();\n\tprogress = gs['progress'];\n\tread_size = gs['read_size'];\n\ttotal_size = gs['total_size'];\n\n\tprogress_2 = int(float(read_size)/total_size * 100);\n\tif(progress_2 - progress >= 5 || read_size == total_size){\n\t\tgs['progress'] = progress_2;\n\t\tprintf(\"%2d%%\\n\", progress_2);\n\t}\n}\n\nfunction my_readline(c){\n\tif(c == null){\n\t\tc = '';\n\t}\n\ttry{\n\t\treturn raw_input(c);\n\t}catch(Exception e){\n\t}\n\treturn '';\n}\n\nfunction run(link, args){\n\tgs = globals();\n\n\tkstart = '';\n\tkend = '';\n\thstart = '';\n\thend = '';\n\tzstart = '';\n\tzend = '';\n\tqstart = '';\n\tqend = '';\n\n\toutput_file = false;\n\tinteractive = false;\n\tforeach(args as arg){\n\t\tif(arg == '-i'){\n\t\t\tinteractive = true;\n\t\t}else{\n\t\t\toutput_file = arg;\n\t\t}\n\t}\n\tif(output_file == false){\n\t\tsys.stderr.write('Usage: export [-i] out_file\\n');\n\t\treturn;\n\t}\n\tif(os.path.exists(output_file)){\n\t\tprint 'Error: ' + output_file + ' already exists!';\n\t\treturn;\n\t}\n\n\tif(interactive){\n\t\tprintf(\"input KV range[start, end]: \\n\");\n\t\tkstart = my_readline('  start(inclusive, default none): ');\n\t\tkend   = my_readline('    end(inclusive, default none): ');\n\t\tprintf(\"input HASH range: \\n\");\n\t\thstart = my_readline('  start(inclusive, default none): ');\n\t\thend   = my_readline('    end(inclusive, default none): ');\n\t\tprintf(\"input ZSET range: \\n\");\n\t\tzstart = my_readline('  start(inclusive, default none): ');\n\t\tzend   = my_readline('    end(inclusive, default none): ');\n\t\tprintf(\"input QUEUE range: \\n\");\n\t\tqstart = my_readline('  start(inclusive, default none): ');\n\t\tqend   = my_readline('    end(inclusive, default none): ');\n\t}\n\t\n\tgs['fp'] = open(output_file, 'w');\n\t\n\tgs = globals();\n\tgs['total_size'] = dbsize(link);\n\n\tif(gs['total_size'] <= 0){\n\t\tgs['total_size'] = 1;\n\t}\n\tgs['total_size'] *= 1024 * 1024;\n\n\t// KV\n\tls = new SSDB_kv_scan(link);\n\tls.set_range(kstart, kend);\n\t// by default, ssdb's iterator is start-exclusive,\n\tr = link.request('get', [ls.key]);\n\tif(r.ok()){\n\t\twrite_line(['set', ls.key, r.data]);\n\t}\n\twhile(ls.next()){\n\t\tshow_progress();\n\t\twrite_line(['set', ls.key, ls.val]);\n\t}\n\n\t// HASH\n\tls = new SSDB_hash_list(link);\n\tls.set_range(hstart, hend);\n\tscan = new SSDB_hash_scan(link);\n\tscan.name = ls.key;\n\twhile(scan.next()){\n\t\tshow_progress();\n\t\twrite_line(['hset', ls.key, scan.key, scan.val]);\n\t}\n\twhile(ls.next()){\n\t\tscan = new SSDB_hash_scan(link);\n\t\tscan.name = ls.key;\n\t\twhile(scan.next()){\n\t\t\tshow_progress();\n\t\t\twrite_line(['hset', ls.key, scan.key, scan.val]);\n\t\t}\n\t}\n\n\t// ZSET\n\tls = new SSDB_zset_list(link);\n\tls.set_range(zstart, zend);\n\tscan = new SSDB_zset_scan(link);\n\tscan.name = ls.key;\n\twhile(scan.next()){\n\t\tshow_progress();\n\t\twrite_line(['zset', ls.key, scan.key, scan.val]);\n\t}\n\twhile(ls.next()){\n\t\tscan = new SSDB_zset_scan(link);\n\t\tscan.name = ls.key;\n\t\twhile(scan.next()){\n\t\t\tshow_progress();\n\t\t\twrite_line(['zset', ls.key, scan.key, scan.val]);\n\t\t}\n\t}\n\n\t// QUEUE\n\tls = new SSDB_queue_list(link);\n\tls.set_range(qstart, qend);\n\tscan = new SSDB_queue_scan(link);\n\tscan.name = ls.key;\n\twhile(scan.next()){\n\t\tshow_progress();\n\t\twrite_line(['qpush', ls.key, scan.val]);\n\t}\n\twhile(ls.next()){\n\t\tscan = new SSDB_queue_scan(link);\n\t\tscan.name = ls.key;\n\t\twhile(scan.next()){\n\t\t\tshow_progress();\n\t\t\twrite_line(['qpush', ls.key, scan.val]);\n\t\t}\n\t}\n\t\n\tif(gs['fp']){\n\t\tgs['fp'].close();\n\t}\n\n\tgs['read_size'] = gs['total_size'];\n\tshow_progress();\n\tprint 'done.';\n}\n"
  },
  {
    "path": "tools/ssdb_cli/flushdb.cpy",
    "content": "function hclear(link, hname, verbose=true){\n\tret = 0;\n\tr = link.request('hclear', [hname]);\n\ttry{\n\t\tret = r.data;\n\t}catch(Exception e){\n\t}\n\treturn ret;\n}\n\nfunction zclear(link, zname, verbose=true){\n\tret = 0;\n\tr = link.request('zclear', [zname]);\n\ttry{\n\t\tret = r.data;\n\t}catch(Exception e){\n\t}\n\treturn ret;\n}\n\nfunction qclear(link, zname, verbose=true){\n\tret = 0;\n\tr = link.request('qclear', [zname]);\n\ttry{\n\t\tret = r.data;\n\t}catch(Exception e){\n\t}\n\treturn ret;\n}\nfunction flushdb(link, data_type){\n\tresp = link.request('info');\n\tfor(i=1; i<len(resp.data); i+=2){\n\t\tif(resp.data[i] == 'replication'){\n\t\t\tthrow new Exception('flushdb is not allowed when replication is in use!');\n\t\t}\n\t}\n\n\tprintf('\\n');\n\tprintf('============================ DANGER! ============================\\n');\n\tprintf('This operation is DANGEROUS and is not recoverable, if you\\n');\n\tprintf('really want to flush the whole db(delete ALL data in ssdb server),\\n');\n\tprintf('input \\'yes\\' and press Enter, or just press Enter to cancel\\n');\n\tprintf('\\n');\n\tprintf('flushdb will break replication states, you must fully understand\\n');\n\tprintf('the RISK before you doing this!\\n');\n\tprintf('\\n');\n\tprintf('> flushdb? ');\n\t\n\tline = sys.stdin.readline().strip();\n\tif(line != 'yes'){\n\t\tprintf('Operation cancelled.\\n\\n');\n\t\treturn;\n\t}\n\n\tprint 'Begin to flushdb...\\n';\n\n\tif(data_type == ''){\n\t\tresp = link.request('flushdb', []);\n\t\tif(resp.code != 'ok' && resp.code != 'client_error'){\n\t\t\tthrow new Exception(resp.message);\n\t\t}\n\t}\n\t\n\tbatch = 1000;\n\t\n\td_kv = 0;\n\tif(data_type == '' || data_type == 'kv'){\n\t\twhile(true){\n\t\t\tresp = link.request('keys', ['', '', batch]);\n\t\t\tif(len(resp.data) == 0){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\td_kv += len(resp.data);\n\t\t\tlink.request('multi_del', resp.data);\n\t\t\tprintf('delete[kv  ] %d key(s).\\n', d_kv);\n\t\t}\n\t}\n\t\n\td_hash = 0;\n\td_hkeys = 0;\n\tif(data_type == '' || data_type == 'hash'){\n\t\twhile(true){\n\t\t\tresp = link.request('hlist', ['', '', batch]);\n\t\t\tif(len(resp.data) == 0){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tlast_num = 0;\n\t\t\tforeach(resp.data as hname){\n\t\t\t\td_hash += 1;\n\t\t\t\tdeleted_num = hclear(link, hname, false);\n\t\t\t\td_hkeys += deleted_num;\n\t\t\t\tif(d_hkeys - last_num >= batch){\n\t\t\t\t\tlast_num = d_hkeys;\n\t\t\t\t\tprintf('delete[hash] %d hash(s), %d key(s).\\n', d_hash, d_hkeys);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(d_hkeys - last_num >= batch){\n\t\t\t\tprintf('delete[hash] %d hash(s), %d key(s).\\n', d_hash, d_hkeys);\n\t\t\t}\n\t\t}\n\t\tprintf('delete[hash] %d hash(s), %d key(s).\\n', d_hash, d_hkeys);\n\t}\n\t\n\td_zset = 0;\n\td_zkeys = 0;\n\tif(data_type == '' || data_type == 'zset'){\n\t\twhile(true){\n\t\t\tresp = link.request('zlist', ['', '', batch]);\n\t\t\tif(len(resp.data) == 0){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tlast_num = 0;\n\t\t\tforeach(resp.data as zname){\n\t\t\t\td_zset += 1;\n\t\t\t\tdeleted_num = zclear(link, zname, false);\n\t\t\t\td_zkeys += deleted_num;\n\t\t\t\tif(d_zkeys - last_num >= batch){\n\t\t\t\t\tlast_num = d_zkeys;\n\t\t\t\t\tprintf('delete[zset] %d zset(s), %d key(s).\\n', d_zset, d_zkeys);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(d_zkeys - last_num >= batch){\n\t\t\t\tprintf('delete[zset] %d zset(s), %d key(s).\\n', d_zset, d_zkeys);\n\t\t\t}\n\t\t}\n\t\tprintf('delete[zset] %d zset(s), %d key(s).\\n', d_zset, d_zkeys);\n\t}\n\t\n\td_list = 0;\n\td_lkeys = 0;\n\tif(data_type == '' || data_type == 'list'){\n\t\twhile(true){\n\t\t\tresp = link.request('qlist', ['', '', batch]);\n\t\t\tif(len(resp.data) == 0){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tlast_num = 0;\n\t\t\tforeach(resp.data as zname){\n\t\t\t\td_list += 1;\n\t\t\t\tdeleted_num = qclear(link, zname, false);\n\t\t\t\td_lkeys += deleted_num;\n\t\t\t\tif(d_zkeys - last_num >= batch){\n\t\t\t\t\tlast_num = d_lkeys;\n\t\t\t\t\tprintf('delete[list] %d list(s), %d key(s).\\n', d_list, d_lkeys);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(d_lkeys - last_num >= batch){\n\t\t\t\tprintf('delete[list] %d list(s), %d key(s).\\n', d_list, d_lkeys);\n\t\t\t}\n\t\t}\n\t\tprintf('delete[list] %d list(s), %d key(s).\\n', d_list, d_lkeys);\n\t}\n\n\tprintf('\\n');\n\tprintf('===== flushdb stats =====\\n');\n\tif(data_type == '' || data_type == 'kv'){\n\t\tprintf('[kv]   %8d key(s).\\n', d_kv);\n\t}\n\tif(data_type == '' || data_type == 'hash'){\n\t\tprintf('[hash] %8d hash(s), %8d key(s).\\n', d_hash, d_hkeys);\n\t}\n\tif(data_type == '' || data_type == 'zset'){\n\t\tprintf('[zset] %8d zset(s), %8d key(s).\\n', d_zset, d_zkeys);\n\t}\n\tif(data_type == '' || data_type == 'list'){\n\t\tprintf('[list] %8d list(s), %8d key(s).\\n', d_list, d_lkeys);\n\t}\n\tprintf('\\n');\n\t\n\tprintf('clear binlog\\n');\n\tlink.request('clear_binlog');\n\tprintf('\\n');\n\n\tprintf('compacting...\\n');\n\tlink.request('compact');\n\tprintf('done.\\n');\n\tprintf('\\n');\n}\n"
  },
  {
    "path": "tools/ssdb_cli/importer.cpy",
    "content": "function run(link, filename){\n\tif(!os.path.exists(filename)){\n\t\tprint 'Error: ' + filename + ' not exists!';\n\t\treturn;\n\t}\n\ttotal_size = os.path.getsize(filename);\n\tif(total_size == 0){\n\t\ttotal_size = 1;\n\t}\n\n\tprogress = 0;\n\tread_size = 0;\n\tfp = open(filename, 'r');\n\tlineno = 0;\n\tforeach(fp as line){\n\t\tlineno ++;\n\t\tread_size += len(line);\n\t\tprogress_2 = int(float(read_size)/total_size * 100);\n\t\tif(progress_2 - progress >= 5 || read_size == total_size){\n\t\t\tprogress = progress_2;\n\t\t\tprintf(\"%2d%%\\n\", progress_2);\n\t\t}\n\t\t\n\t\tps = line.strip('\\n').split('\\t');\n\t\tif(len(ps) < 2){\n\t\t\tprint 'Error: bad format at line ' + str(lineno) + ', abort!';\n\t\t\treturn;\n\t\t}\n\t\tcmd = ps[0].lower();\n\t\tforeach(ps as k=>v){\n\t\t\tps[k] = str(v).decode('string-escape');\n\t\t}\n\t\t\n\t\tlink.request(cmd, ps[ 1 ..]);\n\t}\n\tprint 'done.';\n}\n"
  },
  {
    "path": "tools/ssdb_cli/nagios.cpy",
    "content": "nagios_probe = '';\nnagios_warn = 85;\nnagios_critical = 95;\n\nfunction run(link, cli_args){\n\tgs = globals();\n\topt = '';\n\tforeach(cli_args as arg){\n\t\tif(opt == '' && arg.startswith('-')){\n\t\t\topt = arg;\n\t\t}else{\n\t\t\tswitch(opt){\n\t\t\t\tcase '-n':\n\t\t\t\t\topt = '';\n\t\t\t\t\tgs['nagios_probe'] = arg;\n\t\t\t\t\tbreak;\n\t\t\t\tcase '-w':\n\t\t\t\t\tgs['nagios_warn'] = arg;\n\t\t\t\t\topt = '';\n\t\t\t\t\tbreak;\n\t\t\t\tcase '-c':\n\t\t\t\t\tgs['nagios_critical'] = arg;\n\t\t\t\t\topt = '';\n\t\t\t\t\tbreak;\n\t\t\t\tdefault: \n\t\t\t\t\t# ignore args '-h host -p port'\n\t\t\t\t\topt = '';\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\ttry{\n\t\tresp = link.request('info', []);\n\t\tif(nagios_probe == 'info'){\n\t\t\tnagios_info(resp);\n\t\t}\n\t\tif(nagios_probe == 'dbsize'){\n\t\t\tnagios_dbsize(resp);\n\t\t}\n\t\tif(nagios_probe == 'replication'){\n\t\t\tnagios_replication(resp);\n\t\t}\n\t\tif(nagios_probe == 'write_read'){\n\t\t\tnagios_write_read(link);\n\t\t}\n\t\t# Possible future checks:\n\t\t# - check if binlogs.max_seq == replication.client.last_seq\n\t\t# - does total_calls is growing\n\t}catch(Exception e){\n\t\tsys.stderr.write(str(e) + '\\n');\n\t\texit(2);\n\t}\n\t#sys.stderr.write('exit\\n');\n\texit(0);\n}\n\nfunction nagios_info(resp){\n\tis_val = false;\n\tfor(i=1; i<len(resp.data); i++){\n\t\ts = resp.data[i];\n\t\tif(is_val){\n\t\t\ts = '\t' + s.replace('\\n', '\\n\t');\n\t\t}\n\t\tprint s;\n\t\tis_val = !is_val;\n\t}\n}\n\nfunction nagios_probe_check(resp){\n\tnext_val = false;\n\tret = '';\n\tfor(i=1; i<len(resp.data); i++){\n\t\ts = resp.data[i];\n\t\tif(next_val){\n\t\t\ts = s.replace('\\n', '\\n\t');\n\t\t\tnext_val = !next_val;\n\t\t\t#print s;\n\t\t\tret += s;\n\t\t}\n\t\tif(s == nagios_probe){\n\t\t\tnext_val = !next_val;\n\t\t}\n\t}\n\treturn ret;\n}\n\nfunction nagios_dbsize(resp){\n\tdbsize = nagios_probe_check(resp);\n\tif(long(dbsize) > long(nagios_critical)){\n\t\tprint 'CRITICAL: dbsize ' + str(dbsize) + ' larger than ' + str(nagios_critical);\n\t\texit(2);\n\t}else if(long(dbsize) > long(nagios_warn)){\n\t\tprint 'WARN: dbsize ' + str(dbsize) + ' larger than ' + str(nagios_warn);\n\t\texit(1);\n\t}else{\n\t\tprint 'OK: dbsize ' + str(dbsize) + ' less than ' + str(nagios_critical);\n\t\texit(0);\n\t}\n}\n\nfunction nagios_replication(resp){\n\treplication = nagios_probe_check(resp);\n\treplication = replication.replace('slaveof', '\\nslaveof');\n\tif(replication.find('DISCONNECTED') > 0 ){\n\t\tprint 'CRITICAL: ' + replication;\n\t\texit(2);\n\t}else if(replication.find('COPY') > 0 || replication.find('INIT') > 0 || replication.find('OUT_OF_SYNC') > 0){\n\t\tprint 'WARN: ' + replication;\n\t\texit(1);\n\t}else if(replication.find('SYNC') > 0){\n\t\tprint 'OK: ' + replication;\n\t\texit(0);\n\t}else{\n\t\tprint 'WARN, is replication configured? Status: ' + replication;\n\t\texit(1);\n\t}\n}\n\nfunction nagios_write_read(link){\n\timport datetime;\n\ttest_date = datetime.datetime.now().strftime(\"%Y%m%d%H%M\");\n\ttest_key = 'write_read_test_key' + str(test_date);\n\tresp = link.request('set', [test_key, test_key]);\n\t#print resp;\n\tresp = link.request('get', [test_key]);\n\t#print resp;\n\tresp_del = link.request('del', [test_key]);\n\t#print resp_del;\n\tif (resp.data == test_key){\n\t\tprint 'OK: ' + str(resp.data);\n\t\texit(0);\n\t}else{\n\t\tprint 'WRITE_READ failed: ' + str(resp.data);\n\t\texit(2);\n\t}\n}\n"
  },
  {
    "path": "tools/ssdb_cli/util.cpy",
    "content": "\nfunction show_version(link){\n\ttry{\n\t\tresp = link.request('info', []);\n\t\tif(resp.code == 'ok'){\n\t\t\tif(len(resp.data) > 2){\n\t\t\t\tsys.stderr.write(resp.data[0] + ' ' + resp.data[2] + '\\n\\n');\n\t\t\t}\n\t\t}else{\n\t\t\tsys.stderr.write(str(resp.message) + '\\n');\n\t\t\tif(resp.code == 'noauth'){\n\t\t\t\t//\n\t\t\t}else{\n\t\t\t\tsys.exit(0);\n\t\t\t}\n\t\t}\n\t}catch(Exception e){\n\t\tsys.stderr.write('Unexpected error: ' + str(e) + '\\n');\n\t\tsys.exit(0);\n\t}\n}\n\nfunction dbsize(link){\n\tresp = link.request('info', []);\n\tforeach(resp.data as k=>v){\n\t\tif(v != 'leveldb.stats'){\n\t\t\tcontinue;\n\t\t}\n\t\ts = resp.data[k + 1];\n\t\tlines = s.strip().split('\\n');\n\t\tlines = lines[ 3 ..];\n\t\tsize = 0;\n\t\tforeach(lines as line){\n\t\t\tps = line.split();\n\t\t\tsize += int(ps[2]);\n\t\t}\n\t\treturn size;\n\t}\n\treturn 0;\n}\n\nclass SSDB_iterator_base\n{\n\tpublic link;\n\tpublic finish = false;\n\tpublic batch = 2;\n\tpublic index = [];\n\tpublic key = '';\n\tpublic val = '';\n\tpublic end = '';\n\t\n\tfunction init(link){\n\t\tthis.link = link;\n\t}\n\t\n\tfunction seek(s){\n\t\tthis.key = s;\n\t}\n\t\n\tfunction set_range(s, e=''){\n\t\tthis.key = s;\n\t\tthis.end = e;\n\t}\n}\n\n\nclass SSDB_kv_scan extends SSDB_iterator_base\n{\n\tpublic items = [];\n\n\tfunction init(link){\n\t}\n\t\n\tfunction next(){\n\t\tif(this.finish){\n\t\t\treturn false;\n\t\t}\n\t\tif(len(this.index) == 0){\n\t\t\tresp = this.link.request('scan', [this.key, this.end, this.batch]);\n\t\t\tif(len(resp.data['index']) == 0){\n\t\t\t\tthis.finish = true;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.index = resp.data['index'];\n\t\t\tthis.items = resp.data['items'];\n\t\t}\n\t\tthis.key = this.index.pop(0);\n\t\tthis.val = this.items[this.key];\n\t\treturn true;\n\t}\n}\n\n/*\nscan = new SSDB_kv_scan();\nwhile(kvs.next()){\n\tprint scan.key, scan.val;\n}\n*/\n\nclass SSDB_hash_list extends SSDB_iterator_base\n{\n\tfunction init(link){\n\t}\n\t\n\tfunction next(){\n\t\tif(this.finish){\n\t\t\treturn false;\n\t\t}\n\t\tif(len(this.index) == 0){\n\t\t\tresp = this.link.request('hlist', [this.key, this.end, this.batch]);\n\t\t\tif(len(resp.data) == 0){\n\t\t\t\tthis.finish = true;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.index = resp.data;\n\t\t}\n\t\tthis.key = this.index.pop(0);\n\t\treturn true;\n\t}\n}\n\n\nclass SSDB_zset_list extends SSDB_iterator_base\n{\n\tfunction init(link){\n\t}\n\t\n\tfunction next(){\n\t\tif(this.finish){\n\t\t\treturn false;\n\t\t}\n\t\tif(len(this.index) == 0){\n\t\t\tresp = this.link.request('zlist', [this.key, this.end, this.batch]);\n\t\t\tif(len(resp.data) == 0){\n\t\t\t\tthis.finish = true;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.index = resp.data;\n\t\t}\n\t\tthis.key = this.index.pop(0);\n\t\treturn true;\n\t}\n}\n\n/*\nkvs = new SSDB_zset_list();\nwhile(kvs.next()){\n\tprint kvs.name;\n}\n*/\n\n\nclass SSDB_queue_list extends SSDB_iterator_base\n{\n\tfunction init(link){\n\t}\n\t\n\tfunction next(){\n\t\tif(this.finish){\n\t\t\treturn false;\n\t\t}\n\t\tif(len(this.index) == 0){\n\t\t\tresp = this.link.request('qlist', [this.key, this.end, this.batch]);\n\t\t\tif(len(resp.data) == 0){\n\t\t\t\tthis.finish = true;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.index = resp.data;\n\t\t}\n\t\tthis.key = this.index.pop(0);\n\t\treturn true;\n\t}\n}\n\n\n\nclass SSDB_hash_scan extends SSDB_iterator_base\n{\n\tpublic name = '';\n\tpublic items = [];\n\t\n\tfunction init(link){\n\t}\n\t\n\tfunction next(){\n\t\tif(this.finish){\n\t\t\treturn false;\n\t\t}\n\t\tif(len(this.index) == 0){\n\t\t\tresp = this.link.request('hscan', [this.name, this.key, '', this.batch]);\n\t\t\tif(len(resp.data['index']) == 0){\n\t\t\t\tthis.finish = true;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.index = resp.data['index'];\n\t\t\tthis.items = resp.data['items'];\n\t\t}\n\t\tthis.key = this.index.pop(0);\n\t\tthis.val = this.items[this.key];\n\t\treturn true;\n\t}\n}\n\n/*\nscan = new SSDB_hash_scan('n');\nwhile(scan.next()){\n\tprint scan.key, scan.val;\n}\n*/\n\n\n\nclass SSDB_zset_scan extends SSDB_iterator_base\n{\n\tpublic name = '';\n\tpublic items = [];\n\t\n\tfunction init(link){\n\t}\n\t\n\tfunction next(){\n\t\tif(this.finish){\n\t\t\treturn false;\n\t\t}\n\t\tif(len(this.index) == 0){\n\t\t\tresp = this.link.request('zscan', [this.name, this.key, this.val, '', this.batch]);\n\t\t\tif(len(resp.data['index']) == 0){\n\t\t\t\tthis.finish = true;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.index = resp.data['index'];\n\t\t\tthis.items = resp.data['items'];\n\t\t}\n\t\tthis.key = this.index.pop(0);\n\t\tthis.val = this.items[this.key];\n\t\treturn true;\n\t}\n}\n\n/*\nscan = new SSDB_zset_scan('n');\nwhile(scan.next()){\n\tprint scan.key, scan.val;\n}\n*/\n\n\n\nclass SSDB_queue_scan extends SSDB_iterator_base\n{\n\tpublic items = [];\n\tpublic offset = 0;\n\t\n\tfunction init(link){\n\t}\n\t\n\tfunction next(){\n\t\tif(this.finish){\n\t\t\treturn false;\n\t\t}\n\t\tif(len(this.index) == 0){\n\t\t\tresp = this.link.request('qrange', [this.name, this.offset, this.batch]);\n\t\t\tif(len(resp.data) == 0){\n\t\t\t\tthis.finish = true;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.index = resp.data;\n\t\t}\n\t\tthis.key = this.offset;\n\t\tthis.val = this.index.pop(0);\n\t\tthis.offset += 1;\n\t\treturn true;\n\t}\n}\n\n/*\nscan = new SSDB_queue_scan('q');\nwhile(scan.next()){\n\tprint scan.item;\n}\n*/\n"
  },
  {
    "path": "tools/test_slow_client.php",
    "content": "<?php\n$host = '127.0.0.1';\n$port = 8888;\n$sock = @stream_socket_client(\"$host:$port\", $errno, $errstr);\n$s = \"3\\r\\nget\\n1\\r\\nk\\r\\n\\r\\n\";\n$s .= str_replace(\"\\r\\n\", \"\\n\", $s);\n\nfor($i=0; $i<strlen($s); $i++){\n\tfwrite($sock, $s[$i]);\n\tfflush($sock);\n\tusleep(100 * 1000);\n\tprintf(\"write %d byte(s)\\n\", $i+1);\n}\n\n\n"
  },
  {
    "path": "tools/unittest.php",
    "content": "<?php\n/**\n * Copyright (c) 2012, ideawu\n * All rights reserved.\n * @author: ideawu\n * @link: http://www.ideawu.com/\n *\n * unit test.\n */\n\ninclude(dirname(__FILE__) . '/../api/php/SSDB.php');\n\nclass SSDBTest extends UnitTest{\n\tprivate $ssdb;\n\n\tfunction __construct(){\n\t\t$host = '127.0.0.1';\n\t\t$port = 8888;\n\t\t$this->ssdb = new SimpleSSDB($host, $port);\n\t\t$this->ssdb->auth('very-strong-password-11111111111111111');\n\t\t$this->clear();\n\t}\n\n\tfunction clear(){\n\t\t$ssdb = $this->ssdb;\n\t\t$deleted = 0;\n\t\twhile(1){\n\t\t\t$ret = $ssdb->scan('TEST_', 'TEST_'.pack('C', 255), 1000);\n\t\t\tif(!$ret){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tforeach($ret as $k=>$v){\n\t\t\t\t$ssdb->del($k);\n\t\t\t\t$deleted += 1;\n\t\t\t}\n\t\t}\n\t\twhile(1){\n\t\t\t$names = $ssdb->hlist('TEST_', 'TEST_'.pack('C', 255), 1000);\n\t\t\tif(!$names){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tforeach($names as $name){\n\t\t\t\t$deleted += $ssdb->hclear($name);\n\t\t\t\t$ret = $ssdb->hsize($name);\n\t\t\t\t$this->assert($ret == 0);\n\t\t\t}\n\t\t}\n\t\twhile(1){\n\t\t\t$names = $ssdb->zlist('TEST_', 'TEST_'.pack('C', 255), 1000);\n\t\t\tif(!$names){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tforeach($names as $name){\n\t\t\t\t$deleted += $ssdb->zclear($name);\n\t\t\t\t$ret = $ssdb->zsize($name);\n\t\t\t\t$this->assert($ret == 0);\n\t\t\t}\n\t\t}\n\t\twhile(1){\n\t\t\t$names = $ssdb->qlist('TEST_', 'TEST_'.pack('C', 255), 1000);\n\t\t\tif(!$names){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tforeach($names as $name){\n\t\t\t\t$deleted += $ssdb->qclear($name);\n\t\t\t\t$ret = $ssdb->qsize($name);\n\t\t\t\t$this->assert($ret == 0);\n\t\t\t}\n\t\t}\n\t\tif($deleted > 0){\n\t\t\techo \"clear $deleted\\n\";\n\t\t}\n\t}\n\n\tfunction test_kv(){\n\t\t$ssdb = $this->ssdb;\n\t\t$val = str_repeat(mt_rand(), mt_rand(1, 100));\n\t\t\n\t\t$ssdb->del('TEST_a');\n\t\t$ret = $ssdb->ttl('TEST_a');\n\t\t$this->assert($ret === -1);\n\t\t$ret = $ssdb->expire('TEST_a', 10);\n\t\t$this->assert($ret === 0);\n\t\t$ssdb->set('TEST_a', $val);\n\t\t$ret = $ssdb->expire('TEST_a', 10);\n\t\t$this->assert($ret === 1);\n\t\t\n\t\t$ssdb->setx('TEST_a', $val, 1);\n\t\t$ret = $this->ssdb->get('TEST_a');\n\t\t$this->assert($ret === $val);\n\t\tusleep(1.5 * 1000 * 1000);\n\t\t$ret = $this->ssdb->get('TEST_a');\n\t\t$this->assert($ret === null);\n\n\t\t$ssdb->set('TEST_a', $val);\n\t\t$ssdb->set('TEST_b', $val);\n\t\t\n\t\t$ret = $this->ssdb->get('TEST_a');\n\t\t$this->assert($ret === $val);\n\n\t\t$ret = $ssdb->scan('TEST_', 'TEST_'.pack('C', 255), 10);\n\t\t$this->assert(count($ret) == 2);\n\t\t$ret = $ssdb->scan('TEST_a', 'TEST_'.pack('C', 255), 10);\n\t\t$this->assert(count($ret) == 1);\n\t\t$ret = $ssdb->scan('TEST_b', 'TEST_'.pack('C', 255), 10);\n\t\t$this->assert(count($ret) == 0);\n\t\t$ret = $ssdb->scan('TEST_', 'TEST_a', 10);\n\t\t$this->assert(count($ret) == 1);\n\t\t$ret = $ssdb->scan('TEST_', 'TEST_b', 10);\n\t\t$this->assert(count($ret) == 2);\n\n\t\t$ret = $ssdb->rscan('TEST_'.pack('C', 255), 'TEST_', 10);\n\t\t$this->assert(count($ret) == 2);\n\t\t$ret = $ssdb->rscan('TEST_b', 'TEST_'.pack('C', 0), 10);\n\t\t$this->assert(count($ret) == 1);\n\t\t$ret = $ssdb->rscan('TEST_a', 'TEST_'.pack('C', 0), 10);\n\t\t$this->assert(count($ret) == 0);\n\t\t$ret = $ssdb->rscan('TEST_'.pack('C', 255), 'TEST_a', 10);\n\t\t$this->assert(count($ret) == 2);\n\t\t$ret = $ssdb->rscan('TEST_'.pack('C', 255), 'TEST_b', 10);\n\t\t$this->assert(count($ret) == 1);\n\n\t\t$ret = $ssdb->keys('TEST_', 'TEST_'.pack('C', 255), 10);\n\t\t$this->assert(count($ret) == 2);\n\n\t\t$kvs = array();\n\t\tfor($i=0; $i<5; $i++){\n\t\t\t$kvs['TEST_' . $i] = $i;\n\t\t\t$ssdb->multi_set($kvs);\n\t\t\t$ret = $ssdb->multi_get(array_keys($kvs));\n\t\t\t$this->assert(count($ret) == count($kvs));\n\t\t\t$ret = $ssdb->multi_del(array_keys($kvs));\n\t\t\t$ret = $ssdb->multi_get(array_keys($kvs));\n\t\t\t$this->assert(count($ret) == 0);\n\t\t}\n\n\t\t$ret = $ssdb->exists('TEST_a');\n\t\t$this->assert($ret === true);\n\t\t$ssdb->del('TEST_a');\n\t\t$ret = $ssdb->exists('TEST_a');\n\t\t$this->assert($ret === false);\n\t\t$ret = $ssdb->get('TEST_a');\n\t\t$this->assert($ret === null);\n\t\t$ssdb->del('TEST_b');\n\t\t\n\t\t$ssdb->del('TEST_a');\n\t\t$ret = $ssdb->setnx('TEST_a', 'a');\n\t\t$this->assert($ret === 1);\n\t\t$ret = $ssdb->setnx('TEST_a', 't');\n\t\t$this->assert($ret === 0);\n\t\t$ret = $ssdb->get('TEST_a');\n\t\t$this->assert($ret === 'a');\n\t\t\n\t\t$ssdb->del('TEST_a');\n\t\t$ret = $ssdb->getset('TEST_a', 'a');\n\t\t$this->assert($ret === null);\n\t\t$ret = $ssdb->getset('TEST_a', 'b');\n\t\t$this->assert($ret === 'a');\n\t\t$ret = $ssdb->get('TEST_a');\n\t\t$this->assert($ret === 'b');\n\n\t\t$key = 'TEST_a';\n\t\t$ssdb->del($key);\n\t\t$ret = $ssdb->setbit($key, 8, 1);\n\t\t$this->assert($ret === 0);\n\t\t$ret = $ssdb->setbit($key, 8, 1);\n\t\t$this->assert($ret === 1);\n\t\t$ret = $ssdb->countbit($key, 0, 1);\n\t\t$this->assert($ret === 0);\n\t\t$ret = $ssdb->countbit($key, 0, 2);\n\t\t$this->assert($ret === 1);\n\t\t$ret = $ssdb->countbit($key, 0);\n\t\t$this->assert($ret === 1);\n\t\t$ret = $ssdb->strlen($key);\n\t\t$this->assert($ret === 2);\n\t\t$val = '0123456789';\n\t\t$ssdb->set($key, $val);\n\t\t$this->assert($ssdb->substr($key, 0, 1) === substr($val, 0, 1));\n\t\t$this->assert($ssdb->substr($key, -1, -1) === substr($val, -1, -1));\n\t\t$this->assert($ssdb->substr($key, 0, -1) === substr($val, 0, -1));\n\t\t$this->assert($ssdb->substr($key, -1, -2) === substr($val, -1, -2));\n\t\t$this->assert($ssdb->substr($key, -2, -1) === substr($val, -2, -1));\n\t\t$this->assert($ssdb->substr($key, -2, 2) === substr($val, -2, 2));\n\t}\n\t\n\tfunction test_queue(){\n\t\t$ssdb = $this->ssdb;\n\t\t$name = \"TEST_\" . str_repeat(mt_rand(), mt_rand(1, 3));\n\t\t$key = \"TEST_\" . str_repeat(mt_rand(), mt_rand(1, 3));\n\t\t$val = str_repeat(mt_rand(), mt_rand(1, 30));\n\t\t\t\t\n\t\tfor($i=0; $i<7; $i++){\n\t\t\t$size = $ssdb->qpush($name, $i);\n\t\t\t$this->assert($size === $i + 1);\n\t\t}\n\t\t$size = $ssdb->qpush($name, array(7,8,9));\n\t\t$this->assert($size == 10);\n\t\t\n\t\t$ret = $ssdb->qget($name, 3);\n\t\t$this->assert($ret == 3);\n\t\t$ret = $ssdb->qslice($name, 0, -1);\n\t\tfor($i=0; $i<10; $i++){\n\t\t\t$this->assert($ret[$i] == $i);\n\t\t}\n\t\t$ret = $ssdb->qsize($name);\n\t\t$this->assert($ret === 10);\n\t\t$ret = $ssdb->qfront($name);\n\t\t$this->assert($ret == 0);\n\t\t$ret = $ssdb->qback($name);\n\t\t$this->assert($ret == 9);\n\t\tfor($i=0; $i<10; $i++){\n\t\t\t$ret = $ssdb->qpop($name);\n\t\t\tif($ret != $i){\n\t\t\t\t$this->assert(false);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t$ret = $ssdb->qfront($name);\n\t\t$this->assert($ret === null);\n\t\t$ret = $ssdb->qback($name);\n\t\t$this->assert($ret === null);\n\t\t\n\t\t$ssdb->qpush_back($name, 0);\n\t\t$ssdb->qpush_front($name, 9);\n\t\t$ret = $ssdb->qfront($name);\n\t\t$this->assert($ret == 9);\n\t\t$ret = $ssdb->qback($name);\n\t\t$this->assert($ret == 0);\n\n\t\t$ssdb->qclear($name);\n\t\tfor($i=0; $i<7; $i++){\n\t\t\t$size = $ssdb->qpush_back($name, $i);\n\t\t}\n\t\t$ret = $ssdb->qpop_front($name, 2);\n\t\t$this->assert(is_array($ret));\n\t\t$this->assert(count($ret) == 2);\n\t\t$this->assert($ret[0] == 0);\n\t\t$this->assert($ret[1] == 1);\n\t\t\n\t\t$ret = $ssdb->qpop_back($name, 2);\n\t\t$this->assert(is_array($ret));\n\t\t$ret = $ssdb->qpop($name, 2);\n\t\t$this->assert(is_array($ret));\n\n\t\t$ssdb->qclear($name);\n\t\tfor($i=0; $i<3; $i++){\n\t\t\t$ssdb->qpush_back($name, $i);\n\t\t}\n\n\t\t$ret = $ssdb->qset($name, 0, 'www');\n\t\t$this->assert($ret !== false);\n\t\t$ret = $ssdb->qset($name, 9990, 'www');\n\t\t$this->assert($ret === false);\n\t\t$ret = $ssdb->qget($name, 0);\n\t\t$this->assert($ret === 'www');\n\n\t\t$ret = $ssdb->qtrim_front($name, 2);\n\t\t$this->assert($ret === 2);\n\t\t$ret = $ssdb->qtrim_back($name, 2);\n\t\t$this->assert($ret === 1);\n\t}\n\n\tfunction test_hash(){\n\t\t$ssdb = $this->ssdb;\n\t\t$name = \"TEST_\" . mt_rand();\n\t\t$key = \"TEST_\" . mt_rand();\n\t\t$val = str_repeat(mt_rand(), mt_rand(1, 30));\n\n\t\t$ret = $ssdb->hsize($name);\n\t\t$this->assert($ret === 0);\n\n\t\t$ret = $ssdb->multi_hset($name, array('a' => 1, 'a' => 2));\n\t\t$this->assert($ret == 1);\n\t\t$ret = $ssdb->multi_hdel($name, array('a', 'a'));\n\t\t$this->assert($ret == 1);\n\n\t\t$ret = $ssdb->hset($name, $key, $val);\n\t\t$ret = $ssdb->hexists($name, $key);\n\t\t$this->assert($ret);\n\t\t$ret = $ssdb->hget($name, $key);\n\t\t$this->assert($ret === $val);\n\n\t\t$ret = $ssdb->hsize($name);\n\t\t$this->assert($ret === 1);\n\t\t$ret = $ssdb->hscan($name, '', '', 10);\n\t\t$this->assert(count($ret) == 1);\n\t\t$ret = $ssdb->hrscan($name, '', '', 10);\n\t\t$this->assert(count($ret) == 1);\n\t\t$ret = $ssdb->hkeys($name, '', '', 10);\n\t\t$this->assert(count($ret) == 1);\n\n\t\t$ret = $ssdb->hdel($name, $key);\n\t\t$ret = $ssdb->hsize($name);\n\t\t$this->assert($ret === 0);\n\t\t$ret = $ssdb->hscan($name, '', '', 10);\n\t\t$this->assert(count($ret) == 0);\n\t\t$ret = $ssdb->hrscan($name, '', '', 10);\n\t\t$this->assert(count($ret) == 0);\n\t\t$ret = $ssdb->hkeys($name, '', '', 10);\n\t\t$this->assert(count($ret) == 0);\n\n\t\t$ret = $ssdb->hset($name, 'a', $val);\n\t\t$ret = $ssdb->hset($name, 'b', $val);\n\t\t$ret = $ssdb->hscan($name, '', '', 10);\n\t\t$this->assert(count($ret) == 2);\n\t\tforeach($ret as $k=>$v){\n\t\t\t$this->assert($v === $val);\n\t\t}\n\t\t$ret = $ssdb->hscan($name, '', 'a', 10);\n\t\t$this->assert(count($ret) == 1);\n\t\t$ret = $ssdb->hscan($name, '', 'b', 10);\n\t\t$this->assert(count($ret) == 2);\n\t\t$ret = $ssdb->hrscan($name, '', 'b', 10);\n\t\t$this->assert(count($ret) == 1);\n\t\t$ret = $ssdb->hrscan($name, '', 'a', 10);\n\t\t$this->assert(count($ret) == 2);\n\n\t\t$ret = $ssdb->hscan($name, 'a', '', 10);\n\t\t$this->assert(count($ret) == 1);\n\t\t$ret = $ssdb->hscan($name, 'b', '', 10);\n\t\t$this->assert(count($ret) == 0);\n\t\t$ret = $ssdb->hrscan($name, '', '', 10);\n\t\t$this->assert(count($ret) == 2);\n\t\t$ret = $ssdb->hrscan($name, 'b', '', 10);\n\t\t$this->assert(count($ret) == 1);\n\t\t$ret = $ssdb->hrscan($name, 'a', '', 10);\n\t\t$this->assert(count($ret) == 0);\n\t\t$ret = $ssdb->hkeys($name, '', '', 10);\n\t\t$this->assert(count($ret) == 2);\n\t\t$ret = $ssdb->hkeys($name, 'a', '', 10);\n\t\t$this->assert(count($ret) == 1);\n\t\t$ret = $ssdb->hkeys($name, 'b', '', 10);\n\t\t$this->assert(count($ret) == 0);\n\t\t$ret = $ssdb->hdel($name, 'a');\n\t\t$ret = $ssdb->hdel($name, 'b');\n\n\t\t$ssdb->hset(\"TEST_a\", 'a', 1);\n\t\t$ssdb->hset(\"TEST_b\", 'a', 1);\n\t\t$ssdb->hset(\"TEST_c\", 'a', 1);\n\t\t$ret = $ssdb->hlist(\"TEST_a\", \"TEST_b\", 100);\n\t\t$this->assert(count($ret) == 1);\n\t\t$this->assert($ret[0] == \"TEST_b\");\n\n\t\t$ret = $ssdb->hexists('TEST_a', 'a');\n\t\t$this->assert($ret === true);\n\t\t$ssdb->hdel('TEST_a', 'a');\n\t\t$ret = $ssdb->hexists('TEST_a', 'a');\n\t\t$this->assert($ret === false);\n\t\t$ret = $ssdb->hget('TEST_a', 'a');\n\t\t$this->assert($ret === null);\n\t}\n\n\tfunction test_zset(){\n\t\t$ssdb = $this->ssdb;\n\t\t$name = \"TEST_\" . mt_rand();\n\t\t$key = \"TEST_\" . mt_rand();\n\t\t$val = mt_rand();\n\n\t\t$ret = $ssdb->zsize($name);\n\t\t$this->assert($ret === 0);\n\n\t\t$ret = $ssdb->multi_zset($name, array('a' => 1, 'a' => 2));\n\t\t$this->assert($ret == 1);\n\t\t$ret = $ssdb->multi_zdel($name, array('a', 'a'));\n\t\t$this->assert($ret == 1);\n\n\t\t$ret = $ssdb->zset($name, $key, $val);\n\t\t$ret = $ssdb->zexists($name, $key);\n\t\t$this->assert($ret);\n\t\t$ret = $ssdb->zget($name, $key);\n\t\t$this->assert($ret === $val);\n\n\t\t$ret = $ssdb->zsize($name);\n\t\t$this->assert($ret === 1);\n\t\t$ret = $ssdb->zscan($name, '', '', '', 10);\n\t\t$this->assert(count($ret) == 1);\n\t\t$ret = $ssdb->zrscan($name, '', '', '', 10);\n\t\t$this->assert(count($ret) == 1);\n\t\t$ret = $ssdb->zkeys($name, '', '', '', 10);\n\t\t$this->assert(count($ret) == 1);\n\n\t\t$ret = $ssdb->zdel($name, $key);\n\t\t$ret = $ssdb->zsize($name);\n\t\t$this->assert($ret === 0);\n\t\t$ret = $ssdb->zscan($name, '', '', '', 10);\n\t\t$this->assert(count($ret) == 0);\n\t\t$ret = $ssdb->zrscan($name, '', '', '', 10);\n\t\t$this->assert(count($ret) == 0);\n\t\t$ret = $ssdb->zkeys($name, '', '', '', 10);\n\t\t$this->assert(count($ret) == 0);\n\n\t\t$ret = $ssdb->zset($name, 'a', $val);\n\t\t$ret = $ssdb->zset($name, 'b', $val);\n\n\t\t$ret = $ssdb->zrank($name, 'aaaaaaaa');\n\t\t$this->assert($ret === null);\n\t\t$ret = $ssdb->zrank($name, 'a');\n\t\t$this->assert($ret != -1);\n\t\t$ret = $ssdb->zrrank($name, 'a');\n\t\t$this->assert($ret != -1);\n\n\t\t$ret = $ssdb->zrange($name, 0, 10);\n\t\t$this->assert(count($ret) == 2);\n\t\t$ret = $ssdb->zrrange($name, 0, 10);\n\t\t$this->assert(count($ret) == 2);\n\n\t\t$ret = $ssdb->zscan($name, '', '', '', 10);\n\t\t$this->assert(count($ret) == 2);\n\t\tforeach($ret as $k=>$v){\n\t\t\t$this->assert($v == $val);\n\t\t}\n\t\t$ret = $ssdb->zscan($name, 'a', '', '', 10);\n\t\t$this->assert(count($ret) == 1);\n\t\t$ret = $ssdb->zscan($name, 'b', '', '', 10);\n\t\t$this->assert(count($ret) == 0);\n\t\t$ret = $ssdb->zrscan($name, '', '', '', 10);\n\t\t$this->assert(count($ret) == 2);\n\t\t$ret = $ssdb->zrscan($name, 'b', $val, '', 10);\n\t\t$this->assert(count($ret) == 1);\n\t\t$ret = $ssdb->zrscan($name, 'a', $val, '', 10);\n\t\t$this->assert(count($ret) == 0);\n\t\t$ret = $ssdb->zkeys($name, '', '', '', 10);\n\t\t$this->assert(count($ret) == 2);\n\t\t$ret = $ssdb->zkeys($name, 'a', $val, '', 10);\n\t\t$this->assert(count($ret) == 1);\n\t\t$ret = $ssdb->zkeys($name, 'b', $val, '', 10);\n\t\t$this->assert(count($ret) == 0);\n\t\t$ret = $ssdb->zdel($name, 'a');\n\t\t$ret = $ssdb->zdel($name, 'b');\n\n\t\t$ssdb->zset(\"TEST_a\", 'a', 1);\n\t\t$ssdb->zset(\"TEST_b\", 'a', 1);\n\t\t$ssdb->zset(\"TEST_c\", 'a', 1);\n\t\t$ret = $ssdb->zlist(\"TEST_a\", \"TEST_b\", 100);\n\t\t$this->assert(count($ret) == 1);\n\t\t$this->assert($ret[0] == \"TEST_b\");\n\n\t\t$ret = $ssdb->zexists('TEST_a', 'a');\n\t\t$this->assert($ret === true);\n\t\t$ssdb->zdel('TEST_a', 'a');\n\t\t$ret = $ssdb->zexists('TEST_a', 'a');\n\t\t$this->assert($ret === false);\n\t\t$ret = $ssdb->zget('TEST_a', 'a');\n\t\t$this->assert($ret === null);\n\t\t\n\t\t$ssdb->zclear($name);\n\t\t$ssdb->request('multi_zset', $name, 'a', '1', 'b', '2', 'c', '3', 'd', '4', 'e', '5');\n\t\t$ret = $ssdb->zcount($name, 2, 4);\n\t\t$this->assert($ret === 3);\n\t\t$ret = $ssdb->zsum($name, 2, 4);\n\t\t$this->assert($ret === 9);\n\t\t$ret = $ssdb->zavg($name, 2, 3);\n\t\t$this->assert($ret === 2.5);\n\t\t$ret = $ssdb->zRemRangeByScore($name, 4, 5);\n\t\t$this->assert($ret === 2);\n\t\t$ret = $ssdb->zRemRangeByRank($name, 1, 2);\n\t\t$this->assert($ret === 2);\n\n\t\t$ssdb->zclear($name);\n\t\tfor($i=0; $i<10; $i++){\n\t\t\t$ssdb->zset($name, $i, $i);\n\t\t}\n\t\t$ret = $ssdb->zscan($name, '', 3, 10, 1);\n\t\t$vals = array_values($ret);\n\t\t$this->assert($vals[0] === 3);\n\t\t$ret = $ssdb->zscan($name, '3', 3, 10, 1);\n\t\t$vals = array_values($ret);\n\t\t$this->assert($vals[0] === 4);\n\n\t\t$ret = $ssdb->zrscan($name, '', 3, 1, 1);\n\t\t$vals = array_values($ret);\n\t\t$this->assert($vals[0] === 3);\n\t\t$ret = $ssdb->zrscan($name, '3', 3, 1, 1);\n\t\t$vals = array_values($ret);\n\t\t$this->assert($vals[0] === 2);\n\n\t\t$ssdb->zclear($name);\n\t\tfor($i=0; $i<10; $i++){\n\t\t\t$ssdb->zset($name, $i, $i);\n\t\t}\n\t\t$ret = $ssdb->zpop_front($name, 2);\n\t\t$keys = array_keys($ret);\n\t\t$vals = array_values($ret);\n\t\t$this->assert($keys[0] === 0 && $vals[0] === 0);\n\t\t$this->assert($keys[1] === 1 && $vals[1] === 1);\n\t\t$ret = $ssdb->zpop_back($name, 2);\n\t\t$keys = array_keys($ret);\n\t\t$vals = array_values($ret);\n\t\t$this->assert($keys[0] === 9 && $vals[0] === 9);\n\t\t$this->assert($keys[1] === 8 && $vals[1] === 8);\n\t}\n}\n\nclass UnitTest{\n\tprivate $result = array(\n\t\t\t'passed' => 0,\n\t\t\t'failed' => 0,\n\t\t\t'tests' => array(\n\t\t\t\t),\n\t\t\t);\n\n\tfunction run(){\n\t\t$class_name = get_class($this);\n\t\t$methods = get_class_methods($class_name);\n\t\tforeach($methods as $method){\n\t\t\tif(strpos($method, 'test_') === 0){\n\t\t\t\t$this->$method();\n\t\t\t}\n\t\t}\n\t\t$this->report();\n\t\t$this->clear();\n\t}\n\n\tfunction report(){\n\t\t$res = $this->result;\n\t\tprintf(\"passed: %3d, failed: %3d\\n\", $res['passed'], $res['failed']);\n\t\tforeach($res['tests'] as $test){\n\t\t\tif($test[0] === false){\n\t\t\t\tprintf(\"    Failed: %s:%d %s() %s\\n\", $test[2], $test[3], $test[1], $test[4]);\n\t\t\t}\n\t\t}\n\t\tif($res['failed']){\n\t\t\tprintf(\"passed: %3d, failed: %3d\\n\", $res['passed'], $res['failed']);\n\t\t}\n\t}\n\n\tfunction assert($val, $desc=''){\n\t\tif($val === true){\n\t\t\t$this->result['passed'] ++;\n\t\t}else{\n\t\t\t$val = false;\n\t\t\t$this->result['failed'] ++;\n\t\t}\n\t\t$bt = debug_backtrace(false);\n\t\t$func = $bt[1]['function'];\n\t\t$file = basename($bt[1]['file']);\n\t\t$line = $bt[0]['line'];\n\t\t$this->result['tests'][] = array(\n\t\t\t\t$val, $func, $file, $line, $desc\n\t\t\t\t);\n\t}\n\n}\n\n\n$test = new SSDBTest();\n$test->run();\n\n"
  },
  {
    "path": "version",
    "content": "1.9.8\n"
  }
]