]> granicus.if.org Git - icinga2/commitdiff
Remove experimental redis feature before 2.7 release 5369/head
authorMichael Friedrich <michael.friedrich@icinga.com>
Tue, 20 Jun 2017 09:52:24 +0000 (11:52 +0200)
committerMichael Friedrich <michael.friedrich@icinga.com>
Tue, 20 Jun 2017 09:52:24 +0000 (11:52 +0200)
50 files changed:
CMakeLists.txt
etc/icinga2/features-available/redis.conf [deleted file]
lib/CMakeLists.txt
lib/redis/CMakeLists.txt [deleted file]
lib/redis/rediswriter-status.cpp [deleted file]
lib/redis/rediswriter-utility.cpp [deleted file]
lib/redis/rediswriter.cpp [deleted file]
lib/redis/rediswriter.hpp [deleted file]
lib/redis/rediswriter.ti [deleted file]
third-party/CMakeLists.txt
third-party/hiredis/.gitignore [deleted file]
third-party/hiredis/.travis.yml [deleted file]
third-party/hiredis/CHANGELOG.md [deleted file]
third-party/hiredis/CMakeLists.txt [deleted file]
third-party/hiredis/COPYING [deleted file]
third-party/hiredis/Makefile [deleted file]
third-party/hiredis/README.md [deleted file]
third-party/hiredis/adapters/ae.h [deleted file]
third-party/hiredis/adapters/glib.h [deleted file]
third-party/hiredis/adapters/ivykis.h [deleted file]
third-party/hiredis/adapters/libev.h [deleted file]
third-party/hiredis/adapters/libevent.h [deleted file]
third-party/hiredis/adapters/libuv.h [deleted file]
third-party/hiredis/adapters/macosx.h [deleted file]
third-party/hiredis/adapters/qt.h [deleted file]
third-party/hiredis/async.c [deleted file]
third-party/hiredis/async.h [deleted file]
third-party/hiredis/dict.c [deleted file]
third-party/hiredis/dict.h [deleted file]
third-party/hiredis/examples/example-ae.c [deleted file]
third-party/hiredis/examples/example-glib.c [deleted file]
third-party/hiredis/examples/example-ivykis.c [deleted file]
third-party/hiredis/examples/example-libev.c [deleted file]
third-party/hiredis/examples/example-libevent.c [deleted file]
third-party/hiredis/examples/example-libuv.c [deleted file]
third-party/hiredis/examples/example-macosx.c [deleted file]
third-party/hiredis/examples/example-qt.cpp [deleted file]
third-party/hiredis/examples/example-qt.h [deleted file]
third-party/hiredis/examples/example.c [deleted file]
third-party/hiredis/fmacros.h [deleted file]
third-party/hiredis/hiredis.c [deleted file]
third-party/hiredis/hiredis.h [deleted file]
third-party/hiredis/net.c [deleted file]
third-party/hiredis/net.h [deleted file]
third-party/hiredis/read.c [deleted file]
third-party/hiredis/read.h [deleted file]
third-party/hiredis/sds.c [deleted file]
third-party/hiredis/sds.h [deleted file]
third-party/hiredis/test.c [deleted file]
third-party/hiredis/win32.h [deleted file]

index ae784f2ba0f821b2f5a0748a87cc69360ee8b6c2..5af82851f1604376e82a4594f8698d2e42e7ef05 100644 (file)
@@ -37,7 +37,6 @@ option(ICINGA2_WITH_HELLO "Build the hello module" OFF)
 option(ICINGA2_WITH_LIVESTATUS "Build the Livestatus module" ON)
 option(ICINGA2_WITH_NOTIFICATION "Build the notification module" ON)
 option(ICINGA2_WITH_PERFDATA "Build the perfdata module" ON)
-option(ICINGA2_WITH_REDIS "Build the redis module" ON)
 option(ICINGA2_WITH_STUDIO "Build the Icinga Studio application" OFF)
 option(ICINGA2_WITH_TESTS "Run unit tests" ON)
 
diff --git a/etc/icinga2/features-available/redis.conf b/etc/icinga2/features-available/redis.conf
deleted file mode 100644 (file)
index bcf781a..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * The redis library implements functionality for putting Icinga
- * event data into a redis database.
- *
- * NOTE: This is experimental and may change without further notice.
- */
-
-library "redis"
-
-object RedisWriter "redis" {
-  //host = "127.0.0.1"
-  //port = 6379
-  //password = "xxx"
-}
index 334d9709dcdd88032e530cc370ac833275f08ebb..b0d702ce3f97821492b5e9d48b3611606ef59b5d 100644 (file)
@@ -62,8 +62,4 @@ if(ICINGA2_WITH_PERFDATA)
   add_subdirectory(perfdata)
 endif()
 
-if(ICINGA2_WITH_REDIS)
-  add_subdirectory(redis)
-endif()
-
 set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS}" PARENT_SCOPE)
diff --git a/lib/redis/CMakeLists.txt b/lib/redis/CMakeLists.txt
deleted file mode 100644 (file)
index 540fffa..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-# Icinga 2
-# Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/)
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
-mkclass_target(rediswriter.ti rediswriter.tcpp rediswriter.thpp)
-
-set(redis_SOURCES
-  rediswriter.cpp rediswriter-status.cpp rediswriter-utility.cpp rediswriter.thpp
-)
-
-if(ICINGA2_UNITY_BUILD)
-    mkunity_target(redis redis redis_SOURCES)
-endif()
-
-add_library(redis SHARED ${redis_SOURCES})
-
-target_link_libraries(redis ${Boost_LIBRARIES} base config icinga remote hiredis)
-
-include_directories(${icinga2_SOURCE_DIR}/third-party)
-link_directories(${icinga2_BINARY_DIR}/third-party/hiredis)
-
-set_target_properties (
-  redis PROPERTIES
-  INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}/icinga2
-  DEFINE_SYMBOL I2_REDIS_BUILD
-  FOLDER Components
-  VERSION ${SPEC_VERSION}
-)
-
-install_if_not_exists(
-  ${PROJECT_SOURCE_DIR}/etc/icinga2/features-available/redis.conf
-  ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available
-)
-
-install(
-  TARGETS redis
-  RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/icinga2
-)
-
diff --git a/lib/redis/rediswriter-status.cpp b/lib/redis/rediswriter-status.cpp
deleted file mode 100644 (file)
index 985fd0e..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-/******************************************************************************
- * Icinga 2                                                                   *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/)  *
- *                                                                            *
- * This program is free software; you can redistribute it and/or              *
- * modify it under the terms of the GNU General Public License                *
- * as published by the Free Software Foundation; either version 2             *
- * of the License, or (at your option) any later version.                     *
- *                                                                            *
- * This program is distributed in the hope that it will be useful,            *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
- * GNU General Public License for more details.                               *
- *                                                                            *
- * You should have received a copy of the GNU General Public License          *
- * along with this program; if not, write to the Free Software Foundation     *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
- ******************************************************************************/
-
-#include "redis/rediswriter.hpp"
-#include "icinga/customvarobject.hpp"
-#include "icinga/host.hpp"
-#include "icinga/service.hpp"
-#include "base/json.hpp"
-#include "base/logger.hpp"
-#include "base/serializer.hpp"
-#include "base/tlsutility.hpp"
-#include "base/initialize.hpp"
-
-using namespace icinga;
-
-/*
-- icinga:config:<type> as hash
-key: sha1 checksum(name)
-value: JsonEncode(Serialize(object, FAConfig)) + config_checksum
-
-Diff between calculated config_checksum and Redis json config_checksum
-Alternative: Replace into.
-
-
-- icinga:status:<type> as hash
-key: sha1 checksum(name)
-value: JsonEncode(Serialize(object, FAState))
-*/
-
-INITIALIZE_ONCE(&RedisWriter::ConfigStaticInitialize);
-
-void RedisWriter::ConfigStaticInitialize(void)
-{
-       /* triggered in ProcessCheckResult(), requires UpdateNextCheck() to be called before */
-       ConfigObject::OnStateChanged.connect(boost::bind(&RedisWriter::StateChangedHandler, _1));
-       CustomVarObject::OnVarsChanged.connect(boost::bind(&RedisWriter::VarsChangedHandler, _1));
-
-       /* triggered on create, update and delete objects */
-       ConfigObject::OnActiveChanged.connect(boost::bind(&RedisWriter::VersionChangedHandler, _1));
-       ConfigObject::OnVersionChanged.connect(boost::bind(&RedisWriter::VersionChangedHandler, _1));
-}
-
-void RedisWriter::UpdateAllConfigObjects(void)
-{
-       AssertOnWorkQueue();
-
-       double startTime = Utility::GetTime();
-
-       //TODO: "Publish" the config dump by adding another event, globally or by object
-       ExecuteQuery({ "MULTI" });
-
-       for (const Type::Ptr& type : Type::GetAllTypes()) {
-               if (!ConfigObject::TypeInstance->IsAssignableFrom(type))
-                       continue;
-
-               String typeName = type->GetName();
-
-               /* replace into aka delete insert is faster than a full diff */
-               ExecuteQuery({ "DEL", "icinga:config:" + typeName, "icinga:config:" + typeName + ":checksum", "icinga:status:" + typeName });
-
-               /* fetch all objects and dump them */
-               ConfigType *ctype = dynamic_cast<ConfigType *>(type.get());
-               VERIFY(ctype);
-
-               for (const ConfigObject::Ptr& object : ctype->GetObjects()) {
-                       SendConfigUpdate(object, typeName);
-                       SendStatusUpdate(object, typeName);
-               }
-
-               /* publish config type dump finished */
-               ExecuteQuery({ "PUBLISH", "icinga:config:dump", typeName });
-       }
-
-       ExecuteQuery({ "EXEC" });
-
-       Log(LogInformation, "RedisWriter")
-           << "Initial config/status dump finished in " << Utility::GetTime() - startTime << " seconds.";
-}
-
-void RedisWriter::SendConfigUpdate(const ConfigObject::Ptr& object, const String& typeName, bool runtimeUpdate)
-{
-       AssertOnWorkQueue();
-
-       /* during startup we might send duplicated object config, ignore them without any connection */
-       if (!m_Context)
-               return;
-
-       /* TODO: This isn't essentially correct as we don't keep track of config objects ourselves. This would avoid duplicated config updates at startup.
-       if (!runtimeUpdate && m_ConfigDumpInProgress)
-               return;
-       */
-
-       /* Serialize config object attributes */
-       Dictionary::Ptr objectAttrs = SerializeObjectAttrs(object, FAConfig);
-
-       String jsonBody = JsonEncode(objectAttrs);
-
-       String objectName = object->GetName();
-
-       ExecuteQuery({ "HSET", "icinga:config:" + typeName, objectName, jsonBody });
-
-       /* check sums */
-       /* hset icinga:config:Host:checksums localhost { "name_checksum": "...", "properties_checksum": "...", "groups_checksum": "...", "vars_checksum": null } */
-       Dictionary::Ptr checkSum = new Dictionary();
-
-       checkSum->Set("name_checksum", CalculateCheckSumString(object->GetName()));
-
-       // TODO: move this elsewhere
-       Checkable::Ptr checkable = dynamic_pointer_cast<Checkable>(object);
-
-       if (checkable) {
-               Host::Ptr host;
-               Service::Ptr service;
-
-               tie(host, service) = GetHostService(checkable);
-
-               if (service)
-                       checkSum->Set("groups_checksum", CalculateCheckSumGroups(service->GetGroups()));
-               else
-                       checkSum->Set("groups_checksum", CalculateCheckSumGroups(host->GetGroups()));
-       }
-
-       checkSum->Set("properties_checksum", CalculateCheckSumProperties(object));
-       checkSum->Set("vars_checksum", CalculateCheckSumVars(object));
-
-       String checkSumBody = JsonEncode(checkSum);
-
-       ExecuteQuery({ "HSET", "icinga:config:" + typeName + ":checksum", objectName, checkSumBody });
-
-       /* publish runtime updated objects immediately */
-       if (!runtimeUpdate)
-               return;
-
-       /*
-       PUBLISH "icinga:config:dump" "Host"
-       PUBLISH "icinga:config:update" "Host:__name!checksumBody"
-       PUBLISH "icinga:config:delete" "Host:__name"
-       */
-
-       ExecuteQuery({ "PUBLISH", "icinga:config:update", typeName + ":" + objectName + "!" + checkSumBody });
-}
-
-void RedisWriter::SendConfigDelete(const ConfigObject::Ptr& object, const String& typeName)
-{
-       AssertOnWorkQueue();
-
-       /* during startup we might send duplicated object config, ignore them without any connection */
-       if (!m_Context)
-               return;
-
-       String objectName = object->GetName();
-
-       ExecuteQuery({ "HDEL", "icinga:config:" + typeName, objectName });
-       ExecuteQuery({ "HDEL", "icinga:config:" + typeName + ":checksum", objectName });
-       ExecuteQuery({ "HDEL", "icinga:status:" + typeName, objectName });
-
-       /*
-       PUBLISH "icinga:config:dump" "Host"
-       PUBLISH "icinga:config:update" "Host:__name!checksumBody"
-       PUBLISH "icinga:config:delete" "Host:__name"
-       */
-
-       ExecuteQuery({ "PUBLISH", "icinga:config:delete", typeName + ":" + objectName });
-}
-
-void RedisWriter::SendStatusUpdate(const ConfigObject::Ptr& object, const String& typeName)
-{
-       AssertOnWorkQueue();
-
-       /* during startup we might receive check results, ignore them without any connection */
-       if (!m_Context)
-               return;
-
-       /* Serialize config object attributes */
-       Dictionary::Ptr objectAttrs = SerializeObjectAttrs(object, FAState);
-
-       String jsonBody = JsonEncode(objectAttrs);
-
-       String objectName = object->GetName();
-
-       ExecuteQuery({ "HSET", "icinga:status:" + typeName, objectName, jsonBody });
-
-       /* Icinga DB part for Icinga Web 2 */
-       Checkable::Ptr checkable = dynamic_pointer_cast<Checkable>(object);
-
-       if (checkable) {
-               Dictionary::Ptr attrs = new Dictionary();
-               String tableName;
-               String objectCheckSum = CalculateCheckSumString(objectName, true); //store binary checksum here
-
-               Host::Ptr host;
-               Service::Ptr service;
-
-               tie(host, service) = GetHostService(checkable);
-
-               if (service) {
-                       tableName = "servicestate";
-                       attrs->Set("service_checksum", objectCheckSum);
-                       attrs->Set("host_checksum", CalculateCheckSumString(host->GetName(), true));
-               } else {
-                       tableName = "hoststate";
-                       attrs->Set("host_checksum", objectCheckSum);
-               }
-
-               attrs->Set("last_check", checkable->GetLastCheck());
-               attrs->Set("next_check", checkable->GetNextCheck());
-
-               attrs->Set("severity", checkable->GetSeverity());
-
-/*
-        'host_checksum'    => null,
-        'command'          => null, // JSON, array
-        'execution_start'  => null,
-        'execution_end'    => null,
-        'schedule_start'   => null,
-        'schedule_end'     => null,
-        'exit_status'      => null,
-        'output'           => null,
-        'performance_data' => null, // JSON, array
-
-
-10.0.3.12:6379> keys icinga:hoststate.*
-1) "icinga:hoststate.~\xf5a\x91+\x03\x97\x99\xb5(\x16 CYm\xb1\xdf\x85\xa2\xcb"
-10.0.3.12:6379> get "icinga:hoststate.~\xf5a\x91+\x03\x97\x99\xb5(\x16 CYm\xb1\xdf\x85\xa2\xcb"
-"{\"command\":[\"\\/usr\\/lib\\/nagios\\/plugins\\/check_ping\",\"-H\",\"127.0.0.1\",\"-c\",\"5000,100%\",\"-w\",\"3000,80%\"],\"execution_start\":1492007581.7624,\"execution_end\":1492007585.7654,\"schedule_start\":1492007581.7609,\"schedule_end\":1492007585.7655,\"exit_status\":0,\"output\":\"PING OK - Packet loss = 0%, RTA = 0.08 ms\",\"performance_data\":[\"rta=0.076000ms;3000.000000;5000.000000;0.000000\",\"pl=0%;80;100;0\"]}"
-
-*/
-
-               CheckResult::Ptr cr = checkable->GetLastCheckResult();
-
-               if (cr) {
-                       attrs->Set("command", JsonEncode(cr->GetCommand()));
-                       attrs->Set("execution_start", cr->GetExecutionStart());
-                       attrs->Set("execution_end", cr->GetExecutionEnd());
-                       attrs->Set("schedule_start", cr->GetScheduleStart());
-                       attrs->Set("schedule_end", cr->GetScheduleStart());
-                       attrs->Set("exit_status", cr->GetExitStatus());
-                       attrs->Set("output", cr->GetOutput());
-                       attrs->Set("performance_data", JsonEncode(cr->GetPerformanceData()));
-               }
-
-               String jsonAttrs = JsonEncode(attrs);
-               String key = "icinga:" + tableName + "." + objectCheckSum;
-               ExecuteQuery({ "SET", key, jsonAttrs });
-
-               /* expire in check_interval * attempts + timeout + some more seconds */
-               double expireTime = checkable->GetCheckInterval() * checkable->GetMaxCheckAttempts() + 60;
-               ExecuteQuery({ "EXPIRE", key, String(expireTime) });
-       }
-}
-
-void RedisWriter::StateChangedHandler(const ConfigObject::Ptr& object)
-{
-       Type::Ptr type = object->GetReflectionType();
-
-       for (const RedisWriter::Ptr& rw : ConfigType::GetObjectsByType<RedisWriter>()) {
-               rw->m_WorkQueue.Enqueue(boost::bind(&RedisWriter::SendStatusUpdate, rw, object, type->GetName()));
-       }
-}
-
-void RedisWriter::VarsChangedHandler(const ConfigObject::Ptr& object)
-{
-       Type::Ptr type = object->GetReflectionType();
-
-       for (const RedisWriter::Ptr& rw : ConfigType::GetObjectsByType<RedisWriter>()) {
-               rw->m_WorkQueue.Enqueue(boost::bind(&RedisWriter::SendConfigUpdate, rw, object, type->GetName(), true));
-       }
-}
-
-void RedisWriter::VersionChangedHandler(const ConfigObject::Ptr& object)
-{
-       Type::Ptr type = object->GetReflectionType();
-
-       if (object->IsActive()) {
-               /* Create or update the object config */
-               for (const RedisWriter::Ptr& rw : ConfigType::GetObjectsByType<RedisWriter>()) {
-                       rw->m_WorkQueue.Enqueue(boost::bind(&RedisWriter::SendConfigUpdate, rw.get(), object, type->GetName(), true));
-               }
-       } else if (!object->IsActive() && object->GetExtension("ConfigObjectDeleted")) { /* same as in apilistener-configsync.cpp */
-               /* Delete object config */
-               for (const RedisWriter::Ptr& rw : ConfigType::GetObjectsByType<RedisWriter>()) {
-                       rw->m_WorkQueue.Enqueue(boost::bind(&RedisWriter::SendConfigDelete, rw.get(), object, type->GetName()));
-               }
-       }
-}
diff --git a/lib/redis/rediswriter-utility.cpp b/lib/redis/rediswriter-utility.cpp
deleted file mode 100644 (file)
index e91edc8..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/******************************************************************************
- * Icinga 2                                                                   *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/)  *
- *                                                                            *
- * This program is free software; you can redistribute it and/or              *
- * modify it under the terms of the GNU General Public License                *
- * as published by the Free Software Foundation; either version 2             *
- * of the License, or (at your option) any later version.                     *
- *                                                                            *
- * This program is distributed in the hope that it will be useful,            *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
- * GNU General Public License for more details.                               *
- *                                                                            *
- * You should have received a copy of the GNU General Public License          *
- * along with this program; if not, write to the Free Software Foundation     *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
- ******************************************************************************/
-
-#include "redis/rediswriter.hpp"
-#include "icinga/customvarobject.hpp"
-#include "base/json.hpp"
-#include "base/logger.hpp"
-#include "base/serializer.hpp"
-#include "base/tlsutility.hpp"
-#include "base/initialize.hpp"
-
-using namespace icinga;
-
-String RedisWriter::FormatCheckSumBinary(const String& str)
-{
-       char output[20*2+1];
-       for (int i = 0; i < 20; i++)
-               sprintf(output + 2 * i, "%02x", str[i]);
-
-       return output;
-}
-
-String RedisWriter::CalculateCheckSumString(const String& str, bool binary)
-{
-       return SHA1(str, binary);
-}
-
-String RedisWriter::CalculateCheckSumGroups(const Array::Ptr& groups, bool binary)
-{
-       String output;
-
-       ObjectLock olock(groups);
-
-       for (const String& group : groups) {
-               output += SHA1(group, true); //binary checksum required here
-       }
-
-       return SHA1(output, binary);
-}
-
-String RedisWriter::CalculateCheckSumProperties(const ConfigObject::Ptr& object, bool binary)
-{
-       //TODO: consider precision of 6 for double values; use specific config fields for hashing?
-       return HashValue(object, binary);
-}
-
-String RedisWriter::CalculateCheckSumVars(const ConfigObject::Ptr& object, bool binary)
-{
-       CustomVarObject::Ptr customVarObject = dynamic_pointer_cast<CustomVarObject>(object);
-
-       if (!customVarObject)
-               return HashValue(Empty, binary);
-
-       Dictionary::Ptr vars = customVarObject->GetVars();
-
-       if (!vars)
-               return HashValue(Empty, binary);
-
-       return HashValue(vars, binary);
-}
-
-String RedisWriter::HashValue(const Value& value, bool binary)
-{
-       Value temp;
-
-       Type::Ptr type = value.GetReflectionType();
-
-       if (ConfigObject::TypeInstance->IsAssignableFrom(type))
-               temp = Serialize(value, FAConfig);
-       else
-               temp = value;
-
-       return SHA1(JsonEncode(temp), binary);
-}
-
-Dictionary::Ptr RedisWriter::SerializeObjectAttrs(const Object::Ptr& object, int fieldType)
-{
-       Type::Ptr type = object->GetReflectionType();
-
-       Dictionary::Ptr resultAttrs = new Dictionary();
-
-       for (int fid = 0; fid < type->GetFieldCount(); fid++) {
-               Field field = type->GetFieldInfo(fid);
-
-               if ((field.Attributes & fieldType) == 0)
-                       continue;
-
-               Value val = object->GetField(fid);
-
-               /* hide attributes which shouldn't be user-visible */
-               if (field.Attributes & FANoUserView)
-                       continue;
-
-               /* hide internal navigation fields */
-               if (field.Attributes & FANavigation && !(field.Attributes & (FAConfig | FAState)))
-                       continue;
-
-               Value sval = Serialize(val);
-               resultAttrs->Set(field.Name, sval);
-       }
-
-       return resultAttrs;
-}
-
diff --git a/lib/redis/rediswriter.cpp b/lib/redis/rediswriter.cpp
deleted file mode 100644 (file)
index 7040306..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-/******************************************************************************
- * Icinga 2                                                                   *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/)  *
- *                                                                            *
- * This program is free software; you can redistribute it and/or              *
- * modify it under the terms of the GNU General Public License                *
- * as published by the Free Software Foundation; either version 2             *
- * of the License, or (at your option) any later version.                     *
- *                                                                            *
- * This program is distributed in the hope that it will be useful,            *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
- * GNU General Public License for more details.                               *
- *                                                                            *
- * You should have received a copy of the GNU General Public License          *
- * along with this program; if not, write to the Free Software Foundation     *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
- ******************************************************************************/
-
-#include "redis/rediswriter.hpp"
-#include "redis/rediswriter.tcpp"
-#include "remote/eventqueue.hpp"
-#include "base/json.hpp"
-#include "base/statsfunction.hpp"
-
-using namespace icinga;
-
-REGISTER_TYPE(RedisWriter);
-
-RedisWriter::RedisWriter(void)
-    : m_Context(NULL)
-{ }
-
-/**
- * Starts the component.
- */
-void RedisWriter::Start(bool runtimeCreated)
-{
-       ObjectImpl<RedisWriter>::Start(runtimeCreated);
-
-       Log(LogInformation, "RedisWriter")
-           << "'" << GetName() << "' started.";
-
-       m_ConfigDumpInProgress = false;
-
-       m_WorkQueue.SetExceptionCallback(boost::bind(&RedisWriter::ExceptionHandler, this, _1));
-
-       m_ReconnectTimer = new Timer();
-       m_ReconnectTimer->SetInterval(15);
-       m_ReconnectTimer->OnTimerExpired.connect(boost::bind(&RedisWriter::ReconnectTimerHandler, this));
-       m_ReconnectTimer->Start();
-       m_ReconnectTimer->Reschedule(0);
-
-       m_SubscriptionTimer = new Timer();
-       m_SubscriptionTimer->SetInterval(15);
-       m_SubscriptionTimer->OnTimerExpired.connect(boost::bind(&RedisWriter::UpdateSubscriptionsTimerHandler, this));
-       m_SubscriptionTimer->Start();
-
-       m_StatsTimer = new Timer();
-       m_StatsTimer->SetInterval(10);
-       m_StatsTimer->OnTimerExpired.connect(boost::bind(&RedisWriter::PublishStatsTimerHandler, this));
-       m_StatsTimer->Start();
-
-       boost::thread thread(boost::bind(&RedisWriter::HandleEvents, this));
-       thread.detach();
-}
-
-void RedisWriter::ExceptionHandler(boost::exception_ptr exp)
-{
-       Log(LogCritical, "RedisWriter", "Exception during redis query. Verify that Redis is operational.");
-
-       Log(LogDebug, "RedisWriter")
-           << "Exception during redis operation: " << DiagnosticInformation(exp);
-
-       if (m_Context) {
-               redisFree(m_Context);
-               m_Context = NULL;
-       }
-}
-
-void RedisWriter::ReconnectTimerHandler(void)
-{
-       m_WorkQueue.Enqueue(boost::bind(&RedisWriter::TryToReconnect, this));
-}
-
-void RedisWriter::TryToReconnect(void)
-{
-       AssertOnWorkQueue();
-
-       if (m_Context)
-               return;
-
-       String path = GetPath();
-       String host = GetHost();
-
-       Log(LogInformation, "RedisWriter", "Trying to connect to redis server");
-
-       if (path.IsEmpty())
-               m_Context = redisConnect(host.CStr(), GetPort());
-       else
-               m_Context = redisConnectUnix(path.CStr());
-
-       if (!m_Context || m_Context->err) {
-               if (!m_Context) {
-                       Log(LogWarning, "RedisWriter", "Cannot allocate redis context.");
-               } else {
-                       Log(LogWarning, "RedisWriter", "Connection error: ")
-                           << m_Context->errstr;
-               }
-
-               if (m_Context) {
-                       redisFree(m_Context);
-                       m_Context = NULL;
-               }
-
-               return;
-       }
-
-       String password = GetPassword();
-
-       /* TODO: exception is fired but terminates reconnect silently.
-        * Error case: Password does not match, or even: "Client sent AUTH, but no password is set" which also results in an error.
-        */
-       if (!password.IsEmpty())
-               ExecuteQuery({ "AUTH", password });
-
-       int dbIndex = GetDbIndex();
-
-       if (dbIndex != 0)
-               ExecuteQuery({ "SELECT", Convert::ToString(dbIndex) });
-
-       /* Config dump */
-       m_ConfigDumpInProgress = true;
-
-       UpdateAllConfigObjects();
-
-       m_ConfigDumpInProgress = false;
-}
-
-void RedisWriter::UpdateSubscriptionsTimerHandler(void)
-{
-       m_WorkQueue.Enqueue(boost::bind(&RedisWriter::UpdateSubscriptions, this));
-}
-
-void RedisWriter::UpdateSubscriptions(void)
-{
-       AssertOnWorkQueue();
-
-       if (!m_Context)
-               return;
-
-       Log(LogInformation, "RedisWriter", "Updating Redis subscriptions");
-
-       std::map<String, String> subscriptions;
-       long long cursor = 0;
-
-       do {
-               boost::shared_ptr<redisReply> reply = ExecuteQuery({ "SCAN", Convert::ToString(cursor), "MATCH", "icinga:subscription:*", "COUNT", "1000" });
-
-               VERIFY(reply->type == REDIS_REPLY_ARRAY);
-               VERIFY(reply->elements % 2 == 0);
-
-               redisReply *cursorReply = reply->element[0];
-               cursor = Convert::ToLong(cursorReply->str);
-
-               redisReply *keysReply = reply->element[1];
-
-               for (size_t i = 0; i < keysReply->elements; i++) {
-                       redisReply *keyReply = keysReply->element[i];
-                       VERIFY(keyReply->type == REDIS_REPLY_STRING);
-
-                       boost::shared_ptr<redisReply> vreply = ExecuteQuery({ "GET", keyReply->str });
-
-                       subscriptions[keyReply->str] = vreply->str;
-               }
-       } while (cursor != 0);
-
-       m_Subscriptions.clear();
-
-       for (const std::pair<String, String>& kv : subscriptions) {
-               const String& key = kv.first.SubStr(20); /* removes the "icinga:subscription: prefix */
-               const String& value = kv.second;
-
-               try {
-                       Dictionary::Ptr subscriptionInfo = JsonDecode(value);
-
-                       Log(LogInformation, "RedisWriter")
-                           << "Subscriber Info - Key: " << key << " Value: " << Value(subscriptionInfo);
-
-                       RedisSubscriptionInfo rsi;
-
-                       Array::Ptr types = subscriptionInfo->Get("types");
-
-                       if (types)
-                               rsi.EventTypes = types->ToSet<String>();
-
-                       m_Subscriptions[key] = rsi;
-               } catch (const std::exception& ex) {
-                       Log(LogWarning, "RedisWriter")
-                           << "Invalid Redis subscriber info for subscriber '" << key << "': " << DiagnosticInformation(ex);
-
-                       continue;
-               }
-               //TODO
-       }
-
-       Log(LogInformation, "RedisWriter")
-           << "Current Redis event subscriptions: " << m_Subscriptions.size();
-}
-
-void RedisWriter::PublishStatsTimerHandler(void)
-{
-       m_WorkQueue.Enqueue(boost::bind(&RedisWriter::PublishStats, this));
-}
-
-void RedisWriter::PublishStats(void)
-{
-       AssertOnWorkQueue();
-
-       if (!m_Context)
-               return;
-
-       //TODO: Figure out if more stats can be useful here.
-       StatsFunction::Ptr func = StatsFunctionRegistry::GetInstance()->GetItem("CIB");
-       Dictionary::Ptr status = new Dictionary();
-       Array::Ptr perfdata = new Array();
-       func->Invoke(status, perfdata);
-       String jsonStats = JsonEncode(status);
-
-       ExecuteQuery({ "PUBLISH", "icinga:stats", jsonStats });
-}
-
-void RedisWriter::HandleEvents(void)
-{
-       String queueName = Utility::NewUniqueID();
-       EventQueue::Ptr queue = new EventQueue(queueName);
-       EventQueue::Register(queueName, queue);
-
-       std::set<String> types;
-       types.insert("CheckResult");
-       types.insert("StateChange");
-       types.insert("Notification");
-       types.insert("AcknowledgementSet");
-       types.insert("AcknowledgementCleared");
-       types.insert("CommentAdded");
-       types.insert("CommentRemoved");
-       types.insert("DowntimeAdded");
-       types.insert("DowntimeRemoved");
-       types.insert("DowntimeStarted");
-       types.insert("DowntimeTriggered");
-
-       queue->SetTypes(types);
-
-       queue->AddClient(this);
-
-       for (;;) {
-               Dictionary::Ptr event = queue->WaitForEvent(this);
-
-               if (!event)
-                       continue;
-
-               m_WorkQueue.Enqueue(boost::bind(&RedisWriter::HandleEvent, this, event));
-       }
-
-       queue->RemoveClient(this);
-       EventQueue::UnregisterIfUnused(queueName, queue);
-}
-
-void RedisWriter::HandleEvent(const Dictionary::Ptr& event)
-{
-       AssertOnWorkQueue();
-
-       if (!m_Context)
-               return;
-
-       for (const std::pair<String, RedisSubscriptionInfo>& kv : m_Subscriptions) {
-               const auto& name = kv.first;
-               const auto& rsi = kv.second;
-
-               if (rsi.EventTypes.find(event->Get("type")) == rsi.EventTypes.end())
-                       continue;
-
-               String body = JsonEncode(event);
-
-               ExecuteQuery({ "LPUSH", "icinga:event:" + name, body });
-       }
-}
-
-void RedisWriter::Stop(bool runtimeRemoved)
-{
-       Log(LogInformation, "RedisWriter")
-           << "'" << GetName() << "' stopped.";
-
-       ObjectImpl<RedisWriter>::Stop(runtimeRemoved);
-}
-
-void RedisWriter::AssertOnWorkQueue(void)
-{
-       ASSERT(m_WorkQueue.IsWorkerThread());
-}
-
-boost::shared_ptr<redisReply> RedisWriter::ExecuteQuery(const std::vector<String>& query)
-{
-       const char **argv;
-       size_t *argvlen;
-
-       argv = new const char *[query.size()];
-       argvlen = new size_t[query.size()];
-
-       for (std::vector<String>::size_type i = 0; i < query.size(); i++) {
-               argv[i] = query[i].CStr();
-               argvlen[i] = query[i].GetLength();
-       }
-
-       redisReply *reply = reinterpret_cast<redisReply *>(redisCommandArgv(m_Context, query.size(), argv, argvlen));
-
-       delete [] argv;
-       delete [] argvlen;
-
-       if (reply->type == REDIS_REPLY_ERROR) {
-               Log(LogCritical, "RedisWriter")
-                   << "Redis query failed: " << reply->str;
-
-               String msg = reply->str;
-
-               freeReplyObject(reply);
-
-               BOOST_THROW_EXCEPTION(
-                   redis_error()
-                       << errinfo_message(msg)
-                       << errinfo_redis_query(Utility::Join(Array::FromVector(query), ' ', false))
-               );
-       }
-
-       return boost::shared_ptr<redisReply>(reply);
-}
diff --git a/lib/redis/rediswriter.hpp b/lib/redis/rediswriter.hpp
deleted file mode 100644 (file)
index 07f56a1..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/******************************************************************************
- * Icinga 2                                                                   *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/)  *
- *                                                                            *
- * This program is free software; you can redistribute it and/or              *
- * modify it under the terms of the GNU General Public License                *
- * as published by the Free Software Foundation; either version 2             *
- * of the License, or (at your option) any later version.                     *
- *                                                                            *
- * This program is distributed in the hope that it will be useful,            *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
- * GNU General Public License for more details.                               *
- *                                                                            *
- * You should have received a copy of the GNU General Public License          *
- * along with this program; if not, write to the Free Software Foundation     *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
- ******************************************************************************/
-
-#ifndef REDISWRITER_H
-#define REDISWRITER_H
-
-#include "redis/rediswriter.thpp"
-#include "remote/messageorigin.hpp"
-#include "base/timer.hpp"
-#include "base/workqueue.hpp"
-#include <hiredis/hiredis.h>
-
-namespace icinga
-{
-
-struct RedisSubscriptionInfo
-{
-       std::set<String> EventTypes;
-};
-
-/**
- * @ingroup redis
- */
-class RedisWriter : public ObjectImpl<RedisWriter>
-{
-public:
-       DECLARE_OBJECT(RedisWriter);
-       DECLARE_OBJECTNAME(RedisWriter);
-
-       RedisWriter(void);
-
-       static void ConfigStaticInitialize(void);
-
-       virtual void Start(bool runtimeCreated) override;
-       virtual void Stop(bool runtimeRemoved) override;
-
-private:
-       void ReconnectTimerHandler(void);
-       void TryToReconnect(void);
-       void HandleEvents(void);
-       void HandleEvent(const Dictionary::Ptr& event);
-
-       void UpdateSubscriptionsTimerHandler(void);
-       void UpdateSubscriptions(void);
-       void PublishStatsTimerHandler(void);
-       void PublishStats(void);
-
-       /* config & status dump */
-       void UpdateAllConfigObjects(void);
-       void SendConfigUpdate(const ConfigObject::Ptr& object, const String& typeName, bool runtimeUpdate = false);
-       void SendConfigDelete(const ConfigObject::Ptr& object, const String& typeName);
-       void SendStatusUpdate(const ConfigObject::Ptr& object, const String& typeName);
-
-       /* utilities */
-       static String FormatCheckSumBinary(const String& str);
-
-       static String CalculateCheckSumString(const String& str, bool binary = false);
-       static String CalculateCheckSumGroups(const Array::Ptr& groups, bool binary = false);
-       static String CalculateCheckSumProperties(const ConfigObject::Ptr& object, bool binary = false);
-       static String CalculateCheckSumVars(const ConfigObject::Ptr& object, bool binary = false);
-
-       static String HashValue(const Value& value, bool binary = false);
-       static Dictionary::Ptr SerializeObjectAttrs(const Object::Ptr& object, int fieldType);
-
-       static void StateChangedHandler(const ConfigObject::Ptr& object);
-       static void VarsChangedHandler(const ConfigObject::Ptr& object);
-       static void VersionChangedHandler(const ConfigObject::Ptr& object);
-
-       void AssertOnWorkQueue(void);
-
-       void ExceptionHandler(boost::exception_ptr exp);
-
-       boost::shared_ptr<redisReply> ExecuteQuery(const std::vector<String>& query);
-
-       Timer::Ptr m_StatsTimer;
-       Timer::Ptr m_ReconnectTimer;
-       Timer::Ptr m_SubscriptionTimer;
-       WorkQueue m_WorkQueue;
-       redisContext *m_Context;
-       std::map<String, RedisSubscriptionInfo> m_Subscriptions;
-       bool m_ConfigDumpInProgress;
-};
-
-struct redis_error : virtual std::exception, virtual boost::exception { };
-
-struct errinfo_redis_query_;
-typedef boost::error_info<struct errinfo_redis_query_, std::string> errinfo_redis_query;
-
-}
-
-#endif /* REDISWRITER_H */
diff --git a/lib/redis/rediswriter.ti b/lib/redis/rediswriter.ti
deleted file mode 100644 (file)
index 0aa76c9..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/******************************************************************************
- * Icinga 2                                                                   *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/)  *
- *                                                                            *
- * This program is free software; you can redistribute it and/or              *
- * modify it under the terms of the GNU General Public License                *
- * as published by the Free Software Foundation; either version 2             *
- * of the License, or (at your option) any later version.                     *
- *                                                                            *
- * This program is distributed in the hope that it will be useful,            *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
- * GNU General Public License for more details.                               *
- *                                                                            *
- * You should have received a copy of the GNU General Public License          *
- * along with this program; if not, write to the Free Software Foundation     *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
- ******************************************************************************/
-
-#include "base/configobject.hpp"
-
-library demo;
-
-namespace icinga
-{
-
-class RedisWriter : ConfigObject
-{
-       [config] String host {
-               default {{{ return "127.0.0.1"; }}}
-       };
-       [config] int port {
-               default {{{ return 6379; }}}
-       };
-       [config] String path;
-       [config] String password;
-       [config] int db_index;
-};
-
-}
index 2606e50387ac34e0ae538eebd83ab628e71ea592..2c714b312390b6b472cc5c05320e2a39086c804b 100644 (file)
@@ -25,8 +25,4 @@ if(UNIX OR CYGWIN)
   add_subdirectory(execvpe)
 endif()
 
