redis-server 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (290) hide show
  1. data/LICENSE +38 -0
  2. data/README.md +33 -0
  3. data/bin/redis +114 -0
  4. data/redis/Makefile +5 -0
  5. data/redis/extconf.rb +3 -0
  6. data/redis/redis-2.2.11/00-RELEASENOTES +199 -0
  7. data/redis/redis-2.2.11/BUGS +1 -0
  8. data/redis/redis-2.2.11/CONTRIBUTING +13 -0
  9. data/redis/redis-2.2.11/COPYING +10 -0
  10. data/redis/redis-2.2.11/Changelog +1032 -0
  11. data/redis/redis-2.2.11/INSTALL +30 -0
  12. data/redis/redis-2.2.11/Makefile +22 -0
  13. data/redis/redis-2.2.11/README +83 -0
  14. data/redis/redis-2.2.11/TODO +4 -0
  15. data/redis/redis-2.2.11/client-libraries/README +11 -0
  16. data/redis/redis-2.2.11/deps/hiredis/COPYING +10 -0
  17. data/redis/redis-2.2.11/deps/hiredis/Makefile +115 -0
  18. data/redis/redis-2.2.11/deps/hiredis/README.md +311 -0
  19. data/redis/redis-2.2.11/deps/hiredis/TODO +2 -0
  20. data/redis/redis-2.2.11/deps/hiredis/adapters/ae.h +95 -0
  21. data/redis/redis-2.2.11/deps/hiredis/adapters/libev.h +113 -0
  22. data/redis/redis-2.2.11/deps/hiredis/adapters/libevent.h +76 -0
  23. data/redis/redis-2.2.11/deps/hiredis/async.c +321 -0
  24. data/redis/redis-2.2.11/deps/hiredis/async.h +112 -0
  25. data/redis/redis-2.2.11/deps/hiredis/example-ae.c +53 -0
  26. data/redis/redis-2.2.11/deps/hiredis/example-libev.c +47 -0
  27. data/redis/redis-2.2.11/deps/hiredis/example-libevent.c +48 -0
  28. data/redis/redis-2.2.11/deps/hiredis/example.c +67 -0
  29. data/redis/redis-2.2.11/deps/hiredis/fmacros.h +15 -0
  30. data/redis/redis-2.2.11/deps/hiredis/hiredis.c +1058 -0
  31. data/redis/redis-2.2.11/deps/hiredis/hiredis.h +170 -0
  32. data/redis/redis-2.2.11/deps/hiredis/net.c +170 -0
  33. data/redis/redis-2.2.11/deps/hiredis/net.h +43 -0
  34. data/redis/redis-2.2.11/deps/hiredis/sds.c +479 -0
  35. data/redis/redis-2.2.11/deps/hiredis/sds.h +77 -0
  36. data/redis/redis-2.2.11/deps/hiredis/test.c +479 -0
  37. data/redis/redis-2.2.11/deps/hiredis/util.h +40 -0
  38. data/redis/redis-2.2.11/deps/linenoise/Makefile +10 -0
  39. data/redis/redis-2.2.11/deps/linenoise/README.markdown +45 -0
  40. data/redis/redis-2.2.11/deps/linenoise/example.c +27 -0
  41. data/redis/redis-2.2.11/deps/linenoise/linenoise.c +609 -0
  42. data/redis/redis-2.2.11/deps/linenoise/linenoise.h +55 -0
  43. data/redis/redis-2.2.11/design-documents/REDIS-CLUSTER +214 -0
  44. data/redis/redis-2.2.11/design-documents/REDIS-CLUSTER-2 +343 -0
  45. data/redis/redis-2.2.11/doc/AppendCommand.html +48 -0
  46. data/redis/redis-2.2.11/doc/AppendOnlyFileHowto.html +41 -0
  47. data/redis/redis-2.2.11/doc/AuthCommand.html +39 -0
  48. data/redis/redis-2.2.11/doc/Benchmarks.html +129 -0
  49. data/redis/redis-2.2.11/doc/BgrewriteaofCommand.html +41 -0
  50. data/redis/redis-2.2.11/doc/BgsaveCommand.html +39 -0
  51. data/redis/redis-2.2.11/doc/BlpopCommand.html +51 -0
  52. data/redis/redis-2.2.11/doc/BrpoplpushCommand.html +39 -0
  53. data/redis/redis-2.2.11/doc/CommandReference.html +47 -0
  54. data/redis/redis-2.2.11/doc/Comparisons.html +42 -0
  55. data/redis/redis-2.2.11/doc/ConfigCommand.html +76 -0
  56. data/redis/redis-2.2.11/doc/Configuration.html +38 -0
  57. data/redis/redis-2.2.11/doc/ConnectionHandlingSidebar.html +36 -0
  58. data/redis/redis-2.2.11/doc/ControlCommandsSidebar.html +36 -0
  59. data/redis/redis-2.2.11/doc/Credits.html +38 -0
  60. data/redis/redis-2.2.11/doc/DbsizeCommand.html +38 -0
  61. data/redis/redis-2.2.11/doc/DelCommand.html +41 -0
  62. data/redis/redis-2.2.11/doc/DesignPatterns.html +37 -0
  63. data/redis/redis-2.2.11/doc/EventLibray.html +44 -0
  64. data/redis/redis-2.2.11/doc/ExistsCommand.html +42 -0
  65. data/redis/redis-2.2.11/doc/ExpireCommand.html +96 -0
  66. data/redis/redis-2.2.11/doc/FAQ.html +70 -0
  67. data/redis/redis-2.2.11/doc/Features.html +38 -0
  68. data/redis/redis-2.2.11/doc/FlushallCommand.html +39 -0
  69. data/redis/redis-2.2.11/doc/FlushdbCommand.html +39 -0
  70. data/redis/redis-2.2.11/doc/FromSqlToDataStructures.html +37 -0
  71. data/redis/redis-2.2.11/doc/GenericCommandsSidebar.html +36 -0
  72. data/redis/redis-2.2.11/doc/GetCommand.html +39 -0
  73. data/redis/redis-2.2.11/doc/GetbitCommand.html +39 -0
  74. data/redis/redis-2.2.11/doc/GetsetCommand.html +38 -0
  75. data/redis/redis-2.2.11/doc/HackingStrings.html +83 -0
  76. data/redis/redis-2.2.11/doc/HashCommandsSidebar.html +36 -0
  77. data/redis/redis-2.2.11/doc/Hashes.html +37 -0
  78. data/redis/redis-2.2.11/doc/HdelCommand.html +39 -0
  79. data/redis/redis-2.2.11/doc/HexistsCommand.html +39 -0
  80. data/redis/redis-2.2.11/doc/HgetCommand.html +39 -0
  81. data/redis/redis-2.2.11/doc/HgetallCommand.html +40 -0
  82. data/redis/redis-2.2.11/doc/HincrbyCommand.html +45 -0
  83. data/redis/redis-2.2.11/doc/HlenCommand.html +38 -0
  84. data/redis/redis-2.2.11/doc/HmgetCommand.html +40 -0
  85. data/redis/redis-2.2.11/doc/HmsetCommand.html +40 -0
  86. data/redis/redis-2.2.11/doc/HsetCommand.html +40 -0
  87. data/redis/redis-2.2.11/doc/HsetnxCommand.html +41 -0
  88. data/redis/redis-2.2.11/doc/IncrCommand.html +43 -0
  89. data/redis/redis-2.2.11/doc/InfoCommand.html +48 -0
  90. data/redis/redis-2.2.11/doc/IntroductionToRedisDataTypes.html +152 -0
  91. data/redis/redis-2.2.11/doc/KeysCommand.html +43 -0
  92. data/redis/redis-2.2.11/doc/LastsaveCommand.html +39 -0
  93. data/redis/redis-2.2.11/doc/LindexCommand.html +40 -0
  94. data/redis/redis-2.2.11/doc/ListCommandsSidebar.html +36 -0
  95. data/redis/redis-2.2.11/doc/Lists.html +42 -0
  96. data/redis/redis-2.2.11/doc/LlenCommand.html +41 -0
  97. data/redis/redis-2.2.11/doc/LpopCommand.html +41 -0
  98. data/redis/redis-2.2.11/doc/LrangeCommand.html +47 -0
  99. data/redis/redis-2.2.11/doc/LremCommand.html +41 -0
  100. data/redis/redis-2.2.11/doc/LsetCommand.html +38 -0
  101. data/redis/redis-2.2.11/doc/LtrimCommand.html +47 -0
  102. data/redis/redis-2.2.11/doc/MgetCommand.html +52 -0
  103. data/redis/redis-2.2.11/doc/MonitorCommand.html +63 -0
  104. data/redis/redis-2.2.11/doc/MoveCommand.html +42 -0
  105. data/redis/redis-2.2.11/doc/MsetCommand.html +44 -0
  106. data/redis/redis-2.2.11/doc/MultiExecCommand.html +166 -0
  107. data/redis/redis-2.2.11/doc/NonexistentCommands.html +51 -0
  108. data/redis/redis-2.2.11/doc/ObjectHashMappers.html +39 -0
  109. data/redis/redis-2.2.11/doc/Pipelining.html +36 -0
  110. data/redis/redis-2.2.11/doc/ProgrammingExamples.html +38 -0
  111. data/redis/redis-2.2.11/doc/ProtocolSpecification.html +137 -0
  112. data/redis/redis-2.2.11/doc/PublishSubscribe.html +115 -0
  113. data/redis/redis-2.2.11/doc/QuickStart.html +68 -0
  114. data/redis/redis-2.2.11/doc/QuitCommand.html +38 -0
  115. data/redis/redis-2.2.11/doc/README.html +119 -0
  116. data/redis/redis-2.2.11/doc/RandomkeyCommand.html +39 -0
  117. data/redis/redis-2.2.11/doc/Redis0100ChangeLog.html +67 -0
  118. data/redis/redis-2.2.11/doc/Redis0900ChangeLog.html +56 -0
  119. data/redis/redis-2.2.11/doc/RedisBigData.html +61 -0
  120. data/redis/redis-2.2.11/doc/RedisCLI.html +37 -0
  121. data/redis/redis-2.2.11/doc/RedisEventLibrary.html +70 -0
  122. data/redis/redis-2.2.11/doc/RedisGuides.html +37 -0
  123. data/redis/redis-2.2.11/doc/RedisInternals.html +38 -0
  124. data/redis/redis-2.2.11/doc/RedisPipelining.html +93 -0
  125. data/redis/redis-2.2.11/doc/RedisStatus.html +56 -0
  126. data/redis/redis-2.2.11/doc/Redis_1_2_0_Changelog.html +40 -0
  127. data/redis/redis-2.2.11/doc/Redis_2_0_0_Changelog.html +62 -0
  128. data/redis/redis-2.2.11/doc/Redis_2_0_Whats_new.html +59 -0
  129. data/redis/redis-2.2.11/doc/RenameCommand.html +39 -0
  130. data/redis/redis-2.2.11/doc/RenamenxCommand.html +42 -0
  131. data/redis/redis-2.2.11/doc/ReplicationHowto.html +43 -0
  132. data/redis/redis-2.2.11/doc/ReplyTypes.html +42 -0
  133. data/redis/redis-2.2.11/doc/RoadMap.html +38 -0
  134. data/redis/redis-2.2.11/doc/RpoplpushCommand.html +44 -0
  135. data/redis/redis-2.2.11/doc/RpushCommand.html +40 -0
  136. data/redis/redis-2.2.11/doc/SaddCommand.html +41 -0
  137. data/redis/redis-2.2.11/doc/SaveCommand.html +39 -0
  138. data/redis/redis-2.2.11/doc/ScardCommand.html +41 -0
  139. data/redis/redis-2.2.11/doc/SdiffCommand.html +45 -0
  140. data/redis/redis-2.2.11/doc/SdiffstoreCommand.html +38 -0
  141. data/redis/redis-2.2.11/doc/SelectCommand.html +39 -0
  142. data/redis/redis-2.2.11/doc/SetCommand.html +39 -0
  143. data/redis/redis-2.2.11/doc/SetCommandsSidebar.html +36 -0
  144. data/redis/redis-2.2.11/doc/SetbitCommand.html +45 -0
  145. data/redis/redis-2.2.11/doc/SetexCommand.html +42 -0
  146. data/redis/redis-2.2.11/doc/SetnxCommand.html +51 -0
  147. data/redis/redis-2.2.11/doc/SetrangeCommand.html +58 -0
  148. data/redis/redis-2.2.11/doc/Sets.html +36 -0
  149. data/redis/redis-2.2.11/doc/ShutdownCommand.html +39 -0
  150. data/redis/redis-2.2.11/doc/SideBar.html +36 -0
  151. data/redis/redis-2.2.11/doc/SinterCommand.html +40 -0
  152. data/redis/redis-2.2.11/doc/SinterstoreCommand.html +39 -0
  153. data/redis/redis-2.2.11/doc/SismemberCommand.html +42 -0
  154. data/redis/redis-2.2.11/doc/SlaveofCommand.html +41 -0
  155. data/redis/redis-2.2.11/doc/SmembersCommand.html +38 -0
  156. data/redis/redis-2.2.11/doc/SmoveCommand.html +44 -0
  157. data/redis/redis-2.2.11/doc/SortCommand.html +75 -0
  158. data/redis/redis-2.2.11/doc/SortedSetCommandsSidebar.html +36 -0
  159. data/redis/redis-2.2.11/doc/SortedSets.html +36 -0
  160. data/redis/redis-2.2.11/doc/Speed.html +38 -0
  161. data/redis/redis-2.2.11/doc/SponsorshipHistory.html +38 -0
  162. data/redis/redis-2.2.11/doc/SpopCommand.html +40 -0
  163. data/redis/redis-2.2.11/doc/SrandmemberCommand.html +40 -0
  164. data/redis/redis-2.2.11/doc/SremCommand.html +42 -0
  165. data/redis/redis-2.2.11/doc/StringCommandsSidebar.html +36 -0
  166. data/redis/redis-2.2.11/doc/Strings.html +37 -0
  167. data/redis/redis-2.2.11/doc/StrlenCommand.html +39 -0
  168. data/redis/redis-2.2.11/doc/SubstrCommand.html +52 -0
  169. data/redis/redis-2.2.11/doc/SunionCommand.html +40 -0
  170. data/redis/redis-2.2.11/doc/SunionstoreCommand.html +38 -0
  171. data/redis/redis-2.2.11/doc/SupportedLanguages.html +60 -0
  172. data/redis/redis-2.2.11/doc/SupportedPlatforms.html +37 -0
  173. data/redis/redis-2.2.11/doc/TemplateCommand.html +38 -0
  174. data/redis/redis-2.2.11/doc/TtlCommand.html +38 -0
  175. data/redis/redis-2.2.11/doc/TwitterAlikeExample.html +250 -0
  176. data/redis/redis-2.2.11/doc/TypeCommand.html +46 -0
  177. data/redis/redis-2.2.11/doc/UnstableSource.html +39 -0
  178. data/redis/redis-2.2.11/doc/VirtualMemorySpecification.html +156 -0
  179. data/redis/redis-2.2.11/doc/VirtualMemoryUserGuide.html +66 -0
  180. data/redis/redis-2.2.11/doc/ZaddCommand.html +43 -0
  181. data/redis/redis-2.2.11/doc/ZcardCommand.html +41 -0
  182. data/redis/redis-2.2.11/doc/ZincrbyCommand.html +42 -0
  183. data/redis/redis-2.2.11/doc/ZrangeCommand.html +42 -0
  184. data/redis/redis-2.2.11/doc/ZrangebyscoreCommand.html +77 -0
  185. data/redis/redis-2.2.11/doc/ZrankCommand.html +43 -0
  186. data/redis/redis-2.2.11/doc/ZremCommand.html +42 -0
  187. data/redis/redis-2.2.11/doc/ZremrangebyrankCommand.html +39 -0
  188. data/redis/redis-2.2.11/doc/ZremrangebyscoreCommand.html +39 -0
  189. data/redis/redis-2.2.11/doc/ZscoreCommand.html +41 -0
  190. data/redis/redis-2.2.11/doc/ZunionCommand.html +42 -0
  191. data/redis/redis-2.2.11/doc/ZunionstoreCommand.html +43 -0
  192. data/redis/redis-2.2.11/doc/index.html +43 -0
  193. data/redis/redis-2.2.11/doc/redis.png +0 -0
  194. data/redis/redis-2.2.11/doc/style.css +25 -0
  195. data/redis/redis-2.2.11/redis.conf +417 -0
  196. data/redis/redis-2.2.11/src/Makefile +177 -0
  197. data/redis/redis-2.2.11/src/adlist.c +325 -0
  198. data/redis/redis-2.2.11/src/adlist.h +92 -0
  199. data/redis/redis-2.2.11/src/ae.c +390 -0
  200. data/redis/redis-2.2.11/src/ae.h +117 -0
  201. data/redis/redis-2.2.11/src/ae_epoll.c +91 -0
  202. data/redis/redis-2.2.11/src/ae_kqueue.c +93 -0
  203. data/redis/redis-2.2.11/src/ae_select.c +72 -0
  204. data/redis/redis-2.2.11/src/anet.c +347 -0
  205. data/redis/redis-2.2.11/src/anet.h +57 -0
  206. data/redis/redis-2.2.11/src/aof.c +675 -0
  207. data/redis/redis-2.2.11/src/config.c +627 -0
  208. data/redis/redis-2.2.11/src/config.h +64 -0
  209. data/redis/redis-2.2.11/src/db.c +543 -0
  210. data/redis/redis-2.2.11/src/debug.c +314 -0
  211. data/redis/redis-2.2.11/src/dict.c +721 -0
  212. data/redis/redis-2.2.11/src/dict.h +156 -0
  213. data/redis/redis-2.2.11/src/fmacros.h +15 -0
  214. data/redis/redis-2.2.11/src/help.h +638 -0
  215. data/redis/redis-2.2.11/src/intset.c +422 -0
  216. data/redis/redis-2.2.11/src/intset.h +19 -0
  217. data/redis/redis-2.2.11/src/lzf.h +100 -0
  218. data/redis/redis-2.2.11/src/lzfP.h +159 -0
  219. data/redis/redis-2.2.11/src/lzf_c.c +295 -0
  220. data/redis/redis-2.2.11/src/lzf_d.c +150 -0
  221. data/redis/redis-2.2.11/src/mkreleasehdr.sh +9 -0
  222. data/redis/redis-2.2.11/src/multi.c +268 -0
  223. data/redis/redis-2.2.11/src/networking.c +899 -0
  224. data/redis/redis-2.2.11/src/object.c +484 -0
  225. data/redis/redis-2.2.11/src/pqsort.c +197 -0
  226. data/redis/redis-2.2.11/src/pqsort.h +15 -0
  227. data/redis/redis-2.2.11/src/pubsub.c +267 -0
  228. data/redis/redis-2.2.11/src/rdb.c +1020 -0
  229. data/redis/redis-2.2.11/src/redis-benchmark.c +530 -0
  230. data/redis/redis-2.2.11/src/redis-check-aof.c +185 -0
  231. data/redis/redis-2.2.11/src/redis-check-dump.c +681 -0
  232. data/redis/redis-2.2.11/src/redis-cli.c +773 -0
  233. data/redis/redis-2.2.11/src/redis.c +1677 -0
  234. data/redis/redis-2.2.11/src/redis.h +1022 -0
  235. data/redis/redis-2.2.11/src/release.c +13 -0
  236. data/redis/redis-2.2.11/src/replication.c +557 -0
  237. data/redis/redis-2.2.11/src/sds.c +639 -0
  238. data/redis/redis-2.2.11/src/sds.h +78 -0
  239. data/redis/redis-2.2.11/src/sha1.c +276 -0
  240. data/redis/redis-2.2.11/src/sha1.h +17 -0
  241. data/redis/redis-2.2.11/src/solarisfixes.h +22 -0
  242. data/redis/redis-2.2.11/src/sort.c +389 -0
  243. data/redis/redis-2.2.11/src/syncio.c +154 -0
  244. data/redis/redis-2.2.11/src/t_hash.c +476 -0
  245. data/redis/redis-2.2.11/src/t_list.c +986 -0
  246. data/redis/redis-2.2.11/src/t_set.c +610 -0
  247. data/redis/redis-2.2.11/src/t_string.c +438 -0
  248. data/redis/redis-2.2.11/src/t_zset.c +1084 -0
  249. data/redis/redis-2.2.11/src/testhelp.h +54 -0
  250. data/redis/redis-2.2.11/src/util.c +243 -0
  251. data/redis/redis-2.2.11/src/valgrind.sup +5 -0
  252. data/redis/redis-2.2.11/src/version.h +1 -0
  253. data/redis/redis-2.2.11/src/vm.c +1149 -0
  254. data/redis/redis-2.2.11/src/ziplist.c +1323 -0
  255. data/redis/redis-2.2.11/src/ziplist.h +15 -0
  256. data/redis/redis-2.2.11/src/zipmap.c +455 -0
  257. data/redis/redis-2.2.11/src/zipmap.h +48 -0
  258. data/redis/redis-2.2.11/src/zmalloc.c +278 -0
  259. data/redis/redis-2.2.11/src/zmalloc.h +47 -0
  260. data/redis/redis-2.2.11/tests/assets/default.conf +308 -0
  261. data/redis/redis-2.2.11/tests/integration/aof.tcl +104 -0
  262. data/redis/redis-2.2.11/tests/integration/redis-cli.tcl +208 -0
  263. data/redis/redis-2.2.11/tests/integration/replication.tcl +98 -0
  264. data/redis/redis-2.2.11/tests/support/redis.tcl +241 -0
  265. data/redis/redis-2.2.11/tests/support/server.tcl +294 -0
  266. data/redis/redis-2.2.11/tests/support/test.tcl +190 -0
  267. data/redis/redis-2.2.11/tests/support/tmpfile.tcl +15 -0
  268. data/redis/redis-2.2.11/tests/support/util.tcl +296 -0
  269. data/redis/redis-2.2.11/tests/test_helper.tcl +221 -0
  270. data/redis/redis-2.2.11/tests/unit/auth.tcl +15 -0
  271. data/redis/redis-2.2.11/tests/unit/basic.tcl +616 -0
  272. data/redis/redis-2.2.11/tests/unit/cas.tcl +135 -0
  273. data/redis/redis-2.2.11/tests/unit/expire.tcl +74 -0
  274. data/redis/redis-2.2.11/tests/unit/other.tcl +240 -0
  275. data/redis/redis-2.2.11/tests/unit/printver.tcl +6 -0
  276. data/redis/redis-2.2.11/tests/unit/protocol.tcl +62 -0
  277. data/redis/redis-2.2.11/tests/unit/pubsub.tcl +195 -0
  278. data/redis/redis-2.2.11/tests/unit/quit.tcl +40 -0
  279. data/redis/redis-2.2.11/tests/unit/sort.tcl +189 -0
  280. data/redis/redis-2.2.11/tests/unit/type/hash.tcl +300 -0
  281. data/redis/redis-2.2.11/tests/unit/type/list.tcl +819 -0
  282. data/redis/redis-2.2.11/tests/unit/type/set.tcl +334 -0
  283. data/redis/redis-2.2.11/tests/unit/type/zset.tcl +587 -0
  284. data/redis/redis-2.2.11/utils/build-static-symbols.tcl +22 -0
  285. data/redis/redis-2.2.11/utils/generate-command-help.rb +112 -0
  286. data/redis/redis-2.2.11/utils/mktarball.sh +13 -0
  287. data/redis/redis-2.2.11/utils/redis-copy.rb +78 -0
  288. data/redis/redis-2.2.11/utils/redis-sha1.rb +52 -0
  289. data/redis/redis-2.2.11/utils/redis_init_script +42 -0
  290. metadata +362 -0