-if(ICINGA2_WITH_REDIS)
-  add_subdirectory(hiredis)
-endif()
-
-add_subdirectory(socketpair)
\ No newline at end of file
+add_subdirectory(socketpair)
diff --git a/third-party/hiredis/.gitignore b/third-party/hiredis/.gitignore
deleted file mode 100644 (file)
index c44b5c5..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/hiredis-test
-/examples/hiredis-example*
-/*.o
-/*.so
-/*.dylib
-/*.a
-/*.pc
diff --git a/third-party/hiredis/.travis.yml b/third-party/hiredis/.travis.yml
deleted file mode 100644 (file)
index 1e1ce30..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-language: c
-sudo: false
-compiler:
-  - gcc
-  - clang
-
-addons:
-  apt:
-    packages:
-    - libc6-dbg
-    - libc6-dev
-    - libc6:i386
-    - libc6-dev-i386
-    - libc6-dbg:i386
-    - gcc-multilib
-    - valgrind
-
-env:
-    - CFLAGS="-Werror"
-    - PRE="valgrind --track-origins=yes --leak-check=full"
-    - TARGET="32bit" TARGET_VARS="32bit-vars" CFLAGS="-Werror"
-    - TARGET="32bit" TARGET_VARS="32bit-vars" PRE="valgrind --track-origins=yes --leak-check=full"
-
-script: make $TARGET CFLAGS="$CFLAGS" && make check PRE="$PRE" && make $TARGET_VARS hiredis-example
diff --git a/third-party/hiredis/CHANGELOG.md b/third-party/hiredis/CHANGELOG.md
deleted file mode 100644 (file)
index a5015c5..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-### 0.13.3 (2015-09-16)
-
-* Revert "Clear `REDIS_CONNECTED` flag when connection is closed".
-* Make tests pass on FreeBSD (Thanks, Giacomo Olgeni)
-
-
-If the `REDIS_CONNECTED` flag is cleared,
-the async onDisconnect callback function will never be called.
-This causes problems as the disconnect is never reported back to the user.
-
-### 0.13.2 (2015-08-25)
-
-* Prevent crash on pending replies in async code (Thanks, @switch-st)
-* Clear `REDIS_CONNECTED` flag when connection is closed (Thanks, Jerry Jacobs)
-* Add MacOS X addapter (Thanks, @dizzus)
-* Add Qt adapter (Thanks, Pietro Cerutti)
-* Add Ivykis adapter (Thanks, Gergely Nagy)
-
-All adapters are provided as is and are only tested where possible.
-
-### 0.13.1 (2015-05-03)
-
-This is a bug fix release.
-The new `reconnect` method introduced new struct members, which clashed with pre-defined names in pre-C99 code.
-Another commit forced C99 compilation just to make it work, but of course this is not desirable for outside projects.
-Other non-C99 code can now use hiredis as usual again.
-Sorry for the inconvenience.
-
-* Fix memory leak in async reply handling (Salvatore Sanfilippo)
-* Rename struct member to avoid name clash with pre-c99 code (Alex Balashov, ncopa)
-
-### 0.13.0 (2015-04-16)
-
-This release adds a minimal Windows compatibility layer.
-The parser, standalone since v0.12.0, can now be compiled on Windows
-(and thus used in other client libraries as well)
-
-* Windows compatibility layer for parser code (tzickel)
-* Properly escape data printed to PKGCONF file (Dan Skorupski)
-* Fix tests when assert() undefined (Keith Bennett, Matt Stancliff)
-* Implement a reconnect method for the client context, this changes the structure of `redisContext` (Aaron Bedra)
-
-### 0.12.1 (2015-01-26)
-
-* Fix `make install`: DESTDIR support, install all required files, install PKGCONF in proper location
-* Fix `make test` as 32 bit build on 64 bit platform
-
-### 0.12.0 (2015-01-22)
-
-* Add optional KeepAlive support
-
-* Try again on EINTR errors
-
-* Add libuv adapter
-
-* Add IPv6 support
-
-* Remove possiblity of multiple close on same fd
-
-* Add ability to bind source address on connect
-
-* Add redisConnectFd() and redisFreeKeepFd()
-
-* Fix getaddrinfo() memory leak
-
-* Free string if it is unused (fixes memory leak)
-
-* Improve redisAppendCommandArgv performance 2.5x
-
-* Add support for SO_REUSEADDR
-
-* Fix redisvFormatCommand format parsing
-
-* Add GLib 2.0 adapter
-
-* Refactor reading code into read.c
-
-* Fix errno error buffers to not clobber errors
-
-* Generate pkgconf during build
-
-* Silence _BSD_SOURCE warnings
-
-* Improve digit counting for multibulk creation
-
-
-### 0.11.0
-
-* Increase the maximum multi-bulk reply depth to 7.
-
-* Increase the read buffer size from 2k to 16k.
-
-* Use poll(2) instead of select(2) to support large fds (>= 1024).
-
-### 0.10.1
-
-* Makefile overhaul. Important to check out if you override one or more
-  variables using environment variables or via arguments to the "make" tool.
-
-* Issue #45: Fix potential memory leak for a multi bulk reply with 0 elements
-  being created by the default reply object functions.
-
-* Issue #43: Don't crash in an asynchronous context when Redis returns an error
-  reply after the connection has been made (this happens when the maximum
-  number of connections is reached).
-
-### 0.10.0
-
-* See commit log.
-
diff --git a/third-party/hiredis/CMakeLists.txt b/third-party/hiredis/CMakeLists.txt
deleted file mode 100644 (file)
index afda957..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-# Icinga 2
-# Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/)
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
-add_library(hiredis SHARED net.c net.h hiredis.c hiredis.h sds.c sds.h async.c async.h read.c read.h)
-
-if(HAVE_VISIBILITY_HIDDEN)
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=default")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=default")
-endif()
-
-set_target_properties (
-  hiredis PROPERTIES
-  FOLDER Lib
-  VERSION ${SPEC_VERSION}
-)
-
-install(
-  TARGETS hiredis
-  RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/icinga2
-)
-
-if(APPLE)
-  install(
-    TARGETS hiredis
-    LIBRARY DESTINATION ${CMAKE_INSTALL_BINDIR}/icinga-studio.app/Contents
-  )
-endif()
diff --git a/third-party/hiredis/COPYING b/third-party/hiredis/COPYING
deleted file mode 100644 (file)
index a5fc973..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
-Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice,
-  this list of conditions and the following disclaimer.
-
-* 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.
-
-* Neither the name of Redis nor the names of its contributors may be used
-  to endorse or promote products derived from this software without specific
-  prior written permission.
-
-THIS 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 OWNER 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.
diff --git a/third-party/hiredis/Makefile b/third-party/hiredis/Makefile
deleted file mode 100644 (file)
index cff2a84..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-# Hiredis Makefile
-# Copyright (C) 2010-2011 Salvatore Sanfilippo <antirez at gmail dot com>
-# Copyright (C) 2010-2011 Pieter Noordhuis <pcnoordhuis at gmail dot com>
-# This file is released under the BSD license, see the COPYING file
-
-OBJ=net.o hiredis.o sds.o async.o read.o
-EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib
-TESTS=hiredis-test
-LIBNAME=libhiredis
-PKGCONFNAME=hiredis.pc
-
-HIREDIS_MAJOR=$(shell grep HIREDIS_MAJOR hiredis.h | awk '{print $$3}')
-HIREDIS_MINOR=$(shell grep HIREDIS_MINOR hiredis.h | awk '{print $$3}')
-HIREDIS_PATCH=$(shell grep HIREDIS_PATCH hiredis.h | awk '{print $$3}')
-HIREDIS_SONAME=$(shell grep HIREDIS_SONAME hiredis.h | awk '{print $$3}')
-
-# Installation related variables and target
-PREFIX?=/usr/local
-INCLUDE_PATH?=include/hiredis
-LIBRARY_PATH?=lib
-PKGCONF_PATH?=pkgconfig
-INSTALL_INCLUDE_PATH= $(DESTDIR)$(PREFIX)/$(INCLUDE_PATH)
-INSTALL_LIBRARY_PATH= $(DESTDIR)$(PREFIX)/$(LIBRARY_PATH)
-INSTALL_PKGCONF_PATH= $(INSTALL_LIBRARY_PATH)/$(PKGCONF_PATH)
-
-# redis-server configuration used for testing
-REDIS_PORT=56379
-REDIS_SERVER=redis-server
-define REDIS_TEST_CONFIG
-       daemonize yes
-       pidfile /tmp/hiredis-test-redis.pid
-       port $(REDIS_PORT)
-       bind 127.0.0.1
-       unixsocket /tmp/hiredis-test-redis.sock
-endef
-export REDIS_TEST_CONFIG
-
-# Fallback to gcc when $CC is not in $PATH.
-CC:=$(shell sh -c 'type $(CC) >/dev/null 2>/dev/null && echo $(CC) || echo gcc')
-CXX:=$(shell sh -c 'type $(CXX) >/dev/null 2>/dev/null && echo $(CXX) || echo g++')
-OPTIMIZATION?=-O3
-WARNINGS=-Wall -W -Wstrict-prototypes -Wwrite-strings
-DEBUG?= -g -ggdb
-REAL_CFLAGS=$(OPTIMIZATION) -fPIC $(CFLAGS) $(WARNINGS) $(DEBUG) $(ARCH)
-REAL_LDFLAGS=$(LDFLAGS) $(ARCH)
-
-DYLIBSUFFIX=so
-STLIBSUFFIX=a
-DYLIB_MINOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_SONAME)
-DYLIB_MAJOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_MAJOR)
-DYLIBNAME=$(LIBNAME).$(DYLIBSUFFIX)
-DYLIB_MAKE_CMD=$(CC) -shared -Wl,-soname,$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS)
-STLIBNAME=$(LIBNAME).$(STLIBSUFFIX)
-STLIB_MAKE_CMD=ar rcs $(STLIBNAME)
-
-# Platform-specific overrides
-uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
-ifeq ($(uname_S),SunOS)
-  REAL_LDFLAGS+= -ldl -lnsl -lsocket
-  DYLIB_MAKE_CMD=$(CC) -G -o $(DYLIBNAME) -h $(DYLIB_MINOR_NAME) $(LDFLAGS)
-  INSTALL= cp -r
-endif
-ifeq ($(uname_S),Darwin)
-  DYLIBSUFFIX=dylib
-  DYLIB_MINOR_NAME=$(LIBNAME).$(HIREDIS_SONAME).$(DYLIBSUFFIX)
-  DYLIB_MAKE_CMD=$(CC) -shared -Wl,-install_name,$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS)
-endif
-
-all: $(DYLIBNAME) $(STLIBNAME) hiredis-test $(PKGCONFNAME)
-
-# Deps (use make dep to generate this)
-async.o: async.c fmacros.h async.h hiredis.h read.h sds.h net.h dict.c dict.h
-dict.o: dict.c fmacros.h dict.h
-hiredis.o: hiredis.c fmacros.h hiredis.h read.h sds.h net.h
-net.o: net.c fmacros.h net.h hiredis.h read.h sds.h
-read.o: read.c fmacros.h read.h sds.h
-sds.o: sds.c sds.h
-test.o: test.c fmacros.h hiredis.h read.h sds.h
-
-$(DYLIBNAME): $(OBJ)
-       $(DYLIB_MAKE_CMD) $(OBJ)
-
-$(STLIBNAME): $(OBJ)
-       $(STLIB_MAKE_CMD) $(OBJ)
-
-dynamic: $(DYLIBNAME)
-static: $(STLIBNAME)
-
-# Binaries:
-hiredis-example-libevent: examples/example-libevent.c adapters/libevent.h $(STLIBNAME)
-       $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -levent $(STLIBNAME)
-
-hiredis-example-libev: examples/example-libev.c adapters/libev.h $(STLIBNAME)
-       $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -lev $(STLIBNAME)
-
-hiredis-example-glib: examples/example-glib.c adapters/glib.h $(STLIBNAME)
-       $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) $(shell pkg-config --cflags --libs glib-2.0) -I. $< $(STLIBNAME)
-
-hiredis-example-ivykis: examples/example-ivykis.c adapters/ivykis.h $(STLIBNAME)
-       $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -livykis $(STLIBNAME)
-
-hiredis-example-macosx: examples/example-macosx.c adapters/macosx.h $(STLIBNAME)
-       $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -framework CoreFoundation $(STLIBNAME)
-
-ifndef AE_DIR
-hiredis-example-ae:
-       @echo "Please specify AE_DIR (e.g. <redis repository>/src)"
-       @false
-else
-hiredis-example-ae: examples/example-ae.c adapters/ae.h $(STLIBNAME)
-       $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(AE_DIR) $< $(AE_DIR)/ae.o $(AE_DIR)/zmalloc.o $(AE_DIR)/../deps/jemalloc/lib/libjemalloc.a -pthread $(STLIBNAME)
-endif
-
-ifndef LIBUV_DIR
-hiredis-example-libuv:
-       @echo "Please specify LIBUV_DIR (e.g. ../libuv/)"
-       @false
-else
-hiredis-example-libuv: examples/example-libuv.c adapters/libuv.h $(STLIBNAME)
-       $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(LIBUV_DIR)/include $< $(LIBUV_DIR)/.libs/libuv.a -lpthread -lrt $(STLIBNAME)
-endif
-
-ifeq ($(and $(QT_MOC),$(QT_INCLUDE_DIR),$(QT_LIBRARY_DIR)),)
-hiredis-example-qt:
-       @echo "Please specify QT_MOC, QT_INCLUDE_DIR AND QT_LIBRARY_DIR"
-       @false
-else
-hiredis-example-qt: examples/example-qt.cpp adapters/qt.h $(STLIBNAME)
-       $(QT_MOC) adapters/qt.h -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | \
-           $(CXX) -x c++ -o qt-adapter-moc.o -c - $(REAL_CFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore
-       $(QT_MOC) examples/example-qt.h -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | \
-           $(CXX) -x c++ -o qt-example-moc.o -c - $(REAL_CFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore
-       $(CXX) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore -L$(QT_LIBRARY_DIR) qt-adapter-moc.o qt-example-moc.o $< -pthread $(STLIBNAME) -lQtCore
-endif
-
-hiredis-example: examples/example.c $(STLIBNAME)
-       $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< $(STLIBNAME)
-
-examples: $(EXAMPLES)
-
-hiredis-test: test.o $(STLIBNAME)
-
-hiredis-%: %.o $(STLIBNAME)
-       $(CC) $(REAL_CFLAGS) -o $@ $(REAL_LDFLAGS) $< $(STLIBNAME)
-
-test: hiredis-test
-       ./hiredis-test
-
-check: hiredis-test
-       @echo "$$REDIS_TEST_CONFIG" | $(REDIS_SERVER) -
-       $(PRE) ./hiredis-test -h 127.0.0.1 -p $(REDIS_PORT) -s /tmp/hiredis-test-redis.sock || \
-                       ( kill `cat /tmp/hiredis-test-redis.pid` && false )
-       kill `cat /tmp/hiredis-test-redis.pid`
-
-.c.o:
-       $(CC) -std=c99 -pedantic -c $(REAL_CFLAGS) $<
-
-clean:
-       rm -rf $(DYLIBNAME) $(STLIBNAME) $(TESTS) $(PKGCONFNAME) examples/hiredis-example* *.o *.gcda *.gcno *.gcov
-
-dep:
-       $(CC) -MM *.c
-
-ifeq ($(uname_S),SunOS)
-  INSTALL?= cp -r
-endif
-
-INSTALL?= cp -a
-
-$(PKGCONFNAME): hiredis.h
-       @echo "Generating $@ for pkgconfig..."
-       @echo prefix=$(PREFIX) > $@
-       @echo exec_prefix=\$${prefix} >> $@
-       @echo libdir=$(PREFIX)/$(LIBRARY_PATH) >> $@
-       @echo includedir=$(PREFIX)/$(INCLUDE_PATH) >> $@
-       @echo >> $@
-       @echo Name: hiredis >> $@
-       @echo Description: Minimalistic C client library for Redis. >> $@
-       @echo Version: $(HIREDIS_MAJOR).$(HIREDIS_MINOR).$(HIREDIS_PATCH) >> $@
-       @echo Libs: -L\$${libdir} -lhiredis >> $@
-       @echo Cflags: -I\$${includedir} -D_FILE_OFFSET_BITS=64 >> $@
-
-install: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME)
-       mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_LIBRARY_PATH)
-       $(INSTALL) hiredis.h async.h read.h sds.h adapters $(INSTALL_INCLUDE_PATH)
-       $(INSTALL) $(DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(DYLIB_MINOR_NAME)
-       cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MINOR_NAME) $(DYLIBNAME)
-       $(INSTALL) $(STLIBNAME) $(INSTALL_LIBRARY_PATH)
-       mkdir -p $(INSTALL_PKGCONF_PATH)
-       $(INSTALL) $(PKGCONFNAME) $(INSTALL_PKGCONF_PATH)
-
-32bit:
-       @echo ""
-       @echo "WARNING: if this fails under Linux you probably need to install libc6-dev-i386"
-       @echo ""
-       $(MAKE) CFLAGS="-m32" LDFLAGS="-m32"
-
-32bit-vars:
-       $(eval CFLAGS=-m32)
-       $(eval LDFLAGS=-m32)
-
-gprof:
-       $(MAKE) CFLAGS="-pg" LDFLAGS="-pg"
-
-gcov:
-       $(MAKE) CFLAGS="-fprofile-arcs -ftest-coverage" LDFLAGS="-fprofile-arcs"
-
-coverage: gcov
-       make check
-       mkdir -p tmp/lcov
-       lcov -d . -c -o tmp/lcov/hiredis.info
-       genhtml --legend -o tmp/lcov/report tmp/lcov/hiredis.info
-
-noopt:
-       $(MAKE) OPTIMIZATION=""
-
-.PHONY: all test check clean dep install 32bit 32bit-vars gprof gcov noopt
diff --git a/third-party/hiredis/README.md b/third-party/hiredis/README.md
deleted file mode 100644 (file)
index 4f1a58d..0000000
+++ /dev/null
@@ -1,392 +0,0 @@
-[![Build Status](https://travis-ci.org/redis/hiredis.png)](https://travis-ci.org/redis/hiredis)
-
-# HIREDIS
-
-Hiredis is a minimalistic C client library for the [Redis](http://redis.io/) database.
-
-It is minimalistic because it just adds minimal support for the protocol, but
-at the same time it uses a high level printf-alike API in order to make it
-much higher level than otherwise suggested by its minimal code base and the
-lack of explicit bindings for every Redis command.
-
-Apart from supporting sending commands and receiving replies, it comes with
-a reply parser that is decoupled from the I/O layer. It
-is a stream parser designed for easy reusability, which can for instance be used
-in higher level language bindings for efficient reply parsing.
-
-Hiredis only supports the binary-safe Redis protocol, so you can use it with any
-Redis version >= 1.2.0.
-
-The library comes with multiple APIs. There is the
-*synchronous API*, the *asynchronous API* and the *reply parsing API*.
-
-## UPGRADING
-
-Version 0.9.0 is a major overhaul of hiredis in every aspect. However, upgrading existing
-code using hiredis should not be a big pain. The key thing to keep in mind when
-upgrading is that hiredis >= 0.9.0 uses a `redisContext*` to keep state, in contrast to
-the stateless 0.0.1 that only has a file descriptor to work with.
-
-## Synchronous API
-
-To consume the synchronous API, there are only a few function calls that need to be introduced:
-
-```c
-redisContext *redisConnect(const char *ip, int port);
-void *redisCommand(redisContext *c, const char *format, ...);
-void freeReplyObject(void *reply);
-```
-
-### Connecting
-
-The function `redisConnect` is used to create a so-called `redisContext`. The
-context is where Hiredis holds state for a connection. The `redisContext`
-struct has an integer `err` field that is non-zero when the connection is in
-an error state. The field `errstr` will contain a string with a description of
-the error. More information on errors can be found in the **Errors** section.
-After trying to connect to Redis using `redisConnect` you should
-check the `err` field to see if establishing the connection was successful:
-```c
-redisContext *c = redisConnect("127.0.0.1", 6379);
-if (c != NULL && c->err) {
-    printf("Error: %s\n", c->errstr);
-    // handle error
-}
-```
-
-### Sending commands
-
-There are several ways to issue commands to Redis. The first that will be introduced is
-`redisCommand`. This function takes a format similar to printf. In the simplest form,
-it is used like this:
-```c
-reply = redisCommand(context, "SET foo bar");
-```
-
-The specifier `%s` interpolates a string in the command, and uses `strlen` to
-determine the length of the string:
-```c
-reply = redisCommand(context, "SET foo %s", value);
-```
-When you need to pass binary safe strings in a command, the `%b` specifier can be
-used. Together with a pointer to the string, it requires a `size_t` length argument
-of the string:
-```c
-reply = redisCommand(context, "SET foo %b", value, (size_t) valuelen);
-```
-Internally, Hiredis splits the command in different arguments and will
-convert it to the protocol used to communicate with Redis.
-One or more spaces separates arguments, so you can use the specifiers
-anywhere in an argument:
-```c
-reply = redisCommand(context, "SET key:%s %s", myid, value);
-```
-
-### Using replies
-
-The return value of `redisCommand` holds a reply when the command was
-successfully executed. When an error occurs, the return value is `NULL` and
-the `err` field in the context will be set (see section on **Errors**).
-Once an error is returned the context cannot be reused and you should set up
-a new connection.
-
-The standard replies that `redisCommand` are of the type `redisReply`. The
-`type` field in the `redisReply` should be used to test what kind of reply
-was received:
-
-* **`REDIS_REPLY_STATUS`**:
-    * The command replied with a status reply. The status string can be accessed using `reply->str`.
-      The length of this string can be accessed using `reply->len`.
-
-* **`REDIS_REPLY_ERROR`**:
-    *  The command replied with an error. The error string can be accessed identical to `REDIS_REPLY_STATUS`.
-
-* **`REDIS_REPLY_INTEGER`**:
-    * The command replied with an integer. The integer value can be accessed using the
-      `reply->integer` field of type `long long`.
-
-* **`REDIS_REPLY_NIL`**:
-    * The command replied with a **nil** object. There is no data to access.
-
-* **`REDIS_REPLY_STRING`**:
-    * A bulk (string) reply. The value of the reply can be accessed using `reply->str`.
-      The length of this string can be accessed using `reply->len`.
-
-* **`REDIS_REPLY_ARRAY`**:
-    * A multi bulk reply. The number of elements in the multi bulk reply is stored in
-      `reply->elements`. Every element in the multi bulk reply is a `redisReply` object as well
-      and can be accessed via `reply->element[..index..]`.
-      Redis may reply with nested arrays but this is fully supported.
-
-Replies should be freed using the `freeReplyObject()` function.
-Note that this function will take care of freeing sub-reply objects
-contained in arrays and nested arrays, so there is no need for the user to
-free the sub replies (it is actually harmful and will corrupt the memory).
-
-**Important:** the current version of hiredis (0.10.0) frees replies when the
-asynchronous API is used. This means you should not call `freeReplyObject` when
-you use this API. The reply is cleaned up by hiredis _after_ the callback
-returns. This behavior will probably change in future releases, so make sure to
-keep an eye on the changelog when upgrading (see issue #39).
-
-### Cleaning up
-
-To disconnect and free the context the following function can be used:
-```c
-void redisFree(redisContext *c);
-```
-This function immediately closes the socket and then frees the allocations done in
-creating the context.
-
-### Sending commands (cont'd)
-
-Together with `redisCommand`, the function `redisCommandArgv` can be used to issue commands.
-It has the following prototype:
-```c
-void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
-```
-It takes the number of arguments `argc`, an array of strings `argv` and the lengths of the
-arguments `argvlen`. For convenience, `argvlen` may be set to `NULL` and the function will
-use `strlen(3)` on every argument to determine its length. Obviously, when any of the arguments
-need to be binary safe, the entire array of lengths `argvlen` should be provided.
-
-The return value has the same semantic as `redisCommand`.
-
-### Pipelining
-
-To explain how Hiredis supports pipelining in a blocking connection, there needs to be
-understanding of the internal execution flow.
-
-When any of the functions in the `redisCommand` family is called, Hiredis first formats the
-command according to the Redis protocol. The formatted command is then put in the output buffer
-of the context. This output buffer is dynamic, so it can hold any number of commands.
-After the command is put in the output buffer, `redisGetReply` is called. This function has the
-following two execution paths:
-
-1. The input buffer is non-empty:
-    * Try to parse a single reply from the input buffer and return it
-    * If no reply could be parsed, continue at *2*
-2. The input buffer is empty:
-    * Write the **entire** output buffer to the socket
-    * Read from the socket until a single reply could be parsed
-
-The function `redisGetReply` is exported as part of the Hiredis API and can be used when a reply
-is expected on the socket. To pipeline commands, the only things that needs to be done is
-filling up the output buffer. For this cause, two commands can be used that are identical
-to the `redisCommand` family, apart from not returning a reply:
-```c
-void redisAppendCommand(redisContext *c, const char *format, ...);
-void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
-```
-After calling either function one or more times, `redisGetReply` can be used to receive the
-subsequent replies. The return value for this function is either `REDIS_OK` or `REDIS_ERR`, where
-the latter means an error occurred while reading a reply. Just as with the other commands,
-the `err` field in the context can be used to find out what the cause of this error is.
-
-The following examples shows a simple pipeline (resulting in only a single call to `write(2)` and
-a single call to `read(2)`):
-```c
-redisReply *reply;
-redisAppendCommand(context,"SET foo bar");
-redisAppendCommand(context,"GET foo");
-redisGetReply(context,&reply); // reply for SET
-freeReplyObject(reply);
-redisGetReply(context,&reply); // reply for GET
-freeReplyObject(reply);
-```
-This API can also be used to implement a blocking subscriber:
-```c
-reply = redisCommand(context,"SUBSCRIBE foo");
-freeReplyObject(reply);
-while(redisGetReply(context,&reply) == REDIS_OK) {
-    // consume message
-    freeReplyObject(reply);
-}
-```
-### Errors
-
-When a function call is not successful, depending on the function either `NULL` or `REDIS_ERR` is
-returned. The `err` field inside the context will be non-zero and set to one of the
-following constants:
-
-* **`REDIS_ERR_IO`**:
-    There was an I/O error while creating the connection, trying to write
-    to the socket or read from the socket. If you included `errno.h` in your
-    application, you can use the global `errno` variable to find out what is
-    wrong.
-
-* **`REDIS_ERR_EOF`**:
-    The server closed the connection which resulted in an empty read.
-
-* **`REDIS_ERR_PROTOCOL`**:
-    There was an error while parsing the protocol.
-
-* **`REDIS_ERR_OTHER`**:
-    Any other error. Currently, it is only used when a specified hostname to connect
-    to cannot be resolved.
-
-In every case, the `errstr` field in the context will be set to hold a string representation
-of the error.
-
-## Asynchronous API
-
-Hiredis comes with an asynchronous API that works easily with any event library.
-Examples are bundled that show using Hiredis with [libev](http://software.schmorp.de/pkg/libev.html)
-and [libevent](http://monkey.org/~provos/libevent/).
-
-### Connecting
-
-The function `redisAsyncConnect` can be used to establish a non-blocking connection to
-Redis. It returns a pointer to the newly created `redisAsyncContext` struct. The `err` field
-should be checked after creation to see if there were errors creating the connection.
-Because the connection that will be created is non-blocking, the kernel is not able to
-instantly return if the specified host and port is able to accept a connection.
-```c
-redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
-if (c->err) {
-    printf("Error: %s\n", c->errstr);
-    // handle error
-}
-```
-
-The asynchronous context can hold a disconnect callback function that is called when the
-connection is disconnected (either because of an error or per user request). This function should
-have the following prototype:
-```c
-void(const redisAsyncContext *c, int status);
-```
-On a disconnect, the `status` argument is set to `REDIS_OK` when disconnection was initiated by the
-user, or `REDIS_ERR` when the disconnection was caused by an error. When it is `REDIS_ERR`, the `err`
-field in the context can be accessed to find out the cause of the error.
-
-The context object is always freed after the disconnect callback fired. When a reconnect is needed,
-the disconnect callback is a good point to do so.
-
-Setting the disconnect callback can only be done once per context. For subsequent calls it will
-return `REDIS_ERR`. The function to set the disconnect callback has the following prototype:
-```c
-int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);
-```
-### Sending commands and their callbacks
-
-In an asynchronous context, commands are automatically pipelined due to the nature of an event loop.
-Therefore, unlike the synchronous API, there is only a single way to send commands.
-Because commands are sent to Redis asynchronously, issuing a command requires a callback function
-that is called when the reply is received. Reply callbacks should have the following prototype:
-```c
-void(redisAsyncContext *c, void *reply, void *privdata);
-```
-The `privdata` argument can be used to curry arbitrary data to the callback from the point where
-the command is initially queued for execution.
-
-The functions that can be used to issue commands in an asynchronous context are:
-```c
-int redisAsyncCommand(
-  redisAsyncContext *ac, redisCallbackFn *fn, void *privdata,
-  const char *format, ...);
-int redisAsyncCommandArgv(
-  redisAsyncContext *ac, redisCallbackFn *fn, void *privdata,
-  int argc, const char **argv, const size_t *argvlen);
-```
-Both functions work like their blocking counterparts. The return value is `REDIS_OK` when the command
-was successfully added to the output buffer and `REDIS_ERR` otherwise. Example: when the connection
-is being disconnected per user-request, no new commands may be added to the output buffer and `REDIS_ERR` is
-returned on calls to the `redisAsyncCommand` family.
-
-If the reply for a command with a `NULL` callback is read, it is immediately freed. When the callback
-for a command is non-`NULL`, the memory is freed immediately following the callback: the reply is only
-valid for the duration of the callback.
-
-All pending callbacks are called with a `NULL` reply when the context encountered an error.
-
-### Disconnecting
-
-An asynchronous connection can be terminated using:
-```c
-void redisAsyncDisconnect(redisAsyncContext *ac);
-```
-When this function is called, the connection is **not** immediately terminated. Instead, new
-commands are no longer accepted and the connection is only terminated when all pending commands
-have been written to the socket, their respective replies have been read and their respective
-callbacks have been executed. After this, the disconnection callback is executed with the
-`REDIS_OK` status and the context object is freed.
-
-### Hooking it up to event library *X*
-
-There are a few hooks that need to be set on the context object after it is created.
-See the `adapters/` directory for bindings to *libev* and *libevent*.
-
-## Reply parsing API
-
-Hiredis comes with a reply parsing API that makes it easy for writing higher
-level language bindings.
-
-The reply parsing API consists of the following functions:
-```c
-redisReader *redisReaderCreate(void);
-void redisReaderFree(redisReader *reader);
-int redisReaderFeed(redisReader *reader, const char *buf, size_t len);
-int redisReaderGetReply(redisReader *reader, void **reply);
-```
-The same set of functions are used internally by hiredis when creating a
-normal Redis context, the above API just exposes it to the user for a direct
-usage.
-
-### Usage
-
-The function `redisReaderCreate` creates a `redisReader` structure that holds a
-buffer with unparsed data and state for the protocol parser.
-
-Incoming data -- most likely from a socket -- can be placed in the internal
-buffer of the `redisReader` using `redisReaderFeed`. This function will make a
-copy of the buffer pointed to by `buf` for `len` bytes. This data is parsed
-when `redisReaderGetReply` is called. This function returns an integer status
-and a reply object (as described above) via `void **reply`. The returned status
-can be either `REDIS_OK` or `REDIS_ERR`, where the latter means something went
-wrong (either a protocol error, or an out of memory error).
-
-The parser limits the level of nesting for multi bulk payloads to 7. If the
-multi bulk nesting level is higher than this, the parser returns an error.
-
-### Customizing replies
-
-The function `redisReaderGetReply` creates `redisReply` and makes the function
-argument `reply` point to the created `redisReply` variable. For instance, if
-the response of type `REDIS_REPLY_STATUS` then the `str` field of `redisReply`
-will hold the status as a vanilla C string. However, the functions that are
-responsible for creating instances of the `redisReply` can be customized by
-setting the `fn` field on the `redisReader` struct. This should be done
-immediately after creating the `redisReader`.
-
-For example, [hiredis-rb](https://github.com/pietern/hiredis-rb/blob/master/ext/hiredis_ext/reader.c)
-uses customized reply object functions to create Ruby objects.
-
-### Reader max buffer
-
-Both when using the Reader API directly or when using it indirectly via a
-normal Redis context, the redisReader structure uses a buffer in order to
-accumulate data from the server.
-Usually this buffer is destroyed when it is empty and is larger than 16
-KiB in order to avoid wasting memory in unused buffers
-
-However when working with very big payloads destroying the buffer may slow
-down performances considerably, so it is possible to modify the max size of
-an idle buffer changing the value of the `maxbuf` field of the reader structure
-to the desired value. The special value of 0 means that there is no maximum
-value for an idle buffer, so the buffer will never get freed.
-
-For instance if you have a normal Redis context you can set the maximum idle
-buffer to zero (unlimited) just with:
-```c
-context->reader->maxbuf = 0;
-```
-This should be done only in order to maximize performances when working with
-large payloads. The context should be set back to `REDIS_READER_MAX_BUF` again
-as soon as possible in order to prevent allocation of useless memory.
-
-## AUTHORS
-
-Hiredis was written by Salvatore Sanfilippo (antirez at gmail) and
-Pieter Noordhuis (pcnoordhuis at gmail) and is released under the BSD license.  
-Hiredis is currently maintained by Matt Stancliff (matt at genges dot com) and
-Jan-Erik Rediger (janerik at fnordig dot com)
diff --git a/third-party/hiredis/adapters/ae.h b/third-party/hiredis/adapters/ae.h
deleted file mode 100644 (file)
index 5c551c2..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   * Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *   * 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.
- *   * Neither the name of Redis nor the names of its contributors may be used
- *     to endorse or promote products derived from this software without
- *     specific prior written permission.
- *
- * THIS 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 OWNER 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.
- */
-
-#ifndef __HIREDIS_AE_H__
-#define __HIREDIS_AE_H__
-#include <sys/types.h>
-#include <ae.h>
-#include "../hiredis.h"
-#include "../async.h"
-
-typedef struct redisAeEvents {
-    redisAsyncContext *context;
-    aeEventLoop *loop;
-    int fd;
-    int reading, writing;
-} redisAeEvents;
-
-static void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
-    ((void)el); ((void)fd); ((void)mask);
-
-    redisAeEvents *e = (redisAeEvents*)privdata;
-    redisAsyncHandleRead(e->context);
-}
-
-static void redisAeWriteEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
-    ((void)el); ((void)fd); ((void)mask);
-
-    redisAeEvents *e = (redisAeEvents*)privdata;
-    redisAsyncHandleWrite(e->context);
-}
-
-static void redisAeAddRead(void *privdata) {
-    redisAeEvents *e = (redisAeEvents*)privdata;
-    aeEventLoop *loop = e->loop;
-    if (!e->reading) {
-        e->reading = 1;
-        aeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e);
-    }
-}
-
-static void redisAeDelRead(void *privdata) {
-    redisAeEvents *e = (redisAeEvents*)privdata;
-    aeEventLoop *loop = e->loop;
-    if (e->reading) {
-        e->reading = 0;
-        aeDeleteFileEvent(loop,e->fd,AE_READABLE);
-    }
-}
-
-static void redisAeAddWrite(void *privdata) {
-    redisAeEvents *e = (redisAeEvents*)privdata;
-    aeEventLoop *loop = e->loop;
-    if (!e->writing) {
-        e->writing = 1;
-        aeCreateFileEvent(loop,e->fd,AE_WRITABLE,redisAeWriteEvent,e);
-    }
-}
-
-static void redisAeDelWrite(void *privdata) {
-    redisAeEvents *e = (redisAeEvents*)privdata;
-    aeEventLoop *loop = e->loop;
-    if (e->writing) {
-        e->writing = 0;
-        aeDeleteFileEvent(loop,e->fd,AE_WRITABLE);
-    }
-}
-
-static void redisAeCleanup(void *privdata) {
-    redisAeEvents *e = (redisAeEvents*)privdata;
-    redisAeDelRead(privdata);
-    redisAeDelWrite(privdata);
-    free(e);
-}
-
-static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) {
-    redisContext *c = &(ac->c);
-    redisAeEvents *e;
-
-    /* Nothing should be attached when something is already attached */
-    if (ac->ev.data != NULL)
-        return REDIS_ERR;
-
-    /* Create container for context and r/w events */
-    e = (redisAeEvents*)malloc(sizeof(*e));
-    e->context = ac;
-    e->loop = loop;
-    e->fd = c->fd;
-    e->reading = e->writing = 0;
-
-    /* Register functions to start/stop listening for events */
-    ac->ev.addRead = redisAeAddRead;
-    ac->ev.delRead = redisAeDelRead;
-    ac->ev.addWrite = redisAeAddWrite;
-    ac->ev.delWrite = redisAeDelWrite;
-    ac->ev.cleanup = redisAeCleanup;
-    ac->ev.data = e;
-
-    return REDIS_OK;
-}
-#endif
diff --git a/third-party/hiredis/adapters/glib.h b/third-party/hiredis/adapters/glib.h
deleted file mode 100644 (file)
index e0a6411..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-#ifndef __HIREDIS_GLIB_H__
-#define __HIREDIS_GLIB_H__
-
-#include <glib.h>
-
-#include "../hiredis.h"
-#include "../async.h"
-
-typedef struct
-{
-    GSource source;
-    redisAsyncContext *ac;
-    GPollFD poll_fd;
-} RedisSource;
-
-static void
-redis_source_add_read (gpointer data)
-{
-    RedisSource *source = (RedisSource *)data;
-    g_return_if_fail(source);
-    source->poll_fd.events |= G_IO_IN;
-    g_main_context_wakeup(g_source_get_context((GSource *)data));
-}
-
-static void
-redis_source_del_read (gpointer data)
-{
-    RedisSource *source = (RedisSource *)data;
-    g_return_if_fail(source);
-    source->poll_fd.events &= ~G_IO_IN;
-    g_main_context_wakeup(g_source_get_context((GSource *)data));
-}
-
-static void
-redis_source_add_write (gpointer data)
-{
-    RedisSource *source = (RedisSource *)data;
-    g_return_if_fail(source);
-    source->poll_fd.events |= G_IO_OUT;
-    g_main_context_wakeup(g_source_get_context((GSource *)data));
-}
-
-static void
-redis_source_del_write (gpointer data)
-{
-    RedisSource *source = (RedisSource *)data;
-    g_return_if_fail(source);
-    source->poll_fd.events &= ~G_IO_OUT;
-    g_main_context_wakeup(g_source_get_context((GSource *)data));
-}
-
-static void
-redis_source_cleanup (gpointer data)
-{
-    RedisSource *source = (RedisSource *)data;
-
-    g_return_if_fail(source);
-
-    redis_source_del_read(source);
-    redis_source_del_write(source);
-    /*
-     * It is not our responsibility to remove ourself from the
-     * current main loop. However, we will remove the GPollFD.
-     */
-    if (source->poll_fd.fd >= 0) {
-        g_source_remove_poll((GSource *)data, &source->poll_fd);
-        source->poll_fd.fd = -1;
-    }
-}
-
-static gboolean
-redis_source_prepare (GSource *source,
-                      gint    *timeout_)
-{
-    RedisSource *redis = (RedisSource *)source;
-    *timeout_ = -1;
-    return !!(redis->poll_fd.events & redis->poll_fd.revents);
-}
-
-static gboolean
-redis_source_check (GSource *source)
-{
-    RedisSource *redis = (RedisSource *)source;
-    return !!(redis->poll_fd.events & redis->poll_fd.revents);
-}
-
-static gboolean
-redis_source_dispatch (GSource      *source,
-                       GSourceFunc   callback,
-                       gpointer      user_data)
-{
-    RedisSource *redis = (RedisSource *)source;
-
-    if ((redis->poll_fd.revents & G_IO_OUT)) {
-        redisAsyncHandleWrite(redis->ac);
-        redis->poll_fd.revents &= ~G_IO_OUT;
-    }
-
-    if ((redis->poll_fd.revents & G_IO_IN)) {
-        redisAsyncHandleRead(redis->ac);
-        redis->poll_fd.revents &= ~G_IO_IN;
-    }
-
-    if (callback) {
-        return callback(user_data);
-    }
-
-    return TRUE;
-}
-
-static void
-redis_source_finalize (GSource *source)
-{
-    RedisSource *redis = (RedisSource *)source;
-
-    if (redis->poll_fd.fd >= 0) {
-        g_source_remove_poll(source, &redis->poll_fd);
-        redis->poll_fd.fd = -1;
-    }
-}
-
-static GSource *
-redis_source_new (redisAsyncContext *ac)
-{
-    static GSourceFuncs source_funcs = {
-        .prepare  = redis_source_prepare,
-        .check     = redis_source_check,
-        .dispatch = redis_source_dispatch,
-        .finalize = redis_source_finalize,
-    };
-    redisContext *c = &ac->c;
-    RedisSource *source;
-
-    g_return_val_if_fail(ac != NULL, NULL);
-
-    source = (RedisSource *)g_source_new(&source_funcs, sizeof *source);
-    source->ac = ac;
-    source->poll_fd.fd = c->fd;
-    source->poll_fd.events = 0;
-    source->poll_fd.revents = 0;
-    g_source_add_poll((GSource *)source, &source->poll_fd);
-
-    ac->ev.addRead = redis_source_add_read;
-    ac->ev.delRead = redis_source_del_read;
-    ac->ev.addWrite = redis_source_add_write;
-    ac->ev.delWrite = redis_source_del_write;
-    ac->ev.cleanup = redis_source_cleanup;
-    ac->ev.data = source;
-
-    return (GSource *)source;
-}
-
-#endif /* __HIREDIS_GLIB_H__ */
diff --git a/third-party/hiredis/adapters/ivykis.h b/third-party/hiredis/adapters/ivykis.h
deleted file mode 100644 (file)
index 6a12a86..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef __HIREDIS_IVYKIS_H__
-#define __HIREDIS_IVYKIS_H__
-#include <iv.h>
-#include "../hiredis.h"
-#include "../async.h"
-
-typedef struct redisIvykisEvents {
-    redisAsyncContext *context;
-    struct iv_fd fd;
-} redisIvykisEvents;
-
-static void redisIvykisReadEvent(void *arg) {
-    redisAsyncContext *context = (redisAsyncContext *)arg;
-    redisAsyncHandleRead(context);
-}
-
-static void redisIvykisWriteEvent(void *arg) {
-    redisAsyncContext *context = (redisAsyncContext *)arg;
-    redisAsyncHandleWrite(context);
-}
-
-static void redisIvykisAddRead(void *privdata) {
-    redisIvykisEvents *e = (redisIvykisEvents*)privdata;
-    iv_fd_set_handler_in(&e->fd, redisIvykisReadEvent);
-}
-
-static void redisIvykisDelRead(void *privdata) {
-    redisIvykisEvents *e = (redisIvykisEvents*)privdata;
-    iv_fd_set_handler_in(&e->fd, NULL);
-}
-
-static void redisIvykisAddWrite(void *privdata) {
-    redisIvykisEvents *e = (redisIvykisEvents*)privdata;
-    iv_fd_set_handler_out(&e->fd, redisIvykisWriteEvent);
-}
-
-static void redisIvykisDelWrite(void *privdata) {
-    redisIvykisEvents *e = (redisIvykisEvents*)privdata;
-    iv_fd_set_handler_out(&e->fd, NULL);
-}
-
-static void redisIvykisCleanup(void *privdata) {
-    redisIvykisEvents *e = (redisIvykisEvents*)privdata;
-
-    iv_fd_unregister(&e->fd);
-    free(e);
-}
-
-static int redisIvykisAttach(redisAsyncContext *ac) {
-    redisContext *c = &(ac->c);
-    redisIvykisEvents *e;
-
-    /* Nothing should be attached when something is already attached */
-    if (ac->ev.data != NULL)
-        return REDIS_ERR;
-
-    /* Create container for context and r/w events */
-    e = (redisIvykisEvents*)malloc(sizeof(*e));
-    e->context = ac;
-
-    /* Register functions to start/stop listening for events */
-    ac->ev.addRead = redisIvykisAddRead;
-    ac->ev.delRead = redisIvykisDelRead;
-    ac->ev.addWrite = redisIvykisAddWrite;
-    ac->ev.delWrite = redisIvykisDelWrite;
-    ac->ev.cleanup = redisIvykisCleanup;
-    ac->ev.data = e;
-
-    /* Initialize and install read/write events */
-    IV_FD_INIT(&e->fd);
-    e->fd.fd = c->fd;
-    e->fd.handler_in = redisIvykisReadEvent;
-    e->fd.handler_out = redisIvykisWriteEvent;
-    e->fd.handler_err = NULL;
-    e->fd.cookie = e->context;
-
-    iv_fd_register(&e->fd);
-
-    return REDIS_OK;
-}
-#endif
diff --git a/third-party/hiredis/adapters/libev.h b/third-party/hiredis/adapters/libev.h
deleted file mode 100644 (file)
index 2bf8d52..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   * Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *   * 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.
- *   * Neither the name of Redis nor the names of its contributors may be used
- *     to endorse or promote products derived from this software without
- *     specific prior written permission.
- *
- * THIS 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 OWNER 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.
- */
-
-#ifndef __HIREDIS_LIBEV_H__
-#define __HIREDIS_LIBEV_H__
-#include <stdlib.h>
-#include <sys/types.h>
-#include <ev.h>
-#include "../hiredis.h"
-#include "../async.h"
-
-typedef struct redisLibevEvents {
-    redisAsyncContext *context;
-    struct ev_loop *loop;
-    int reading, writing;
-    ev_io rev, wev;
-} redisLibevEvents;
-
-static void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) {
-#if EV_MULTIPLICITY
-    ((void)loop);
-#endif
-    ((void)revents);
-
-    redisLibevEvents *e = (redisLibevEvents*)watcher->data;
-    redisAsyncHandleRead(e->context);
-}
-
-static void redisLibevWriteEvent(EV_P_ ev_io *watcher, int revents) {
-#if EV_MULTIPLICITY
-    ((void)loop);
-#endif
-    ((void)revents);
-
-    redisLibevEvents *e = (redisLibevEvents*)watcher->data;
-    redisAsyncHandleWrite(e->context);
-}
-
-static void redisLibevAddRead(void *privdata) {
-    redisLibevEvents *e = (redisLibevEvents*)privdata;
-    struct ev_loop *loop = e->loop;
-    ((void)loop);
-    if (!e->reading) {
-        e->reading = 1;
-        ev_io_start(EV_A_ &e->rev);
-    }
-}
-
-static void redisLibevDelRead(void *privdata) {
-    redisLibevEvents *e = (redisLibevEvents*)privdata;
-    struct ev_loop *loop = e->loop;
-    ((void)loop);
-    if (e->reading) {
-        e->reading = 0;
-        ev_io_stop(EV_A_ &e->rev);
-    }
-}
-
-static void redisLibevAddWrite(void *privdata) {
-    redisLibevEvents *e = (redisLibevEvents*)privdata;
-    struct ev_loop *loop = e->loop;
-    ((void)loop);
-    if (!e->writing) {
-        e->writing = 1;
-        ev_io_start(EV_A_ &e->wev);
-    }
-}
-
-static void redisLibevDelWrite(void *privdata) {
-    redisLibevEvents *e = (redisLibevEvents*)privdata;
-    struct ev_loop *loop = e->loop;
-    ((void)loop);
-    if (e->writing) {
-        e->writing = 0;
-        ev_io_stop(EV_A_ &e->wev);
-    }
-}
-
-static void redisLibevCleanup(void *privdata) {
-    redisLibevEvents *e = (redisLibevEvents*)privdata;
-    redisLibevDelRead(privdata);
-    redisLibevDelWrite(privdata);
-    free(e);
-}
-
-static int redisLibevAttach(EV_P_ redisAsyncContext *ac) {
-    redisContext *c = &(ac->c);
-    redisLibevEvents *e;
-
-    /* Nothing should be attached when something is already attached */
-    if (ac->ev.data != NULL)
-        return REDIS_ERR;
-
-    /* Create container for context and r/w events */
-    e = (redisLibevEvents*)malloc(sizeof(*e));
-    e->context = ac;
-#if EV_MULTIPLICITY
-    e->loop = loop;
-#else
-    e->loop = NULL;
-#endif
-    e->reading = e->writing = 0;
-    e->rev.data = e;
-    e->wev.data = e;
-
-    /* Register functions to start/stop listening for events */
-    ac->ev.addRead = redisLibevAddRead;
-    ac->ev.delRead = redisLibevDelRead;
-    ac->ev.addWrite = redisLibevAddWrite;
-    ac->ev.delWrite = redisLibevDelWrite;
-    ac->ev.cleanup = redisLibevCleanup;
-    ac->ev.data = e;
-
-    /* Initialize read/write events */
-    ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ);
-    ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE);
-    return REDIS_OK;
-}
-
-#endif
diff --git a/third-party/hiredis/adapters/libevent.h b/third-party/hiredis/adapters/libevent.h
deleted file mode 100644 (file)
index 1c2b271..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   * Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *   * 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.
- *   * Neither the name of Redis nor the names of its contributors may be used
- *     to endorse or promote products derived from this software without
- *     specific prior written permission.
- *
- * THIS 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 OWNER 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.
- */
-
-#ifndef __HIREDIS_LIBEVENT_H__
-#define __HIREDIS_LIBEVENT_H__
-#include <event.h>
-#include "../hiredis.h"
-#include "../async.h"
-
-typedef struct redisLibeventEvents {
-    redisAsyncContext *context;
-    struct event rev, wev;
-} redisLibeventEvents;
-
-static void redisLibeventReadEvent(int fd, short event, void *arg) {
-    ((void)fd); ((void)event);
-    redisLibeventEvents *e = (redisLibeventEvents*)arg;
-    redisAsyncHandleRead(e->context);
-}
-
-static void redisLibeventWriteEvent(int fd, short event, void *arg) {
-    ((void)fd); ((void)event);
-    redisLibeventEvents *e = (redisLibeventEvents*)arg;
-    redisAsyncHandleWrite(e->context);
-}
-
-static void redisLibeventAddRead(void *privdata) {
-    redisLibeventEvents *e = (redisLibeventEvents*)privdata;
-    event_add(&e->rev,NULL);
-}
-
-static void redisLibeventDelRead(void *privdata) {
-    redisLibeventEvents *e = (redisLibeventEvents*)privdata;
-    event_del(&e->rev);
-}
-
-static void redisLibeventAddWrite(void *privdata) {
-    redisLibeventEvents *e = (redisLibeventEvents*)privdata;
-    event_add(&e->wev,NULL);
-}
-
-static void redisLibeventDelWrite(void *privdata) {
-    redisLibeventEvents *e = (redisLibeventEvents*)privdata;
-    event_del(&e->wev);
-}
-
-static void redisLibeventCleanup(void *privdata) {
-    redisLibeventEvents *e = (redisLibeventEvents*)privdata;
-    event_del(&e->rev);
-    event_del(&e->wev);
-    free(e);
-}
-
-static int redisLibeventAttach(redisAsyncContext *ac, struct event_base *base) {
-    redisContext *c = &(ac->c);
-    redisLibeventEvents *e;
-
-    /* Nothing should be attached when something is already attached */
-    if (ac->ev.data != NULL)
-        return REDIS_ERR;
-
-    /* Create container for context and r/w events */
-    e = (redisLibeventEvents*)malloc(sizeof(*e));
-    e->context = ac;
-
-    /* Register functions to start/stop listening for events */
-    ac->ev.addRead = redisLibeventAddRead;
-    ac->ev.delRead = redisLibeventDelRead;
-    ac->ev.addWrite = redisLibeventAddWrite;
-    ac->ev.delWrite = redisLibeventDelWrite;
-    ac->ev.cleanup = redisLibeventCleanup;
-    ac->ev.data = e;
-
-    /* Initialize and install read/write events */
-    event_set(&e->rev,c->fd,EV_READ,redisLibeventReadEvent,e);
-    event_set(&e->wev,c->fd,EV_WRITE,redisLibeventWriteEvent,e);
-    event_base_set(base,&e->rev);
-    event_base_set(base,&e->wev);
-    return REDIS_OK;
-}
-#endif
diff --git a/third-party/hiredis/adapters/libuv.h b/third-party/hiredis/adapters/libuv.h
deleted file mode 100644 (file)
index 3cdf3d3..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-#ifndef __HIREDIS_LIBUV_H__
-#define __HIREDIS_LIBUV_H__
-#include <stdlib.h>
-#include <uv.h>
-#include "../hiredis.h"
-#include "../async.h"
-#include <string.h>
-
-typedef struct redisLibuvEvents {
-  redisAsyncContext* context;
-  uv_poll_t          handle;
-  int                events;
-} redisLibuvEvents;
-
-
-static void redisLibuvPoll(uv_poll_t* handle, int status, int events) {
-  redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
-
-  if (status != 0) {
-    return;
-  }
-
-  if (events & UV_READABLE) {
-    redisAsyncHandleRead(p->context);
-  }
-  if (events & UV_WRITABLE) {
-    redisAsyncHandleWrite(p->context);
-  }
-}
-
-
-static void redisLibuvAddRead(void *privdata) {
-  redisLibuvEvents* p = (redisLibuvEvents*)privdata;
-
-  p->events |= UV_READABLE;
-
-  uv_poll_start(&p->handle, p->events, redisLibuvPoll);
-}
-
-
-static void redisLibuvDelRead(void *privdata) {
-  redisLibuvEvents* p = (redisLibuvEvents*)privdata;
-
-  p->events &= ~UV_READABLE;
-
-  if (p->events) {
-    uv_poll_start(&p->handle, p->events, redisLibuvPoll);
-  } else {
-    uv_poll_stop(&p->handle);
-  }
-}
-
-
-static void redisLibuvAddWrite(void *privdata) {
-  redisLibuvEvents* p = (redisLibuvEvents*)privdata;
-
-  p->events |= UV_WRITABLE;
-
-  uv_poll_start(&p->handle, p->events, redisLibuvPoll);
-}
-
-
-static void redisLibuvDelWrite(void *privdata) {
-  redisLibuvEvents* p = (redisLibuvEvents*)privdata;
-
-  p->events &= ~UV_WRITABLE;
-
-  if (p->events) {
-    uv_poll_start(&p->handle, p->events, redisLibuvPoll);
-  } else {
-    uv_poll_stop(&p->handle);
-  }
-}
-
-
-static void on_close(uv_handle_t* handle) {
-  redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
-
-  free(p);
-}
-
-
-static void redisLibuvCleanup(void *privdata) {
-  redisLibuvEvents* p = (redisLibuvEvents*)privdata;
-
-  uv_close((uv_handle_t*)&p->handle, on_close);
-}
-
-
-static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) {
-  redisContext *c = &(ac->c);
-
-  if (ac->ev.data != NULL) {
-    return REDIS_ERR;
-  }
-
-  ac->ev.addRead  = redisLibuvAddRead;
-  ac->ev.delRead  = redisLibuvDelRead;
-  ac->ev.addWrite = redisLibuvAddWrite;
-  ac->ev.delWrite = redisLibuvDelWrite;
-  ac->ev.cleanup  = redisLibuvCleanup;
-
-  redisLibuvEvents* p = (redisLibuvEvents*)malloc(sizeof(*p));
-
-  if (!p) {
-    return REDIS_ERR;
-  }
-
-  memset(p, 0, sizeof(*p));
-
-  if (uv_poll_init(loop, &p->handle, c->fd) != 0) {
-    return REDIS_ERR;
-  }
-
-  ac->ev.data    = p;
-  p->handle.data = p;
-  p->context     = ac;
-
-  return REDIS_OK;
-}
-#endif
diff --git a/third-party/hiredis/adapters/macosx.h b/third-party/hiredis/adapters/macosx.h
deleted file mode 100644 (file)
index 72121f6..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-//
-//  Created by Ð”митрий Ð‘ахвалов on 13.07.15.
-//  Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved.
-//
-
-#ifndef __HIREDIS_MACOSX_H__
-#define __HIREDIS_MACOSX_H__
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#include "../hiredis.h"
-#include "../async.h"
-
-typedef struct {
-    redisAsyncContext *context;
-    CFSocketRef socketRef;
-    CFRunLoopSourceRef sourceRef;
-} RedisRunLoop;
-
-static int freeRedisRunLoop(RedisRunLoop* redisRunLoop) {
-    if( redisRunLoop != NULL ) {
-        if( redisRunLoop->sourceRef != NULL ) {
-            CFRunLoopSourceInvalidate(redisRunLoop->sourceRef);
-            CFRelease(redisRunLoop->sourceRef);
-        }
-        if( redisRunLoop->socketRef != NULL ) {
-            CFSocketInvalidate(redisRunLoop->socketRef);
-            CFRelease(redisRunLoop->socketRef);
-        }
-        free(redisRunLoop);
-    }
-    return REDIS_ERR;
-}
-
-static void redisMacOSAddRead(void *privdata) {
-    RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
-    CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack);
-}
-
-static void redisMacOSDelRead(void *privdata) {
-    RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
-    CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack);
-}
-
-static void redisMacOSAddWrite(void *privdata) {
-    RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
-    CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack);
-}
-
-static void redisMacOSDelWrite(void *privdata) {
-    RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
-    CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack);
-}
-
-static void redisMacOSCleanup(void *privdata) {
-    RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
-    freeRedisRunLoop(redisRunLoop);
-}
-
-static void redisMacOSAsyncCallback(CFSocketRef __unused s, CFSocketCallBackType callbackType, CFDataRef __unused address, const void __unused *data, void *info) {
-    redisAsyncContext* context = (redisAsyncContext*) info;
-
-    switch (callbackType) {
-        case kCFSocketReadCallBack:
-            redisAsyncHandleRead(context);
-            break;
-
-        case kCFSocketWriteCallBack:
-            redisAsyncHandleWrite(context);
-            break;
-
-        default:
-            break;
-    }
-}
-
-static int redisMacOSAttach(redisAsyncContext *redisAsyncCtx, CFRunLoopRef runLoop) {
-    redisContext *redisCtx = &(redisAsyncCtx->c);
-
-    /* Nothing should be attached when something is already attached */
-    if( redisAsyncCtx->ev.data != NULL ) return REDIS_ERR;
-
-    RedisRunLoop* redisRunLoop = (RedisRunLoop*) calloc(1, sizeof(RedisRunLoop));
-    if( !redisRunLoop ) return REDIS_ERR;
-
-    /* Setup redis stuff */
-    redisRunLoop->context = redisAsyncCtx;
-
-    redisAsyncCtx->ev.addRead  = redisMacOSAddRead;
-    redisAsyncCtx->ev.delRead  = redisMacOSDelRead;
-    redisAsyncCtx->ev.addWrite = redisMacOSAddWrite;
-    redisAsyncCtx->ev.delWrite = redisMacOSDelWrite;
-    redisAsyncCtx->ev.cleanup  = redisMacOSCleanup;
-    redisAsyncCtx->ev.data     = redisRunLoop;
-
-    /* Initialize and install read/write events */
-    CFSocketContext socketCtx = { 0, redisAsyncCtx, NULL, NULL, NULL };
-
-    redisRunLoop->socketRef = CFSocketCreateWithNative(NULL, redisCtx->fd,
-                                                       kCFSocketReadCallBack | kCFSocketWriteCallBack,
-                                                       redisMacOSAsyncCallback,
-                                                       &socketCtx);
-    if( !redisRunLoop->socketRef ) return freeRedisRunLoop(redisRunLoop);
-
-    redisRunLoop->sourceRef = CFSocketCreateRunLoopSource(NULL, redisRunLoop->socketRef, 0);
-    if( !redisRunLoop->sourceRef ) return freeRedisRunLoop(redisRunLoop);
-
-    CFRunLoopAddSource(runLoop, redisRunLoop->sourceRef, kCFRunLoopDefaultMode);
-
-    return REDIS_OK;
-}
-
-#endif
-
diff --git a/third-party/hiredis/adapters/qt.h b/third-party/hiredis/adapters/qt.h
deleted file mode 100644 (file)
index 5cc02e6..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/*-
- * Copyright (C) 2014 Pietro Cerutti <gahr@gahr.ch>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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.
- */
-
-#ifndef __HIREDIS_QT_H__
-#define __HIREDIS_QT_H__
-#include <QSocketNotifier>
-#include "../async.h"
-
-static void RedisQtAddRead(void *);
-static void RedisQtDelRead(void *);
-static void RedisQtAddWrite(void *);
-static void RedisQtDelWrite(void *);
-static void RedisQtCleanup(void *);
-
-class RedisQtAdapter : public QObject {
-
-    Q_OBJECT
-
-    friend
-    void RedisQtAddRead(void * adapter) {
-        RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
-        a->addRead();
-    }
-
-    friend
-    void RedisQtDelRead(void * adapter) {
-        RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
-        a->delRead();
-    }
-
-    friend
-    void RedisQtAddWrite(void * adapter) {
-        RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
-        a->addWrite();
-    }
-
-    friend
-    void RedisQtDelWrite(void * adapter) {
-        RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
-        a->delWrite();
-    }
-
-    friend
-    void RedisQtCleanup(void * adapter) {
-        RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
-        a->cleanup();
-    }
-
-    public:
-        RedisQtAdapter(QObject * parent = 0)
-            : QObject(parent), m_ctx(0), m_read(0), m_write(0) { }
-
-        ~RedisQtAdapter() {
-            if (m_ctx != 0) {
-                m_ctx->ev.data = NULL;
-            }
-        }
-
-        int setContext(redisAsyncContext * ac) {
-            if (ac->ev.data != NULL) {
-                return REDIS_ERR;
-            }
-            m_ctx = ac;
-            m_ctx->ev.data = this;
-            m_ctx->ev.addRead = RedisQtAddRead;
-            m_ctx->ev.delRead = RedisQtDelRead;
-            m_ctx->ev.addWrite = RedisQtAddWrite;
-            m_ctx->ev.delWrite = RedisQtDelWrite;
-            m_ctx->ev.cleanup = RedisQtCleanup;
-            return REDIS_OK;
-        }
-
-    private:
-        void addRead() {
-            if (m_read) return;
-            m_read = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Read, 0);
-            connect(m_read, SIGNAL(activated(int)), this, SLOT(read()));
-        }
-
-        void delRead() {
-            if (!m_read) return;
-            delete m_read;
-            m_read = 0;
-        }
-
-        void addWrite() {
-            if (m_write) return;
-            m_write = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Write, 0);
-            connect(m_write, SIGNAL(activated(int)), this, SLOT(write()));
-        }
-
-        void delWrite() {
-            if (!m_write) return;
-            delete m_write;
-            m_write = 0;
-        }
-
-        void cleanup() {
-            delRead();
-            delWrite();
-        }
-
-    private slots:
-        void read() { redisAsyncHandleRead(m_ctx); }
-        void write() { redisAsyncHandleWrite(m_ctx); }
-
-    private:
-        redisAsyncContext * m_ctx;
-        QSocketNotifier * m_read;
-        QSocketNotifier * m_write;
-};
-
-#endif /* !__HIREDIS_QT_H__ */
diff --git a/third-party/hiredis/async.c b/third-party/hiredis/async.c
deleted file mode 100644 (file)
index acca29a..0000000
+++ /dev/null
@@ -1,687 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   * Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *   * 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.
- *   * Neither the name of Redis nor the names of its contributors may be used
- *     to endorse or promote products derived from this software without
- *     specific prior written permission.
- *
- * THIS 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 OWNER 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.
- */
-
-#include "fmacros.h"
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include "async.h"
-#include "net.h"
-#include "dict.c"
-#include "sds.h"
-
-#define _EL_ADD_READ(ctx) do { \
-        if ((ctx)->ev.addRead) (ctx)->ev.addRead((ctx)->ev.data); \
-    } while(0)
-#define _EL_DEL_READ(ctx) do { \
-        if ((ctx)->ev.delRead) (ctx)->ev.delRead((ctx)->ev.data); \
-    } while(0)
-#define _EL_ADD_WRITE(ctx) do { \
-        if ((ctx)->ev.addWrite) (ctx)->ev.addWrite((ctx)->ev.data); \
-    } while(0)
-#define _EL_DEL_WRITE(ctx) do { \
-        if ((ctx)->ev.delWrite) (ctx)->ev.delWrite((ctx)->ev.data); \
-    } while(0)
-#define _EL_CLEANUP(ctx) do { \
-        if ((ctx)->ev.cleanup) (ctx)->ev.cleanup((ctx)->ev.data); \
-    } while(0);
-
-/* Forward declaration of function in hiredis.c */
-int __redisAppendCommand(redisContext *c, const char *cmd, size_t len);
-
-/* Functions managing dictionary of callbacks for pub/sub. */
-static unsigned int callbackHash(const void *key) {
-    return dictGenHashFunction((const unsigned char *)key,
-                               sdslen((const sds)key));
-}
-
-static void *callbackValDup(void *privdata, const void *src) {
-    ((void) privdata);
-    redisCallback *dup = malloc(sizeof(*dup));
-    memcpy(dup,src,sizeof(*dup));
-    return dup;
-}
-
-static int callbackKeyCompare(void *privdata, const void *key1, const void *key2) {
-    int l1, l2;
-    ((void) privdata);
-
-    l1 = sdslen((const sds)key1);
-    l2 = sdslen((const sds)key2);
-    if (l1 != l2) return 0;
-    return memcmp(key1,key2,l1) == 0;
-}
-
-static void callbackKeyDestructor(void *privdata, void *key) {
-    ((void) privdata);
-    sdsfree((sds)key);
-}
-
-static void callbackValDestructor(void *privdata, void *val) {
-    ((void) privdata);
-    free(val);
-}
-
-static dictType callbackDict = {
-    callbackHash,
-    NULL,
-    callbackValDup,
-    callbackKeyCompare,
-    callbackKeyDestructor,
-    callbackValDestructor
-};
-
-static redisAsyncContext *redisAsyncInitialize(redisContext *c) {
-    redisAsyncContext *ac;
-
-    ac = realloc(c,sizeof(redisAsyncContext));
-    if (ac == NULL)
-        return NULL;
-
-    c = &(ac->c);
-
-    /* The regular connect functions will always set the flag REDIS_CONNECTED.
-     * For the async API, we want to wait until the first write event is
-     * received up before setting this flag, so reset it here. */
-    c->flags &= ~REDIS_CONNECTED;
-
-    ac->err = 0;
-    ac->errstr = NULL;
-    ac->data = NULL;
-
-    ac->ev.data = NULL;
-    ac->ev.addRead = NULL;
-    ac->ev.delRead = NULL;
-    ac->ev.addWrite = NULL;
-    ac->ev.delWrite = NULL;
-    ac->ev.cleanup = NULL;
-
-    ac->onConnect = NULL;
-    ac->onDisconnect = NULL;
-
-    ac->replies.head = NULL;
-    ac->replies.tail = NULL;
-    ac->sub.invalid.head = NULL;
-    ac->sub.invalid.tail = NULL;
-    ac->sub.channels = dictCreate(&callbackDict,NULL);
-    ac->sub.patterns = dictCreate(&callbackDict,NULL);
-    return ac;
-}
-
-/* We want the error field to be accessible directly instead of requiring
- * an indirection to the redisContext struct. */
-static void __redisAsyncCopyError(redisAsyncContext *ac) {
-    if (!ac)
-        return;
-
-    redisContext *c = &(ac->c);
-    ac->err = c->err;
-    ac->errstr = c->errstr;
-}
-
-redisAsyncContext *redisAsyncConnect(const char *ip, int port) {
-    redisContext *c;
-    redisAsyncContext *ac;
-
-    c = redisConnectNonBlock(ip,port);
-    if (c == NULL)
-        return NULL;
-
-    ac = redisAsyncInitialize(c);
-    if (ac == NULL) {
-        redisFree(c);
-        return NULL;
-    }
-
-    __redisAsyncCopyError(ac);
-    return ac;
-}
-
-redisAsyncContext *redisAsyncConnectBind(const char *ip, int port,
-                                         const char *source_addr) {
-    redisContext *c = redisConnectBindNonBlock(ip,port,source_addr);
-    redisAsyncContext *ac = redisAsyncInitialize(c);
-    __redisAsyncCopyError(ac);
-    return ac;
-}
-
-redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port,
-                                                  const char *source_addr) {
-    redisContext *c = redisConnectBindNonBlockWithReuse(ip,port,source_addr);
-    redisAsyncContext *ac = redisAsyncInitialize(c);
-    __redisAsyncCopyError(ac);
-    return ac;
-}
-
-redisAsyncContext *redisAsyncConnectUnix(const char *path) {
-    redisContext *c;
-    redisAsyncContext *ac;
-
-    c = redisConnectUnixNonBlock(path);
-    if (c == NULL)
-        return NULL;
-
-    ac = redisAsyncInitialize(c);
-    if (ac == NULL) {
-        redisFree(c);
-        return NULL;
-    }
-
-    __redisAsyncCopyError(ac);
-    return ac;
-}
-
-int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn) {
-    if (ac->onConnect == NULL) {
-        ac->onConnect = fn;
-
-        /* The common way to detect an established connection is to wait for
-         * the first write event to be fired. This assumes the related event
-         * library functions are already set. */
-        _EL_ADD_WRITE(ac);
-        return REDIS_OK;
-    }
-    return REDIS_ERR;
-}
-
-int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn) {
-    if (ac->onDisconnect == NULL) {
-        ac->onDisconnect = fn;
-        return REDIS_OK;
-    }
-    return REDIS_ERR;
-}
-
-/* Helper functions to push/shift callbacks */
-static int __redisPushCallback(redisCallbackList *list, redisCallback *source) {
-    redisCallback *cb;
-
-    /* Copy callback from stack to heap */
-    cb = malloc(sizeof(*cb));
-    if (cb == NULL)
-        return REDIS_ERR_OOM;
-
-    if (source != NULL) {
-        memcpy(cb,source,sizeof(*cb));
-        cb->next = NULL;
-    }
-
-    /* Store callback in list */
-    if (list->head == NULL)
-        list->head = cb;
-    if (list->tail != NULL)
-        list->tail->next = cb;
-    list->tail = cb;
-    return REDIS_OK;
-}
-
-static int __redisShiftCallback(redisCallbackList *list, redisCallback *target) {
-    redisCallback *cb = list->head;
-    if (cb != NULL) {
-        list->head = cb->next;
-        if (cb == list->tail)
-            list->tail = NULL;
-
-        /* Copy callback from heap to stack */
-        if (target != NULL)
-            memcpy(target,cb,sizeof(*cb));
-        free(cb);
-        return REDIS_OK;
-    }
-    return REDIS_ERR;
-}
-
-static void __redisRunCallback(redisAsyncContext *ac, redisCallback *cb, redisReply *reply) {
-    redisContext *c = &(ac->c);
-    if (cb->fn != NULL) {
-        c->flags |= REDIS_IN_CALLBACK;
-        cb->fn(ac,reply,cb->privdata);
-        c->flags &= ~REDIS_IN_CALLBACK;
-    }
-}
-
-/* Helper function to free the context. */
-static void __redisAsyncFree(redisAsyncContext *ac) {
-    redisContext *c = &(ac->c);
-    redisCallback cb;
-    dictIterator *it;
-    dictEntry *de;
-
-    /* Execute pending callbacks with NULL reply. */
-    while (__redisShiftCallback(&ac->replies,&cb) == REDIS_OK)
-        __redisRunCallback(ac,&cb,NULL);
-
-    /* Execute callbacks for invalid commands */
-    while (__redisShiftCallback(&ac->sub.invalid,&cb) == REDIS_OK)
-        __redisRunCallback(ac,&cb,NULL);
-
-    /* Run subscription callbacks callbacks with NULL reply */
-    it = dictGetIterator(ac->sub.channels);
-    while ((de = dictNext(it)) != NULL)
-        __redisRunCallback(ac,dictGetEntryVal(de),NULL);
-    dictReleaseIterator(it);
-    dictRelease(ac->sub.channels);
-
-    it = dictGetIterator(ac->sub.patterns);
-    while ((de = dictNext(it)) != NULL)
-        __redisRunCallback(ac,dictGetEntryVal(de),NULL);
-    dictReleaseIterator(it);
-    dictRelease(ac->sub.patterns);
-
-    /* Signal event lib to clean up */
-    _EL_CLEANUP(ac);
-
-    /* Execute disconnect callback. When redisAsyncFree() initiated destroying
-     * this context, the status will always be REDIS_OK. */
-    if (ac->onDisconnect && (c->flags & REDIS_CONNECTED)) {
-        if (c->flags & REDIS_FREEING) {
-            ac->onDisconnect(ac,REDIS_OK);
-        } else {
-            ac->onDisconnect(ac,(ac->err == 0) ? REDIS_OK : REDIS_ERR);
-        }
-    }
-
-    /* Cleanup self */
-    redisFree(c);
-}
-
-/* Free the async context. When this function is called from a callback,
- * control needs to be returned to redisProcessCallbacks() before actual
- * free'ing. To do so, a flag is set on the context which is picked up by
- * redisProcessCallbacks(). Otherwise, the context is immediately free'd. */
-void redisAsyncFree(redisAsyncContext *ac) {
-    redisContext *c = &(ac->c);
-    c->flags |= REDIS_FREEING;
-    if (!(c->flags & REDIS_IN_CALLBACK))
-        __redisAsyncFree(ac);
-}
-
-/* Helper function to make the disconnect happen and clean up. */
-static void __redisAsyncDisconnect(redisAsyncContext *ac) {
-    redisContext *c = &(ac->c);
-
-    /* Make sure error is accessible if there is any */
-    __redisAsyncCopyError(ac);
-
-    if (ac->err == 0) {
-        /* For clean disconnects, there should be no pending callbacks. */
-        assert(__redisShiftCallback(&ac->replies,NULL) == REDIS_ERR);
-    } else {
-        /* Disconnection is caused by an error, make sure that pending
-         * callbacks cannot call new commands. */
-        c->flags |= REDIS_DISCONNECTING;
-    }
-
-    /* For non-clean disconnects, __redisAsyncFree() will execute pending
-     * callbacks with a NULL-reply. */
-    __redisAsyncFree(ac);
-}
-
-/* Tries to do a clean disconnect from Redis, meaning it stops new commands
- * from being issued, but tries to flush the output buffer and execute
- * callbacks for all remaining replies. When this function is called from a
- * callback, there might be more replies and we can safely defer disconnecting
- * to redisProcessCallbacks(). Otherwise, we can only disconnect immediately
- * when there are no pending callbacks. */
-void redisAsyncDisconnect(redisAsyncContext *ac) {
-    redisContext *c = &(ac->c);
-    c->flags |= REDIS_DISCONNECTING;
-    if (!(c->flags & REDIS_IN_CALLBACK) && ac->replies.head == NULL)
-        __redisAsyncDisconnect(ac);
-}
-
-static int __redisGetSubscribeCallback(redisAsyncContext *ac, redisReply *reply, redisCallback *dstcb) {
-    redisContext *c = &(ac->c);
-    dict *callbacks;
-    dictEntry *de;
-    int pvariant;
-    char *stype;
-    sds sname;
-
-    /* Custom reply functions are not supported for pub/sub. This will fail
-     * very hard when they are used... */
-    if (reply->type == REDIS_REPLY_ARRAY) {
-        assert(reply->elements >= 2);
-        assert(reply->element[0]->type == REDIS_REPLY_STRING);
-        stype = reply->element[0]->str;
-        pvariant = (tolower(stype[0]) == 'p') ? 1 : 0;
-
-        if (pvariant)
-            callbacks = ac->sub.patterns;
-        else
-            callbacks = ac->sub.channels;
-
-        /* Locate the right callback */
-        assert(reply->element[1]->type == REDIS_REPLY_STRING);
-        sname = sdsnewlen(reply->element[1]->str,reply->element[1]->len);
-        de = dictFind(callbacks,sname);
-        if (de != NULL) {
-            memcpy(dstcb,dictGetEntryVal(de),sizeof(*dstcb));
-
-            /* If this is an unsubscribe message, remove it. */
-            if (strcasecmp(stype+pvariant,"unsubscribe") == 0) {
-                dictDelete(callbacks,sname);
-
-                /* If this was the last unsubscribe message, revert to
-                 * non-subscribe mode. */
-                assert(reply->element[2]->type == REDIS_REPLY_INTEGER);
-                if (reply->element[2]->integer == 0)
-                    c->flags &= ~REDIS_SUBSCRIBED;
-            }
-        }
-        sdsfree(sname);
-    } else {
-        /* Shift callback for invalid commands. */
-        __redisShiftCallback(&ac->sub.invalid,dstcb);
-    }
-    return REDIS_OK;
-}
-
-void redisProcessCallbacks(redisAsyncContext *ac) {
-    redisContext *c = &(ac->c);
-    redisCallback cb = {NULL, NULL, NULL};
-    void *reply = NULL;
-    int status;
-
-    while((status = redisGetReply(c,&reply)) == REDIS_OK) {
-        if (reply == NULL) {
-            /* When the connection is being disconnected and there are
-             * no more replies, this is the cue to really disconnect. */
-            if (c->flags & REDIS_DISCONNECTING && sdslen(c->obuf) == 0
-                && ac->replies.head == NULL) {
-                __redisAsyncDisconnect(ac);
-                return;
-            }
-
-            /* If monitor mode, repush callback */
-            if(c->flags & REDIS_MONITORING) {
-                __redisPushCallback(&ac->replies,&cb);
-            }
-
-            /* When the connection is not being disconnected, simply stop
-             * trying to get replies and wait for the next loop tick. */
-            break;
-        }
-
-        /* Even if the context is subscribed, pending regular callbacks will
-         * get a reply before pub/sub messages arrive. */
-        if (__redisShiftCallback(&ac->replies,&cb) != REDIS_OK) {
-            /*
-             * A spontaneous reply in a not-subscribed context can be the error
-             * reply that is sent when a new connection exceeds the maximum
-             * number of allowed connections on the server side.
-             *
-             * This is seen as an error instead of a regular reply because the
-             * server closes the connection after sending it.
-             *
-             * To prevent the error from being overwritten by an EOF error the
-             * connection is closed here. See issue #43.
-             *
-             * Another possibility is that the server is loading its dataset.
-             * In this case we also want to close the connection, and have the
-             * user wait until the server is ready to take our request.
-             */
-            if (((redisReply*)reply)->type == REDIS_REPLY_ERROR) {
-                c->err = REDIS_ERR_OTHER;
-                snprintf(c->errstr,sizeof(c->errstr),"%s",((redisReply*)reply)->str);
-                c->reader->fn->freeObject(reply);
-                __redisAsyncDisconnect(ac);
-                return;
-            }
-            /* No more regular callbacks and no errors, the context *must* be subscribed or monitoring. */
-            assert((c->flags & REDIS_SUBSCRIBED || c->flags & REDIS_MONITORING));
-            if(c->flags & REDIS_SUBSCRIBED)
-                __redisGetSubscribeCallback(ac,reply,&cb);
-        }
-
-        if (cb.fn != NULL) {
-            __redisRunCallback(ac,&cb,reply);
-            c->reader->fn->freeObject(reply);
-
-            /* Proceed with free'ing when redisAsyncFree() was called. */
-            if (c->flags & REDIS_FREEING) {
-                __redisAsyncFree(ac);
-                return;
-            }
-        } else {
-            /* No callback for this reply. This can either be a NULL callback,
-             * or there were no callbacks to begin with. Either way, don't
-             * abort with an error, but simply ignore it because the client
-             * doesn't know what the server will spit out over the wire. */
-            c->reader->fn->freeObject(reply);
-        }
-    }
-
-    /* Disconnect when there was an error reading the reply */
-    if (status != REDIS_OK)
-        __redisAsyncDisconnect(ac);
-}
-
-/* Internal helper function to detect socket status the first time a read or
- * write event fires. When connecting was not succesful, the connect callback
- * is called with a REDIS_ERR status and the context is free'd. */
-static int __redisAsyncHandleConnect(redisAsyncContext *ac) {
-    redisContext *c = &(ac->c);
-
-    if (redisCheckSocketError(c) == REDIS_ERR) {
-        /* Try again later when connect(2) is still in progress. */
-        if (errno == EINPROGRESS)
-            return REDIS_OK;
-
-        if (ac->onConnect) ac->onConnect(ac,REDIS_ERR);
-        __redisAsyncDisconnect(ac);
-        return REDIS_ERR;
-    }
-
-    /* Mark context as connected. */
-    c->flags |= REDIS_CONNECTED;
-    if (ac->onConnect) ac->onConnect(ac,REDIS_OK);
-    return REDIS_OK;
-}
-
-/* This function should be called when the socket is readable.
- * It processes all replies that can be read and executes their callbacks.
- */
-void redisAsyncHandleRead(redisAsyncContext *ac) {
-    redisContext *c = &(ac->c);
-
-    if (!(c->flags & REDIS_CONNECTED)) {
-        /* Abort connect was not successful. */
-        if (__redisAsyncHandleConnect(ac) != REDIS_OK)
-            return;
-        /* Try again later when the context is still not connected. */
-        if (!(c->flags & REDIS_CONNECTED))
-            return;
-    }
-
-    if (redisBufferRead(c) == REDIS_ERR) {
-        __redisAsyncDisconnect(ac);
-    } else {
-        /* Always re-schedule reads */
-        _EL_ADD_READ(ac);
-        redisProcessCallbacks(ac);
-    }
-}
-
-void redisAsyncHandleWrite(redisAsyncContext *ac) {
-    redisContext *c = &(ac->c);
-    int done = 0;
-
-    if (!(c->flags & REDIS_CONNECTED)) {
-        /* Abort connect was not successful. */
-        if (__redisAsyncHandleConnect(ac) != REDIS_OK)
-            return;
-        /* Try again later when the context is still not connected. */
-        if (!(c->flags & REDIS_CONNECTED))
-            return;
-    }
-
-    if (redisBufferWrite(c,&done) == REDIS_ERR) {
-        __redisAsyncDisconnect(ac);
-    } else {
-        /* Continue writing when not done, stop writing otherwise */
-        if (!done)
-            _EL_ADD_WRITE(ac);
-        else
-            _EL_DEL_WRITE(ac);
-
-        /* Always schedule reads after writes */
-        _EL_ADD_READ(ac);
-    }
-}
-
-/* Sets a pointer to the first argument and its length starting at p. Returns
- * the number of bytes to skip to get to the following argument. */
-static const char *nextArgument(const char *start, const char **str, size_t *len) {
-    const char *p = start;
-    if (p[0] != '$') {
-        p = strchr(p,'$');
-        if (p == NULL) return NULL;
-    }
-
-    *len = (int)strtol(p+1,NULL,10);
-    p = strchr(p,'\r');
-    assert(p);
-    *str = p+2;
-    return p+2+(*len)+2;
-}
-
-/* Helper function for the redisAsyncCommand* family of functions. Writes a
- * formatted command to the output buffer and registers the provided callback
- * function with the context. */
-static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) {
-    redisContext *c = &(ac->c);
-    redisCallback cb;
-    int pvariant, hasnext;
-    const char *cstr, *astr;
-    size_t clen, alen;
-    const char *p;
-    sds sname;
-    int ret;
-
-    /* Don't accept new commands when the connection is about to be closed. */
-    if (c->flags & (REDIS_DISCONNECTING | REDIS_FREEING)) return REDIS_ERR;
-
-    /* Setup callback */
-    cb.fn = fn;
-    cb.privdata = privdata;
-
-    /* Find out which command will be appended. */
-    p = nextArgument(cmd,&cstr,&clen);
-    assert(p != NULL);
-    hasnext = (p[0] == '$');
-    pvariant = (tolower(cstr[0]) == 'p') ? 1 : 0;
-    cstr += pvariant;
-    clen -= pvariant;
-
-    if (hasnext && strncasecmp(cstr,"subscribe\r\n",11) == 0) {
-        c->flags |= REDIS_SUBSCRIBED;
-
-        /* Add every channel/pattern to the list of subscription callbacks. */
-        while ((p = nextArgument(p,&astr,&alen)) != NULL) {
-            sname = sdsnewlen(astr,alen);
-            if (pvariant)
-                ret = dictReplace(ac->sub.patterns,sname,&cb);
-            else
-                ret = dictReplace(ac->sub.channels,sname,&cb);
-
-            if (ret == 0) sdsfree(sname);
-        }
-    } else if (strncasecmp(cstr,"unsubscribe\r\n",13) == 0) {
-        /* It is only useful to call (P)UNSUBSCRIBE when the context is
-         * subscribed to one or more channels or patterns. */
-        if (!(c->flags & REDIS_SUBSCRIBED)) return REDIS_ERR;
-
-        /* (P)UNSUBSCRIBE does not have its own response: every channel or
-         * pattern that is unsubscribed will receive a message. This means we
-         * should not append a callback function for this command. */
-     } else if(strncasecmp(cstr,"monitor\r\n",9) == 0) {
-         /* Set monitor flag and push callback */
-         c->flags |= REDIS_MONITORING;
-         __redisPushCallback(&ac->replies,&cb);
-    } else {
-        if (c->flags & REDIS_SUBSCRIBED)
-            /* This will likely result in an error reply, but it needs to be
-             * received and passed to the callback. */
-            __redisPushCallback(&ac->sub.invalid,&cb);
-        else
-            __redisPushCallback(&ac->replies,&cb);
-    }
-
-    __redisAppendCommand(c,cmd,len);
-
-    /* Always schedule a write when the write buffer is non-empty */
-    _EL_ADD_WRITE(ac);
-
-    return REDIS_OK;
-}
-
-int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap) {
-    char *cmd;
-    int len;
-    int status;
-    len = redisvFormatCommand(&cmd,format,ap);
-
-    /* We don't want to pass -1 or -2 to future functions as a length. */
-    if (len < 0)
-        return REDIS_ERR;
-
-    status = __redisAsyncCommand(ac,fn,privdata,cmd,len);
-    free(cmd);
-    return status;
-}
-
-int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...) {
-    va_list ap;
-    int status;
-    va_start(ap,format);
-    status = redisvAsyncCommand(ac,fn,privdata,format,ap);
-    va_end(ap);
-    return status;
-}
-
-int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen) {
-    sds cmd;
-    int len;
-    int status;
-    len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen);
-    status = __redisAsyncCommand(ac,fn,privdata,cmd,len);
-    sdsfree(cmd);
-    return status;
-}
-
-int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) {
-    int status = __redisAsyncCommand(ac,fn,privdata,cmd,len);
-    return status;
-}
diff --git a/third-party/hiredis/async.h b/third-party/hiredis/async.h
deleted file mode 100644 (file)
index 59cbf46..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   * Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *   * 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.
- *   * Neither the name of Redis nor the names of its contributors may be used
- *     to endorse or promote products derived from this software without
- *     specific prior written permission.
- *
- * THIS 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 OWNER 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.
- */
-
-#ifndef __HIREDIS_ASYNC_H
-#define __HIREDIS_ASYNC_H
-#include "hiredis.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct redisAsyncContext; /* need forward declaration of redisAsyncContext */
-struct dict; /* dictionary header is included in async.c */
-
-/* Reply callback prototype and container */
-typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*);
-typedef struct redisCallback {
-    struct redisCallback *next; /* simple singly linked list */
-    redisCallbackFn *fn;
-    void *privdata;
-} redisCallback;
-
-/* List of callbacks for either regular replies or pub/sub */
-typedef struct redisCallbackList {
-    redisCallback *head, *tail;
-} redisCallbackList;
-
-/* Connection callback prototypes */
-typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status);
-typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status);
-
-/* Context for an async connection to Redis */
-typedef struct redisAsyncContext {
-    /* Hold the regular context, so it can be realloc'ed. */
-    redisContext c;
-
-    /* Setup error flags so they can be used directly. */
-    int err;
-    char *errstr;
-
-    /* Not used by hiredis */
-    void *data;
-
-    /* Event library data and hooks */
-    struct {
-        void *data;
-
-        /* Hooks that are called when the library expects to start
-         * reading/writing. These functions should be idempotent. */
-        void (*addRead)(void *privdata);
-        void (*delRead)(void *privdata);
-        void (*addWrite)(void *privdata);
-        void (*delWrite)(void *privdata);
-        void (*cleanup)(void *privdata);
-    } ev;
-
-    /* Called when either the connection is terminated due to an error or per
-     * user request. The status is set accordingly (REDIS_OK, REDIS_ERR). */
-    redisDisconnectCallback *onDisconnect;
-
-    /* Called when the first write event was received. */
-    redisConnectCallback *onConnect;
-
-    /* Regular command callbacks */
-    redisCallbackList replies;
-
-    /* Subscription callbacks */
-    struct {
-        redisCallbackList invalid;
-        struct dict *channels;
-        struct dict *patterns;
-    } sub;
-} redisAsyncContext;
-
-/* Functions that proxy to hiredis */
-redisAsyncContext *redisAsyncConnect(const char *ip, int port);
-redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr);
-redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port,
-                                                  const char *source_addr);
-redisAsyncContext *redisAsyncConnectUnix(const char *path);
-int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn);
-int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);
-void redisAsyncDisconnect(redisAsyncContext *ac);
-void redisAsyncFree(redisAsyncContext *ac);
-
-/* Handle read/write events */
-void redisAsyncHandleRead(redisAsyncContext *ac);
-void redisAsyncHandleWrite(redisAsyncContext *ac);
-
-/* Command functions for an async context. Write the command to the
- * output buffer and register the provided callback. */
-int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap);
-int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...);
-int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen);
-int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/third-party/hiredis/dict.c b/third-party/hiredis/dict.c
deleted file mode 100644 (file)
index 79b1041..0000000
+++ /dev/null
@@ -1,338 +0,0 @@
-/* Hash table implementation.
- *
- * This file implements in memory hash tables with insert/del/replace/find/
- * get-random-element operations. Hash tables will auto resize if needed
- * tables of power of two in size are used, collisions are handled by
- * chaining. See the source code for more information... :)
- *
- * Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   * Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *   * 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.
- *   * Neither the name of Redis nor the names of its contributors may be used
- *     to endorse or promote products derived from this software without
- *     specific prior written permission.
- *
- * THIS 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 OWNER 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.
- */
-
-#include "fmacros.h"
-#include <stdlib.h>
-#include <assert.h>
-#include <limits.h>
-#include "dict.h"
-
-/* -------------------------- private prototypes ---------------------------- */
-
-static int _dictExpandIfNeeded(dict *ht);
-static unsigned long _dictNextPower(unsigned long size);
-static int _dictKeyIndex(dict *ht, const void *key);
-static int _dictInit(dict *ht, dictType *type, void *privDataPtr);
-
-/* -------------------------- hash functions -------------------------------- */
-
-/* Generic hash function (a popular one from Bernstein).
- * I tested a few and this was the best. */
-static unsigned int dictGenHashFunction(const unsigned char *buf, int len) {
-    unsigned int hash = 5381;
-
-    while (len--)
-        hash = ((hash << 5) + hash) + (*buf++); /* hash * 33 + c */
-    return hash;
-}
-
-/* ----------------------------- API implementation ------------------------- */
-
-/* Reset an hashtable already initialized with ht_init().
- * NOTE: This function should only called by ht_destroy(). */
-static void _dictReset(dict *ht) {
-    ht->table = NULL;
-    ht->size = 0;
-    ht->sizemask = 0;
-    ht->used = 0;
-}
-
-/* Create a new hash table */
-static dict *dictCreate(dictType *type, void *privDataPtr) {
-    dict *ht = malloc(sizeof(*ht));
-    _dictInit(ht,type,privDataPtr);
-    return ht;
-}
-
-/* Initialize the hash table */
-static int _dictInit(dict *ht, dictType *type, void *privDataPtr) {
-    _dictReset(ht);
-    ht->type = type;
-    ht->privdata = privDataPtr;
-    return DICT_OK;
-}
-
-/* Expand or create the hashtable */
-static int dictExpand(dict *ht, unsigned long size) {
-    dict n; /* the new hashtable */
-    unsigned long realsize = _dictNextPower(size), i;
-
-    /* the size is invalid if it is smaller than the number of
-     * elements already inside the hashtable */
-    if (ht->used > size)
-        return DICT_ERR;
-
-    _dictInit(&n, ht->type, ht->privdata);
-    n.size = realsize;
-    n.sizemask = realsize-1;
-    n.table = calloc(realsize,sizeof(dictEntry*));
-
-    /* Copy all the elements from the old to the new table:
-     * note that if the old hash table is empty ht->size is zero,
-     * so dictExpand just creates an hash table. */
-    n.used = ht->used;
-    for (i = 0; i < ht->size && ht->used > 0; i++) {
-        dictEntry *he, *nextHe;
-
-        if (ht->table[i] == NULL) continue;
-
-        /* For each hash entry on this slot... */
-        he = ht->table[i];
-        while(he) {
-            unsigned int h;
-
-            nextHe = he->next;
-            /* Get the new element index */
-            h = dictHashKey(ht, he->key) & n.sizemask;
-            he->next = n.table[h];
-            n.table[h] = he;
-            ht->used--;
-            /* Pass to the next element */
-            he = nextHe;
-        }
-    }
-    assert(ht->used == 0);
-    free(ht->table);
-
-    /* Remap the new hashtable in the old */
-    *ht = n;
-    return DICT_OK;
-}
-
-/* Add an element to the target hash table */
-static int dictAdd(dict *ht, void *key, void *val) {
-    int index;
-    dictEntry *entry;
-
-    /* Get the index of the new element, or -1 if
-     * the element already exists. */
-    if ((index = _dictKeyIndex(ht, key)) == -1)
-        return DICT_ERR;
-
-    /* Allocates the memory and stores key */
-    entry = malloc(sizeof(*entry));
-    entry->next = ht->table[index];
-    ht->table[index] = entry;
-
-    /* Set the hash entry fields. */
-    dictSetHashKey(ht, entry, key);
-    dictSetHashVal(ht, entry, val);
-    ht->used++;
-    return DICT_OK;
-}
-
-/* Add an element, discarding the old if the key already exists.
- * Return 1 if the key was added from scratch, 0 if there was already an
- * element with such key and dictReplace() just performed a value update
- * operation. */
-static int dictReplace(dict *ht, void *key, void *val) {
-    dictEntry *entry, auxentry;
-
-    /* Try to add the element. If the key
-     * does not exists dictAdd will suceed. */
-    if (dictAdd(ht, key, val) == DICT_OK)
-        return 1;
-    /* It already exists, get the entry */
-    entry = dictFind(ht, key);
-    /* Free the old value and set the new one */
-    /* Set the new value and free the old one. Note that it is important
-     * to do that in this order, as the value may just be exactly the same
-     * as the previous one. In this context, think to reference counting,
-     * you want to increment (set), and then decrement (free), and not the
-     * reverse. */
-    auxentry = *entry;
-    dictSetHashVal(ht, entry, val);
-    dictFreeEntryVal(ht, &auxentry);
-    return 0;
-}
-
-/* Search and remove an element */
-static int dictDelete(dict *ht, const void *key) {
-    unsigned int h;
-    dictEntry *de, *prevde;
-
-    if (ht->size == 0)
-        return DICT_ERR;
-    h = dictHashKey(ht, key) & ht->sizemask;
-    de = ht->table[h];
-
-    prevde = NULL;
-    while(de) {
-        if (dictCompareHashKeys(ht,key,de->key)) {
-            /* Unlink the element from the list */
-            if (prevde)
-                prevde->next = de->next;
-            else
-                ht->table[h] = de->next;
-
-            dictFreeEntryKey(ht,de);
-            dictFreeEntryVal(ht,de);
-            free(de);
-            ht->used--;
-            return DICT_OK;
-        }
-        prevde = de;
-        de = de->next;
-    }
-    return DICT_ERR; /* not found */
-}
-
-/* Destroy an entire hash table */
-static int _dictClear(dict *ht) {
-    unsigned long i;
-
-    /* Free all the elements */
-    for (i = 0; i < ht->size && ht->used > 0; i++) {
-        dictEntry *he, *nextHe;
-
-        if ((he = ht->table[i]) == NULL) continue;
-        while(he) {
-            nextHe = he->next;
-            dictFreeEntryKey(ht, he);
-            dictFreeEntryVal(ht, he);
-            free(he);
-            ht->used--;
-            he = nextHe;
-        }
-    }
-    /* Free the table and the allocated cache structure */
-    free(ht->table);
-    /* Re-initialize the table */
-    _dictReset(ht);
-    return DICT_OK; /* never fails */
-}
-
-/* Clear & Release the hash table */
-static void dictRelease(dict *ht) {
-    _dictClear(ht);
-    free(ht);
-}
-
-static dictEntry *dictFind(dict *ht, const void *key) {
-    dictEntry *he;
-    unsigned int h;
-
-    if (ht->size == 0) return NULL;
-    h = dictHashKey(ht, key) & ht->sizemask;
-    he = ht->table[h];
-    while(he) {
-        if (dictCompareHashKeys(ht, key, he->key))
-            return he;
-        he = he->next;
-    }
-    return NULL;
-}
-
-static dictIterator *dictGetIterator(dict *ht) {
-    dictIterator *iter = malloc(sizeof(*iter));
-
-    iter->ht = ht;
-    iter->index = -1;
-    iter->entry = NULL;
-    iter->nextEntry = NULL;
-    return iter;
-}
-
-static dictEntry *dictNext(dictIterator *iter) {
-    while (1) {
-        if (iter->entry == NULL) {
-            iter->index++;
-            if (iter->index >=
-                    (signed)iter->ht->size) break;
-            iter->entry = iter->ht->table[iter->index];
-        } else {
-            iter->entry = iter->nextEntry;
-        }
-        if (iter->entry) {
-            /* We need to save the 'next' here, the iterator user
-             * may delete the entry we are returning. */
-            iter->nextEntry = iter->entry->next;
-            return iter->entry;
-        }
-    }
-    return NULL;
-}
-
-static void dictReleaseIterator(dictIterator *iter) {
-    free(iter);
-}
-
-/* ------------------------- private functions ------------------------------ */
-
-/* Expand the hash table if needed */
-static int _dictExpandIfNeeded(dict *ht) {
-    /* If the hash table is empty expand it to the intial size,
-     * if the table is "full" dobule its size. */
-    if (ht->size == 0)
-        return dictExpand(ht, DICT_HT_INITIAL_SIZE);
-    if (ht->used == ht->size)
-        return dictExpand(ht, ht->size*2);
-    return DICT_OK;
-}
-
-/* Our hash table capability is a power of two */
-static unsigned long _dictNextPower(unsigned long size) {
-    unsigned long i = DICT_HT_INITIAL_SIZE;
-
-    if (size >= LONG_MAX) return LONG_MAX;
-    while(1) {
-        if (i >= size)
-            return i;
-        i *= 2;
-    }
-}
-
-/* Returns the index of a free slot that can be populated with
- * an hash entry for the given 'key'.
- * If the key already exists, -1 is returned. */
-static int _dictKeyIndex(dict *ht, const void *key) {
-    unsigned int h;
-    dictEntry *he;
-
-    /* Expand the hashtable if needed */
-    if (_dictExpandIfNeeded(ht) == DICT_ERR)
-        return -1;
-    /* Compute the key hash value */
-    h = dictHashKey(ht, key) & ht->sizemask;
-    /* Search if this slot does not already contain the given key */
-    he = ht->table[h];
-    while(he) {
-        if (dictCompareHashKeys(ht, key, he->key))
-            return -1;
-        he = he->next;
-    }
-    return h;
-}
-
diff --git a/third-party/hiredis/dict.h b/third-party/hiredis/dict.h
deleted file mode 100644 (file)
index 95fcd28..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Hash table implementation.
- *
- * This file implements in memory hash tables with insert/del/replace/find/
- * get-random-element operations. Hash tables will auto resize if needed
- * tables of power of two in size are used, collisions are handled by
- * chaining. See the source code for more information... :)
- *
- * Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   * Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *   * 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.
- *   * Neither the name of Redis nor the names of its contributors may be used
- *     to endorse or promote products derived from this software without
- *     specific prior written permission.
- *
- * THIS 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 OWNER 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.
- */
-
-#ifndef __DICT_H
-#define __DICT_H
-
-#define DICT_OK 0
-#define DICT_ERR 1
-
-/* Unused arguments generate annoying warnings... */
-#define DICT_NOTUSED(V) ((void) V)
-
-typedef struct dictEntry {
-    void *key;
-    void *val;
-    struct dictEntry *next;
-} dictEntry;
-
-typedef struct dictType {
-    unsigned int (*hashFunction)(const void *key);
-    void *(*keyDup)(void *privdata, const void *key);
-    void *(*valDup)(void *privdata, const void *obj);
-    int (*keyCompare)(void *privdata, const void *key1, const void *key2);
-    void (*keyDestructor)(void *privdata, void *key);
-    void (*valDestructor)(void *privdata, void *obj);
-} dictType;
-
-typedef struct dict {
-    dictEntry **table;
-    dictType *type;
-    unsigned long size;
-    unsigned long sizemask;
-    unsigned long used;
-    void *privdata;
-} dict;
-
-typedef struct dictIterator {
-    dict *ht;
-    int index;
-    dictEntry *entry, *nextEntry;
-} dictIterator;
-
-/* This is the initial size of every hash table */
-#define DICT_HT_INITIAL_SIZE     4
-
-/* ------------------------------- Macros ------------------------------------*/
-#define dictFreeEntryVal(ht, entry) \
-    if ((ht)->type->valDestructor) \
-        (ht)->type->valDestructor((ht)->privdata, (entry)->val)
-
-#define dictSetHashVal(ht, entry, _val_) do { \
-    if ((ht)->type->valDup) \
-        entry->val = (ht)->type->valDup((ht)->privdata, _val_); \
-    else \
-        entry->val = (_val_); \
-} while(0)
-
-#define dictFreeEntryKey(ht, entry) \
-    if ((ht)->type->keyDestructor) \
-        (ht)->type->keyDestructor((ht)->privdata, (entry)->key)
-
-#define dictSetHashKey(ht, entry, _key_) do { \
-    if ((ht)->type->keyDup) \
-        entry->key = (ht)->type->keyDup((ht)->privdata, _key_); \
-    else \
-        entry->key = (_key_); \
-} while(0)
-
-#define dictCompareHashKeys(ht, key1, key2) \
-    (((ht)->type->keyCompare) ? \
-        (ht)->type->keyCompare((ht)->privdata, key1, key2) : \
-        (key1) == (key2))
-
-#define dictHashKey(ht, key) (ht)->type->hashFunction(key)
-
-#define dictGetEntryKey(he) ((he)->key)
-#define dictGetEntryVal(he) ((he)->val)
-#define dictSlots(ht) ((ht)->size)
-#define dictSize(ht) ((ht)->used)
-
-/* API */
-static unsigned int dictGenHashFunction(const unsigned char *buf, int len);
-static dict *dictCreate(dictType *type, void *privDataPtr);
-static int dictExpand(dict *ht, unsigned long size);
-static int dictAdd(dict *ht, void *key, void *val);
-static int dictReplace(dict *ht, void *key, void *val);
-static int dictDelete(dict *ht, const void *key);
-static void dictRelease(dict *ht);
-static dictEntry * dictFind(dict *ht, const void *key);
-static dictIterator *dictGetIterator(dict *ht);
-static dictEntry *dictNext(dictIterator *iter);
-static void dictReleaseIterator(dictIterator *iter);
-
-#endif /* __DICT_H */
diff --git a/third-party/hiredis/examples/example-ae.c b/third-party/hiredis/examples/example-ae.c
deleted file mode 100644 (file)
index 8efa730..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/ae.h>
-
-/* Put event loop in the global scope, so it can be explicitly stopped */
-static aeEventLoop *loop;
-
-void getCallback(redisAsyncContext *c, void *r, void *privdata) {
-    redisReply *reply = r;
-    if (reply == NULL) return;
-    printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
-    /* Disconnect after receiving the reply to GET */
-    redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
-    if (status != REDIS_OK) {
-        printf("Error: %s\n", c->errstr);
-        aeStop(loop);
-        return;
-    }
-
-    printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
-    if (status != REDIS_OK) {
-        printf("Error: %s\n", c->errstr);
-        aeStop(loop);
-        return;
-    }
-
-    printf("Disconnected...\n");
-    aeStop(loop);
-}
-
-int main (int argc, char **argv) {
-    signal(SIGPIPE, SIG_IGN);
-
-    redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
-    if (c->err) {
-        /* Let *c leak for now... */
-        printf("Error: %s\n", c->errstr);
-        return 1;
-    }
-
-    loop = aeCreateEventLoop(64);
-    redisAeAttach(loop, c);
-    redisAsyncSetConnectCallback(c,connectCallback);
-    redisAsyncSetDisconnectCallback(c,disconnectCallback);
-    redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
-    redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
-    aeMain(loop);
-    return 0;
-}
-
diff --git a/third-party/hiredis/examples/example-glib.c b/third-party/hiredis/examples/example-glib.c
deleted file mode 100644 (file)
index d6e10f8..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-#include <stdlib.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/glib.h>
-
-static GMainLoop *mainloop;
-
-static void
-connect_cb (const redisAsyncContext *ac G_GNUC_UNUSED,
-            int status)
-{
-    if (status != REDIS_OK) {
-        g_printerr("Failed to connect: %s\n", ac->errstr);
-        g_main_loop_quit(mainloop);
-    } else {
-        g_printerr("Connected...\n");
-    }
-}
-
-static void
-disconnect_cb (const redisAsyncContext *ac G_GNUC_UNUSED,
-               int status)
-{
-    if (status != REDIS_OK) {
-        g_error("Failed to disconnect: %s", ac->errstr);
-    } else {
-        g_printerr("Disconnected...\n");
-        g_main_loop_quit(mainloop);
-    }
-}
-
-static void
-command_cb(redisAsyncContext *ac,
-           gpointer r,
-           gpointer user_data G_GNUC_UNUSED)
-{
-    redisReply *reply = r;
-
-    if (reply) {
-        g_print("REPLY: %s\n", reply->str);
-    }
-
-    redisAsyncDisconnect(ac);
-}
-
-gint
-main (gint argc     G_GNUC_UNUSED,
-      gchar *argv[] G_GNUC_UNUSED)
-{
-    redisAsyncContext *ac;
-    GMainContext *context = NULL;
-    GSource *source;
-
-    ac = redisAsyncConnect("127.0.0.1", 6379);
-    if (ac->err) {
-        g_printerr("%s\n", ac->errstr);
-        exit(EXIT_FAILURE);
-    }
-
-    source = redis_source_new(ac);
-    mainloop = g_main_loop_new(context, FALSE);
-    g_source_attach(source, context);
-
-    redisAsyncSetConnectCallback(ac, connect_cb);
-    redisAsyncSetDisconnectCallback(ac, disconnect_cb);
-    redisAsyncCommand(ac, command_cb, NULL, "SET key 1234");
-    redisAsyncCommand(ac, command_cb, NULL, "GET key");
-
-    g_main_loop_run(mainloop);
-
-    return EXIT_SUCCESS;
-}
diff --git a/third-party/hiredis/examples/example-ivykis.c b/third-party/hiredis/examples/example-ivykis.c
deleted file mode 100644 (file)
index 67affce..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/ivykis.h>
-
-void getCallback(redisAsyncContext *c, void *r, void *privdata) {
-    redisReply *reply = r;
-    if (reply == NULL) return;
-    printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
-    /* Disconnect after receiving the reply to GET */
-    redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
-    if (status != REDIS_OK) {
-        printf("Error: %s\n", c->errstr);
-        return;
-    }
-    printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
-    if (status != REDIS_OK) {
-        printf("Error: %s\n", c->errstr);
-        return;
-    }
-    printf("Disconnected...\n");
-}
-
-int main (int argc, char **argv) {
-    signal(SIGPIPE, SIG_IGN);
-
-    iv_init();
-
-    redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
-    if (c->err) {
-        /* Let *c leak for now... */
-        printf("Error: %s\n", c->errstr);
-        return 1;
-    }
-
-    redisIvykisAttach(c);
-    redisAsyncSetConnectCallback(c,connectCallback);
-    redisAsyncSetDisconnectCallback(c,disconnectCallback);
-    redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
-    redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
-
-    iv_main();
-
-    iv_deinit();
-
-    return 0;
-}
diff --git a/third-party/hiredis/examples/example-libev.c b/third-party/hiredis/examples/example-libev.c
deleted file mode 100644 (file)
index cc8b166..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/libev.h>
-
-void getCallback(redisAsyncContext *c, void *r, void *privdata) {
-    redisReply *reply = r;
-    if (reply == NULL) return;
-    printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
-    /* Disconnect after receiving the reply to GET */
-    redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
-    if (status != REDIS_OK) {
-        printf("Error: %s\n", c->errstr);
-        return;
-    }
-    printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
-    if (status != REDIS_OK) {
-        printf("Error: %s\n", c->errstr);
-        return;
-    }
-    printf("Disconnected...\n");
-}
-
-int main (int argc, char **argv) {
-    signal(SIGPIPE, SIG_IGN);
-
-    redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
-    if (c->err) {
-        /* Let *c leak for now... */
-        printf("Error: %s\n", c->errstr);
-        return 1;
-    }
-
-    redisLibevAttach(EV_DEFAULT_ c);
-    redisAsyncSetConnectCallback(c,connectCallback);
-    redisAsyncSetDisconnectCallback(c,disconnectCallback);
-    redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
-    redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
-    ev_loop(EV_DEFAULT_ 0);
-    return 0;
-}
diff --git a/third-party/hiredis/examples/example-libevent.c b/third-party/hiredis/examples/example-libevent.c
deleted file mode 100644 (file)
index d333c22..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/libevent.h>
-
-void getCallback(redisAsyncContext *c, void *r, void *privdata) {
-    redisReply *reply = r;
-    if (reply == NULL) return;
-    printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
-    /* Disconnect after receiving the reply to GET */
-    redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
-    if (status != REDIS_OK) {
-        printf("Error: %s\n", c->errstr);
-        return;
-    }
-    printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
-    if (status != REDIS_OK) {
-        printf("Error: %s\n", c->errstr);
-        return;
-    }
-    printf("Disconnected...\n");
-}
-
-int main (int argc, char **argv) {
-    signal(SIGPIPE, SIG_IGN);
-    struct event_base *base = event_base_new();
-
-    redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
-    if (c->err) {
-        /* Let *c leak for now... */
-        printf("Error: %s\n", c->errstr);
-        return 1;
-    }
-
-    redisLibeventAttach(c,base);
-    redisAsyncSetConnectCallback(c,connectCallback);
-    redisAsyncSetDisconnectCallback(c,disconnectCallback);
-    redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
-    redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
-    event_base_dispatch(base);
-    return 0;
-}
diff --git a/third-party/hiredis/examples/example-libuv.c b/third-party/hiredis/examples/example-libuv.c
deleted file mode 100644 (file)
index a5462d4..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/libuv.h>
-
-void getCallback(redisAsyncContext *c, void *r, void *privdata) {
-    redisReply *reply = r;
-    if (reply == NULL) return;
-    printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
-    /* Disconnect after receiving the reply to GET */
-    redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
-    if (status != REDIS_OK) {
-        printf("Error: %s\n", c->errstr);
-        return;
-    }
-    printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
-    if (status != REDIS_OK) {
-        printf("Error: %s\n", c->errstr);
-        return;
-    }
-    printf("Disconnected...\n");
-}
-
-int main (int argc, char **argv) {
-    signal(SIGPIPE, SIG_IGN);
-    uv_loop_t* loop = uv_default_loop();
-
-    redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
-    if (c->err) {
-        /* Let *c leak for now... */
-        printf("Error: %s\n", c->errstr);
-        return 1;
-    }
-
-    redisLibuvAttach(c,loop);
-    redisAsyncSetConnectCallback(c,connectCallback);
-    redisAsyncSetDisconnectCallback(c,disconnectCallback);
-    redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
-    redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
-    uv_run(loop, UV_RUN_DEFAULT);
-    return 0;
-}
diff --git a/third-party/hiredis/examples/example-macosx.c b/third-party/hiredis/examples/example-macosx.c
deleted file mode 100644 (file)
index bc84ed5..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-//
-//  Created by Ð”митрий Ð‘ахвалов on 13.07.15.
-//  Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved.
-//
-
-#include <stdio.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/macosx.h>
-
-void getCallback(redisAsyncContext *c, void *r, void *privdata) {
-    redisReply *reply = r;
-    if (reply == NULL) return;
-    printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
-    /* Disconnect after receiving the reply to GET */
-    redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
-    if (status != REDIS_OK) {
-        printf("Error: %s\n", c->errstr);
-        return;
-    }
-    printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
-    if (status != REDIS_OK) {
-        printf("Error: %s\n", c->errstr);
-        return;
-    }
-    CFRunLoopStop(CFRunLoopGetCurrent());
-    printf("Disconnected...\n");
-}
-
-int main (int argc, char **argv) {
-    signal(SIGPIPE, SIG_IGN);
-
-    CFRunLoopRef loop = CFRunLoopGetCurrent();
-    if( !loop ) {
-        printf("Error: Cannot get current run loop\n");
-        return 1;
-    }
-
-    redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
-    if (c->err) {
-        /* Let *c leak for now... */
-        printf("Error: %s\n", c->errstr);
-        return 1;
-    }
-
-    redisMacOSAttach(c, loop);
-
-    redisAsyncSetConnectCallback(c,connectCallback);
-    redisAsyncSetDisconnectCallback(c,disconnectCallback);
-
-    redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
-    redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
-
-    CFRunLoopRun();
-
-    return 0;
-}
-
diff --git a/third-party/hiredis/examples/example-qt.cpp b/third-party/hiredis/examples/example-qt.cpp
deleted file mode 100644 (file)
index f524c3f..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#include <iostream>
-using namespace std;
-
-#include <QCoreApplication>
-#include <QTimer>
-
-#include "example-qt.h"
-
-void getCallback(redisAsyncContext *, void * r, void * privdata) {
-
-    redisReply * reply = static_cast<redisReply *>(r);
-    ExampleQt * ex = static_cast<ExampleQt *>(privdata);
-    if (reply == nullptr || ex == nullptr) return;
-
-    cout << "key: " << reply->str << endl;
-
-    ex->finish();
-}
-
-void ExampleQt::run() {
-
-    m_ctx = redisAsyncConnect("localhost", 6379);
-
-    if (m_ctx->err) {
-        cerr << "Error: " << m_ctx->errstr << endl;
-        redisAsyncFree(m_ctx);
-        emit finished();
-    }
-
-    m_adapter.setContext(m_ctx);
-
-    redisAsyncCommand(m_ctx, NULL, NULL, "SET key %s", m_value);
-    redisAsyncCommand(m_ctx, getCallback, this, "GET key");
-}
-
-int main (int argc, char **argv) {
-
-    QCoreApplication app(argc, argv);
-
-    ExampleQt example(argv[argc-1]);
-
-    QObject::connect(&example, SIGNAL(finished()), &app, SLOT(quit()));
-    QTimer::singleShot(0, &example, SLOT(run()));
-
-    return app.exec();
-}
diff --git a/third-party/hiredis/examples/example-qt.h b/third-party/hiredis/examples/example-qt.h
deleted file mode 100644 (file)
index 374f476..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef __HIREDIS_EXAMPLE_QT_H
-#define __HIREDIS_EXAMPLE_QT_H
-
-#include <adapters/qt.h>
-
-class ExampleQt : public QObject {
-
-    Q_OBJECT
-
-    public:
-        ExampleQt(const char * value, QObject * parent = 0)
-            : QObject(parent), m_value(value) {}
-
-    signals:
-        void finished();
-
-    public slots:
-        void run();
-
-    private:
-        void finish() { emit finished(); }
-
-    private:
-        const char * m_value;
-        redisAsyncContext * m_ctx;
-        RedisQtAdapter m_adapter;
-
-    friend
-    void getCallback(redisAsyncContext *, void *, void *);
-};
-
-#endif /* !__HIREDIS_EXAMPLE_QT_H */
diff --git a/third-party/hiredis/examples/example.c b/third-party/hiredis/examples/example.c
deleted file mode 100644 (file)
index 25226a8..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <hiredis.h>
-
-int main(int argc, char **argv) {
-    unsigned int j;
-    redisContext *c;
-    redisReply *reply;
-    const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1";
-    int port = (argc > 2) ? atoi(argv[2]) : 6379;
-
-    struct timeval timeout = { 1, 500000 }; // 1.5 seconds
-    c = redisConnectWithTimeout(hostname, port, timeout);
-    if (c == NULL || c->err) {
-        if (c) {
-            printf("Connection error: %s\n", c->errstr);
-            redisFree(c);
-        } else {
-            printf("Connection error: can't allocate redis context\n");
-        }
-        exit(1);
-    }
-
-    /* PING server */
-    reply = redisCommand(c,"PING");
-    printf("PING: %s\n", reply->str);
-    freeReplyObject(reply);
-
-    /* Set a key */
-    reply = redisCommand(c,"SET %s %s", "foo", "hello world");
-    printf("SET: %s\n", reply->str);
-    freeReplyObject(reply);
-
-    /* Set a key using binary safe API */
-    reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5);
-    printf("SET (binary API): %s\n", reply->str);
-    freeReplyObject(reply);
-
-    /* Try a GET and two INCR */
-    reply = redisCommand(c,"GET foo");
-    printf("GET foo: %s\n", reply->str);
-    freeReplyObject(reply);
-
-    reply = redisCommand(c,"INCR counter");
-    printf("INCR counter: %lld\n", reply->integer);
-    freeReplyObject(reply);
-    /* again ... */
-    reply = redisCommand(c,"INCR counter");
-    printf("INCR counter: %lld\n", reply->integer);
-    freeReplyObject(reply);
-
-    /* Create a list of numbers, from 0 to 9 */
-    reply = redisCommand(c,"DEL mylist");
-    freeReplyObject(reply);
-    for (j = 0; j < 10; j++) {
-        char buf[64];
-
-        snprintf(buf,64,"%d",j);
-        reply = redisCommand(c,"LPUSH mylist element-%s", buf);
-        freeReplyObject(reply);
-    }
-
-    /* Let's check what we have inside the list */
-    reply = redisCommand(c,"LRANGE mylist 0 -1");
-    if (reply->type == REDIS_REPLY_ARRAY) {
-        for (j = 0; j < reply->elements; j++) {
-            printf("%u) %s\n", j, reply->element[j]->str);
-        }
-    }
-    freeReplyObject(reply);
-
-    /* Disconnects and frees the context */
-    redisFree(c);
-
-    return 0;
-}
diff --git a/third-party/hiredis/fmacros.h b/third-party/hiredis/fmacros.h
deleted file mode 100644 (file)
index 19d7b21..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __HIREDIS_FMACRO_H
-#define __HIREDIS_FMACRO_H
-
-#if defined(__linux__)
-#define _BSD_SOURCE
-#define _DEFAULT_SOURCE
-#endif
-
-#if defined(__sun__)
-#define _POSIX_C_SOURCE 200112L
-#elif defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__)
-#define _XOPEN_SOURCE 600
-#else
-#define _XOPEN_SOURCE
-#endif
-
-#if __APPLE__ && __MACH__
-#define _OSX
-#endif
-
-#endif
diff --git a/third-party/hiredis/hiredis.c b/third-party/hiredis/hiredis.c
deleted file mode 100644 (file)
index 73d0251..0000000
+++ /dev/null
@@ -1,1021 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
- *                     Jan-Erik Rediger <janerik at fnordig dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   * Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *   * 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.
- *   * Neither the name of Redis nor the names of its contributors may be used
- *     to endorse or promote products derived from this software without
- *     specific prior written permission.
- *
- * THIS 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 OWNER 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.
- */
-
-#include "fmacros.h"
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <assert.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include "hiredis.h"
-#include "net.h"
-#include "sds.h"
-
-static redisReply *createReplyObject(int type);
-static void *createStringObject(const redisReadTask *task, char *str, size_t len);
-static void *createArrayObject(const redisReadTask *task, int elements);
-static void *createIntegerObject(const redisReadTask *task, long long value);
-static void *createNilObject(const redisReadTask *task);
-
-/* Default set of functions to build the reply. Keep in mind that such a
- * function returning NULL is interpreted as OOM. */
-static redisReplyObjectFunctions defaultFunctions = {
-    createStringObject,
-    createArrayObject,
-    createIntegerObject,
-    createNilObject,
-    freeReplyObject
-};
-
-/* Create a reply object */
-static redisReply *createReplyObject(int type) {
-    redisReply *r = calloc(1,sizeof(*r));
-
-    if (r == NULL)
-        return NULL;
-
-    r->type = type;
-    return r;
-}
-
-/* Free a reply object */
-void freeReplyObject(void *reply) {
-    redisReply *r = reply;
-    size_t j;
-
-    if (r == NULL)
-        return;
-
-    switch(r->type) {
-    case REDIS_REPLY_INTEGER:
-        break; /* Nothing to free */
-    case REDIS_REPLY_ARRAY:
-        if (r->element != NULL) {
-            for (j = 0; j < r->elements; j++)
-                if (r->element[j] != NULL)
-                    freeReplyObject(r->element[j]);
-            free(r->element);
-        }
-        break;
-    case REDIS_REPLY_ERROR:
-    case REDIS_REPLY_STATUS:
-    case REDIS_REPLY_STRING:
-        if (r->str != NULL)
-            free(r->str);
-        break;
-    }
-    free(r);
-}
-
-static void *createStringObject(const redisReadTask *task, char *str, size_t len) {
-    redisReply *r, *parent;
-    char *buf;
-
-    r = createReplyObject(task->type);
-    if (r == NULL)
-        return NULL;
-
-    buf = malloc(len+1);
-    if (buf == NULL) {
-        freeReplyObject(r);
-        return NULL;
-    }
-
-    assert(task->type == REDIS_REPLY_ERROR  ||
-           task->type == REDIS_REPLY_STATUS ||
-           task->type == REDIS_REPLY_STRING);
-
-    /* Copy string value */
-    memcpy(buf,str,len);
-    buf[len] = '\0';
-    r->str = buf;
-    r->len = len;
-
-    if (task->parent) {
-        parent = task->parent->obj;
-        assert(parent->type == REDIS_REPLY_ARRAY);
-        parent->element[task->idx] = r;
-    }
-    return r;
-}
-
-static void *createArrayObject(const redisReadTask *task, int elements) {
-    redisReply *r, *parent;
-
-    r = createReplyObject(REDIS_REPLY_ARRAY);
-    if (r == NULL)
-        return NULL;
-
-    if (elements > 0) {
-        r->element = calloc(elements,sizeof(redisReply*));
-        if (r->element == NULL) {
-            freeReplyObject(r);
-            return NULL;
-        }
-    }
-
-    r->elements = elements;
-
-    if (task->parent) {
-        parent = task->parent->obj;
-        assert(parent->type == REDIS_REPLY_ARRAY);
-        parent->element[task->idx] = r;
-    }
-    return r;
-}
-
-static void *createIntegerObject(const redisReadTask *task, long long value) {
-    redisReply *r, *parent;
-
-    r = createReplyObject(REDIS_REPLY_INTEGER);
-    if (r == NULL)
-        return NULL;
-
-    r->integer = value;
-
-    if (task->parent) {
-        parent = task->parent->obj;
-        assert(parent->type == REDIS_REPLY_ARRAY);
-        parent->element[task->idx] = r;
-    }
-    return r;
-}
-
-static void *createNilObject(const redisReadTask *task) {
-    redisReply *r, *parent;
-
-    r = createReplyObject(REDIS_REPLY_NIL);
-    if (r == NULL)
-        return NULL;
-
-    if (task->parent) {
-        parent = task->parent->obj;
-        assert(parent->type == REDIS_REPLY_ARRAY);
-        parent->element[task->idx] = r;
-    }
-    return r;
-}
-
-/* Return the number of digits of 'v' when converted to string in radix 10.
- * Implementation borrowed from link in redis/src/util.c:string2ll(). */
-static uint32_t countDigits(uint64_t v) {
-  uint32_t result = 1;
-  for (;;) {
-    if (v < 10) return result;
-    if (v < 100) return result + 1;
-    if (v < 1000) return result + 2;
-    if (v < 10000) return result + 3;
-    v /= 10000U;
-    result += 4;
-  }
-}
-
-/* Helper that calculates the bulk length given a certain string length. */
-static size_t bulklen(size_t len) {
-    return 1+countDigits(len)+2+len+2;
-}
-
-int redisvFormatCommand(char **target, const char *format, va_list ap) {
-    const char *c = format;
-    char *cmd = NULL; /* final command */
-    int pos; /* position in final command */
-    sds curarg, newarg; /* current argument */
-    int touched = 0; /* was the current argument touched? */
-    char **curargv = NULL, **newargv = NULL;
-    int argc = 0;
-    int totlen = 0;
-    int error_type = 0; /* 0 = no error; -1 = memory error; -2 = format error */
-    int j;
-
-    /* Abort if there is not target to set */
-    if (target == NULL)
-        return -1;
-
-    /* Build the command string accordingly to protocol */
-    curarg = sdsempty();
-    if (curarg == NULL)
-        return -1;
-
-    while(*c != '\0') {
-        if (*c != '%' || c[1] == '\0') {
-            if (*c == ' ') {
-                if (touched) {
-                    newargv = realloc(curargv,sizeof(char*)*(argc+1));
-                    if (newargv == NULL) goto memory_err;
-                    curargv = newargv;
-                    curargv[argc++] = curarg;
-                    totlen += bulklen(sdslen(curarg));
-
-                    /* curarg is put in argv so it can be overwritten. */
-                    curarg = sdsempty();
-                    if (curarg == NULL) goto memory_err;
-                    touched = 0;
-                }
-            } else {
-                newarg = sdscatlen(curarg,c,1);
-                if (newarg == NULL) goto memory_err;
-                curarg = newarg;
-                touched = 1;
-            }
-        } else {
-            char *arg;
-            size_t size;
-
-            /* Set newarg so it can be checked even if it is not touched. */
-            newarg = curarg;
-
-            switch(c[1]) {
-            case 's':
-                arg = va_arg(ap,char*);
-                size = strlen(arg);
-                if (size > 0)
-                    newarg = sdscatlen(curarg,arg,size);
-                break;
-            case 'b':
-                arg = va_arg(ap,char*);
-                size = va_arg(ap,size_t);
-                if (size > 0)
-                    newarg = sdscatlen(curarg,arg,size);
-                break;
-            case '%':
-                newarg = sdscat(curarg,"%");
-                break;
-            default:
-                /* Try to detect printf format */
-                {
-                    static const char intfmts[] = "diouxX";
-                    static const char flags[] = "#0-+ ";
-                    char _format[16];
-                    const char *_p = c+1;
-                    size_t _l = 0;
-                    va_list _cpy;
-
-                    /* Flags */
-                    while (*_p != '\0' && strchr(flags,*_p) != NULL) _p++;
-
-                    /* Field width */
-                    while (*_p != '\0' && isdigit(*_p)) _p++;
-
-                    /* Precision */
-                    if (*_p == '.') {
-                        _p++;
-                        while (*_p != '\0' && isdigit(*_p)) _p++;
-                    }
-
-                    /* Copy va_list before consuming with va_arg */
-                    va_copy(_cpy,ap);
-
-                    /* Integer conversion (without modifiers) */
-                    if (strchr(intfmts,*_p) != NULL) {
-                        va_arg(ap,int);
-                        goto fmt_valid;
-                    }
-
-                    /* Double conversion (without modifiers) */
-                    if (strchr("eEfFgGaA",*_p) != NULL) {
-                        va_arg(ap,double);
-                        goto fmt_valid;
-                    }
-
-                    /* Size: char */
-                    if (_p[0] == 'h' && _p[1] == 'h') {
-                        _p += 2;
-                        if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
-                            va_arg(ap,int); /* char gets promoted to int */
-                            goto fmt_valid;
-                        }
-                        goto fmt_invalid;
-                    }
-
-                    /* Size: short */
-                    if (_p[0] == 'h') {
-                        _p += 1;
-                        if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
-                            va_arg(ap,int); /* short gets promoted to int */
-                            goto fmt_valid;
-                        }
-                        goto fmt_invalid;
-                    }
-
-                    /* Size: long long */
-                    if (_p[0] == 'l' && _p[1] == 'l') {
-                        _p += 2;
-                        if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
-                            va_arg(ap,long long);
-                            goto fmt_valid;
-                        }
-                        goto fmt_invalid;
-                    }
-
-                    /* Size: long */
-                    if (_p[0] == 'l') {
-                        _p += 1;
-                        if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
-                            va_arg(ap,long);
-                            goto fmt_valid;
-                        }
-                        goto fmt_invalid;
-                    }
-
-                fmt_invalid:
-                    va_end(_cpy);
-                    goto format_err;
-
-                fmt_valid:
-                    _l = (_p+1)-c;
-                    if (_l < sizeof(_format)-2) {
-                        memcpy(_format,c,_l);
-                        _format[_l] = '\0';
-                        newarg = sdscatvprintf(curarg,_format,_cpy);
-
-                        /* Update current position (note: outer blocks
-                         * increment c twice so compensate here) */
-                        c = _p-1;
-                    }
-
-                    va_end(_cpy);
-                    break;
-                }
-            }
-
-            if (newarg == NULL) goto memory_err;
-            curarg = newarg;
-
-            touched = 1;
-            c++;
-        }
-        c++;
-    }
-
-    /* Add the last argument if needed */
-    if (touched) {
-        newargv = realloc(curargv,sizeof(char*)*(argc+1));
-        if (newargv == NULL) goto memory_err;
-        curargv = newargv;
-        curargv[argc++] = curarg;
-        totlen += bulklen(sdslen(curarg));
-    } else {
-        sdsfree(curarg);
-    }
-
-    /* Clear curarg because it was put in curargv or was free'd. */
-    curarg = NULL;
-
-    /* Add bytes needed to hold multi bulk count */
-    totlen += 1+countDigits(argc)+2;
-
-    /* Build the command at protocol level */
-    cmd = malloc(totlen+1);
-    if (cmd == NULL) goto memory_err;
-
-    pos = sprintf(cmd,"*%d\r\n",argc);
-    for (j = 0; j < argc; j++) {
-        pos += sprintf(cmd+pos,"$%zu\r\n",sdslen(curargv[j]));
-        memcpy(cmd+pos,curargv[j],sdslen(curargv[j]));
-        pos += sdslen(curargv[j]);
-        sdsfree(curargv[j]);
-        cmd[pos++] = '\r';
-        cmd[pos++] = '\n';
-    }
-    assert(pos == totlen);
-    cmd[pos] = '\0';
-
-    free(curargv);
-    *target = cmd;
-    return totlen;
-
-format_err:
-    error_type = -2;
-    goto cleanup;
-
-memory_err:
-    error_type = -1;
-    goto cleanup;
-
-cleanup:
-    if (curargv) {
-        while(argc--)
-            sdsfree(curargv[argc]);
-        free(curargv);
-    }
-
-    sdsfree(curarg);
-
-    /* No need to check cmd since it is the last statement that can fail,
-     * but do it anyway to be as defensive as possible. */
-    if (cmd != NULL)
-        free(cmd);
-
-    return error_type;
-}
-
-/* Format a command according to the Redis protocol. This function
- * takes a format similar to printf:
- *
- * %s represents a C null terminated string you want to interpolate
- * %b represents a binary safe string
- *
- * When using %b you need to provide both the pointer to the string
- * and the length in bytes as a size_t. Examples:
- *
- * len = redisFormatCommand(target, "GET %s", mykey);
- * len = redisFormatCommand(target, "SET %s %b", mykey, myval, myvallen);
- */
-int redisFormatCommand(char **target, const char *format, ...) {
-    va_list ap;
-    int len;
-    va_start(ap,format);
-    len = redisvFormatCommand(target,format,ap);
-    va_end(ap);
-
-    /* The API says "-1" means bad result, but we now also return "-2" in some
-     * cases.  Force the return value to always be -1. */
-    if (len < 0)
-        len = -1;
-
-    return len;
-}
-
-/* Format a command according to the Redis protocol using an sds string and
- * sdscatfmt for the processing of arguments. This function takes the
- * number of arguments, an array with arguments and an array with their
- * lengths. If the latter is set to NULL, strlen will be used to compute the
- * argument lengths.
- */
-int redisFormatSdsCommandArgv(sds *target, int argc, const char **argv,
-                              const size_t *argvlen)
-{
-    sds cmd;
-    unsigned long long totlen;
-    int j;
-    size_t len;
-
-    /* Abort on a NULL target */
-    if (target == NULL)
-        return -1;
-
-    /* Calculate our total size */
-    totlen = 1+countDigits(argc)+2;
-    for (j = 0; j < argc; j++) {
-        len = argvlen ? argvlen[j] : strlen(argv[j]);
-        totlen += bulklen(len);
-    }
-
-    /* Use an SDS string for command construction */
-    cmd = sdsempty();
-    if (cmd == NULL)
-        return -1;
-
-    /* We already know how much storage we need */
-    cmd = sdsMakeRoomFor(cmd, totlen);
-    if (cmd == NULL)
-        return -1;
-
-    /* Construct command */
-    cmd = sdscatfmt(cmd, "*%i\r\n", argc);
-    for (j=0; j < argc; j++) {
-        len = argvlen ? argvlen[j] : strlen(argv[j]);
-        cmd = sdscatfmt(cmd, "$%T\r\n", len);
-        cmd = sdscatlen(cmd, argv[j], len);
-        cmd = sdscatlen(cmd, "\r\n", sizeof("\r\n")-1);
-    }
-
-    assert(sdslen(cmd)==totlen);
-
-    *target = cmd;
-    return totlen;
-}
-
-void redisFreeSdsCommand(sds cmd) {
-    sdsfree(cmd);
-}
-
-/* Format a command according to the Redis protocol. This function takes the
- * number of arguments, an array with arguments and an array with their
- * lengths. If the latter is set to NULL, strlen will be used to compute the
- * argument lengths.
- */
-int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen) {
-    char *cmd = NULL; /* final command */
-    int pos; /* position in final command */
-    size_t len;
-    int totlen, j;
-
-    /* Abort on a NULL target */
-    if (target == NULL)
-        return -1;
-
-    /* Calculate number of bytes needed for the command */
-    totlen = 1+countDigits(argc)+2;
-    for (j = 0; j < argc; j++) {
-        len = argvlen ? argvlen[j] : strlen(argv[j]);
-        totlen += bulklen(len);
-    }
-
-    /* Build the command at protocol level */
-    cmd = malloc(totlen+1);
-    if (cmd == NULL)
-        return -1;
-
-    pos = sprintf(cmd,"*%d\r\n",argc);
-    for (j = 0; j < argc; j++) {
-        len = argvlen ? argvlen[j] : strlen(argv[j]);
-        pos += sprintf(cmd+pos,"$%zu\r\n",len);
-        memcpy(cmd+pos,argv[j],len);
-        pos += len;
-        cmd[pos++] = '\r';
-        cmd[pos++] = '\n';
-    }
-    assert(pos == totlen);
-    cmd[pos] = '\0';
-
-    *target = cmd;
-    return totlen;
-}
-
-void redisFreeCommand(char *cmd) {
-    free(cmd);
-}
-
-void __redisSetError(redisContext *c, int type, const char *str) {
-    size_t len;
-
-    c->err = type;
-    if (str != NULL) {
-        len = strlen(str);
-        len = len < (sizeof(c->errstr)-1) ? len : (sizeof(c->errstr)-1);
-        memcpy(c->errstr,str,len);
-        c->errstr[len] = '\0';
-    } else {
-        /* Only REDIS_ERR_IO may lack a description! */
-        assert(type == REDIS_ERR_IO);
-        __redis_strerror_r(errno, c->errstr, sizeof(c->errstr));
-    }
-}
-
-redisReader *redisReaderCreate(void) {
-    return redisReaderCreateWithFunctions(&defaultFunctions);
-}
-
-static redisContext *redisContextInit(void) {
-    redisContext *c;
-
-    c = calloc(1,sizeof(redisContext));
-    if (c == NULL)
-        return NULL;
-
-    c->err = 0;
-    c->errstr[0] = '\0';
-    c->obuf = sdsempty();
-    c->reader = redisReaderCreate();
-    c->tcp.host = NULL;
-    c->tcp.source_addr = NULL;
-    c->unix_sock.path = NULL;
-    c->timeout = NULL;
-
-    if (c->obuf == NULL || c->reader == NULL) {
-        redisFree(c);
-        return NULL;
-    }
-
-    return c;
-}
-
-void redisFree(redisContext *c) {
-    if (c == NULL)
-        return;
-    if (c->fd > 0)
-        close(c->fd);
-    if (c->obuf != NULL)
-        sdsfree(c->obuf);
-    if (c->reader != NULL)
-        redisReaderFree(c->reader);
-    if (c->tcp.host)
-        free(c->tcp.host);
-    if (c->tcp.source_addr)
-        free(c->tcp.source_addr);
-    if (c->unix_sock.path)
-        free(c->unix_sock.path);
-    if (c->timeout)
-        free(c->timeout);
-    free(c);
-}
-
-int redisFreeKeepFd(redisContext *c) {
-    int fd = c->fd;
-    c->fd = -1;
-    redisFree(c);
-    return fd;
-}
-
-int redisReconnect(redisContext *c) {
-    c->err = 0;
-    memset(c->errstr, '\0', strlen(c->errstr));
-
-    if (c->fd > 0) {
-        close(c->fd);
-    }
-
-    sdsfree(c->obuf);
-    redisReaderFree(c->reader);
-
-    c->obuf = sdsempty();
-    c->reader = redisReaderCreate();
-
-    if (c->connection_type == REDIS_CONN_TCP) {
-        return redisContextConnectBindTcp(c, c->tcp.host, c->tcp.port,
-                c->timeout, c->tcp.source_addr);
-    } else if (c->connection_type == REDIS_CONN_UNIX) {
-        return redisContextConnectUnix(c, c->unix_sock.path, c->timeout);
-    } else {
-        /* Something bad happened here and shouldn't have. There isn't
-           enough information in the context to reconnect. */
-        __redisSetError(c,REDIS_ERR_OTHER,"Not enough information to reconnect");
-    }
-
-    return REDIS_ERR;
-}
-
-/* Connect to a Redis instance. On error the field error in the returned
- * context will be set to the return value of the error function.
- * When no set of reply functions is given, the default set will be used. */
-redisContext *redisConnect(const char *ip, int port) {
-    redisContext *c;
-
-    c = redisContextInit();
-    if (c == NULL)
-        return NULL;
-
-    c->flags |= REDIS_BLOCK;
-    redisContextConnectTcp(c,ip,port,NULL);
-    return c;
-}
-
-redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv) {
-    redisContext *c;
-
-    c = redisContextInit();
-    if (c == NULL)
-        return NULL;
-
-    c->flags |= REDIS_BLOCK;
-    redisContextConnectTcp(c,ip,port,&tv);
-    return c;
-}
-
-redisContext *redisConnectNonBlock(const char *ip, int port) {
-    redisContext *c;
-
-    c = redisContextInit();
-    if (c == NULL)
-        return NULL;
-
-    c->flags &= ~REDIS_BLOCK;
-    redisContextConnectTcp(c,ip,port,NULL);
-    return c;
-}
-
-redisContext *redisConnectBindNonBlock(const char *ip, int port,
-                                       const char *source_addr) {
-    redisContext *c = redisContextInit();
-    c->flags &= ~REDIS_BLOCK;
-    redisContextConnectBindTcp(c,ip,port,NULL,source_addr);
-    return c;
-}
-
-redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,
-                                                const char *source_addr) {
-    redisContext *c = redisContextInit();
-    c->flags &= ~REDIS_BLOCK;
-    c->flags |= REDIS_REUSEADDR;
-    redisContextConnectBindTcp(c,ip,port,NULL,source_addr);
-    return c;
-}
-
-redisContext *redisConnectUnix(const char *path) {
-    redisContext *c;
-
-    c = redisContextInit();
-    if (c == NULL)
-        return NULL;
-
-    c->flags |= REDIS_BLOCK;
-    redisContextConnectUnix(c,path,NULL);
-    return c;
-}
-
-redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv) {
-    redisContext *c;
-
-    c = redisContextInit();
-    if (c == NULL)
-        return NULL;
-
-    c->flags |= REDIS_BLOCK;
-    redisContextConnectUnix(c,path,&tv);
-    return c;
-}
-
-redisContext *redisConnectUnixNonBlock(const char *path) {
-    redisContext *c;
-
-    c = redisContextInit();
-    if (c == NULL)
-        return NULL;
-
-    c->flags &= ~REDIS_BLOCK;
-    redisContextConnectUnix(c,path,NULL);
-    return c;
-}
-
-redisContext *redisConnectFd(int fd) {
-    redisContext *c;
-
-    c = redisContextInit();
-    if (c == NULL)
-        return NULL;
-
-    c->fd = fd;
-    c->flags |= REDIS_BLOCK | REDIS_CONNECTED;
-    return c;
-}
-
-/* Set read/write timeout on a blocking socket. */
-int redisSetTimeout(redisContext *c, const struct timeval tv) {
-    if (c->flags & REDIS_BLOCK)
-        return redisContextSetTimeout(c,tv);
-    return REDIS_ERR;
-}
-
-/* Enable connection KeepAlive. */
-int redisEnableKeepAlive(redisContext *c) {
-    if (redisKeepAlive(c, REDIS_KEEPALIVE_INTERVAL) != REDIS_OK)
-        return REDIS_ERR;
-    return REDIS_OK;
-}
-
-/* Use this function to handle a read event on the descriptor. It will try
- * and read some bytes from the socket and feed them to the reply parser.
- *
- * After this function is called, you may use redisContextReadReply to
- * see if there is a reply available. */
-int redisBufferRead(redisContext *c) {
-    char buf[1024*16];
-    int nread;
-
-    /* Return early when the context has seen an error. */
-    if (c->err)
-        return REDIS_ERR;
-
-    nread = read(c->fd,buf,sizeof(buf));
-    if (nread == -1) {
-        if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
-            /* Try again later */
-        } else {
-            __redisSetError(c,REDIS_ERR_IO,NULL);
-            return REDIS_ERR;
-        }
-    } else if (nread == 0) {
-        __redisSetError(c,REDIS_ERR_EOF,"Server closed the connection");
-        return REDIS_ERR;
-    } else {
-        if (redisReaderFeed(c->reader,buf,nread) != REDIS_OK) {
-            __redisSetError(c,c->reader->err,c->reader->errstr);
-            return REDIS_ERR;
-        }
-    }
-    return REDIS_OK;
-}
-
-/* Write the output buffer to the socket.
- *
- * Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was
- * succesfully written to the socket. When the buffer is empty after the
- * write operation, "done" is set to 1 (if given).
- *
- * Returns REDIS_ERR if an error occured trying to write and sets
- * c->errstr to hold the appropriate error string.
- */
-int redisBufferWrite(redisContext *c, int *done) {
-    int nwritten;
-
-    /* Return early when the context has seen an error. */
-    if (c->err)
-        return REDIS_ERR;
-
-    if (sdslen(c->obuf) > 0) {
-        nwritten = write(c->fd,c->obuf,sdslen(c->obuf));
-        if (nwritten == -1) {
-            if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
-                /* Try again later */
-            } else {
-                __redisSetError(c,REDIS_ERR_IO,NULL);
-                return REDIS_ERR;
-            }
-        } else if (nwritten > 0) {
-            if (nwritten == (signed)sdslen(c->obuf)) {
-                sdsfree(c->obuf);
-                c->obuf = sdsempty();
-            } else {
-                sdsrange(c->obuf,nwritten,-1);
-            }
-        }
-    }
-    if (done != NULL) *done = (sdslen(c->obuf) == 0);
-    return REDIS_OK;
-}
-
-/* Internal helper function to try and get a reply from the reader,
- * or set an error in the context otherwise. */
-int redisGetReplyFromReader(redisContext *c, void **reply) {
-    if (redisReaderGetReply(c->reader,reply) == REDIS_ERR) {
-        __redisSetError(c,c->reader->err,c->reader->errstr);
-        return REDIS_ERR;
-    }
-    return REDIS_OK;
-}
-
-int redisGetReply(redisContext *c, void **reply) {
-    int wdone = 0;
-    void *aux = NULL;
-
-    /* Try to read pending replies */
-    if (redisGetReplyFromReader(c,&aux) == REDIS_ERR)
-        return REDIS_ERR;
-
-    /* For the blocking context, flush output buffer and read reply */
-    if (aux == NULL && c->flags & REDIS_BLOCK) {
-        /* Write until done */
-        do {
-            if (redisBufferWrite(c,&wdone) == REDIS_ERR)
-                return REDIS_ERR;
-        } while (!wdone);
-
-        /* Read until there is a reply */
-        do {
-            if (redisBufferRead(c) == REDIS_ERR)
-                return REDIS_ERR;
-            if (redisGetReplyFromReader(c,&aux) == REDIS_ERR)
-                return REDIS_ERR;
-        } while (aux == NULL);
-    }
-
-    /* Set reply object */
-    if (reply != NULL) *reply = aux;
-    return REDIS_OK;
-}
-
-
-/* Helper function for the redisAppendCommand* family of functions.
- *
- * Write a formatted command to the output buffer. When this family
- * is used, you need to call redisGetReply yourself to retrieve
- * the reply (or replies in pub/sub).
- */
-int __redisAppendCommand(redisContext *c, const char *cmd, size_t len) {
-    sds newbuf;
-
-    newbuf = sdscatlen(c->obuf,cmd,len);
-    if (newbuf == NULL) {
-        __redisSetError(c,REDIS_ERR_OOM,"Out of memory");
-        return REDIS_ERR;
-    }
-
-    c->obuf = newbuf;
-    return REDIS_OK;
-}
-
-int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len) {
-
-    if (__redisAppendCommand(c, cmd, len) != REDIS_OK) {
-        return REDIS_ERR;
-    }
-
-    return REDIS_OK;
-}
-
-int redisvAppendCommand(redisContext *c, const char *format, va_list ap) {
-    char *cmd;
-    int len;
-
-    len = redisvFormatCommand(&cmd,format,ap);
-    if (len == -1) {
-        __redisSetError(c,REDIS_ERR_OOM,"Out of memory");
-        return REDIS_ERR;
-    } else if (len == -2) {
-        __redisSetError(c,REDIS_ERR_OTHER,"Invalid format string");
-        return REDIS_ERR;
-    }
-
-    if (__redisAppendCommand(c,cmd,len) != REDIS_OK) {
-        free(cmd);
-        return REDIS_ERR;
-    }
-
-    free(cmd);
-    return REDIS_OK;
-}
-
-int redisAppendCommand(redisContext *c, const char *format, ...) {
-    va_list ap;
-    int ret;
-
-    va_start(ap,format);
-    ret = redisvAppendCommand(c,format,ap);
-    va_end(ap);
-    return ret;
-}
-
-int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) {
-    sds cmd;
-    int len;
-
-    len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen);
-    if (len == -1) {
-        __redisSetError(c,REDIS_ERR_OOM,"Out of memory");
-        return REDIS_ERR;
-    }
-
-    if (__redisAppendCommand(c,cmd,len) != REDIS_OK) {
-        sdsfree(cmd);
-        return REDIS_ERR;
-    }
-
-    sdsfree(cmd);
-    return REDIS_OK;
-}
-
-/* Helper function for the redisCommand* family of functions.
- *
- * Write a formatted command to the output buffer. If the given context is
- * blocking, immediately read the reply into the "reply" pointer. When the
- * context is non-blocking, the "reply" pointer will not be used and the
- * command is simply appended to the write buffer.
- *
- * Returns the reply when a reply was succesfully retrieved. Returns NULL
- * otherwise. When NULL is returned in a blocking context, the error field
- * in the context will be set.
- */
-static void *__redisBlockForReply(redisContext *c) {
-    void *reply;
-
-    if (c->flags & REDIS_BLOCK) {
-        if (redisGetReply(c,&reply) != REDIS_OK)
-            return NULL;
-        return reply;
-    }
-    return NULL;
-}
-
-void *redisvCommand(redisContext *c, const char *format, va_list ap) {
-    if (redisvAppendCommand(c,format,ap) != REDIS_OK)
-        return NULL;
-    return __redisBlockForReply(c);
-}
-
-void *redisCommand(redisContext *c, const char *format, ...) {
-    va_list ap;
-    void *reply = NULL;
-    va_start(ap,format);
-    reply = redisvCommand(c,format,ap);
-    va_end(ap);
-    return reply;
-}
-
-void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) {
-    if (redisAppendCommandArgv(c,argc,argv,argvlen) != REDIS_OK)
-        return NULL;
-    return __redisBlockForReply(c);
-}
diff --git a/third-party/hiredis/hiredis.h b/third-party/hiredis/hiredis.h
deleted file mode 100644 (file)
index fe267b9..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
- *                     Jan-Erik Rediger <janerik at fnordig dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   * Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *   * 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.
- *   * Neither the name of Redis nor the names of its contributors may be used
- *     to endorse or promote products derived from this software without
- *     specific prior written permission.
- *
- * THIS 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 OWNER 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.
- */
-
-#ifndef __HIREDIS_H
-#define __HIREDIS_H
-#include "read.h"
-#include <stdarg.h> /* for va_list */
-#include <sys/time.h> /* for struct timeval */
-#include <stdint.h> /* uintXX_t, etc */
-#include "sds.h" /* for sds */
-
-#define HIREDIS_MAJOR 0
-#define HIREDIS_MINOR 13
-#define HIREDIS_PATCH 3
-#define HIREDIS_SONAME 0.13
-
-/* Connection type can be blocking or non-blocking and is set in the
- * least significant bit of the flags field in redisContext. */
-#define REDIS_BLOCK 0x1
-
-/* Connection may be disconnected before being free'd. The second bit
- * in the flags field is set when the context is connected. */
-#define REDIS_CONNECTED 0x2
-
-/* The async API might try to disconnect cleanly and flush the output
- * buffer and read all subsequent replies before disconnecting.
- * This flag means no new commands can come in and the connection
- * should be terminated once all replies have been read. */
-#define REDIS_DISCONNECTING 0x4
-
-/* Flag specific to the async API which means that the context should be clean
- * up as soon as possible. */
-#define REDIS_FREEING 0x8
-
-/* Flag that is set when an async callback is executed. */
-#define REDIS_IN_CALLBACK 0x10
-
-/* Flag that is set when the async context has one or more subscriptions. */
-#define REDIS_SUBSCRIBED 0x20
-
-/* Flag that is set when monitor mode is active */
-#define REDIS_MONITORING 0x40
-
-/* Flag that is set when we should set SO_REUSEADDR before calling bind() */
-#define REDIS_REUSEADDR 0x80
-
-#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */
-
-/* number of times we retry to connect in the case of EADDRNOTAVAIL and
- * SO_REUSEADDR is being used. */
-#define REDIS_CONNECT_RETRIES  10
-
-/* strerror_r has two completely different prototypes and behaviors
- * depending on system issues, so we need to operate on the error buffer
- * differently depending on which strerror_r we're using. */
-#ifndef _GNU_SOURCE
-/* "regular" POSIX strerror_r that does the right thing. */
-#define __redis_strerror_r(errno, buf, len)                                    \
-    do {                                                                       \
-        strerror_r((errno), (buf), (len));                                     \
-    } while (0)
-#else
-/* "bad" GNU strerror_r we need to clean up after. */
-#define __redis_strerror_r(errno, buf, len)                                    \
-    do {                                                                       \
-        char *err_str = strerror_r((errno), (buf), (len));                     \
-        /* If return value _isn't_ the start of the buffer we passed in,       \
-         * then GNU strerror_r returned an internal static buffer and we       \
-         * need to copy the result into our private buffer. */                 \
-        if (err_str != (buf)) {                                                \
-            buf[(len)] = '\0';                                                 \
-            strncat((buf), err_str, ((len) - 1));                              \
-        }                                                                      \
-    } while (0)
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* This is the reply object returned by redisCommand() */
-typedef struct redisReply {
-    int type; /* REDIS_REPLY_* */
-    long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
-    int len; /* Length of string */
-    char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */
-    size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
-    struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */
-} redisReply;
-
-redisReader *redisReaderCreate(void);
-
-/* Function to free the reply objects hiredis returns by default. */
-void freeReplyObject(void *reply);
-
-/* Functions to format a command according to the protocol. */
-int redisvFormatCommand(char **target, const char *format, va_list ap);
-int redisFormatCommand(char **target, const char *format, ...);
-int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen);
-int redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen);
-void redisFreeCommand(char *cmd);
-void redisFreeSdsCommand(sds cmd);
-
-enum redisConnectionType {
-    REDIS_CONN_TCP,
-    REDIS_CONN_UNIX,
-};
-
-/* Context for a connection to Redis */
-typedef struct redisContext {
-    int err; /* Error flags, 0 when there is no error */
-    char errstr[128]; /* String representation of error when applicable */
-    int fd;
-    int flags;
-    char *obuf; /* Write buffer */
-    redisReader *reader; /* Protocol reader */
-
-    enum redisConnectionType connection_type;
-    struct timeval *timeout;
-
-    struct {
-        char *host;
-        char *source_addr;
-        int port;
-    } tcp;
-
-    struct {
-        char *path;
-    } unix_sock;
-
-} redisContext;
-
-redisContext *redisConnect(const char *ip, int port);
-redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv);
-redisContext *redisConnectNonBlock(const char *ip, int port);
-redisContext *redisConnectBindNonBlock(const char *ip, int port,
-                                       const char *source_addr);
-redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,
-                                                const char *source_addr);
-redisContext *redisConnectUnix(const char *path);
-redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv);
-redisContext *redisConnectUnixNonBlock(const char *path);
-redisContext *redisConnectFd(int fd);
-
-/**
- * Reconnect the given context using the saved information.
- *
- * This re-uses the exact same connect options as in the initial connection.
- * host, ip (or path), timeout and bind address are reused,
- * flags are used unmodified from the existing context.
- *
- * Returns REDIS_OK on successfull connect or REDIS_ERR otherwise.
- */
-int redisReconnect(redisContext *c);
-
-int redisSetTimeout(redisContext *c, const struct timeval tv);
-int redisEnableKeepAlive(redisContext *c);
-void redisFree(redisContext *c);
-int redisFreeKeepFd(redisContext *c);
-int redisBufferRead(redisContext *c);
-int redisBufferWrite(redisContext *c, int *done);
-
-/* In a blocking context, this function first checks if there are unconsumed
- * replies to return and returns one if so. Otherwise, it flushes the output
- * buffer to the socket and reads until it has a reply. In a non-blocking
- * context, it will return unconsumed replies until there are no more. */
-int redisGetReply(redisContext *c, void **reply);
-int redisGetReplyFromReader(redisContext *c, void **reply);
-
-/* Write a formatted command to the output buffer. Use these functions in blocking mode
- * to get a pipeline of commands. */
-int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len);
-
-/* Write a command to the output buffer. Use these functions in blocking mode
- * to get a pipeline of commands. */
-int redisvAppendCommand(redisContext *c, const char *format, va_list ap);
-int redisAppendCommand(redisContext *c, const char *format, ...);
-int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
-
-/* Issue a command to Redis. In a blocking context, it is identical to calling
- * redisAppendCommand, followed by redisGetReply. The function will return
- * NULL if there was an error in performing the request, otherwise it will
- * return the reply. In a non-blocking context, it is identical to calling
- * only redisAppendCommand and will always return NULL. */
-void *redisvCommand(redisContext *c, const char *format, va_list ap);
-void *redisCommand(redisContext *c, const char *format, ...);
-void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/third-party/hiredis/net.c b/third-party/hiredis/net.c
deleted file mode 100644 (file)
index 60a2dc7..0000000
+++ /dev/null
@@ -1,458 +0,0 @@
-/* Extracted from anet.c to work properly with Hiredis error reporting.
- *
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
- *                     Jan-Erik Rediger <janerik at fnordig dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   * Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *   * 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.
- *   * Neither the name of Redis nor the names of its contributors may be used
- *     to endorse or promote products derived from this software without
- *     specific prior written permission.
- *
- * THIS 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 OWNER 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.
- */
-
-#include "fmacros.h"
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <netdb.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <poll.h>
-#include <limits.h>
-#include <stdlib.h>
-
-#include "net.h"
-#include "sds.h"
-
-/* Defined in hiredis.c */
-void __redisSetError(redisContext *c, int type, const char *str);
-
-static void redisContextCloseFd(redisContext *c) {
-    if (c && c->fd >= 0) {
-        close(c->fd);
-        c->fd = -1;
-    }
-}
-
-static void __redisSetErrorFromErrno(redisContext *c, int type, const char *prefix) {
-    char buf[128] = { 0 };
-    size_t len = 0;
-
-    if (prefix != NULL)
-        len = snprintf(buf,sizeof(buf),"%s: ",prefix);
-    __redis_strerror_r(errno, (char *)(buf + len), sizeof(buf) - len);
-    __redisSetError(c,type,buf);
-}
-
-static int redisSetReuseAddr(redisContext *c) {
-    int on = 1;
-    if (setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
-        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
-        redisContextCloseFd(c);
-        return REDIS_ERR;
-    }
-    return REDIS_OK;
-}
-
-static int redisCreateSocket(redisContext *c, int type) {
-    int s;
-    if ((s = socket(type, SOCK_STREAM, 0)) == -1) {
-        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
-        return REDIS_ERR;
-    }
-    c->fd = s;
-    if (type == AF_INET) {
-        if (redisSetReuseAddr(c) == REDIS_ERR) {
-            return REDIS_ERR;
-        }
-    }
-    return REDIS_OK;
-}
-
-static int redisSetBlocking(redisContext *c, int blocking) {
-    int flags;
-
-    /* Set the socket nonblocking.
-     * Note that fcntl(2) for F_GETFL and F_SETFL can't be
-     * interrupted by a signal. */
-    if ((flags = fcntl(c->fd, F_GETFL)) == -1) {
-        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)");
-        redisContextCloseFd(c);
-        return REDIS_ERR;
-    }
-
-    if (blocking)
-        flags &= ~O_NONBLOCK;
-    else
-        flags |= O_NONBLOCK;
-
-    if (fcntl(c->fd, F_SETFL, flags) == -1) {
-        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)");
-        redisContextCloseFd(c);
-        return REDIS_ERR;
-    }
-    return REDIS_OK;
-}
-
-int redisKeepAlive(redisContext *c, int interval) {
-    int val = 1;
-    int fd = c->fd;
-
-    if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1){
-        __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
-        return REDIS_ERR;
-    }
-
-    val = interval;
-
-#ifdef _OSX
-    if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &val, sizeof(val)) < 0) {
-        __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
-        return REDIS_ERR;
-    }
-#else
-#if defined(__GLIBC__) && !defined(__FreeBSD_kernel__)
-    val = interval;
-    if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) {
-        __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
-        return REDIS_ERR;
-    }
-
-    val = interval/3;
-    if (val == 0) val = 1;
-    if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) {
-        __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
-        return REDIS_ERR;
-    }
-
-    val = 3;
-    if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) {
-        __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
-        return REDIS_ERR;
-    }
-#endif
-#endif
-
-    return REDIS_OK;
-}
-
-static int redisSetTcpNoDelay(redisContext *c) {
-    int yes = 1;
-    if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) {
-        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)");
-        redisContextCloseFd(c);
-        return REDIS_ERR;
-    }
-    return REDIS_OK;
-}
-
-#define __MAX_MSEC (((LONG_MAX) - 999) / 1000)
-
-static int redisContextWaitReady(redisContext *c, const struct timeval *timeout) {
-    struct pollfd   wfd[1];
-    long msec;
-
-    msec          = -1;
-    wfd[0].fd     = c->fd;
-    wfd[0].events = POLLOUT;
-
-    /* Only use timeout when not NULL. */
-    if (timeout != NULL) {
-        if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
-            __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL);
-            redisContextCloseFd(c);
-            return REDIS_ERR;
-        }
-
-        msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);
-
-        if (msec < 0 || msec > INT_MAX) {
-            msec = INT_MAX;
-        }
-    }
-
-    if (errno == EINPROGRESS) {
-        int res;
-
-        if ((res = poll(wfd, 1, msec)) == -1) {
-            __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
-            redisContextCloseFd(c);
-            return REDIS_ERR;
-        } else if (res == 0) {
-            errno = ETIMEDOUT;
-            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
-            redisContextCloseFd(c);
-            return REDIS_ERR;
-        }
-
-        if (redisCheckSocketError(c) != REDIS_OK)
-            return REDIS_ERR;
-
-        return REDIS_OK;
-    }
-
-    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
-    redisContextCloseFd(c);
-    return REDIS_ERR;
-}
-
-int redisCheckSocketError(redisContext *c) {
-    int err = 0;
-    socklen_t errlen = sizeof(err);
-
-    if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
-        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)");
-        return REDIS_ERR;
-    }
-
-    if (err) {
-        errno = err;
-        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
-        return REDIS_ERR;
-    }
-
-    return REDIS_OK;
-}
-
-int redisContextSetTimeout(redisContext *c, const struct timeval tv) {
-    if (setsockopt(c->fd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv)) == -1) {
-        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_RCVTIMEO)");
-        return REDIS_ERR;
-    }
-    if (setsockopt(c->fd,SOL_SOCKET,SO_SNDTIMEO,&tv,sizeof(tv)) == -1) {
-        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_SNDTIMEO)");
-        return REDIS_ERR;
-    }
-    return REDIS_OK;
-}
-
-static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
-                                   const struct timeval *timeout,
-                                   const char *source_addr) {
-    int s, rv, n;
-    char _port[6];  /* strlen("65535"); */
-    struct addrinfo hints, *servinfo, *bservinfo, *p, *b;
-    int blocking = (c->flags & REDIS_BLOCK);
-    int reuseaddr = (c->flags & REDIS_REUSEADDR);
-    int reuses = 0;
-
-    c->connection_type = REDIS_CONN_TCP;
-    c->tcp.port = port;
-
-    /* We need to take possession of the passed parameters
-     * to make them reusable for a reconnect.
-     * We also carefully check we don't free data we already own,
-     * as in the case of the reconnect method.
-     *
-     * This is a bit ugly, but atleast it works and doesn't leak memory.
-     **/
-    if (c->tcp.host != addr) {
-        if (c->tcp.host)
-            free(c->tcp.host);
-
-        c->tcp.host = strdup(addr);
-    }
-
-    if (timeout) {
-        if (c->timeout != timeout) {
-            if (c->timeout == NULL)
-                c->timeout = malloc(sizeof(struct timeval));
-
-            memcpy(c->timeout, timeout, sizeof(struct timeval));
-        }
-    } else {
-        if (c->timeout)
-            free(c->timeout);
-        c->timeout = NULL;
-    }
-
-    if (source_addr == NULL) {
-        free(c->tcp.source_addr);
-        c->tcp.source_addr = NULL;
-    } else if (c->tcp.source_addr != source_addr) {
-        free(c->tcp.source_addr);
-        c->tcp.source_addr = strdup(source_addr);
-    }
-
-    snprintf(_port, 6, "%d", port);
-    memset(&hints,0,sizeof(hints));
-    hints.ai_family = AF_INET;
-    hints.ai_socktype = SOCK_STREAM;
-
-    /* Try with IPv6 if no IPv4 address was found. We do it in this order since
-     * in a Redis client you can't afford to test if you have IPv6 connectivity
-     * as this would add latency to every connect. Otherwise a more sensible
-     * route could be: Use IPv6 if both addresses are available and there is IPv6
-     * connectivity. */
-    if ((rv = getaddrinfo(c->tcp.host,_port,&hints,&servinfo)) != 0) {
-         hints.ai_family = AF_INET6;
-         if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) {
-            __redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv));
-            return REDIS_ERR;
-        }
-    }
-    for (p = servinfo; p != NULL; p = p->ai_next) {
-addrretry:
-        if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1)
-            continue;
-
-        c->fd = s;
-        if (redisSetBlocking(c,0) != REDIS_OK)
-            goto error;
-        if (c->tcp.source_addr) {
-            int bound = 0;
-            /* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */
-            if ((rv = getaddrinfo(c->tcp.source_addr, NULL, &hints, &bservinfo)) != 0) {
-                char buf[128];
-                snprintf(buf,sizeof(buf),"Can't get addr: %s",gai_strerror(rv));
-                __redisSetError(c,REDIS_ERR_OTHER,buf);
-                goto error;
-            }
-
-            if (reuseaddr) {
-                n = 1;
-                if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*) &n,
-                               sizeof(n)) < 0) {
-                    goto error;
-                }
-            }
-
-            for (b = bservinfo; b != NULL; b = b->ai_next) {
-                if (bind(s,b->ai_addr,b->ai_addrlen) != -1) {
-                    bound = 1;
-                    break;
-                }
-            }
-            freeaddrinfo(bservinfo);
-            if (!bound) {
-                char buf[128];
-                snprintf(buf,sizeof(buf),"Can't bind socket: %s",strerror(errno));
-                __redisSetError(c,REDIS_ERR_OTHER,buf);
-                goto error;
-            }
-        }
-        if (connect(s,p->ai_addr,p->ai_addrlen) == -1) {
-            if (errno == EHOSTUNREACH) {
-                redisContextCloseFd(c);
-                continue;
-            } else if (errno == EINPROGRESS && !blocking) {
-                /* This is ok. */
-            } else if (errno == EADDRNOTAVAIL && reuseaddr) {
-                if (++reuses >= REDIS_CONNECT_RETRIES) {
-                    goto error;
-                } else {
-                    goto addrretry;
-                }
-            } else {
-                if (redisContextWaitReady(c,c->timeout) != REDIS_OK)
-                    goto error;
-            }
-        }
-        if (blocking && redisSetBlocking(c,1) != REDIS_OK)
-            goto error;
-        if (redisSetTcpNoDelay(c) != REDIS_OK)
-            goto error;
-
-        c->flags |= REDIS_CONNECTED;
-        rv = REDIS_OK;
-        goto end;
-    }
-    if (p == NULL) {
-        char buf[128];
-        snprintf(buf,sizeof(buf),"Can't create socket: %s",strerror(errno));
-        __redisSetError(c,REDIS_ERR_OTHER,buf);
-        goto error;
-    }
-
-error:
-    rv = REDIS_ERR;
-end:
-    freeaddrinfo(servinfo);
-    return rv;  // Need to return REDIS_OK if alright
-}
-
-int redisContextConnectTcp(redisContext *c, const char *addr, int port,
-                           const struct timeval *timeout) {
-    return _redisContextConnectTcp(c, addr, port, timeout, NULL);
-}
-
-int redisContextConnectBindTcp(redisContext *c, const char *addr, int port,
-                               const struct timeval *timeout,
-                               const char *source_addr) {
-    return _redisContextConnectTcp(c, addr, port, timeout, source_addr);
-}
-
-int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout) {
-    int blocking = (c->flags & REDIS_BLOCK);
-    struct sockaddr_un sa;
-
-    if (redisCreateSocket(c,AF_LOCAL) < 0)
-        return REDIS_ERR;
-    if (redisSetBlocking(c,0) != REDIS_OK)
-        return REDIS_ERR;
-
-    c->connection_type = REDIS_CONN_UNIX;
-    if (c->unix_sock.path != path)
-        c->unix_sock.path = strdup(path);
-
-    if (timeout) {
-        if (c->timeout != timeout) {
-            if (c->timeout == NULL)
-                c->timeout = malloc(sizeof(struct timeval));
-
-            memcpy(c->timeout, timeout, sizeof(struct timeval));
-        }
-    } else {
-        if (c->timeout)
-            free(c->timeout);
-        c->timeout = NULL;
-    }
-
-    sa.sun_family = AF_LOCAL;
-    strncpy(sa.sun_path,path,sizeof(sa.sun_path)-1);
-    if (connect(c->fd, (struct sockaddr*)&sa, sizeof(sa)) == -1) {
-        if (errno == EINPROGRESS && !blocking) {
-            /* This is ok. */
-        } else {
-            if (redisContextWaitReady(c,c->timeout) != REDIS_OK)
-                return REDIS_ERR;
-        }
-    }
-
-    /* Reset socket to be blocking after connect(2). */
-    if (blocking && redisSetBlocking(c,1) != REDIS_OK)
-        return REDIS_ERR;
-
-    c->flags |= REDIS_CONNECTED;
-    return REDIS_OK;
-}
diff --git a/third-party/hiredis/net.h b/third-party/hiredis/net.h
deleted file mode 100644 (file)
index 2f1a0bf..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Extracted from anet.c to work properly with Hiredis error reporting.
- *
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
- *                     Jan-Erik Rediger <janerik at fnordig dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   * Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *   * 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.
- *   * Neither the name of Redis nor the names of its contributors may be used
- *     to endorse or promote products derived from this software without
- *     specific prior written permission.
- *
- * THIS 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 OWNER 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.
- */
-
-#ifndef __NET_H
-#define __NET_H
-
-#include "hiredis.h"
-
-#if defined(__sun)
-#define AF_LOCAL AF_UNIX
-#endif
-
-int redisCheckSocketError(redisContext *c);
-int redisContextSetTimeout(redisContext *c, const struct timeval tv);
-int redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout);
-int redisContextConnectBindTcp(redisContext *c, const char *addr, int port,
-                               const struct timeval *timeout,
-                               const char *source_addr);
-int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout);
-int redisKeepAlive(redisContext *c, int interval);
-
-#endif
diff --git a/third-party/hiredis/read.c b/third-party/hiredis/read.c
deleted file mode 100644 (file)
index df1a467..0000000
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   * Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *   * 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.
- *   * Neither the name of Redis nor the names of its contributors may be used
- *     to endorse or promote products derived from this software without
- *     specific prior written permission.
- *
- * THIS 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 OWNER 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.
- */
-
-
-#include "fmacros.h"
-#include <string.h>
-#include <stdlib.h>
-#ifndef _MSC_VER
-#include <unistd.h>
-#endif
-#include <assert.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include "read.h"
-#include "sds.h"
-
-static void __redisReaderSetError(redisReader *r, int type, const char *str) {
-    size_t len;
-
-    if (r->reply != NULL && r->fn && r->fn->freeObject) {
-        r->fn->freeObject(r->reply);
-        r->reply = NULL;
-    }
-
-    /* Clear input buffer on errors. */
-    if (r->buf != NULL) {
-        sdsfree(r->buf);
-        r->buf = NULL;
-        r->pos = r->len = 0;
-    }
-
-    /* Reset task stack. */
-    r->ridx = -1;
-
-    /* Set error. */
-    r->err = type;
-    len = strlen(str);
-    len = len < (sizeof(r->errstr)-1) ? len : (sizeof(r->errstr)-1);
-    memcpy(r->errstr,str,len);
-    r->errstr[len] = '\0';
-}
-
-static size_t chrtos(char *buf, size_t size, char byte) {
-    size_t len = 0;
-
-    switch(byte) {
-    case '\\':
-    case '"':
-        len = snprintf(buf,size,"\"\\%c\"",byte);
-        break;
-    case '\n': len = snprintf(buf,size,"\"\\n\""); break;
-    case '\r': len = snprintf(buf,size,"\"\\r\""); break;
-    case '\t': len = snprintf(buf,size,"\"\\t\""); break;
-    case '\a': len = snprintf(buf,size,"\"\\a\""); break;
-    case '\b': len = snprintf(buf,size,"\"\\b\""); break;
-    default:
-        if (isprint(byte))
-            len = snprintf(buf,size,"\"%c\"",byte);
-        else
-            len = snprintf(buf,size,"\"\\x%02x\"",(unsigned char)byte);
-        break;
-    }
-
-    return len;
-}
-
-static void __redisReaderSetErrorProtocolByte(redisReader *r, char byte) {
-    char cbuf[8], sbuf[128];
-
-    chrtos(cbuf,sizeof(cbuf),byte);
-    snprintf(sbuf,sizeof(sbuf),
-        "Protocol error, got %s as reply type byte", cbuf);
-    __redisReaderSetError(r,REDIS_ERR_PROTOCOL,sbuf);
-}
-
-static void __redisReaderSetErrorOOM(redisReader *r) {
-    __redisReaderSetError(r,REDIS_ERR_OOM,"Out of memory");
-}
-
-static char *readBytes(redisReader *r, unsigned int bytes) {
-    char *p;
-    if (r->len-r->pos >= bytes) {
-        p = r->buf+r->pos;
-        r->pos += bytes;
-        return p;
-    }
-    return NULL;
-}
-
-/* Find pointer to \r\n. */
-static char *seekNewline(char *s, size_t len) {
-    int pos = 0;
-    int _len = len-1;
-
-    /* Position should be < len-1 because the character at "pos" should be
-     * followed by a \n. Note that strchr cannot be used because it doesn't
-     * allow to search a limited length and the buffer that is being searched
-     * might not have a trailing NULL character. */
-    while (pos < _len) {
-        while(pos < _len && s[pos] != '\r') pos++;
-        if (s[pos] != '\r') {
-            /* Not found. */
-            return NULL;
-        } else {
-            if (s[pos+1] == '\n') {
-                /* Found. */
-                return s+pos;
-            } else {
-                /* Continue searching. */
-                pos++;
-            }
-        }
-    }
-    return NULL;
-}
-
-/* Read a long long value starting at *s, under the assumption that it will be
- * terminated by \r\n. Ambiguously returns -1 for unexpected input. */
-static long long readLongLong(char *s) {
-    long long v = 0;
-    int dec, mult = 1;
-    char c;
-
-    if (*s == '-') {
-        mult = -1;
-        s++;
-    } else if (*s == '+') {
-        mult = 1;
-        s++;
-    }
-
-    while ((c = *(s++)) != '\r') {
-        dec = c - '0';
-        if (dec >= 0 && dec < 10) {
-            v *= 10;
-            v += dec;
-        } else {
-            /* Should not happen... */
-            return -1;
-        }
-    }
-
-    return mult*v;
-}
-
-static char *readLine(redisReader *r, int *_len) {
-    char *p, *s;
-    int len;
-
-    p = r->buf+r->pos;
-    s = seekNewline(p,(r->len-r->pos));
-    if (s != NULL) {
-        len = s-(r->buf+r->pos);
-        r->pos += len+2; /* skip \r\n */
-        if (_len) *_len = len;
-        return p;
-    }
-    return NULL;
-}
-
-static void moveToNextTask(redisReader *r) {
-    redisReadTask *cur, *prv;
-    while (r->ridx >= 0) {
-        /* Return a.s.a.p. when the stack is now empty. */
-        if (r->ridx == 0) {
-            r->ridx--;
-            return;
-        }
-
-        cur = &(r->rstack[r->ridx]);
-        prv = &(r->rstack[r->ridx-1]);
-        assert(prv->type == REDIS_REPLY_ARRAY);
-        if (cur->idx == prv->elements-1) {
-            r->ridx--;
-        } else {
-            /* Reset the type because the next item can be anything */
-            assert(cur->idx < prv->elements);
-            cur->type = -1;
-            cur->elements = -1;
-            cur->idx++;
-            return;
-        }
-    }
-}
-
-static int processLineItem(redisReader *r) {
-    redisReadTask *cur = &(r->rstack[r->ridx]);
-    void *obj;
-    char *p;
-    int len;
-
-    if ((p = readLine(r,&len)) != NULL) {
-        if (cur->type == REDIS_REPLY_INTEGER) {
-            if (r->fn && r->fn->createInteger)
-                obj = r->fn->createInteger(cur,readLongLong(p));
-            else
-                obj = (void*)REDIS_REPLY_INTEGER;
-        } else {
-            /* Type will be error or status. */
-            if (r->fn && r->fn->createString)
-                obj = r->fn->createString(cur,p,len);
-            else
-                obj = (void*)(size_t)(cur->type);
-        }
-
-        if (obj == NULL) {
-            __redisReaderSetErrorOOM(r);
-            return REDIS_ERR;
-        }
-
-        /* Set reply if this is the root object. */
-        if (r->ridx == 0) r->reply = obj;
-        moveToNextTask(r);
-        return REDIS_OK;
-    }
-
-    return REDIS_ERR;
-}
-
-static int processBulkItem(redisReader *r) {
-    redisReadTask *cur = &(r->rstack[r->ridx]);
-    void *obj = NULL;
-    char *p, *s;
-    long len;
-    unsigned long bytelen;
-    int success = 0;
-
-    p = r->buf+r->pos;
-    s = seekNewline(p,r->len-r->pos);
-    if (s != NULL) {
-        p = r->buf+r->pos;
-        bytelen = s-(r->buf+r->pos)+2; /* include \r\n */
-        len = readLongLong(p);
-
-        if (len < 0) {
-            /* The nil object can always be created. */
-            if (r->fn && r->fn->createNil)
-                obj = r->fn->createNil(cur);
-            else
-                obj = (void*)REDIS_REPLY_NIL;
-            success = 1;
-        } else {
-            /* Only continue when the buffer contains the entire bulk item. */
-            bytelen += len+2; /* include \r\n */
-            if (r->pos+bytelen <= r->len) {
-                if (r->fn && r->fn->createString)
-                    obj = r->fn->createString(cur,s+2,len);
-                else
-                    obj = (void*)REDIS_REPLY_STRING;
-                success = 1;
-            }
-        }
-
-        /* Proceed when obj was created. */
-        if (success) {
-            if (obj == NULL) {
-                __redisReaderSetErrorOOM(r);
-                return REDIS_ERR;
-            }
-
-            r->pos += bytelen;
-
-            /* Set reply if this is the root object. */
-            if (r->ridx == 0) r->reply = obj;
-            moveToNextTask(r);
-            return REDIS_OK;
-        }
-    }
-
-    return REDIS_ERR;
-}
-
-static int processMultiBulkItem(redisReader *r) {
-    redisReadTask *cur = &(r->rstack[r->ridx]);
-    void *obj;
-    char *p;
-    long elements;
-    int root = 0;
-
-    /* Set error for nested multi bulks with depth > 7 */
-    if (r->ridx == 8) {
-        __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
-            "No support for nested multi bulk replies with depth > 7");
-        return REDIS_ERR;
-    }
-
-    if ((p = readLine(r,NULL)) != NULL) {
-        elements = readLongLong(p);
-        root = (r->ridx == 0);
-
-        if (elements == -1) {
-            if (r->fn && r->fn->createNil)
-                obj = r->fn->createNil(cur);
-            else
-                obj = (void*)REDIS_REPLY_NIL;
-
-            if (obj == NULL) {
-                __redisReaderSetErrorOOM(r);
-                return REDIS_ERR;
-            }
-
-            moveToNextTask(r);
-        } else {
-            if (r->fn && r->fn->createArray)
-                obj = r->fn->createArray(cur,elements);
-            else
-                obj = (void*)REDIS_REPLY_ARRAY;
-
-            if (obj == NULL) {
-                __redisReaderSetErrorOOM(r);
-                return REDIS_ERR;
-            }
-
-            /* Modify task stack when there are more than 0 elements. */
-            if (elements > 0) {
-                cur->elements = elements;
-                cur->obj = obj;
-                r->ridx++;
-                r->rstack[r->ridx].type = -1;
-                r->rstack[r->ridx].elements = -1;
-                r->rstack[r->ridx].idx = 0;
-                r->rstack[r->ridx].obj = NULL;
-                r->rstack[r->ridx].parent = cur;
-                r->rstack[r->ridx].privdata = r->privdata;
-            } else {
-                moveToNextTask(r);
-            }
-        }
-
-        /* Set reply if this is the root object. */
-        if (root) r->reply = obj;
-        return REDIS_OK;
-    }
-
-    return REDIS_ERR;
-}
-
-static int processItem(redisReader *r) {
-    redisReadTask *cur = &(r->rstack[r->ridx]);
-    char *p;
-
-    /* check if we need to read type */
-    if (cur->type < 0) {
-        if ((p = readBytes(r,1)) != NULL) {
-            switch (p[0]) {
-            case '-':
-                cur->type = REDIS_REPLY_ERROR;
-                break;
-            case '+':
-                cur->type = REDIS_REPLY_STATUS;
-                break;
-            case ':':
-                cur->type = REDIS_REPLY_INTEGER;
-                break;
-            case '$':
-                cur->type = REDIS_REPLY_STRING;
-                break;
-            case '*':
-                cur->type = REDIS_REPLY_ARRAY;
-                break;
-            default:
-                __redisReaderSetErrorProtocolByte(r,*p);
-                return REDIS_ERR;
-            }
-        } else {
-            /* could not consume 1 byte */
-            return REDIS_ERR;
-        }
-    }
-
-    /* process typed item */
-    switch(cur->type) {
-    case REDIS_REPLY_ERROR:
-    case REDIS_REPLY_STATUS:
-    case REDIS_REPLY_INTEGER:
-        return processLineItem(r);
-    case REDIS_REPLY_STRING:
-        return processBulkItem(r);
-    case REDIS_REPLY_ARRAY:
-        return processMultiBulkItem(r);
-    default:
-        assert(NULL);
-        return REDIS_ERR; /* Avoid warning. */
-    }
-}
-
-redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn) {
-    redisReader *r;
-
-    r = calloc(sizeof(redisReader),1);
-    if (r == NULL)
-        return NULL;
-
-    r->err = 0;
-    r->errstr[0] = '\0';
-    r->fn = fn;
-    r->buf = sdsempty();
-    r->maxbuf = REDIS_READER_MAX_BUF;
-    if (r->buf == NULL) {
-        free(r);
-        return NULL;
-    }
-
-    r->ridx = -1;
-    return r;
-}
-
-void redisReaderFree(redisReader *r) {
-    if (r->reply != NULL && r->fn && r->fn->freeObject)
-        r->fn->freeObject(r->reply);
-    if (r->buf != NULL)
-        sdsfree(r->buf);
-    free(r);
-}
-
-int redisReaderFeed(redisReader *r, const char *buf, size_t len) {
-    sds newbuf;
-
-    /* Return early when this reader is in an erroneous state. */
-    if (r->err)
-        return REDIS_ERR;
-
-    /* Copy the provided buffer. */
-    if (buf != NULL && len >= 1) {
-        /* Destroy internal buffer when it is empty and is quite large. */
-        if (r->len == 0 && r->maxbuf != 0 && sdsavail(r->buf) > r->maxbuf) {
-            sdsfree(r->buf);
-            r->buf = sdsempty();
-            r->pos = 0;
-
-            /* r->buf should not be NULL since we just free'd a larger one. */
-            assert(r->buf != NULL);
-        }
-
-        newbuf = sdscatlen(r->buf,buf,len);
-        if (newbuf == NULL) {
-            __redisReaderSetErrorOOM(r);
-            return REDIS_ERR;
-        }
-
-        r->buf = newbuf;
-        r->len = sdslen(r->buf);
-    }
-
-    return REDIS_OK;
-}
-
-int redisReaderGetReply(redisReader *r, void **reply) {
-    /* Default target pointer to NULL. */
-    if (reply != NULL)
-        *reply = NULL;
-
-    /* Return early when this reader is in an erroneous state. */
-    if (r->err)
-        return REDIS_ERR;
-
-    /* When the buffer is empty, there will never be a reply. */
-    if (r->len == 0)
-        return REDIS_OK;
-
-    /* Set first item to process when the stack is empty. */
-    if (r->ridx == -1) {
-        r->rstack[0].type = -1;
-        r->rstack[0].elements = -1;
-        r->rstack[0].idx = -1;
-        r->rstack[0].obj = NULL;
-        r->rstack[0].parent = NULL;
-        r->rstack[0].privdata = r->privdata;
-        r->ridx = 0;
-    }
-
-    /* Process items in reply. */
-    while (r->ridx >= 0)
-        if (processItem(r) != REDIS_OK)
-            break;
-
-    /* Return ASAP when an error occurred. */
-    if (r->err)
-        return REDIS_ERR;
-
-    /* Discard part of the buffer when we've consumed at least 1k, to avoid
-     * doing unnecessary calls to memmove() in sds.c. */
-    if (r->pos >= 1024) {
-        sdsrange(r->buf,r->pos,-1);
-        r->pos = 0;
-        r->len = sdslen(r->buf);
-    }
-
-    /* Emit a reply when there is one. */
-    if (r->ridx == -1) {
-        if (reply != NULL)
-            *reply = r->reply;
-        r->reply = NULL;
-    }
-    return REDIS_OK;
-}
diff --git a/third-party/hiredis/read.h b/third-party/hiredis/read.h
deleted file mode 100644 (file)
index 635a872..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   * Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *   * 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.
- *   * Neither the name of Redis nor the names of its contributors may be used
- *     to endorse or promote products derived from this software without
- *     specific prior written permission.
- *
- * THIS 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 OWNER 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.
- */
-
-
-#ifndef __HIREDIS_READ_H
-#define __HIREDIS_READ_H
-#include <stdio.h> /* for size_t */
-
-#define REDIS_ERR -1
-#define REDIS_OK 0
-
-/* When an error occurs, the err flag in a context is set to hold the type of
- * error that occured. REDIS_ERR_IO means there was an I/O error and you
- * should use the "errno" variable to find out what is wrong.
- * For other values, the "errstr" field will hold a description. */
-#define REDIS_ERR_IO 1 /* Error in read or write */
-#define REDIS_ERR_EOF 3 /* End of file */
-#define REDIS_ERR_PROTOCOL 4 /* Protocol error */
-#define REDIS_ERR_OOM 5 /* Out of memory */
-#define REDIS_ERR_OTHER 2 /* Everything else... */
-
-#define REDIS_REPLY_STRING 1
-#define REDIS_REPLY_ARRAY 2
-#define REDIS_REPLY_INTEGER 3
-#define REDIS_REPLY_NIL 4
-#define REDIS_REPLY_STATUS 5
-#define REDIS_REPLY_ERROR 6
-
-#define REDIS_READER_MAX_BUF (1024*16)  /* Default max unused reader buffer. */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct redisReadTask {
-    int type;
-    int elements; /* number of elements in multibulk container */
-    int idx; /* index in parent (array) object */
-    void *obj; /* holds user-generated value for a read task */
-    struct redisReadTask *parent; /* parent task */
-    void *privdata; /* user-settable arbitrary field */
-} redisReadTask;
-
-typedef struct redisReplyObjectFunctions {
-    void *(*createString)(const redisReadTask*, char*, size_t);
-    void *(*createArray)(const redisReadTask*, int);
-    void *(*createInteger)(const redisReadTask*, long long);
-    void *(*createNil)(const redisReadTask*);
-    void (*freeObject)(void*);
-} redisReplyObjectFunctions;
-
-typedef struct redisReader {
-    int err; /* Error flags, 0 when there is no error */
-    char errstr[128]; /* String representation of error when applicable */
-
-    char *buf; /* Read buffer */
-    size_t pos; /* Buffer cursor */
-    size_t len; /* Buffer length */
-    size_t maxbuf; /* Max length of unused buffer */
-
-    redisReadTask rstack[9];
-    int ridx; /* Index of current read task */
-    void *reply; /* Temporary reply pointer */
-
-    redisReplyObjectFunctions *fn;
-    void *privdata;
-} redisReader;
-
-/* Public API for the protocol parser. */
-redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn);
-void redisReaderFree(redisReader *r);
-int redisReaderFeed(redisReader *r, const char *buf, size_t len);
-int redisReaderGetReply(redisReader *r, void **reply);
-
-/* Backwards compatibility, can be removed on big version bump. */
-#define redisReplyReaderCreate redisReaderCreate
-#define redisReplyReaderFree redisReaderFree
-#define redisReplyReaderFeed redisReaderFeed
-#define redisReplyReaderGetReply redisReaderGetReply
-#define redisReplyReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p))
-#define redisReplyReaderGetObject(_r) (((redisReader*)(_r))->reply)
-#define redisReplyReaderGetError(_r) (((redisReader*)(_r))->errstr)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/third-party/hiredis/sds.c b/third-party/hiredis/sds.c
deleted file mode 100644 (file)
index 5d55b77..0000000
+++ /dev/null
@@ -1,1095 +0,0 @@
-/* SDS (Simple Dynamic Strings), A C dynamic strings library.
- *
- * Copyright (c) 2006-2014, Salvatore Sanfilippo <antirez at gmail dot com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   * Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *   * 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.
- *   * Neither the name of Redis nor the names of its contributors may be used
- *     to endorse or promote products derived from this software without
- *     specific prior written permission.
- *
- * THIS 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 OWNER 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
-
-#include "sds.h"
-
-/* Create a new sds string with the content specified by the 'init' pointer
- * and 'initlen'.
- * If NULL is used for 'init' the string is initialized with zero bytes.
- *
- * The string is always null-termined (all the sds strings are, always) so
- * even if you create an sds string with:
- *
- * mystring = sdsnewlen("abc",3");
- *
- * You can print the string with printf() as there is an implicit \0 at the
- * end of the string. However the string is binary safe and can contain
- * \0 characters in the middle, as the length is stored in the sds header. */
-sds sdsnewlen(const void *init, size_t initlen) {
-    struct sdshdr *sh;
-
-    if (init) {
-        sh = malloc(sizeof *sh+initlen+1);
-    } else {
-        sh = calloc(sizeof *sh+initlen+1,1);
-    }
-    if (sh == NULL) return NULL;
-    sh->len = initlen;
-    sh->free = 0;
-    if (initlen && init)
-        memcpy(sh->buf, init, initlen);
-    sh->buf[initlen] = '\0';
-    return (char*)sh->buf;
-}
-
-/* Create an empty (zero length) sds string. Even in this case the string
- * always has an implicit null term. */
-sds sdsempty(void) {
-    return sdsnewlen("",0);
-}
-
-/* Create a new sds string starting from a null termined C string. */
-sds sdsnew(const char *init) {
-    size_t initlen = (init == NULL) ? 0 : strlen(init);
-    return sdsnewlen(init, initlen);
-}
-
-/* Duplicate an sds string. */
-sds sdsdup(const sds s) {
-    return sdsnewlen(s, sdslen(s));
-}
-
-/* Free an sds string. No operation is performed if 's' is NULL. */
-void sdsfree(sds s) {
-    if (s == NULL) return;
-    free(s-sizeof(struct sdshdr));
-}
-
-/* Set the sds string length to the length as obtained with strlen(), so
- * considering as content only up to the first null term character.
- *
- * This function is useful when the sds string is hacked manually in some
- * way, like in the following example:
- *
- * s = sdsnew("foobar");
- * s[2] = '\0';
- * sdsupdatelen(s);
- * printf("%d\n", sdslen(s));
- *
- * The output will be "2", but if we comment out the call to sdsupdatelen()
- * the output will be "6" as the string was modified but the logical length
- * remains 6 bytes. */
-void sdsupdatelen(sds s) {
-    struct sdshdr *sh = (void*) (s-sizeof *sh);
-    int reallen = strlen(s);
-    sh->free += (sh->len-reallen);
-    sh->len = reallen;
-}
-
-/* Modify an sds string on-place to make it empty (zero length).
- * However all the existing buffer is not discarded but set as free space
- * so that next append operations will not require allocations up to the
- * number of bytes previously available. */
-void sdsclear(sds s) {
-    struct sdshdr *sh = (void*) (s-sizeof *sh);
-    sh->free += sh->len;
-    sh->len = 0;
-    sh->buf[0] = '\0';
-}
-
-/* Enlarge the free space at the end of the sds string so that the caller
- * is sure that after calling this function can overwrite up to addlen
- * bytes after the end of the string, plus one more byte for nul term.
- *
- * Note: this does not change the *length* of the sds string as returned
- * by sdslen(), but only the free buffer space we have. */
-sds sdsMakeRoomFor(sds s, size_t addlen) {
-    struct sdshdr *sh, *newsh;
-    size_t free = sdsavail(s);
-    size_t len, newlen;
-
-    if (free >= addlen) return s;
-    len = sdslen(s);
-    sh = (void*) (s-sizeof *sh);
-    newlen = (len+addlen);
-    if (newlen < SDS_MAX_PREALLOC)
-        newlen *= 2;
-    else
-        newlen += SDS_MAX_PREALLOC;
-    newsh = realloc(sh, sizeof *newsh+newlen+1);
-    if (newsh == NULL) return NULL;
-
-    newsh->free = newlen - len;
-    return newsh->buf;
-}
-
-/* Reallocate the sds string so that it has no free space at the end. The
- * contained string remains not altered, but next concatenation operations
- * will require a reallocation.
- *
- * After the call, the passed sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call. */
-sds sdsRemoveFreeSpace(sds s) {
-    struct sdshdr *sh;
-
-    sh = (void*) (s-sizeof *sh);
-    sh = realloc(sh, sizeof *sh+sh->len+1);
-    sh->free = 0;
-    return sh->buf;
-}
-
-/* Return the total size of the allocation of the specifed sds string,
- * including:
- * 1) The sds header before the pointer.
- * 2) The string.
- * 3) The free buffer at the end if any.
- * 4) The implicit null term.
- */
-size_t sdsAllocSize(sds s) {
-    struct sdshdr *sh = (void*) (s-sizeof *sh);
-
-    return sizeof(*sh)+sh->len+sh->free+1;
-}
-
-/* Increment the sds length and decrements the left free space at the
- * end of the string according to 'incr'. Also set the null term
- * in the new end of the string.
- *
- * This function is used in order to fix the string length after the
- * user calls sdsMakeRoomFor(), writes something after the end of
- * the current string, and finally needs to set the new length.
- *
- * Note: it is possible to use a negative increment in order to
- * right-trim the string.
- *
- * Usage example:
- *
- * Using sdsIncrLen() and sdsMakeRoomFor() it is possible to mount the
- * following schema, to cat bytes coming from the kernel to the end of an
- * sds string without copying into an intermediate buffer:
- *
- * oldlen = sdslen(s);
- * s = sdsMakeRoomFor(s, BUFFER_SIZE);
- * nread = read(fd, s+oldlen, BUFFER_SIZE);
- * ... check for nread <= 0 and handle it ...
- * sdsIncrLen(s, nread);
- */
-void sdsIncrLen(sds s, int incr) {
-    struct sdshdr *sh = (void*) (s-sizeof *sh);
-
-    assert(sh->free >= incr);
-    sh->len += incr;
-    sh->free -= incr;
-    assert(sh->free >= 0);
-    s[sh->len] = '\0';
-}
-
-/* Grow the sds to have the specified length. Bytes that were not part of
- * the original length of the sds will be set to zero.
- *
- * if the specified length is smaller than the current length, no operation
- * is performed. */
-sds sdsgrowzero(sds s, size_t len) {
-    struct sdshdr *sh = (void*) (s-sizeof *sh);
-    size_t totlen, curlen = sh->len;
-
-    if (len <= curlen) return s;
-    s = sdsMakeRoomFor(s,len-curlen);
-    if (s == NULL) return NULL;
-
-    /* Make sure added region doesn't contain garbage */
-    sh = (void*)(s-sizeof *sh);
-    memset(s+curlen,0,(len-curlen+1)); /* also set trailing \0 byte */
-    totlen = sh->len+sh->free;
-    sh->len = len;
-    sh->free = totlen-sh->len;
-    return s;
-}
-
-/* Append the specified binary-safe string pointed by 't' of 'len' bytes to the
- * end of the specified sds string 's'.
- *
- * After the call, the passed sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call. */
-sds sdscatlen(sds s, const void *t, size_t len) {
-    struct sdshdr *sh;
-    size_t curlen = sdslen(s);
-
-    s = sdsMakeRoomFor(s,len);
-    if (s == NULL) return NULL;
-    sh = (void*) (s-sizeof *sh);
-    memcpy(s+curlen, t, len);
-    sh->len = curlen+len;
-    sh->free = sh->free-len;
-    s[curlen+len] = '\0';
-    return s;
-}
-
-/* Append the specified null termianted C string to the sds string 's'.
- *
- * After the call, the passed sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call. */
-sds sdscat(sds s, const char *t) {
-    return sdscatlen(s, t, strlen(t));
-}
-
-/* Append the specified sds 't' to the existing sds 's'.
- *
- * After the call, the modified sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call. */
-sds sdscatsds(sds s, const sds t) {
-    return sdscatlen(s, t, sdslen(t));
-}
-
-/* Destructively modify the sds string 's' to hold the specified binary
- * safe string pointed by 't' of length 'len' bytes. */
-sds sdscpylen(sds s, const char *t, size_t len) {
-    struct sdshdr *sh = (void*) (s-sizeof *sh);
-    size_t totlen = sh->free+sh->len;
-
-    if (totlen < len) {
-        s = sdsMakeRoomFor(s,len-sh->len);
-        if (s == NULL) return NULL;
-        sh = (void*) (s-sizeof *sh);
-        totlen = sh->free+sh->len;
-    }
-    memcpy(s, t, len);
-    s[len] = '\0';
-    sh->len = len;
-    sh->free = totlen-len;
-    return s;
-}
-
-/* Like sdscpylen() but 't' must be a null-termined string so that the length
- * of the string is obtained with strlen(). */
-sds sdscpy(sds s, const char *t) {
-    return sdscpylen(s, t, strlen(t));
-}
-
-/* Helper for sdscatlonglong() doing the actual number -> string
- * conversion. 's' must point to a string with room for at least
- * SDS_LLSTR_SIZE bytes.
- *
- * The function returns the lenght of the null-terminated string
- * representation stored at 's'. */
-#define SDS_LLSTR_SIZE 21
-int sdsll2str(char *s, long long value) {
-    char *p, aux;
-    unsigned long long v;
-    size_t l;
-
-    /* Generate the string representation, this method produces
-     * an reversed string. */
-    v = (value < 0) ? -value : value;
-    p = s;
-    do {
-        *p++ = '0'+(v%10);
-        v /= 10;
-    } while(v);
-    if (value < 0) *p++ = '-';
-
-    /* Compute length and add null term. */
-    l = p-s;
-    *p = '\0';
-
-    /* Reverse the string. */
-    p--;
-    while(s < p) {
-        aux = *s;
-        *s = *p;
-        *p = aux;
-        s++;
-        p--;
-    }
-    return l;
-}
-
-/* Identical sdsll2str(), but for unsigned long long type. */
-int sdsull2str(char *s, unsigned long long v) {
-    char *p, aux;
-    size_t l;
-
-    /* Generate the string representation, this method produces
-     * an reversed string. */
-    p = s;
-    do {
-        *p++ = '0'+(v%10);
-        v /= 10;
-    } while(v);
-
-    /* Compute length and add null term. */
-    l = p-s;
-    *p = '\0';
-
-    /* Reverse the string. */
-    p--;
-    while(s < p) {
-        aux = *s;
-        *s = *p;
-        *p = aux;
-        s++;
-        p--;
-    }
-    return l;
-}
-
-/* Like sdscatpritf() but gets va_list instead of being variadic. */
-sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
-    va_list cpy;
-    char *buf, *t;
-    size_t buflen = 16;
-
-    while(1) {
-        buf = malloc(buflen);
-        if (buf == NULL) return NULL;
-        buf[buflen-2] = '\0';
-        va_copy(cpy,ap);
-        vsnprintf(buf, buflen, fmt, cpy);
-        if (buf[buflen-2] != '\0') {
-            free(buf);
-            buflen *= 2;
-            continue;
-        }
-        break;
-    }
-    t = sdscat(s, buf);
-    free(buf);
-    return t;
-}
-
-/* Append to the sds string 's' a string obtained using printf-alike format
- * specifier.
- *
- * After the call, the modified sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call.
- *
- * Example:
- *
- * s = sdsnew("Sum is: ");
- * s = sdscatprintf(s,"%d+%d = %d",a,b,a+b);
- *
- * Often you need to create a string from scratch with the printf-alike
- * format. When this is the need, just use sdsempty() as the target string:
- *
- * s = sdscatprintf(sdsempty(), "... your format ...", args);
- */
-sds sdscatprintf(sds s, const char *fmt, ...) {
-    va_list ap;
-    char *t;
-    va_start(ap, fmt);
-    t = sdscatvprintf(s,fmt,ap);
-    va_end(ap);
-    return t;
-}
-
-/* This function is similar to sdscatprintf, but much faster as it does
- * not rely on sprintf() family functions implemented by the libc that
- * are often very slow. Moreover directly handling the sds string as
- * new data is concatenated provides a performance improvement.
- *
- * However this function only handles an incompatible subset of printf-alike
- * format specifiers:
- *
- * %s - C String
- * %S - SDS string
- * %i - signed int
- * %I - 64 bit signed integer (long long, int64_t)
- * %u - unsigned int
- * %U - 64 bit unsigned integer (unsigned long long, uint64_t)
- * %T - A size_t variable.
- * %% - Verbatim "%" character.
- */
-sds sdscatfmt(sds s, char const *fmt, ...) {
-    struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
-    size_t initlen = sdslen(s);
-    const char *f = fmt;
-    int i;
-    va_list ap;
-
-    va_start(ap,fmt);
-    f = fmt;    /* Next format specifier byte to process. */
-    i = initlen; /* Position of the next byte to write to dest str. */
-    while(*f) {
-        char next, *str;
-        int l;
-        long long num;
-        unsigned long long unum;
-
-        /* Make sure there is always space for at least 1 char. */
-        if (sh->free == 0) {
-            s = sdsMakeRoomFor(s,1);
-            sh = (void*) (s-(sizeof(struct sdshdr)));
-        }
-
-        switch(*f) {
-        case '%':
-            next = *(f+1);
-            f++;
-            switch(next) {
-            case 's':
-            case 'S':
-                str = va_arg(ap,char*);
-                l = (next == 's') ? strlen(str) : sdslen(str);
-                if (sh->free < l) {
-                    s = sdsMakeRoomFor(s,l);
-                    sh = (void*) (s-(sizeof(struct sdshdr)));
-                }
-                memcpy(s+i,str,l);
-                sh->len += l;
-                sh->free -= l;
-                i += l;
-                break;
-            case 'i':
-            case 'I':
-                if (next == 'i')
-                    num = va_arg(ap,int);
-                else
-                    num = va_arg(ap,long long);
-                {
-                    char buf[SDS_LLSTR_SIZE];
-                    l = sdsll2str(buf,num);
-                    if (sh->free < l) {
-                        s = sdsMakeRoomFor(s,l);
-                        sh = (void*) (s-(sizeof(struct sdshdr)));
-                    }
-                    memcpy(s+i,buf,l);
-                    sh->len += l;
-                    sh->free -= l;
-                    i += l;
-                }
-                break;
-            case 'u':
-            case 'U':
-            case 'T':
-                if (next == 'u')
-                    unum = va_arg(ap,unsigned int);
-                else if(next == 'U')
-                    unum = va_arg(ap,unsigned long long);
-                else
-                    unum = (unsigned long long)va_arg(ap,size_t);
-                {
-                    char buf[SDS_LLSTR_SIZE];
-                    l = sdsull2str(buf,unum);
-                    if (sh->free < l) {
-                        s = sdsMakeRoomFor(s,l);
-                        sh = (void*) (s-(sizeof(struct sdshdr)));
-                    }
-                    memcpy(s+i,buf,l);
-                    sh->len += l;
-                    sh->free -= l;
-                    i += l;
-                }
-                break;
-            default: /* Handle %% and generally %<unknown>. */
-                s[i++] = next;
-                sh->len += 1;
-                sh->free -= 1;
-                break;
-            }
-            break;
-        default:
-            s[i++] = *f;
-            sh->len += 1;
-            sh->free -= 1;
-            break;
-        }
-        f++;
-    }
-    va_end(ap);
-
-    /* Add null-term */
-    s[i] = '\0';
-    return s;
-}
-
-
-/* Remove the part of the string from left and from right composed just of
- * contiguous characters found in 'cset', that is a null terminted C string.
- *
- * After the call, the modified sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call.
- *
- * Example:
- *
- * s = sdsnew("AA...AA.a.aa.aHelloWorld     :::");
- * s = sdstrim(s,"A. :");
- * printf("%s\n", s);
- *
- * Output will be just "Hello World".
- */
-void sdstrim(sds s, const char *cset) {
-    struct sdshdr *sh = (void*) (s-sizeof *sh);
-    char *start, *end, *sp, *ep;
-    size_t len;
-
-    sp = start = s;
-    ep = end = s+sdslen(s)-1;
-    while(sp <= end && strchr(cset, *sp)) sp++;
-    while(ep > start && strchr(cset, *ep)) ep--;
-    len = (sp > ep) ? 0 : ((ep-sp)+1);
-    if (sh->buf != sp) memmove(sh->buf, sp, len);
-    sh->buf[len] = '\0';
-    sh->free = sh->free+(sh->len-len);
-    sh->len = len;
-}
-
-/* Turn the string into a smaller (or equal) string containing only the
- * substring specified by the 'start' and 'end' indexes.
- *
- * start and end can be negative, where -1 means the last character of the
- * string, -2 the penultimate character, and so forth.
- *
- * The interval is inclusive, so the start and end characters will be part
- * of the resulting string.
- *
- * The string is modified in-place.
- *
- * Example:
- *
- * s = sdsnew("Hello World");
- * sdsrange(s,1,-1); => "ello World"
- */
-void sdsrange(sds s, int start, int end) {
-    struct sdshdr *sh = (void*) (s-sizeof *sh);
-    size_t newlen, len = sdslen(s);
-
-    if (len == 0) return;
-    if (start < 0) {
-        start = len+start;
-        if (start < 0) start = 0;
-    }
-    if (end < 0) {
-        end = len+end;
-        if (end < 0) end = 0;
-    }
-    newlen = (start > end) ? 0 : (end-start)+1;
-    if (newlen != 0) {
-        if (start >= (signed)len) {
-            newlen = 0;
-        } else if (end >= (signed)len) {
-            end = len-1;
-            newlen = (start > end) ? 0 : (end-start)+1;
-        }
-    } else {
-        start = 0;
-    }
-    if (start && newlen) memmove(sh->buf, sh->buf+start, newlen);
-    sh->buf[newlen] = 0;
-    sh->free = sh->free+(sh->len-newlen);
-    sh->len = newlen;
-}
-
-/* Apply tolower() to every character of the sds string 's'. */
-void sdstolower(sds s) {
-    int len = sdslen(s), j;
-
-    for (j = 0; j < len; j++) s[j] = tolower(s[j]);
-}
-
-/* Apply toupper() to every character of the sds string 's'. */
-void sdstoupper(sds s) {
-    int len = sdslen(s), j;
-
-    for (j = 0; j < len; j++) s[j] = toupper(s[j]);
-}
-
-/* Compare two sds strings s1 and s2 with memcmp().
- *
- * Return value:
- *
- *     1 if s1 > s2.
- *    -1 if s1 < s2.
- *     0 if s1 and s2 are exactly the same binary string.
- *
- * If two strings share exactly the same prefix, but one of the two has
- * additional characters, the longer string is considered to be greater than
- * the smaller one. */
-int sdscmp(const sds s1, const sds s2) {
-    size_t l1, l2, minlen;
-    int cmp;
-
-    l1 = sdslen(s1);
-    l2 = sdslen(s2);
-    minlen = (l1 < l2) ? l1 : l2;
-    cmp = memcmp(s1,s2,minlen);
-    if (cmp == 0) return l1-l2;
-    return cmp;
-}
-
-/* Split 's' with separator in 'sep'. An array
- * of sds strings is returned. *count will be set
- * by reference to the number of tokens returned.
- *
- * On out of memory, zero length string, zero length
- * separator, NULL is returned.
- *
- * Note that 'sep' is able to split a string using
- * a multi-character separator. For example
- * sdssplit("foo_-_bar","_-_"); will return two
- * elements "foo" and "bar".
- *
- * This version of the function is binary-safe but
- * requires length arguments. sdssplit() is just the
- * same function but for zero-terminated strings.
- */
-sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count) {
-    int elements = 0, slots = 5, start = 0, j;
-    sds *tokens;
-
-    if (seplen < 1 || len < 0) return NULL;
-
-    tokens = malloc(sizeof(sds)*slots);
-    if (tokens == NULL) return NULL;
-
-    if (len == 0) {
-        *count = 0;
-        return tokens;
-    }
-    for (j = 0; j < (len-(seplen-1)); j++) {
-        /* make sure there is room for the next element and the final one */
-        if (slots < elements+2) {
-            sds *newtokens;
-
-            slots *= 2;
-            newtokens = realloc(tokens,sizeof(sds)*slots);
-            if (newtokens == NULL) goto cleanup;
-            tokens = newtokens;
-        }
-        /* search the separator */
-        if ((seplen == 1 && *(s+j) == sep[0]) || (memcmp(s+j,sep,seplen) == 0)) {
-            tokens[elements] = sdsnewlen(s+start,j-start);
-            if (tokens[elements] == NULL) goto cleanup;
-            elements++;
-            start = j+seplen;
-            j = j+seplen-1; /* skip the separator */
-        }
-    }
-    /* Add the final element. We are sure there is room in the tokens array. */
-    tokens[elements] = sdsnewlen(s+start,len-start);
-    if (tokens[elements] == NULL) goto cleanup;
-    elements++;
-    *count = elements;
-    return tokens;
-
-cleanup:
-    {
-        int i;
-        for (i = 0; i < elements; i++) sdsfree(tokens[i]);
-        free(tokens);
-        *count = 0;
-        return NULL;
-    }
-}
-
-/* Free the result returned by sdssplitlen(), or do nothing if 'tokens' is NULL. */
-void sdsfreesplitres(sds *tokens, int count) {
-    if (!tokens) return;
-    while(count--)
-        sdsfree(tokens[count]);
-    free(tokens);
-}
-
-/* Create an sds string from a long long value. It is much faster than:
- *
- * sdscatprintf(sdsempty(),"%lld\n", value);
- */
-sds sdsfromlonglong(long long value) {
-    char buf[32], *p;
-    unsigned long long v;
-
-    v = (value < 0) ? -value : value;
-    p = buf+31; /* point to the last character */
-    do {
-        *p-- = '0'+(v%10);
-        v /= 10;
-    } while(v);
-    if (value < 0) *p-- = '-';
-    p++;
-    return sdsnewlen(p,32-(p-buf));
-}
-
-/* Append to the sds string "s" an escaped string representation where
- * all the non-printable characters (tested with isprint()) are turned into
- * escapes in the form "\n\r\a...." or "\x<hex-number>".
- *
- * After the call, the modified sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call. */
-sds sdscatrepr(sds s, const char *p, size_t len) {
-    s = sdscatlen(s,"\"",1);
-    while(len--) {
-        switch(*p) {
-        case '\\':
-        case '"':
-            s = sdscatprintf(s,"\\%c",*p);
-            break;
-        case '\n': s = sdscatlen(s,"\\n",2); break;
-        case '\r': s = sdscatlen(s,"\\r",2); break;
-        case '\t': s = sdscatlen(s,"\\t",2); break;
-        case '\a': s = sdscatlen(s,"\\a",2); break;
-        case '\b': s = sdscatlen(s,"\\b",2); break;
-        default:
-            if (isprint(*p))
-                s = sdscatprintf(s,"%c",*p);
-            else
-                s = sdscatprintf(s,"\\x%02x",(unsigned char)*p);
-            break;
-        }
-        p++;
-    }
-    return sdscatlen(s,"\"",1);
-}
-
-/* Helper function for sdssplitargs() that returns non zero if 'c'
- * is a valid hex digit. */
-int is_hex_digit(char c) {
-    return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
-           (c >= 'A' && c <= 'F');
-}
-
-/* Helper function for sdssplitargs() that converts a hex digit into an
- * integer from 0 to 15 */
-int hex_digit_to_int(char c) {
-    switch(c) {
-    case '0': return 0;
-    case '1': return 1;
-    case '2': return 2;
-    case '3': return 3;
-    case '4': return 4;
-    case '5': return 5;
-    case '6': return 6;
-    case '7': return 7;
-    case '8': return 8;
-    case '9': return 9;
-    case 'a': case 'A': return 10;
-    case 'b': case 'B': return 11;
-    case 'c': case 'C': return 12;
-    case 'd': case 'D': return 13;
-    case 'e': case 'E': return 14;
-    case 'f': case 'F': return 15;
-    default: return 0;
-    }
-}
-
-/* Split a line into arguments, where every argument can be in the
- * following programming-language REPL-alike form:
- *
- * foo bar "newline are supported\n" and "\xff\x00otherstuff"
- *
- * The number of arguments is stored into *argc, and an array
- * of sds is returned.
- *
- * The caller should free the resulting array of sds strings with
- * sdsfreesplitres().
- *
- * Note that sdscatrepr() is able to convert back a string into
- * a quoted string in the same format sdssplitargs() is able to parse.
- *
- * The function returns the allocated tokens on success, even when the
- * input string is empty, or NULL if the input contains unbalanced
- * quotes or closed quotes followed by non space characters
- * as in: "foo"bar or "foo'
- */
-sds *sdssplitargs(const char *line, int *argc) {
-    const char *p = line;
-    char *current = NULL;
-    char **vector = NULL;
-
-    *argc = 0;
-    while(1) {
-        /* skip blanks */
-        while(*p && isspace(*p)) p++;
-        if (*p) {
-            /* get a token */
-            int inq=0;  /* set to 1 if we are in "quotes" */
-            int insq=0; /* set to 1 if we are in 'single quotes' */
-            int done=0;
-
-            if (current == NULL) current = sdsempty();
-            while(!done) {
-                if (inq) {
-                    if (*p == '\\' && *(p+1) == 'x' &&
-                                             is_hex_digit(*(p+2)) &&
-                                             is_hex_digit(*(p+3)))
-                    {
-                        unsigned char byte;
-
-                        byte = (hex_digit_to_int(*(p+2))*16)+
-                                hex_digit_to_int(*(p+3));
-                        current = sdscatlen(current,(char*)&byte,1);
-                        p += 3;
-                    } else if (*p == '\\' && *(p+1)) {
-                        char c;
-
-                        p++;
-                        switch(*p) {
-                        case 'n': c = '\n'; break;
-                        case 'r': c = '\r'; break;
-                        case 't': c = '\t'; break;
-                        case 'b': c = '\b'; break;
-                        case 'a': c = '\a'; break;
-                        default: c = *p; break;
-                        }
-                        current = sdscatlen(current,&c,1);
-                    } else if (*p == '"') {
-                        /* closing quote must be followed by a space or
-                         * nothing at all. */
-                        if (*(p+1) && !isspace(*(p+1))) goto err;
-                        done=1;
-                    } else if (!*p) {
-                        /* unterminated quotes */
-                        goto err;
-                    } else {
-                        current = sdscatlen(current,p,1);
-                    }
-                } else if (insq) {
-                    if (*p == '\\' && *(p+1) == '\'') {
-                        p++;
-                        current = sdscatlen(current,"'",1);
-                    } else if (*p == '\'') {
-                        /* closing quote must be followed by a space or
-                         * nothing at all. */
-                        if (*(p+1) && !isspace(*(p+1))) goto err;
-                        done=1;
-                    } else if (!*p) {
-                        /* unterminated quotes */
-                        goto err;
-                    } else {
-                        current = sdscatlen(current,p,1);
-                    }
-                } else {
-                    switch(*p) {
-                    case ' ':
-                    case '\n':
-                    case '\r':
-                    case '\t':
-                    case '\0':
-                        done=1;
-                        break;
-                    case '"':
-                        inq=1;
-                        break;
-                    case '\'':
-                        insq=1;
-                        break;
-                    default:
-                        current = sdscatlen(current,p,1);
-                        break;
-                    }
-                }
-                if (*p) p++;
-            }
-            /* add the token to the vector */
-            vector = realloc(vector,((*argc)+1)*sizeof(char*));
-            vector[*argc] = current;
-            (*argc)++;
-            current = NULL;
-        } else {
-            /* Even on empty input string return something not NULL. */
-            if (vector == NULL) vector = malloc(sizeof(void*));
-            return vector;
-        }
-    }
-
-err:
-    while((*argc)--)
-        sdsfree(vector[*argc]);
-    free(vector);
-    if (current) sdsfree(current);
-    *argc = 0;
-    return NULL;
-}
-
-/* Modify the string substituting all the occurrences of the set of
- * characters specified in the 'from' string to the corresponding character
- * in the 'to' array.
- *
- * For instance: sdsmapchars(mystring, "ho", "01", 2)
- * will have the effect of turning the string "hello" into "0ell1".
- *
- * The function returns the sds string pointer, that is always the same
- * as the input pointer since no resize is needed. */
-sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen) {
-    size_t j, i, l = sdslen(s);
-
-    for (j = 0; j < l; j++) {
-        for (i = 0; i < setlen; i++) {
-            if (s[j] == from[i]) {
-                s[j] = to[i];
-                break;
-            }
-        }
-    }
-    return s;
-}
-
-/* Join an array of C strings using the specified separator (also a C string).
- * Returns the result as an sds string. */
-sds sdsjoin(char **argv, int argc, char *sep, size_t seplen) {
-    sds join = sdsempty();
-    int j;
-
-    for (j = 0; j < argc; j++) {
-        join = sdscat(join, argv[j]);
-        if (j != argc-1) join = sdscatlen(join,sep,seplen);
-    }
-    return join;
-}
-
-/* Like sdsjoin, but joins an array of SDS strings. */
-sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen) {
-    sds join = sdsempty();
-    int j;
-
-    for (j = 0; j < argc; j++) {
-        join = sdscatsds(join, argv[j]);
-        if (j != argc-1) join = sdscatlen(join,sep,seplen);
-    }
-    return join;
-}
-
-#ifdef SDS_TEST_MAIN
-#include <stdio.h>
-#include "testhelp.h"
-
-int main(void) {
-    {
-        struct sdshdr *sh;
-        sds x = sdsnew("foo"), y;
-
-        test_cond("Create a string and obtain the length",
-            sdslen(x) == 3 && memcmp(x,"foo\0",4) == 0)
-
-        sdsfree(x);
-        x = sdsnewlen("foo",2);
-        test_cond("Create a string with specified length",
-            sdslen(x) == 2 && memcmp(x,"fo\0",3) == 0)
-
-        x = sdscat(x,"bar");
-        test_cond("Strings concatenation",
-            sdslen(x) == 5 && memcmp(x,"fobar\0",6) == 0);
-
-        x = sdscpy(x,"a");
-        test_cond("sdscpy() against an originally longer string",
-            sdslen(x) == 1 && memcmp(x,"a\0",2) == 0)
-
-        x = sdscpy(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk");
-        test_cond("sdscpy() against an originally shorter string",
-            sdslen(x) == 33 &&
-            memcmp(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk\0",33) == 0)
-
-        sdsfree(x);
-        x = sdscatprintf(sdsempty(),"%d",123);
-        test_cond("sdscatprintf() seems working in the base case",
-            sdslen(x) == 3 && memcmp(x,"123\0",4) ==0)
-
-        sdsfree(x);
-        x = sdsnew("xxciaoyyy");
-        sdstrim(x,"xy");
-        test_cond("sdstrim() correctly trims characters",
-            sdslen(x) == 4 && memcmp(x,"ciao\0",5) == 0)
-
-        y = sdsdup(x);
-        sdsrange(y,1,1);
-        test_cond("sdsrange(...,1,1)",
-            sdslen(y) == 1 && memcmp(y,"i\0",2) == 0)
-
-        sdsfree(y);
-        y = sdsdup(x);
-        sdsrange(y,1,-1);
-        test_cond("sdsrange(...,1,-1)",
-            sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
-
-        sdsfree(y);
-        y = sdsdup(x);
-        sdsrange(y,-2,-1);
-        test_cond("sdsrange(...,-2,-1)",
-            sdslen(y) == 2 && memcmp(y,"ao\0",3) == 0)
-
-        sdsfree(y);
-        y = sdsdup(x);
-        sdsrange(y,2,1);
-        test_cond("sdsrange(...,2,1)",
-            sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
-
-        sdsfree(y);
-        y = sdsdup(x);
-        sdsrange(y,1,100);
-        test_cond("sdsrange(...,1,100)",
-            sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
-
-        sdsfree(y);
-        y = sdsdup(x);
-        sdsrange(y,100,100);
-        test_cond("sdsrange(...,100,100)",
-            sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
-
-        sdsfree(y);
-        sdsfree(x);
-        x = sdsnew("foo");
-        y = sdsnew("foa");
-        test_cond("sdscmp(foo,foa)", sdscmp(x,y) > 0)
-
-        sdsfree(y);
-        sdsfree(x);
-        x = sdsnew("bar");
-        y = sdsnew("bar");
-        test_cond("sdscmp(bar,bar)", sdscmp(x,y) == 0)
-
-        sdsfree(y);
-        sdsfree(x);
-        x = sdsnew("aar");
-        y = sdsnew("bar");
-        test_cond("sdscmp(bar,bar)", sdscmp(x,y) < 0)
-
-        sdsfree(y);
-        sdsfree(x);
-        x = sdsnewlen("\a\n\0foo\r",7);
-        y = sdscatrepr(sdsempty(),x,sdslen(x));
-        test_cond("sdscatrepr(...data...)",
-            memcmp(y,"\"\\a\\n\\x00foo\\r\"",15) == 0)
-
-        {
-            int oldfree;
-
-            sdsfree(x);
-            x = sdsnew("0");
-            sh = (void*) (x-(sizeof(struct sdshdr)));
-            test_cond("sdsnew() free/len buffers", sh->len == 1 && sh->free == 0);
-            x = sdsMakeRoomFor(x,1);
-            sh = (void*) (x-(sizeof(struct sdshdr)));
-            test_cond("sdsMakeRoomFor()", sh->len == 1 && sh->free > 0);
-            oldfree = sh->free;
-            x[1] = '1';
-            sdsIncrLen(x,1);
-            test_cond("sdsIncrLen() -- content", x[0] == '0' && x[1] == '1');
-            test_cond("sdsIncrLen() -- len", sh->len == 2);
-            test_cond("sdsIncrLen() -- free", sh->free == oldfree-1);
-        }
-    }
-    test_report()
-    return 0;
-}
-#endif
diff --git a/third-party/hiredis/sds.h b/third-party/hiredis/sds.h
deleted file mode 100644 (file)
index 19a2abd..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/* SDS (Simple Dynamic Strings), A C dynamic strings library.
- *
- * Copyright (c) 2006-2014, Salvatore Sanfilippo <antirez at gmail dot com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   * Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *   * 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.
- *   * Neither the name of Redis nor the names of its contributors may be used
- *     to endorse or promote products derived from this software without
- *     specific prior written permission.
- *
- * THIS 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 OWNER 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.
- */
-
-#ifndef __SDS_H
-#define __SDS_H
-
-#define SDS_MAX_PREALLOC (1024*1024)
-
-#include <sys/types.h>
-#include <stdarg.h>
-#ifdef _MSC_VER
-#include "win32.h"
-#endif
-
-typedef char *sds;
-
-struct sdshdr {
-    int len;
-    int free;
-    char buf[];
-};
-
-static inline size_t sdslen(const sds s) {
-    struct sdshdr *sh = (struct sdshdr *)(s-sizeof *sh);
-    return sh->len;
-}
-
-static inline size_t sdsavail(const sds s) {
-    struct sdshdr *sh = (struct sdshdr *)(s-sizeof *sh);
-    return sh->free;
-}
-
-sds sdsnewlen(const void *init, size_t initlen);
-sds sdsnew(const char *init);
-sds sdsempty(void);
-size_t sdslen(const sds s);
-sds sdsdup(const sds s);
-void sdsfree(sds s);
-size_t sdsavail(const sds s);
-sds sdsgrowzero(sds s, size_t len);
-sds sdscatlen(sds s, const void *t, size_t len);
-sds sdscat(sds s, const char *t);
-sds sdscatsds(sds s, const sds t);
-sds sdscpylen(sds s, const char *t, size_t len);
-sds sdscpy(sds s, const char *t);
-
-sds sdscatvprintf(sds s, const char *fmt, va_list ap);
-#ifdef __GNUC__
-sds sdscatprintf(sds s, const char *fmt, ...)
-    __attribute__((format(printf, 2, 3)));
-#else
-sds sdscatprintf(sds s, const char *fmt, ...);
-#endif
-
-sds sdscatfmt(sds s, char const *fmt, ...);
-void sdstrim(sds s, const char *cset);
-void sdsrange(sds s, int start, int end);
-void sdsupdatelen(sds s);
-void sdsclear(sds s);
-int sdscmp(const sds s1, const sds s2);
-sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count);
-void sdsfreesplitres(sds *tokens, int count);
-void sdstolower(sds s);
-void sdstoupper(sds s);
-sds sdsfromlonglong(long long value);
-sds sdscatrepr(sds s, const char *p, size_t len);
-sds *sdssplitargs(const char *line, int *argc);
-sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen);
-sds sdsjoin(char **argv, int argc, char *sep, size_t seplen);
-sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen);
-
-/* Low level functions exposed to the user API */
-sds sdsMakeRoomFor(sds s, size_t addlen);
-void sdsIncrLen(sds s, int incr);
-sds sdsRemoveFreeSpace(sds s);
-size_t sdsAllocSize(sds s);
-
-#endif
diff --git a/third-party/hiredis/test.c b/third-party/hiredis/test.c
deleted file mode 100644 (file)
index d5e8217..0000000
+++ /dev/null
@@ -1,807 +0,0 @@
-#include "fmacros.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <sys/time.h>
-#include <assert.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <limits.h>
-
-#include "hiredis.h"
-#include "net.h"
-
-enum connection_type {
-    CONN_TCP,
-    CONN_UNIX,
-    CONN_FD
-};
-
-struct config {
-    enum connection_type type;
-
-    struct {
-        const char *host;
-        int port;
-        struct timeval timeout;
-    } tcp;
-
-    struct {
-        const char *path;
-    } unix;
-};
-
-/* The following lines make up our testing "framework" :) */
-static int tests = 0, fails = 0;
-#define test(_s) { printf("#%02d ", ++tests); printf(_s); }
-#define test_cond(_c) if(_c) printf("\033[0;32mPASSED\033[0;0m\n"); else {printf("\033[0;31mFAILED\033[0;0m\n"); fails++;}
-
-static long long usec(void) {
-    struct timeval tv;
-    gettimeofday(&tv,NULL);
-    return (((long long)tv.tv_sec)*1000000)+tv.tv_usec;
-}
-
-/* The assert() calls below have side effects, so we need assert()
- * even if we are compiling without asserts (-DNDEBUG). */
-#ifdef NDEBUG
-#undef assert
-#define assert(e) (void)(e)
-#endif
-
-static redisContext *select_database(redisContext *c) {
-    redisReply *reply;
-
-    /* Switch to DB 9 for testing, now that we know we can chat. */
-    reply = redisCommand(c,"SELECT 9");
-    assert(reply != NULL);
-    freeReplyObject(reply);
-
-    /* Make sure the DB is emtpy */
-    reply = redisCommand(c,"DBSIZE");
-    assert(reply != NULL);
-    if (reply->type == REDIS_REPLY_INTEGER && reply->integer == 0) {
-        /* Awesome, DB 9 is empty and we can continue. */
-        freeReplyObject(reply);
-    } else {
-        printf("Database #9 is not empty, test can not continue\n");
-        exit(1);
-    }
-
-    return c;
-}
-
-static int disconnect(redisContext *c, int keep_fd) {
-    redisReply *reply;
-
-    /* Make sure we're on DB 9. */
-    reply = redisCommand(c,"SELECT 9");
-    assert(reply != NULL);
-    freeReplyObject(reply);
-    reply = redisCommand(c,"FLUSHDB");
-    assert(reply != NULL);
-    freeReplyObject(reply);
-
-    /* Free the context as well, but keep the fd if requested. */
-    if (keep_fd)
-        return redisFreeKeepFd(c);
-    redisFree(c);
-    return -1;
-}
-
-static redisContext *connect(struct config config) {
-    redisContext *c = NULL;
-
-    if (config.type == CONN_TCP) {
-        c = redisConnect(config.tcp.host, config.tcp.port);
-    } else if (config.type == CONN_UNIX) {
-        c = redisConnectUnix(config.unix.path);
-    } else if (config.type == CONN_FD) {
-        /* Create a dummy connection just to get an fd to inherit */
-        redisContext *dummy_ctx = redisConnectUnix(config.unix.path);
-        if (dummy_ctx) {
-            int fd = disconnect(dummy_ctx, 1);
-            printf("Connecting to inherited fd %d\n", fd);
-            c = redisConnectFd(fd);
-        }
-    } else {
-        assert(NULL);
-    }
-
-    if (c == NULL) {
-        printf("Connection error: can't allocate redis context\n");
-        exit(1);
-    } else if (c->err) {
-        printf("Connection error: %s\n", c->errstr);
-        redisFree(c);
-        exit(1);
-    }
-
-    return select_database(c);
-}
-
-static void test_format_commands(void) {
-    char *cmd;
-    int len;
-
-    test("Format command without interpolation: ");
-    len = redisFormatCommand(&cmd,"SET foo bar");
-    test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 &&
-        len == 4+4+(3+2)+4+(3+2)+4+(3+2));
-    free(cmd);
-
-    test("Format command with %%s string interpolation: ");
-    len = redisFormatCommand(&cmd,"SET %s %s","foo","bar");
-    test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 &&
-        len == 4+4+(3+2)+4+(3+2)+4+(3+2));
-    free(cmd);
-
-    test("Format command with %%s and an empty string: ");
-    len = redisFormatCommand(&cmd,"SET %s %s","foo","");
-    test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 &&
-        len == 4+4+(3+2)+4+(3+2)+4+(0+2));
-    free(cmd);
-
-    test("Format command with an empty string in between proper interpolations: ");
-    len = redisFormatCommand(&cmd,"SET %s %s","","foo");
-    test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$0\r\n\r\n$3\r\nfoo\r\n",len) == 0 &&
-        len == 4+4+(3+2)+4+(0+2)+4+(3+2));
-    free(cmd);
-
-    test("Format command with %%b string interpolation: ");
-    len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"b\0r",(size_t)3);
-    test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nb\0r\r\n",len) == 0 &&
-        len == 4+4+(3+2)+4+(3+2)+4+(3+2));
-    free(cmd);
-
-    test("Format command with %%b and an empty string: ");
-    len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"",(size_t)0);
-    test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 &&
-        len == 4+4+(3+2)+4+(3+2)+4+(0+2));
-    free(cmd);
-
-    test("Format command with literal %%: ");
-    len = redisFormatCommand(&cmd,"SET %% %%");
-    test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$1\r\n%\r\n$1\r\n%\r\n",len) == 0 &&
-        len == 4+4+(3+2)+4+(1+2)+4+(1+2));
-    free(cmd);
-
-    /* Vararg width depends on the type. These tests make sure that the
-     * width is correctly determined using the format and subsequent varargs
-     * can correctly be interpolated. */
-#define INTEGER_WIDTH_TEST(fmt, type) do {                                                \
-    type value = 123;                                                                     \
-    test("Format command with printf-delegation (" #type "): ");                          \
-    len = redisFormatCommand(&cmd,"key:%08" fmt " str:%s", value, "hello");               \
-    test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:00000123\r\n$9\r\nstr:hello\r\n",len) == 0 && \
-        len == 4+5+(12+2)+4+(9+2));                                                       \
-    free(cmd);                                                                            \
-} while(0)
-
-#define FLOAT_WIDTH_TEST(type) do {                                                       \
-    type value = 123.0;                                                                   \
-    test("Format command with printf-delegation (" #type "): ");                          \
-    len = redisFormatCommand(&cmd,"key:%08.3f str:%s", value, "hello");                   \
-    test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:0123.000\r\n$9\r\nstr:hello\r\n",len) == 0 && \
-        len == 4+5+(12+2)+4+(9+2));                                                       \
-    free(cmd);                                                                            \
-} while(0)
-
-    INTEGER_WIDTH_TEST("d", int);
-    INTEGER_WIDTH_TEST("hhd", char);
-    INTEGER_WIDTH_TEST("hd", short);
-    INTEGER_WIDTH_TEST("ld", long);
-    INTEGER_WIDTH_TEST("lld", long long);
-    INTEGER_WIDTH_TEST("u", unsigned int);
-    INTEGER_WIDTH_TEST("hhu", unsigned char);
-    INTEGER_WIDTH_TEST("hu", unsigned short);
-    INTEGER_WIDTH_TEST("lu", unsigned long);
-    INTEGER_WIDTH_TEST("llu", unsigned long long);
-    FLOAT_WIDTH_TEST(float);
-    FLOAT_WIDTH_TEST(double);
-
-    test("Format command with invalid printf format: ");
-    len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",(size_t)3);
-    test_cond(len == -1);
-
-    const char *argv[3];
-    argv[0] = "SET";
-    argv[1] = "foo\0xxx";
-    argv[2] = "bar";
-    size_t lens[3] = { 3, 7, 3 };
-    int argc = 3;
-
-    test("Format command by passing argc/argv without lengths: ");
-    len = redisFormatCommandArgv(&cmd,argc,argv,NULL);
-    test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 &&
-        len == 4+4+(3+2)+4+(3+2)+4+(3+2));
-    free(cmd);
-
-    test("Format command by passing argc/argv with lengths: ");
-    len = redisFormatCommandArgv(&cmd,argc,argv,lens);
-    test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$7\r\nfoo\0xxx\r\n$3\r\nbar\r\n",len) == 0 &&
-        len == 4+4+(3+2)+4+(7+2)+4+(3+2));
-    free(cmd);
-}
-
-static void test_append_formatted_commands(struct config config) {
-    redisContext *c;
-    redisReply *reply;
-    char *cmd;
-    int len;
-
-    c = connect(config);
-
-    test("Append format command: ");
-
-    len = redisFormatCommand(&cmd, "SET foo bar");
-
-    test_cond(redisAppendFormattedCommand(c, cmd, len) == REDIS_OK);
-
-    assert(redisGetReply(c, (void*)&reply) == REDIS_OK);
-
-    free(cmd);
-    freeReplyObject(reply);
-
-    disconnect(c, 0);
-}
-
-static void test_reply_reader(void) {
-    redisReader *reader;
-    void *reply;
-    int ret;
-    int i;
-
-    test("Error handling in reply parser: ");
-    reader = redisReaderCreate();
-    redisReaderFeed(reader,(char*)"@foo\r\n",6);
-    ret = redisReaderGetReply(reader,NULL);
-    test_cond(ret == REDIS_ERR &&
-              strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0);
-    redisReaderFree(reader);
-
-    /* when the reply already contains multiple items, they must be free'd
-     * on an error. valgrind will bark when this doesn't happen. */
-    test("Memory cleanup in reply parser: ");
-    reader = redisReaderCreate();
-    redisReaderFeed(reader,(char*)"*2\r\n",4);
-    redisReaderFeed(reader,(char*)"$5\r\nhello\r\n",11);
-    redisReaderFeed(reader,(char*)"@foo\r\n",6);
-    ret = redisReaderGetReply(reader,NULL);
-    test_cond(ret == REDIS_ERR &&
-              strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0);
-    redisReaderFree(reader);
-
-    test("Set error on nested multi bulks with depth > 7: ");
-    reader = redisReaderCreate();
-
-    for (i = 0; i < 9; i++) {
-        redisReaderFeed(reader,(char*)"*1\r\n",4);
-    }
-
-    ret = redisReaderGetReply(reader,NULL);
-    test_cond(ret == REDIS_ERR &&
-              strncasecmp(reader->errstr,"No support for",14) == 0);
-    redisReaderFree(reader);
-
-    test("Works with NULL functions for reply: ");
-    reader = redisReaderCreate();
-    reader->fn = NULL;
-    redisReaderFeed(reader,(char*)"+OK\r\n",5);
-    ret = redisReaderGetReply(reader,&reply);
-    test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS);
-    redisReaderFree(reader);
-
-    test("Works when a single newline (\\r\\n) covers two calls to feed: ");
-    reader = redisReaderCreate();
-    reader->fn = NULL;
-    redisReaderFeed(reader,(char*)"+OK\r",4);
-    ret = redisReaderGetReply(reader,&reply);
-    assert(ret == REDIS_OK && reply == NULL);
-    redisReaderFeed(reader,(char*)"\n",1);
-    ret = redisReaderGetReply(reader,&reply);
-    test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS);
-    redisReaderFree(reader);
-
-    test("Don't reset state after protocol error: ");
-    reader = redisReaderCreate();
-    reader->fn = NULL;
-    redisReaderFeed(reader,(char*)"x",1);
-    ret = redisReaderGetReply(reader,&reply);
-    assert(ret == REDIS_ERR);
-    ret = redisReaderGetReply(reader,&reply);
-    test_cond(ret == REDIS_ERR && reply == NULL);
-    redisReaderFree(reader);
-
-    /* Regression test for issue #45 on GitHub. */
-    test("Don't do empty allocation for empty multi bulk: ");
-    reader = redisReaderCreate();
-    redisReaderFeed(reader,(char*)"*0\r\n",4);
-    ret = redisReaderGetReply(reader,&reply);
-    test_cond(ret == REDIS_OK &&
-        ((redisReply*)reply)->type == REDIS_REPLY_ARRAY &&
-        ((redisReply*)reply)->elements == 0);
-    freeReplyObject(reply);
-    redisReaderFree(reader);
-}
-
-static void test_free_null(void) {
-    void *redisContext = NULL;
-    void *reply = NULL;
-
-    test("Don't fail when redisFree is passed a NULL value: ");
-    redisFree(redisContext);
-    test_cond(redisContext == NULL);
-
-    test("Don't fail when freeReplyObject is passed a NULL value: ");
-    freeReplyObject(reply);
-    test_cond(reply == NULL);
-}
-
-static void test_blocking_connection_errors(void) {
-    redisContext *c;
-
-    test("Returns error when host cannot be resolved: ");
-    c = redisConnect((char*)"idontexist.test", 6379);
-    test_cond(c->err == REDIS_ERR_OTHER &&
-        (strcmp(c->errstr,"Name or service not known") == 0 ||
-         strcmp(c->errstr,"Can't resolve: idontexist.test") == 0 ||
-         strcmp(c->errstr,"nodename nor servname provided, or not known") == 0 ||
-         strcmp(c->errstr,"No address associated with hostname") == 0 ||
-         strcmp(c->errstr,"Temporary failure in name resolution") == 0 ||
-         strcmp(c->errstr,"hostname nor servname provided, or not known") == 0 ||
-         strcmp(c->errstr,"no address associated with name") == 0));
-    redisFree(c);
-
-    test("Returns error when the port is not open: ");
-    c = redisConnect((char*)"localhost", 1);
-    test_cond(c->err == REDIS_ERR_IO &&
-        strcmp(c->errstr,"Connection refused") == 0);
-    redisFree(c);
-
-    test("Returns error when the unix socket path doesn't accept connections: ");
-    c = redisConnectUnix((char*)"/tmp/idontexist.sock");
-    test_cond(c->err == REDIS_ERR_IO); /* Don't care about the message... */
-    redisFree(c);
-}
-
-static void test_blocking_connection(struct config config) {
-    redisContext *c;
-    redisReply *reply;
-
-    c = connect(config);
-
-    test("Is able to deliver commands: ");
-    reply = redisCommand(c,"PING");
-    test_cond(reply->type == REDIS_REPLY_STATUS &&
-        strcasecmp(reply->str,"pong") == 0)
-    freeReplyObject(reply);
-
-    test("Is a able to send commands verbatim: ");
-    reply = redisCommand(c,"SET foo bar");
-    test_cond (reply->type == REDIS_REPLY_STATUS &&
-        strcasecmp(reply->str,"ok") == 0)
-    freeReplyObject(reply);
-
-    test("%%s String interpolation works: ");
-    reply = redisCommand(c,"SET %s %s","foo","hello world");
-    freeReplyObject(reply);
-    reply = redisCommand(c,"GET foo");
-    test_cond(reply->type == REDIS_REPLY_STRING &&
-        strcmp(reply->str,"hello world") == 0);
-    freeReplyObject(reply);
-
-    test("%%b String interpolation works: ");
-    reply = redisCommand(c,"SET %b %b","foo",(size_t)3,"hello\x00world",(size_t)11);
-    freeReplyObject(reply);
-    reply = redisCommand(c,"GET foo");
-    test_cond(reply->type == REDIS_REPLY_STRING &&
-        memcmp(reply->str,"hello\x00world",11) == 0)
-
-    test("Binary reply length is correct: ");
-    test_cond(reply->len == 11)
-    freeReplyObject(reply);
-
-    test("Can parse nil replies: ");
-    reply = redisCommand(c,"GET nokey");
-    test_cond(reply->type == REDIS_REPLY_NIL)
-    freeReplyObject(reply);
-
-    /* test 7 */
-    test("Can parse integer replies: ");
-    reply = redisCommand(c,"INCR mycounter");
-    test_cond(reply->type == REDIS_REPLY_INTEGER && reply->integer == 1)
-    freeReplyObject(reply);
-
-    test("Can parse multi bulk replies: ");
-    freeReplyObject(redisCommand(c,"LPUSH mylist foo"));
-    freeReplyObject(redisCommand(c,"LPUSH mylist bar"));
-    reply = redisCommand(c,"LRANGE mylist 0 -1");
-    test_cond(reply->type == REDIS_REPLY_ARRAY &&
-              reply->elements == 2 &&
-              !memcmp(reply->element[0]->str,"bar",3) &&
-              !memcmp(reply->element[1]->str,"foo",3))
-    freeReplyObject(reply);
-
-    /* m/e with multi bulk reply *before* other reply.
-     * specifically test ordering of reply items to parse. */
-    test("Can handle nested multi bulk replies: ");
-    freeReplyObject(redisCommand(c,"MULTI"));
-    freeReplyObject(redisCommand(c,"LRANGE mylist 0 -1"));
-    freeReplyObject(redisCommand(c,"PING"));
-    reply = (redisCommand(c,"EXEC"));
-    test_cond(reply->type == REDIS_REPLY_ARRAY &&
-              reply->elements == 2 &&
-              reply->element[0]->type == REDIS_REPLY_ARRAY &&
-              reply->element[0]->elements == 2 &&
-              !memcmp(reply->element[0]->element[0]->str,"bar",3) &&
-              !memcmp(reply->element[0]->element[1]->str,"foo",3) &&
-              reply->element[1]->type == REDIS_REPLY_STATUS &&
-              strcasecmp(reply->element[1]->str,"pong") == 0);
-    freeReplyObject(reply);
-
-    disconnect(c, 0);
-}
-
-static void test_blocking_connection_timeouts(struct config config) {
-    redisContext *c;
-    redisReply *reply;
-    ssize_t s;
-    const char *cmd = "DEBUG SLEEP 3\r\n";
-    struct timeval tv;
-
-    c = connect(config);
-    test("Successfully completes a command when the timeout is not exceeded: ");
-    reply = redisCommand(c,"SET foo fast");
-    freeReplyObject(reply);
-    tv.tv_sec = 0;
-    tv.tv_usec = 10000;
-    redisSetTimeout(c, tv);
-    reply = redisCommand(c, "GET foo");
-    test_cond(reply != NULL && reply->type == REDIS_REPLY_STRING && memcmp(reply->str, "fast", 4) == 0);
-    freeReplyObject(reply);
-    disconnect(c, 0);
-
-    c = connect(config);
-    test("Does not return a reply when the command times out: ");
-    s = write(c->fd, cmd, strlen(cmd));
-    tv.tv_sec = 0;
-    tv.tv_usec = 10000;
-    redisSetTimeout(c, tv);
-    reply = redisCommand(c, "GET foo");
-    test_cond(s > 0 && reply == NULL && c->err == REDIS_ERR_IO && strcmp(c->errstr, "Resource temporarily unavailable") == 0);
-    freeReplyObject(reply);
-
-    test("Reconnect properly reconnects after a timeout: ");
-    redisReconnect(c);
-    reply = redisCommand(c, "PING");
-    test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0);
-    freeReplyObject(reply);
-
-    test("Reconnect properly uses owned parameters: ");
-    config.tcp.host = "foo";
-    config.unix.path = "foo";
-    redisReconnect(c);
-    reply = redisCommand(c, "PING");
-    test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0);
-    freeReplyObject(reply);
-
-    disconnect(c, 0);
-}
-
-static void test_blocking_io_errors(struct config config) {
-    redisContext *c;
-    redisReply *reply;
-    void *_reply;
-    int major, minor;
-
-    /* Connect to target given by config. */
-    c = connect(config);
-    {
-        /* Find out Redis version to determine the path for the next test */
-        const char *field = "redis_version:";
-        char *p, *eptr;
-
-        reply = redisCommand(c,"INFO");
-        p = strstr(reply->str,field);
-        major = strtol(p+strlen(field),&eptr,10);
-        p = eptr+1; /* char next to the first "." */
-        minor = strtol(p,&eptr,10);
-        freeReplyObject(reply);
-    }
-
-    test("Returns I/O error when the connection is lost: ");
-    reply = redisCommand(c,"QUIT");
-    if (major > 2 || (major == 2 && minor > 0)) {
-        /* > 2.0 returns OK on QUIT and read() should be issued once more
-         * to know the descriptor is at EOF. */
-        test_cond(strcasecmp(reply->str,"OK") == 0 &&
-            redisGetReply(c,&_reply) == REDIS_ERR);
-        freeReplyObject(reply);
-    } else {
-        test_cond(reply == NULL);
-    }
-
-    /* On 2.0, QUIT will cause the connection to be closed immediately and
-     * the read(2) for the reply on QUIT will set the error to EOF.
-     * On >2.0, QUIT will return with OK and another read(2) needed to be
-     * issued to find out the socket was closed by the server. In both
-     * conditions, the error will be set to EOF. */
-    assert(c->err == REDIS_ERR_EOF &&
-        strcmp(c->errstr,"Server closed the connection") == 0);
-    redisFree(c);
-
-    c = connect(config);
-    test("Returns I/O error on socket timeout: ");
-    struct timeval tv = { 0, 1000 };
-    assert(redisSetTimeout(c,tv) == REDIS_OK);
-    test_cond(redisGetReply(c,&_reply) == REDIS_ERR &&
-        c->err == REDIS_ERR_IO && errno == EAGAIN);
-    redisFree(c);
-}
-
-static void test_invalid_timeout_errors(struct config config) {
-    redisContext *c;
-
-    test("Set error when an invalid timeout usec value is given to redisConnectWithTimeout: ");
-
-    config.tcp.timeout.tv_sec = 0;
-    config.tcp.timeout.tv_usec = 10000001;
-
-    c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout);
-
-    test_cond(c->err == REDIS_ERR_IO);
-    redisFree(c);
-
-    test("Set error when an invalid timeout sec value is given to redisConnectWithTimeout: ");
-
-    config.tcp.timeout.tv_sec = (((LONG_MAX) - 999) / 1000) + 1;
-    config.tcp.timeout.tv_usec = 0;
-
-    c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout);
-
-    test_cond(c->err == REDIS_ERR_IO);
-    redisFree(c);
-}
-
-static void test_throughput(struct config config) {
-    redisContext *c = connect(config);
-    redisReply **replies;
-    int i, num;
-    long long t1, t2;
-
-    test("Throughput:\n");
-    for (i = 0; i < 500; i++)
-        freeReplyObject(redisCommand(c,"LPUSH mylist foo"));
-
-    num = 1000;
-    replies = malloc(sizeof(redisReply*)*num);
-    t1 = usec();
-    for (i = 0; i < num; i++) {
-        replies[i] = redisCommand(c,"PING");
-        assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_STATUS);
-    }
-    t2 = usec();
-    for (i = 0; i < num; i++) freeReplyObject(replies[i]);
-    free(replies);
-    printf("\t(%dx PING: %.3fs)\n", num, (t2-t1)/1000000.0);
-
-    replies = malloc(sizeof(redisReply*)*num);
-    t1 = usec();
-    for (i = 0; i < num; i++) {
-        replies[i] = redisCommand(c,"LRANGE mylist 0 499");
-        assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_ARRAY);
-        assert(replies[i] != NULL && replies[i]->elements == 500);
-    }
-    t2 = usec();
-    for (i = 0; i < num; i++) freeReplyObject(replies[i]);
-    free(replies);
-    printf("\t(%dx LRANGE with 500 elements: %.3fs)\n", num, (t2-t1)/1000000.0);
-
-    num = 10000;
-    replies = malloc(sizeof(redisReply*)*num);
-    for (i = 0; i < num; i++)
-        redisAppendCommand(c,"PING");
-    t1 = usec();
-    for (i = 0; i < num; i++) {
-        assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK);
-        assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_STATUS);
-    }
-    t2 = usec();
-    for (i = 0; i < num; i++) freeReplyObject(replies[i]);
-    free(replies);
-    printf("\t(%dx PING (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0);
-
-    replies = malloc(sizeof(redisReply*)*num);
-    for (i = 0; i < num; i++)
-        redisAppendCommand(c,"LRANGE mylist 0 499");
-    t1 = usec();
-    for (i = 0; i < num; i++) {
-        assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK);
-        assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_ARRAY);
-        assert(replies[i] != NULL && replies[i]->elements == 500);
-    }
-    t2 = usec();
-    for (i = 0; i < num; i++) freeReplyObject(replies[i]);
-    free(replies);
-    printf("\t(%dx LRANGE with 500 elements (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0);
-
-    disconnect(c, 0);
-}
-
-// static long __test_callback_flags = 0;
-// static void __test_callback(redisContext *c, void *privdata) {
-//     ((void)c);
-//     /* Shift to detect execution order */
-//     __test_callback_flags <<= 8;
-//     __test_callback_flags |= (long)privdata;
-// }
-//
-// static void __test_reply_callback(redisContext *c, redisReply *reply, void *privdata) {
-//     ((void)c);
-//     /* Shift to detect execution order */
-//     __test_callback_flags <<= 8;
-//     __test_callback_flags |= (long)privdata;
-//     if (reply) freeReplyObject(reply);
-// }
-//
-// static redisContext *__connect_nonblock() {
-//     /* Reset callback flags */
-//     __test_callback_flags = 0;
-//     return redisConnectNonBlock("127.0.0.1", port, NULL);
-// }
-//
-// static void test_nonblocking_connection() {
-//     redisContext *c;
-//     int wdone = 0;
-//
-//     test("Calls command callback when command is issued: ");
-//     c = __connect_nonblock();
-//     redisSetCommandCallback(c,__test_callback,(void*)1);
-//     redisCommand(c,"PING");
-//     test_cond(__test_callback_flags == 1);
-//     redisFree(c);
-//
-//     test("Calls disconnect callback on redisDisconnect: ");
-//     c = __connect_nonblock();
-//     redisSetDisconnectCallback(c,__test_callback,(void*)2);
-//     redisDisconnect(c);
-//     test_cond(__test_callback_flags == 2);
-//     redisFree(c);
-//
-//     test("Calls disconnect callback and free callback on redisFree: ");
-//     c = __connect_nonblock();
-//     redisSetDisconnectCallback(c,__test_callback,(void*)2);
-//     redisSetFreeCallback(c,__test_callback,(void*)4);
-//     redisFree(c);
-//     test_cond(__test_callback_flags == ((2 << 8) | 4));
-//
-//     test("redisBufferWrite against empty write buffer: ");
-//     c = __connect_nonblock();
-//     test_cond(redisBufferWrite(c,&wdone) == REDIS_OK && wdone == 1);
-//     redisFree(c);
-//
-//     test("redisBufferWrite against not yet connected fd: ");
-//     c = __connect_nonblock();
-//     redisCommand(c,"PING");
-//     test_cond(redisBufferWrite(c,NULL) == REDIS_ERR &&
-//               strncmp(c->error,"write:",6) == 0);
-//     redisFree(c);
-//
-//     test("redisBufferWrite against closed fd: ");
-//     c = __connect_nonblock();
-//     redisCommand(c,"PING");
-//     redisDisconnect(c);
-//     test_cond(redisBufferWrite(c,NULL) == REDIS_ERR &&
-//               strncmp(c->error,"write:",6) == 0);
-//     redisFree(c);
-//
-//     test("Process callbacks in the right sequence: ");
-//     c = __connect_nonblock();
-//     redisCommandWithCallback(c,__test_reply_callback,(void*)1,"PING");
-//     redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING");
-//     redisCommandWithCallback(c,__test_reply_callback,(void*)3,"PING");
-//
-//     /* Write output buffer */
-//     wdone = 0;
-//     while(!wdone) {
-//         usleep(500);
-//         redisBufferWrite(c,&wdone);
-//     }
-//
-//     /* Read until at least one callback is executed (the 3 replies will
-//      * arrive in a single packet, causing all callbacks to be executed in
-//      * a single pass). */
-//     while(__test_callback_flags == 0) {
-//         assert(redisBufferRead(c) == REDIS_OK);
-//         redisProcessCallbacks(c);
-//     }
-//     test_cond(__test_callback_flags == 0x010203);
-//     redisFree(c);
-//
-//     test("redisDisconnect executes pending callbacks with NULL reply: ");
-//     c = __connect_nonblock();
-//     redisSetDisconnectCallback(c,__test_callback,(void*)1);
-//     redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING");
-//     redisDisconnect(c);
-//     test_cond(__test_callback_flags == 0x0201);
-//     redisFree(c);
-// }
-
-int main(int argc, char **argv) {
-    struct config cfg = {
-        .tcp = {
-            .host = "127.0.0.1",
-            .port = 6379
-        },
-        .unix = {
-            .path = "/tmp/redis.sock"
-        }
-    };
-    int throughput = 1;
-    int test_inherit_fd = 1;
-
-    /* Ignore broken pipe signal (for I/O error tests). */
-    signal(SIGPIPE, SIG_IGN);
-
-    /* Parse command line options. */
-    argv++; argc--;
-    while (argc) {
-        if (argc >= 2 && !strcmp(argv[0],"-h")) {
-            argv++; argc--;
-            cfg.tcp.host = argv[0];
-        } else if (argc >= 2 && !strcmp(argv[0],"-p")) {
-            argv++; argc--;
-            cfg.tcp.port = atoi(argv[0]);
-        } else if (argc >= 2 && !strcmp(argv[0],"-s")) {
-            argv++; argc--;
-            cfg.unix.path = argv[0];
-        } else if (argc >= 1 && !strcmp(argv[0],"--skip-throughput")) {
-            throughput = 0;
-        } else if (argc >= 1 && !strcmp(argv[0],"--skip-inherit-fd")) {
-            test_inherit_fd = 0;
-        } else {
-            fprintf(stderr, "Invalid argument: %s\n", argv[0]);
-            exit(1);
-        }
-        argv++; argc--;
-    }
-
-    test_format_commands();
-    test_reply_reader();
-    test_blocking_connection_errors();
-    test_free_null();
-
-    printf("\nTesting against TCP connection (%s:%d):\n", cfg.tcp.host, cfg.tcp.port);
-    cfg.type = CONN_TCP;
-    test_blocking_connection(cfg);
-    test_blocking_connection_timeouts(cfg);
-    test_blocking_io_errors(cfg);
-    test_invalid_timeout_errors(cfg);
-    test_append_formatted_commands(cfg);
-    if (throughput) test_throughput(cfg);
-
-    printf("\nTesting against Unix socket connection (%s):\n", cfg.unix.path);
-    cfg.type = CONN_UNIX;
-    test_blocking_connection(cfg);
-    test_blocking_connection_timeouts(cfg);
-    test_blocking_io_errors(cfg);
-    if (throughput) test_throughput(cfg);
-
-    if (test_inherit_fd) {
-        printf("\nTesting against inherited fd (%s):\n", cfg.unix.path);
-        cfg.type = CONN_FD;
-        test_blocking_connection(cfg);
-    }
-
-
-    if (fails) {
-        printf("*** %d TESTS FAILED ***\n", fails);
-        return 1;
-    }
-
-    printf("ALL TESTS PASSED\n");
-    return 0;
-}
diff --git a/third-party/hiredis/win32.h b/third-party/hiredis/win32.h
deleted file mode 100644 (file)
index 1a27c18..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef _WIN32_HELPER_INCLUDE
-#define _WIN32_HELPER_INCLUDE
-#ifdef _MSC_VER
-
-#ifndef inline
-#define inline __inline
-#endif
-
-#ifndef va_copy
-#define va_copy(d,s) ((d) = (s))
-#endif
-
-#ifndef snprintf
-#define snprintf c99_snprintf
-
-__inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap)
-{
-    int count = -1;
-
-    if (size != 0)
-        count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
-    if (count == -1)
-        count = _vscprintf(format, ap);
-
-    return count;
-}
-
-__inline int c99_snprintf(char* str, size_t size, const char* format, ...)
-{
-    int count;
-    va_list ap;
-
-    va_start(ap, format);
-    count = c99_vsnprintf(str, size, format, ap);
-    va_end(ap);
-
-    return count;
-}
-#endif
-
-#endif
-#endif
\ No newline at end of file