@@ -0,0 +1,639 @@
1
+ /* SDSLib, A C dynamic strings library
2
+ *
3
+ * Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are met:
8
+ *
9
+ * * Redistributions of source code must retain the above copyright notice,
10
+ * this list of conditions and the following disclaimer.
11
+ * * Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ * * Neither the name of Redis nor the names of its contributors may be used
15
+ * to endorse or promote products derived from this software without
16
+ * specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
+ * POSSIBILITY OF SUCH DAMAGE.
29
+ *
30
+ * History:
31
+ *
32
+ * - 22 March 2011: History section created on top of sds.c
33
+ * - 22 March 2011: Fixed a problem with "\xab" escapes convertion in
34
+ * function sdssplitargs().
35
+ */
36
+
37
+ #define SDS_ABORT_ON_OOM
38
+
39
+ #include "sds.h"
40
+ #include <stdio.h>
41
+ #include <stdlib.h>
42
+ #include <string.h>
43
+ #include <ctype.h>
44
+ #include "zmalloc.h"
45
+
46
+ static void sdsOomAbort(void) {
47
+ fprintf(stderr,"SDS: Out Of Memory (SDS_ABORT_ON_OOM defined)\n");
48
+ abort();
49
+ }
50
+
51
+ sds sdsnewlen(const void *init, size_t initlen) {
52
+ struct sdshdr *sh;
53
+
54
+ sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
55
+ #ifdef SDS_ABORT_ON_OOM
56
+ if (sh == NULL) sdsOomAbort();
57
+ #else
58
+ if (sh == NULL) return NULL;
59
+ #endif
60
+ sh->len = initlen;
61
+ sh->free = 0;
62
+ if (initlen) {
63
+ if (init) memcpy(sh->buf, init, initlen);
64
+ else memset(sh->buf,0,initlen);
65
+ }
66
+ sh->buf[initlen] = '\0';
67
+ return (char*)sh->buf;
68
+ }
69
+
70
+ sds sdsempty(void) {
71
+ return sdsnewlen("",0);
72
+ }
73
+
74
+ sds sdsnew(const char *init) {
75
+ size_t initlen = (init == NULL) ? 0 : strlen(init);
76
+ return sdsnewlen(init, initlen);
77
+ }
78
+
79
+ size_t sdslen(const sds s) {
80
+ struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
81
+ return sh->len;
82
+ }
83
+
84
+ sds sdsdup(const sds s) {
85
+ return sdsnewlen(s, sdslen(s));
86
+ }
87
+
88
+ void sdsfree(sds s) {
89
+ if (s == NULL) return;
90
+ zfree(s-sizeof(struct sdshdr));
91
+ }
92
+
93
+ size_t sdsavail(sds s) {
94
+ struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
95
+ return sh->free;
96
+ }
97
+
98
+ void sdsupdatelen(sds s) {
99
+ struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
100
+ int reallen = strlen(s);
101
+ sh->free += (sh->len-reallen);
102
+ sh->len = reallen;
103
+ }
104
+
105
+ static sds sdsMakeRoomFor(sds s, size_t addlen) {
106
+ struct sdshdr *sh, *newsh;
107
+ size_t free = sdsavail(s);
108
+ size_t len, newlen;
109
+
110
+ if (free >= addlen) return s;
111
+ len = sdslen(s);
112
+ sh = (void*) (s-(sizeof(struct sdshdr)));
113
+ newlen = (len+addlen)*2;
114
+ newsh = zrealloc(sh, sizeof(struct sdshdr)+newlen+1);
115
+ #ifdef SDS_ABORT_ON_OOM
116
+ if (newsh == NULL) sdsOomAbort();
117
+ #else
118
+ if (newsh == NULL) return NULL;
119
+ #endif
120
+
121
+ newsh->free = newlen - len;
122
+ return newsh->buf;
123
+ }
124
+
125
+ /* Grow the sds to have the specified length. Bytes that were not part of
126
+ * the original length of the sds will be set to zero. */
127
+ sds sdsgrowzero(sds s, size_t len) {
128
+ struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
129
+ size_t totlen, curlen = sh->len;
130
+
131
+ if (len <= curlen) return s;
132
+ s = sdsMakeRoomFor(s,len-curlen);
133
+ if (s == NULL) return NULL;
134
+
135
+ /* Make sure added region doesn't contain garbage */
136
+ sh = (void*)(s-(sizeof(struct sdshdr)));
137
+ memset(s+curlen,0,(len-curlen+1)); /* also set trailing \0 byte */
138
+ totlen = sh->len+sh->free;
139
+ sh->len = len;
140
+ sh->free = totlen-sh->len;
141
+ return s;
142
+ }
143
+
144
+ sds sdscatlen(sds s, void *t, size_t len) {
145
+ struct sdshdr *sh;
146
+ size_t curlen = sdslen(s);
147
+
148
+ s = sdsMakeRoomFor(s,len);
149
+ if (s == NULL) return NULL;
150
+ sh = (void*) (s-(sizeof(struct sdshdr)));
151
+ memcpy(s+curlen, t, len);
152
+ sh->len = curlen+len;
153
+ sh->free = sh->free-len;
154
+ s[curlen+len] = '\0';
155
+ return s;
156
+ }
157
+
158
+ sds sdscat(sds s, char *t) {
159
+ return sdscatlen(s, t, strlen(t));
160
+ }
161
+
162
+ sds sdscpylen(sds s, char *t, size_t len) {
163
+ struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
164
+ size_t totlen = sh->free+sh->len;
165
+
166
+ if (totlen < len) {
167
+ s = sdsMakeRoomFor(s,len-sh->len);
168
+ if (s == NULL) return NULL;
169
+ sh = (void*) (s-(sizeof(struct sdshdr)));
170
+ totlen = sh->free+sh->len;
171
+ }
172
+ memcpy(s, t, len);
173
+ s[len] = '\0';
174
+ sh->len = len;
175
+ sh->free = totlen-len;
176
+ return s;
177
+ }
178
+
179
+ sds sdscpy(sds s, char *t) {
180
+ return sdscpylen(s, t, strlen(t));
181
+ }
182
+
183
+ sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
184
+ va_list cpy;
185
+ char *buf, *t;
186
+ size_t buflen = 16;
187
+
188
+ while(1) {
189
+ buf = zmalloc(buflen);
190
+ #ifdef SDS_ABORT_ON_OOM
191
+ if (buf == NULL) sdsOomAbort();
192
+ #else
193
+ if (buf == NULL) return NULL;
194
+ #endif
195
+ buf[buflen-2] = '\0';
196
+ va_copy(cpy,ap);
197
+ vsnprintf(buf, buflen, fmt, cpy);
198
+ if (buf[buflen-2] != '\0') {
199
+ zfree(buf);
200
+ buflen *= 2;
201
+ continue;
202
+ }
203
+ break;
204
+ }
205
+ t = sdscat(s, buf);
206
+ zfree(buf);
207
+ return t;
208
+ }
209
+
210
+ sds sdscatprintf(sds s, const char *fmt, ...) {
211
+ va_list ap;
212
+ char *t;
213
+ va_start(ap, fmt);
214
+ t = sdscatvprintf(s,fmt,ap);
215
+ va_end(ap);
216
+ return t;
217
+ }
218
+
219
+ sds sdstrim(sds s, const char *cset) {
220
+ struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
221
+ char *start, *end, *sp, *ep;
222
+ size_t len;
223
+
224
+ sp = start = s;
225
+ ep = end = s+sdslen(s)-1;
226
+ while(sp <= end && strchr(cset, *sp)) sp++;
227
+ while(ep > start && strchr(cset, *ep)) ep--;
228
+ len = (sp > ep) ? 0 : ((ep-sp)+1);
229
+ if (sh->buf != sp) memmove(sh->buf, sp, len);
230
+ sh->buf[len] = '\0';
231
+ sh->free = sh->free+(sh->len-len);
232
+ sh->len = len;
233
+ return s;
234
+ }
235
+
236
+ sds sdsrange(sds s, int start, int end) {
237
+ struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
238
+ size_t newlen, len = sdslen(s);
239
+
240
+ if (len == 0) return s;
241
+ if (start < 0) {
242
+ start = len+start;
243
+ if (start < 0) start = 0;
244
+ }
245
+ if (end < 0) {
246
+ end = len+end;
247
+ if (end < 0) end = 0;
248
+ }
249
+ newlen = (start > end) ? 0 : (end-start)+1;
250
+ if (newlen != 0) {
251
+ if (start >= (signed)len) {
252
+ newlen = 0;
253
+ } else if (end >= (signed)len) {
254
+ end = len-1;
255
+ newlen = (start > end) ? 0 : (end-start)+1;
256
+ }
257
+ } else {
258
+ start = 0;
259
+ }
260
+ if (start && newlen) memmove(sh->buf, sh->buf+start, newlen);
261
+ sh->buf[newlen] = 0;
262
+ sh->free = sh->free+(sh->len-newlen);
263
+ sh->len = newlen;
264
+ return s;
265
+ }
266
+
267
+ void sdstolower(sds s) {
268
+ int len = sdslen(s), j;
269
+
270
+ for (j = 0; j < len; j++) s[j] = tolower(s[j]);
271
+ }
272
+
273
+ void sdstoupper(sds s) {
274
+ int len = sdslen(s), j;
275
+
276
+ for (j = 0; j < len; j++) s[j] = toupper(s[j]);
277
+ }
278
+
279
+ int sdscmp(sds s1, sds s2) {
280
+ size_t l1, l2, minlen;
281
+ int cmp;
282
+
283
+ l1 = sdslen(s1);
284
+ l2 = sdslen(s2);
285
+ minlen = (l1 < l2) ? l1 : l2;
286
+ cmp = memcmp(s1,s2,minlen);
287
+ if (cmp == 0) return l1-l2;
288
+ return cmp;
289
+ }
290
+
291
+ /* Split 's' with separator in 'sep'. An array
292
+ * of sds strings is returned. *count will be set
293
+ * by reference to the number of tokens returned.
294
+ *
295
+ * On out of memory, zero length string, zero length
296
+ * separator, NULL is returned.
297
+ *
298
+ * Note that 'sep' is able to split a string using
299
+ * a multi-character separator. For example
300
+ * sdssplit("foo_-_bar","_-_"); will return two
301
+ * elements "foo" and "bar".
302
+ *
303
+ * This version of the function is binary-safe but
304
+ * requires length arguments. sdssplit() is just the
305
+ * same function but for zero-terminated strings.
306
+ */
307
+ sds *sdssplitlen(char *s, int len, char *sep, int seplen, int *count) {
308
+ int elements = 0, slots = 5, start = 0, j;
309
+
310
+ sds *tokens = zmalloc(sizeof(sds)*slots);
311
+ #ifdef SDS_ABORT_ON_OOM
312
+ if (tokens == NULL) sdsOomAbort();
313
+ #endif
314
+ if (seplen < 1 || len < 0 || tokens == NULL) return NULL;
315
+ if (len == 0) {
316
+ *count = 0;
317
+ return tokens;
318
+ }
319
+ for (j = 0; j < (len-(seplen-1)); j++) {
320
+ /* make sure there is room for the next element and the final one */
321
+ if (slots < elements+2) {
322
+ sds *newtokens;
323
+
324
+ slots *= 2;
325
+ newtokens = zrealloc(tokens,sizeof(sds)*slots);
326
+ if (newtokens == NULL) {
327
+ #ifdef SDS_ABORT_ON_OOM
328
+ sdsOomAbort();
329
+ #else
330
+ goto cleanup;
331
+ #endif
332
+ }
333
+ tokens = newtokens;
334
+ }
335
+ /* search the separator */
336
+ if ((seplen == 1 && *(s+j) == sep[0]) || (memcmp(s+j,sep,seplen) == 0)) {
337
+ tokens[elements] = sdsnewlen(s+start,j-start);
338
+ if (tokens[elements] == NULL) {
339
+ #ifdef SDS_ABORT_ON_OOM
340
+ sdsOomAbort();
341
+ #else
342
+ goto cleanup;
343
+ #endif
344
+ }
345
+ elements++;
346
+ start = j+seplen;
347
+ j = j+seplen-1; /* skip the separator */
348
+ }
349
+ }
350
+ /* Add the final element. We are sure there is room in the tokens array. */
351
+ tokens[elements] = sdsnewlen(s+start,len-start);
352
+ if (tokens[elements] == NULL) {
353
+ #ifdef SDS_ABORT_ON_OOM
354
+ sdsOomAbort();
355
+ #else
356
+ goto cleanup;
357
+ #endif
358
+ }
359
+ elements++;
360
+ *count = elements;
361
+ return tokens;
362
+
363
+ #ifndef SDS_ABORT_ON_OOM
364
+ cleanup:
365
+ {
366
+ int i;
367
+ for (i = 0; i < elements; i++) sdsfree(tokens[i]);
368
+ zfree(tokens);
369
+ return NULL;
370
+ }
371
+ #endif
372
+ }
373
+
374
+ void sdsfreesplitres(sds *tokens, int count) {
375
+ if (!tokens) return;
376
+ while(count--)
377
+ sdsfree(tokens[count]);
378
+ zfree(tokens);
379
+ }
380
+
381
+ sds sdsfromlonglong(long long value) {
382
+ char buf[32], *p;
383
+ unsigned long long v;
384
+
385
+ v = (value < 0) ? -value : value;
386
+ p = buf+31; /* point to the last character */
387
+ do {
388
+ *p-- = '0'+(v%10);
389
+ v /= 10;
390
+ } while(v);
391
+ if (value < 0) *p-- = '-';
392
+ p++;
393
+ return sdsnewlen(p,32-(p-buf));
394
+ }
395
+
396
+ sds sdscatrepr(sds s, char *p, size_t len) {
397
+ s = sdscatlen(s,"\"",1);
398
+ while(len--) {
399
+ switch(*p) {
400
+ case '\\':
401
+ case '"':
402
+ s = sdscatprintf(s,"\\%c",*p);
403
+ break;
404
+ case '\n': s = sdscatlen(s,"\\n",1); break;
405
+ case '\r': s = sdscatlen(s,"\\r",1); break;
406
+ case '\t': s = sdscatlen(s,"\\t",1); break;
407
+ case '\a': s = sdscatlen(s,"\\a",1); break;
408
+ case '\b': s = sdscatlen(s,"\\b",1); break;
409
+ default:
410
+ if (isprint(*p))
411
+ s = sdscatprintf(s,"%c",*p);
412
+ else
413
+ s = sdscatprintf(s,"\\x%02x",(unsigned char)*p);
414
+ break;
415
+ }
416
+ p++;
417
+ }
418
+ return sdscatlen(s,"\"",1);
419
+ }
420
+
421
+ /* Helper function for sdssplitargs() that returns non zero if 'c'
422
+ * is a valid hex digit. */
423
+ int is_hex_digit(char c) {
424
+ return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
425
+ (c >= 'A' && c <= 'F');
426
+ }
427
+
428
+ /* Helper function for sdssplitargs() that converts an hex digit into an
429
+ * integer from 0 to 15 */
430
+ int hex_digit_to_int(char c) {
431
+ switch(c) {
432
+ case '0': return 0;
433
+ case '1': return 1;
434
+ case '2': return 2;
435
+ case '3': return 3;
436
+ case '4': return 4;
437
+ case '5': return 5;
438
+ case '6': return 6;
439
+ case '7': return 7;
440
+ case '8': return 8;
441
+ case '9': return 9;
442
+ case 'a': case 'A': return 10;
443
+ case 'b': case 'B': return 11;
444
+ case 'c': case 'C': return 12;
445
+ case 'd': case 'D': return 13;
446
+ case 'e': case 'E': return 14;
447
+ case 'f': case 'F': return 15;
448
+ default: return 0;
449
+ }
450
+ }
451
+
452
+ /* Split a line into arguments, where every argument can be in the
453
+ * following programming-language REPL-alike form:
454
+ *
455
+ * foo bar "newline are supported\n" and "\xff\x00otherstuff"
456
+ *
457
+ * The number of arguments is stored into *argc, and an array
458
+ * of sds is returned. The caller should sdsfree() all the returned
459
+ * strings and finally zfree() the array itself.
460
+ *
461
+ * Note that sdscatrepr() is able to convert back a string into
462
+ * a quoted string in the same format sdssplitargs() is able to parse.
463
+ */
464
+ sds *sdssplitargs(char *line, int *argc) {
465
+ char *p = line;
466
+ char *current = NULL;
467
+ char **vector = NULL;
468
+
469
+ *argc = 0;
470
+ while(1) {
471
+ /* skip blanks */
472
+ while(*p && isspace(*p)) p++;
473
+ if (*p) {
474
+ /* get a token */
475
+ int inq=0; /* set to 1 if we are in "quotes" */
476
+ int done=0;
477
+
478
+ if (current == NULL) current = sdsempty();
479
+ while(!done) {
480
+ if (inq) {
481
+ if (*p == '\\' && *(p+1) == 'x' &&
482
+ is_hex_digit(*(p+2)) &&
483
+ is_hex_digit(*(p+3)))
484
+ {
485
+ unsigned char byte;
486
+
487
+ byte = (hex_digit_to_int(*(p+2))*16)+
488
+ hex_digit_to_int(*(p+3));
489
+ current = sdscatlen(current,(char*)&byte,1);
490
+ p += 3;
491
+ } else if (*p == '\\' && *(p+1)) {
492
+ char c;
493
+
494
+ p++;
495
+ switch(*p) {
496
+ case 'n': c = '\n'; break;
497
+ case 'r': c = '\r'; break;
498
+ case 't': c = '\t'; break;
499
+ case 'b': c = '\b'; break;
500
+ case 'a': c = '\a'; break;
501
+ default: c = *p; break;
502
+ }
503
+ current = sdscatlen(current,&c,1);
504
+ } else if (*p == '"') {
505
+ /* closing quote must be followed by a space */
506
+ if (*(p+1) && !isspace(*(p+1))) goto err;
507
+ done=1;
508
+ } else if (!*p) {
509
+ /* unterminated quotes */
510
+ goto err;
511
+ } else {
512
+ current = sdscatlen(current,p,1);
513
+ }
514
+ } else {
515
+ switch(*p) {
516
+ case ' ':
517
+ case '\n':
518
+ case '\r':
519
+ case '\t':
520
+ case '\0':
521
+ done=1;
522
+ break;
523
+ case '"':
524
+ inq=1;
525
+ break;
526
+ default:
527
+ current = sdscatlen(current,p,1);
528
+ break;
529
+ }
530
+ }
531
+ if (*p) p++;
532
+ }
533
+ /* add the token to the vector */
534
+ vector = zrealloc(vector,((*argc)+1)*sizeof(char*));
535
+ vector[*argc] = current;
536
+ (*argc)++;
537
+ current = NULL;
538
+ } else {
539
+ return vector;
540
+ }
541
+ }
542
+
543
+ err:
544
+ while((*argc)--)
545
+ sdsfree(vector[*argc]);
546
+ zfree(vector);
547
+ if (current) sdsfree(current);
548
+ return NULL;
549
+ }
550
+
551
+ #ifdef SDS_TEST_MAIN
552
+ #include <stdio.h>
553
+ #include "testhelp.h"
554
+
555
+ int main(void) {
556
+ {
557
+ sds x = sdsnew("foo"), y;
558
+
559
+ test_cond("Create a string and obtain the length",
560
+ sdslen(x) == 3 && memcmp(x,"foo\0",4) == 0)
561
+
562
+ sdsfree(x);
563
+ x = sdsnewlen("foo",2);
564
+ test_cond("Create a string with specified length",
565
+ sdslen(x) == 2 && memcmp(x,"fo\0",3) == 0)
566
+
567
+ x = sdscat(x,"bar");
568
+ test_cond("Strings concatenation",
569
+ sdslen(x) == 5 && memcmp(x,"fobar\0",6) == 0);
570
+
571
+ x = sdscpy(x,"a");
572
+ test_cond("sdscpy() against an originally longer string",
573
+ sdslen(x) == 1 && memcmp(x,"a\0",2) == 0)
574
+
575
+ x = sdscpy(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk");
576
+ test_cond("sdscpy() against an originally shorter string",
577
+ sdslen(x) == 33 &&
578
+ memcmp(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk\0",33) == 0)
579
+
580
+ sdsfree(x);
581
+ x = sdscatprintf(sdsempty(),"%d",123);
582
+ test_cond("sdscatprintf() seems working in the base case",
583
+ sdslen(x) == 3 && memcmp(x,"123\0",4) ==0)
584
+
585
+ sdsfree(x);
586
+ x = sdstrim(sdsnew("xxciaoyyy"),"xy");
587
+ test_cond("sdstrim() correctly trims characters",
588
+ sdslen(x) == 4 && memcmp(x,"ciao\0",5) == 0)
589
+
590
+ y = sdsrange(sdsdup(x),1,1);
591
+ test_cond("sdsrange(...,1,1)",
592
+ sdslen(y) == 1 && memcmp(y,"i\0",2) == 0)
593
+
594
+ sdsfree(y);
595
+ y = sdsrange(sdsdup(x),1,-1);
596
+ test_cond("sdsrange(...,1,-1)",
597
+ sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
598
+
599
+ sdsfree(y);
600
+ y = sdsrange(sdsdup(x),-2,-1);
601
+ test_cond("sdsrange(...,-2,-1)",
602
+ sdslen(y) == 2 && memcmp(y,"ao\0",3) == 0)
603
+
604
+ sdsfree(y);
605
+ y = sdsrange(sdsdup(x),2,1);
606
+ test_cond("sdsrange(...,2,1)",
607
+ sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
608
+
609
+ sdsfree(y);
610
+ y = sdsrange(sdsdup(x),1,100);
611
+ test_cond("sdsrange(...,1,100)",
612
+ sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
613
+
614
+ sdsfree(y);
615
+ y = sdsrange(sdsdup(x),100,100);
616
+ test_cond("sdsrange(...,100,100)",
617
+ sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
618
+
619
+ sdsfree(y);
620
+ sdsfree(x);
621
+ x = sdsnew("foo");
622
+ y = sdsnew("foa");
623
+ test_cond("sdscmp(foo,foa)", sdscmp(x,y) > 0)
624
+
625
+ sdsfree(y);
626
+ sdsfree(x);
627
+ x = sdsnew("bar");
628
+ y = sdsnew("bar");
629
+ test_cond("sdscmp(bar,bar)", sdscmp(x,y) == 0)
630
+
631
+ sdsfree(y);
632
+ sdsfree(x);
633
+ x = sdsnew("aar");
634
+ y = sdsnew("bar");
635
+ test_cond("sdscmp(bar,bar)", sdscmp(x,y) < 0)
636
+ }
637
+ test_report()
638
+ }
639
+ #endif