zsv 1.3.0

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 (240) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +36 -0
  3. data/LICENSE +21 -0
  4. data/README.md +311 -0
  5. data/ext/zsv/common.h +34 -0
  6. data/ext/zsv/extconf.rb +137 -0
  7. data/ext/zsv/options.c +126 -0
  8. data/ext/zsv/options.h +31 -0
  9. data/ext/zsv/options_internal.h +8 -0
  10. data/ext/zsv/parser.c +300 -0
  11. data/ext/zsv/parser.h +62 -0
  12. data/ext/zsv/row.c +122 -0
  13. data/ext/zsv/row.h +39 -0
  14. data/ext/zsv/vendor/zsv-1.3.0/app/2db.c +756 -0
  15. data/ext/zsv/vendor/zsv-1.3.0/app/2json.c +381 -0
  16. data/ext/zsv/vendor/zsv-1.3.0/app/2tsv.c +228 -0
  17. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/help.c +123 -0
  18. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/license.c +39 -0
  19. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/register.c +104 -0
  20. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/thirdparty.c +41 -0
  21. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/unregister.c +1 -0
  22. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/version.c +14 -0
  23. data/ext/zsv/vendor/zsv-1.3.0/app/check/simdutf_wrapper.h +19 -0
  24. data/ext/zsv/vendor/zsv-1.3.0/app/check/utf8.c +116 -0
  25. data/ext/zsv/vendor/zsv-1.3.0/app/check.c +194 -0
  26. data/ext/zsv/vendor/zsv-1.3.0/app/cli.c +796 -0
  27. data/ext/zsv/vendor/zsv-1.3.0/app/cli_const.h +41 -0
  28. data/ext/zsv/vendor/zsv-1.3.0/app/cli_export.h +16 -0
  29. data/ext/zsv/vendor/zsv-1.3.0/app/cli_ini.c +280 -0
  30. data/ext/zsv/vendor/zsv-1.3.0/app/cli_internal.h +36 -0
  31. data/ext/zsv/vendor/zsv-1.3.0/app/compare.c +913 -0
  32. data/ext/zsv/vendor/zsv-1.3.0/app/compare.h +23 -0
  33. data/ext/zsv/vendor/zsv-1.3.0/app/compare_added_column.c +20 -0
  34. data/ext/zsv/vendor/zsv-1.3.0/app/compare_internal.h +140 -0
  35. data/ext/zsv/vendor/zsv-1.3.0/app/compare_sort.c +91 -0
  36. data/ext/zsv/vendor/zsv-1.3.0/app/compare_unique_colname.c +81 -0
  37. data/ext/zsv/vendor/zsv-1.3.0/app/count-pull.c +82 -0
  38. data/ext/zsv/vendor/zsv-1.3.0/app/count.c +404 -0
  39. data/ext/zsv/vendor/zsv-1.3.0/app/desc.c +569 -0
  40. data/ext/zsv/vendor/zsv-1.3.0/app/echo.c +365 -0
  41. data/ext/zsv/vendor/zsv-1.3.0/app/ext_example/my_extension.c +366 -0
  42. data/ext/zsv/vendor/zsv-1.3.0/app/ext_example/mysheet_extension.c +341 -0
  43. data/ext/zsv/vendor/zsv-1.3.0/app/ext_template/YOUR_EXTENSION_zsvext.c +263 -0
  44. data/ext/zsv/vendor/zsv-1.3.0/app/external/inih/ini.c +298 -0
  45. data/ext/zsv/vendor/zsv-1.3.0/app/external/inih/ini.h +157 -0
  46. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/json_numeric.c +177 -0
  47. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/jsonwriter.c +444 -0
  48. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/jsonwriter.h +145 -0
  49. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/utils.c +110 -0
  50. data/ext/zsv/vendor/zsv-1.3.0/app/external/memfile-1.0/include/memfile.h +15 -0
  51. data/ext/zsv/vendor/zsv-1.3.0/app/external/memfile-1.0/src/memfile.c +64 -0
  52. data/ext/zsv/vendor/zsv-1.3.0/app/external/sglib/sglib.h +1955 -0
  53. data/ext/zsv/vendor/zsv-1.3.0/app/external/simdutf/simdutf.h +6802 -0
  54. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3.c +230517 -0
  55. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3.h +12174 -0
  56. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_and_csv_vtab.c +2 -0
  57. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-mem.c +142 -0
  58. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-mem.h +49 -0
  59. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-zsv.c +485 -0
  60. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab.c +1015 -0
  61. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3ext.h +663 -0
  62. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/vtab_helper.c +85 -0
  63. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_common.h +75 -0
  64. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_gen.h +167 -0
  65. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_parse.h +228 -0
  66. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_tree.h +186 -0
  67. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_version.h +23 -0
  68. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_common.h +76 -0
  69. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_gen.h +167 -0
  70. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_parse.h +238 -0
  71. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_tree.h +186 -0
  72. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl.c +184 -0
  73. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_alloc.c +52 -0
  74. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_alloc.h +34 -0
  75. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_buf.c +103 -0
  76. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_buf.h +57 -0
  77. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_bytestack.h +69 -0
  78. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_encode.c +220 -0
  79. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_encode.h +34 -0
  80. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_gen.c +362 -0
  81. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_lex.c +764 -0
  82. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_lex.h +117 -0
  83. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_parser.c +508 -0
  84. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_parser.h +78 -0
  85. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_tree.c +505 -0
  86. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_version.c +7 -0
  87. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper/json_value.h +59 -0
  88. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper/yajl_helper.h +208 -0
  89. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper.c +795 -0
  90. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper_internal.h +28 -0
  91. data/ext/zsv/vendor/zsv-1.3.0/app/flatten.c +851 -0
  92. data/ext/zsv/vendor/zsv-1.3.0/app/jq.c +106 -0
  93. data/ext/zsv/vendor/zsv-1.3.0/app/jq.h +6 -0
  94. data/ext/zsv/vendor/zsv-1.3.0/app/mv.c +113 -0
  95. data/ext/zsv/vendor/zsv-1.3.0/app/noop.c +90 -0
  96. data/ext/zsv/vendor/zsv-1.3.0/app/overwrite.c +295 -0
  97. data/ext/zsv/vendor/zsv-1.3.0/app/paste.c +175 -0
  98. data/ext/zsv/vendor/zsv-1.3.0/app/pretty.c +693 -0
  99. data/ext/zsv/vendor/zsv-1.3.0/app/prop.c +980 -0
  100. data/ext/zsv/vendor/zsv-1.3.0/app/rm.c +131 -0
  101. data/ext/zsv/vendor/zsv-1.3.0/app/select/fixed.c +130 -0
  102. data/ext/zsv/vendor/zsv-1.3.0/app/select/internal.h +118 -0
  103. data/ext/zsv/vendor/zsv-1.3.0/app/select/parallel.c +45 -0
  104. data/ext/zsv/vendor/zsv-1.3.0/app/select/parallel.h +41 -0
  105. data/ext/zsv/vendor/zsv-1.3.0/app/select/processing.c +107 -0
  106. data/ext/zsv/vendor/zsv-1.3.0/app/select/rand.c +20 -0
  107. data/ext/zsv/vendor/zsv-1.3.0/app/select/regex.c +61 -0
  108. data/ext/zsv/vendor/zsv-1.3.0/app/select/search.c +14 -0
  109. data/ext/zsv/vendor/zsv-1.3.0/app/select/selection.c +192 -0
  110. data/ext/zsv/vendor/zsv-1.3.0/app/select/usage.c +72 -0
  111. data/ext/zsv/vendor/zsv-1.3.0/app/select-pull.c +812 -0
  112. data/ext/zsv/vendor/zsv-1.3.0/app/select.c +753 -0
  113. data/ext/zsv/vendor/zsv-1.3.0/app/serialize.c +372 -0
  114. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/curses.h +15 -0
  115. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/cursor.c +119 -0
  116. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/errors.c +45 -0
  117. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/file.c +63 -0
  118. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/file.h +12 -0
  119. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/filter.c +166 -0
  120. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/handlers.c +214 -0
  121. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/handlers_internal.h +128 -0
  122. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/help.c +43 -0
  123. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/index.c +81 -0
  124. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/index.h +25 -0
  125. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/key-bindings.c +325 -0
  126. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/key-bindings.h +73 -0
  127. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/lexer.c +203 -0
  128. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/newline_handler.c +7 -0
  129. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/pivot.c +318 -0
  130. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/procedure.c +134 -0
  131. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/procedure.h +119 -0
  132. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/read-data.c +322 -0
  133. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/screen_buffer.c +203 -0
  134. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/screen_buffer.h +36 -0
  135. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sheet-sql.c +167 -0
  136. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sheet_internal.h +36 -0
  137. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sqlfilter.c +153 -0
  138. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/terminfo.c +32 -0
  139. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/transformation.c +312 -0
  140. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/transformation.h +29 -0
  141. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/ui_buffer.c +266 -0
  142. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/usage.c +9 -0
  143. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/utf8-width.c +60 -0
  144. data/ext/zsv/vendor/zsv-1.3.0/app/sheet.c +1007 -0
  145. data/ext/zsv/vendor/zsv-1.3.0/app/sql.c +453 -0
  146. data/ext/zsv/vendor/zsv-1.3.0/app/sql_internal.c +101 -0
  147. data/ext/zsv/vendor/zsv-1.3.0/app/sql_internal.h +49 -0
  148. data/ext/zsv/vendor/zsv-1.3.0/app/stack.c +393 -0
  149. data/ext/zsv/vendor/zsv-1.3.0/app/utils/arg.c +322 -0
  150. data/ext/zsv/vendor/zsv-1.3.0/app/utils/cache.c +228 -0
  151. data/ext/zsv/vendor/zsv-1.3.0/app/utils/cat.c +91 -0
  152. data/ext/zsv/vendor/zsv-1.3.0/app/utils/chunk.c +240 -0
  153. data/ext/zsv/vendor/zsv-1.3.0/app/utils/chunk.h +63 -0
  154. data/ext/zsv/vendor/zsv-1.3.0/app/utils/clock.c +57 -0
  155. data/ext/zsv/vendor/zsv-1.3.0/app/utils/db.c +148 -0
  156. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs-no-jq.c +2 -0
  157. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs.c +427 -0
  158. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs_from_json.c +253 -0
  159. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs_to_json.c +121 -0
  160. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dl.c +20 -0
  161. data/ext/zsv/vendor/zsv-1.3.0/app/utils/emcc/fs_api.c +159 -0
  162. data/ext/zsv/vendor/zsv-1.3.0/app/utils/err.c +24 -0
  163. data/ext/zsv/vendor/zsv-1.3.0/app/utils/file-mem.c +180 -0
  164. data/ext/zsv/vendor/zsv-1.3.0/app/utils/file.c +256 -0
  165. data/ext/zsv/vendor/zsv-1.3.0/app/utils/index.c +197 -0
  166. data/ext/zsv/vendor/zsv-1.3.0/app/utils/index.h +49 -0
  167. data/ext/zsv/vendor/zsv-1.3.0/app/utils/jq.c +400 -0
  168. data/ext/zsv/vendor/zsv-1.3.0/app/utils/json.c +120 -0
  169. data/ext/zsv/vendor/zsv-1.3.0/app/utils/mem.c +18 -0
  170. data/ext/zsv/vendor/zsv-1.3.0/app/utils/memmem.c +132 -0
  171. data/ext/zsv/vendor/zsv-1.3.0/app/utils/os.c +178 -0
  172. data/ext/zsv/vendor/zsv-1.3.0/app/utils/overwrite.c +258 -0
  173. data/ext/zsv/vendor/zsv-1.3.0/app/utils/overwrite_writer.c +246 -0
  174. data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8-test.c +123 -0
  175. data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8.c +153 -0
  176. data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8.h +54 -0
  177. data/ext/zsv/vendor/zsv-1.3.0/app/utils/prop.c +267 -0
  178. data/ext/zsv/vendor/zsv-1.3.0/app/utils/signal.c +53 -0
  179. data/ext/zsv/vendor/zsv-1.3.0/app/utils/string.c +357 -0
  180. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/dir_exists_longpath.c +83 -0
  181. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/dl.c +33 -0
  182. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/fopen_longpath.c +184 -0
  183. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/foreach_dirent_longpath.c +292 -0
  184. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/io.c +259 -0
  185. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/io.h +13 -0
  186. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/mkdir_longpath.c +255 -0
  187. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/remove_longpath.c +96 -0
  188. data/ext/zsv/vendor/zsv-1.3.0/app/utils/writer.c +361 -0
  189. data/ext/zsv/vendor/zsv-1.3.0/app/zsv_command.h +40 -0
  190. data/ext/zsv/vendor/zsv-1.3.0/app/zsv_command_standalone.c +16 -0
  191. data/ext/zsv/vendor/zsv-1.3.0/app/zsv_main.h +44 -0
  192. data/ext/zsv/vendor/zsv-1.3.0/examples/js/zsv_parser_api_dummy.c +3 -0
  193. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/parse_by_chunk.c +100 -0
  194. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/print_my_column.c +143 -0
  195. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/pull.c +89 -0
  196. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/simple.c +123 -0
  197. data/ext/zsv/vendor/zsv-1.3.0/fuzz/fuzz.c +16 -0
  198. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/api.h +336 -0
  199. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/common.h +361 -0
  200. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/implementation.h +62 -0
  201. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/implementation_private.h +113 -0
  202. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/sheet.h +73 -0
  203. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext.h +329 -0
  204. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/arg.h +90 -0
  205. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/cache.h +49 -0
  206. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/clock.h +36 -0
  207. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/compiler.h +58 -0
  208. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/db.h +19 -0
  209. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/dirs.h +147 -0
  210. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/dl.h +22 -0
  211. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/emcc/fs_api.h +28 -0
  212. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/err.h +22 -0
  213. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/file-mem.h +17 -0
  214. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/file.h +99 -0
  215. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/jq.h +65 -0
  216. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/json.h +19 -0
  217. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/mem.h +19 -0
  218. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/memmem.h +13 -0
  219. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/os.h +54 -0
  220. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/overwrite.h +71 -0
  221. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/overwrite_writer.h +53 -0
  222. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/prop.h +107 -0
  223. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/signal.h +18 -0
  224. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/sql.h +11 -0
  225. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/string.h +148 -0
  226. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/utf8.h +41 -0
  227. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/win/dl.h +25 -0
  228. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/writer.h +101 -0
  229. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/zsv_export.h +33 -0
  230. data/ext/zsv/vendor/zsv-1.3.0/include/zsv.h +20 -0
  231. data/ext/zsv/vendor/zsv-1.3.0/src/vector_delim.c +60 -0
  232. data/ext/zsv/vendor/zsv-1.3.0/src/zsv.c +484 -0
  233. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_internal.c +731 -0
  234. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_scan_delim.c +285 -0
  235. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_scan_fixed.c +88 -0
  236. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_strencode.c +51 -0
  237. data/ext/zsv/zsv_ext.c +343 -0
  238. data/lib/zsv/version.rb +5 -0
  239. data/lib/zsv.rb +81 -0
  240. metadata +340 -0
@@ -0,0 +1,318 @@
1
+ /*
2
+ * Copyright (C) 2021 Liquidaty and zsv contributors. All rights reserved.
3
+ * This file is part of zsv/lib, distributed under the license defined at
4
+ * https://opensource.org/licenses/MIT
5
+ */
6
+
7
+ #include <assert.h>
8
+ #include <errno.h>
9
+ #include "../external/sqlite3/sqlite3.h"
10
+ #include <zsv/ext/implementation.h>
11
+ #include <zsv/ext/sheet.h>
12
+ #include <zsv/utils/writer.h>
13
+ #include <zsv/utils/file.h>
14
+ #include <zsv/utils/prop.h>
15
+ #include "file.h"
16
+ #include "handlers_internal.h"
17
+ #include "./curses.h"
18
+ #include "../sql_internal.h"
19
+
20
+ #include "sheet-sql.c"
21
+
22
+ struct pivot_row {
23
+ char *value;
24
+ };
25
+
26
+ struct pivot_data {
27
+ char *value_sql; // the sql expression entered by the user e.g. City
28
+ char *data_filename;
29
+ struct {
30
+ struct pivot_row *data; // for each row, the value of the sql expression e.g. New York
31
+ size_t capacity;
32
+ size_t used;
33
+ } rows;
34
+ char column_name_expr;
35
+ };
36
+
37
+ static void pivot_data_delete(void *h) {
38
+ struct pivot_data *pd = h;
39
+ if (pd) {
40
+ for (size_t i = 0; i < pd->rows.used; i++)
41
+ free(pd->rows.data[i].value);
42
+ free(pd->rows.data);
43
+ free(pd->value_sql);
44
+ free(pd->data_filename);
45
+ free(pd);
46
+ }
47
+ }
48
+
49
+ static struct pivot_data *pivot_data_new(const char *data_filename, const char *value_sql, char column_name_expr) {
50
+ struct pivot_data *pd = calloc(1, sizeof(*pd));
51
+ if (pd && (pd->value_sql = strdup(value_sql)) && (pd->data_filename = strdup(data_filename))) {
52
+ pd->column_name_expr = column_name_expr;
53
+ return pd;
54
+ }
55
+ pivot_data_delete(pd);
56
+ return NULL;
57
+ }
58
+
59
+ #define ZSV_MYSHEET_PIVOT_DATA_ROWS_INITIAL 32
60
+ static int pivot_data_grow(struct pivot_data *pd) {
61
+ if (pd->rows.used == pd->rows.capacity) {
62
+ size_t new_capacity = pd->rows.capacity == 0 ? ZSV_MYSHEET_PIVOT_DATA_ROWS_INITIAL : pd->rows.capacity * 2;
63
+ struct pivot_row *new_data = realloc(pd->rows.data, new_capacity * sizeof(*pd->rows.data));
64
+ if (!new_data)
65
+ return ENOMEM;
66
+ pd->rows.data = new_data;
67
+ pd->rows.capacity = new_capacity;
68
+ }
69
+ return 0;
70
+ }
71
+
72
+ static int add_pivot_row(struct pivot_data *pd, const char *value, size_t len) {
73
+ int err = pivot_data_grow(pd);
74
+ char *value_dup = NULL;
75
+ if (!err && value && len) {
76
+ value_dup = malloc(len + 1);
77
+ if (value_dup) {
78
+ memcpy(value_dup, value, len);
79
+ value_dup[len] = '\0';
80
+ }
81
+ }
82
+ pd->rows.data[pd->rows.used++].value = value_dup;
83
+ return err;
84
+ }
85
+
86
+ static struct pivot_row *get_pivot_row_data(struct pivot_data *pd, size_t row_ix) {
87
+ if (pd && row_ix < pd->rows.used)
88
+ return &pd->rows.data[row_ix];
89
+ return NULL;
90
+ }
91
+
92
+ static enum zsv_ext_status get_cell_attrs(void *pdh, zsvsheet_cell_attr_t *attrs, size_t start_row, size_t row_count,
93
+ size_t cols) {
94
+ struct pivot_data *pd = pdh;
95
+ size_t end_row = start_row + row_count;
96
+ int attr = 0;
97
+
98
+ #ifdef A_BOLD
99
+ attr |= A_BOLD;
100
+ #endif
101
+ // Absent on Mac OSX 13
102
+ #ifdef A_ITALIC
103
+ attr |= A_ITALIC;
104
+ #endif
105
+
106
+ if (end_row > pd->rows.used)
107
+ end_row = pd->rows.used;
108
+ for (size_t i = start_row; i < end_row; i++)
109
+ attrs[i * cols] = attr;
110
+ return zsv_ext_status_ok;
111
+ }
112
+
113
+ static void pivot_on_header_cell(void *ctx, size_t col_ix, const char *colname) {
114
+ (void)colname;
115
+ if (col_ix == 0)
116
+ add_pivot_row(ctx, NULL, 0);
117
+ }
118
+
119
+ static void pivot_on_data_cell(void *ctx, size_t col_ix, const char *text, size_t len) {
120
+ if (col_ix == 0)
121
+ add_pivot_row(ctx, text, len);
122
+ }
123
+
124
+ zsvsheet_status pivot_drill_down(zsvsheet_proc_context_t ctx) {
125
+ enum zsvsheet_status zst = zsvsheet_status_ok;
126
+ zsvsheet_buffer_t buff = zsvsheet_buffer_current(ctx);
127
+ struct pivot_data *pd;
128
+ struct zsvsheet_rowcol rc;
129
+ if (zsvsheet_buffer_get_ctx(buff, (void **)&pd) != zsv_ext_status_ok ||
130
+ zsvsheet_buffer_get_selected_cell(buff, &rc) != zsvsheet_status_ok) {
131
+ return zsvsheet_status_error;
132
+ }
133
+ struct pivot_row *pr = get_pivot_row_data(pd, rc.row);
134
+ if (pd && pd->data_filename && pd->value_sql && pr) {
135
+ struct zsv_sqlite3_dbopts dbopts = {0};
136
+ sqlite3_str *sql_str = NULL;
137
+ struct zsv_sqlite3_db *zdb = zsv_sqlite3_db_new(&dbopts);
138
+
139
+ if (!zdb || !(sql_str = sqlite3_str_new(zdb->db)))
140
+ zst = zsvsheet_status_memory;
141
+ else if (zdb->rc == SQLITE_OK && zsv_sqlite3_add_csv_no_dq(zdb, pd->data_filename, NULL, NULL) == SQLITE_OK) {
142
+ if (zsvsheet_buffer_info(buff).has_row_num)
143
+ sqlite3_str_appendf(sql_str, "select *");
144
+ else
145
+ sqlite3_str_appendf(sql_str, "select rowid as [Row #], *");
146
+ if (pd->column_name_expr)
147
+ sqlite3_str_appendf(sql_str, " from data where \"%w\" = %Q", pd->value_sql, pr->value);
148
+ else
149
+ // we haven't tracked whether the underlying value is a string, number or other
150
+ // we only know that its string representation is pr->value
151
+ // so we add `|| ''` to the sql expression to force text conversion
152
+ sqlite3_str_appendf(sql_str, " from data where (%s) || '' = %Q", pd->value_sql, pr->value);
153
+ const char *err_msg = NULL;
154
+ zst = zsv_sqlite3_to_csv(ctx, zdb, sqlite3_str_value(sql_str), &err_msg, NULL, NULL, NULL);
155
+ if (err_msg)
156
+ zsvsheet_ui_buffer_set_status(buff, err_msg);
157
+ else if (zst == zsvsheet_status_no_data)
158
+ zsvsheet_ui_buffer_set_status(buff, "No results returned");
159
+ }
160
+
161
+ if (sql_str)
162
+ sqlite3_free(sqlite3_str_finish(sql_str));
163
+ if (zdb) {
164
+ if (zst != zsvsheet_status_ok) {
165
+ // to do: consolidate this with same code in /app/sql.c
166
+ if (zdb->err_msg)
167
+ fprintf(stderr, "Error: %s\n", zdb->err_msg);
168
+ else if (!zdb->db)
169
+ fprintf(stderr, "Error (unable to open db, code %i): %s\n", zdb->rc, sqlite3_errstr(zdb->rc));
170
+ else if (zdb->rc != SQLITE_OK)
171
+ fprintf(stderr, "Error (code %i): %s\n", zdb->rc, sqlite3_errstr(zdb->rc));
172
+ }
173
+ zsv_sqlite3_db_delete(zdb);
174
+ }
175
+ }
176
+ return zst;
177
+ }
178
+
179
+ static void zsvsheet_check_buffer_worker_updates(struct zsvsheet_ui_buffer *ub,
180
+ struct zsvsheet_display_dimensions *display_dims,
181
+ struct zsvsheet_sheet_context *handler_state);
182
+
183
+ /**
184
+ * Here we define a custom command for the zsv `sheet` feature
185
+ */
186
+ static zsvsheet_status zsvsheet_pivot_handler(struct zsvsheet_proc_context *ctx) {
187
+ char result_buffer[256] = {0};
188
+ const char *expr;
189
+ char column_name_expr;
190
+ struct zsvsheet_rowcol rc;
191
+ int ch = zsvsheet_ext_keypress(ctx);
192
+
193
+ if (ch < 0)
194
+ return zsvsheet_status_error;
195
+
196
+ zsvsheet_buffer_t buff = zsvsheet_buffer_current(ctx);
197
+ const char *data_filename = NULL;
198
+ if (buff)
199
+ data_filename = zsvsheet_buffer_data_filename(buff);
200
+
201
+ if (!data_filename) { // TO DO: check that the underlying data is a tabular file and we know how to parse
202
+ zsvsheet_ui_buffer_set_status(buff, "Pivot table only available for tabular data buffers");
203
+ return zsvsheet_status_ok;
204
+ }
205
+
206
+ char *selected_cell_str_dup = NULL;
207
+ switch (ctx->proc_id) {
208
+ case zsvsheet_builtin_proc_pivot_expr:
209
+ zsvsheet_ext_prompt(ctx, result_buffer, sizeof(result_buffer), "Pivot table: Enter group-by SQL expr");
210
+ if (*result_buffer == '\0')
211
+ return zsvsheet_status_ok;
212
+ expr = result_buffer;
213
+ column_name_expr = 0;
214
+ break;
215
+ case zsvsheet_builtin_proc_pivot_cur_col:
216
+ if (zsvsheet_buffer_get_selected_cell(buff, &rc) != zsvsheet_status_ok)
217
+ return zsvsheet_status_error;
218
+ const unsigned char *selected_cell_str =
219
+ zsvsheet_screen_buffer_cell_display(((struct zsvsheet_ui_buffer *)buff)->buffer, rc.row, rc.col);
220
+ while (selected_cell_str && *selected_cell_str == ' ')
221
+ selected_cell_str++;
222
+ size_t len = selected_cell_str ? strlen((const char *)selected_cell_str) : 0;
223
+ while (len > 0 && selected_cell_str[len - 1] == ' ')
224
+ len--;
225
+ if (len)
226
+ selected_cell_str_dup = zsv_memdup(selected_cell_str, len);
227
+ expr = zsvsheet_ui_buffer_get_header(buff, rc.col);
228
+ column_name_expr = 1;
229
+ assert(expr);
230
+ break;
231
+ default:
232
+ assert(0);
233
+ return zsvsheet_status_error;
234
+ }
235
+
236
+ enum zsvsheet_status zst = zsvsheet_status_ok;
237
+ struct zsv_sqlite3_dbopts dbopts = {0};
238
+ struct zsv_opts zopts = zsvsheet_buffer_get_zsv_opts(buff);
239
+ struct zsv_sqlite3_db *zdb = zsv_sqlite3_db_new(&dbopts);
240
+ sqlite3_str *sql_str = NULL;
241
+ struct pivot_data *pd = NULL;
242
+ if (!zdb || !(sql_str = sqlite3_str_new(zdb->db)))
243
+ zst = zsvsheet_status_memory;
244
+ else if (zdb->rc == SQLITE_OK && zsv_sqlite3_add_csv_no_dq(zdb, data_filename, &zopts, NULL) == SQLITE_OK) {
245
+ int ok = 0;
246
+ const char *err_msg = NULL;
247
+ if (column_name_expr) {
248
+ sqlite3_str_appendf(sql_str, "select \"%w\" as %#Q, count(1) as Count from data group by \"%w\"", expr, expr,
249
+ expr);
250
+ ok = 1;
251
+ } else {
252
+ int err = 0;
253
+ if (is_constant_expression(zdb->db, expr, &err))
254
+ err_msg = "Please enter an expression that is not a constant";
255
+ else {
256
+ enum check_select_expression_result expr_rc = check_select_expression(zdb->db, expr, &err);
257
+ if (expr_rc != zsv_select_sql_expression_valid)
258
+ err_msg = check_select_expression_result_str(expr_rc);
259
+ else if (!err)
260
+ ok = 1;
261
+ }
262
+ if (!ok) {
263
+ if (err)
264
+ zsvsheet_ui_buffer_set_status(buff, strerror(err));
265
+ else if (err_msg)
266
+ zsvsheet_ui_buffer_set_status(buff, err_msg);
267
+ else
268
+ zsvsheet_ui_buffer_set_status(buff, "Unknown error");
269
+ } else
270
+ sqlite3_str_appendf(sql_str, "select %s as %#Q, count(1) as Count from data group by %s", expr, expr, expr);
271
+ }
272
+ if (ok) {
273
+ if (!(pd = pivot_data_new(data_filename, expr, column_name_expr)))
274
+ zst = zsvsheet_status_memory;
275
+ else {
276
+ zst = zsv_sqlite3_to_csv(ctx, zdb, sqlite3_str_value(sql_str), &err_msg, pd, pivot_on_header_cell,
277
+ pivot_on_data_cell);
278
+ if (zst != zsvsheet_status_ok) {
279
+ if (zst == zsvsheet_status_no_data)
280
+ zsvsheet_ui_buffer_set_status(buff, "No results returned");
281
+ else
282
+ zsvsheet_ui_buffer_set_status(buff, err_msg ? err_msg : "Unexpected error preparing SQL");
283
+ } else {
284
+ buff = zsvsheet_buffer_current(ctx);
285
+ zsvsheet_buffer_set_ctx(buff, pd, pivot_data_delete);
286
+ zsvsheet_buffer_set_cell_attrs(buff, get_cell_attrs);
287
+ zsvsheet_buffer_on_newline(buff, pivot_drill_down);
288
+ pd = NULL; // so that it isn't cleaned up below
289
+
290
+ while (!zsvsheet_ui_buffer_index_ready(buff, 0))
291
+ napms(200); // sleep for 200ms, then check index again
292
+ // TO DO: fix this if there is no data!
293
+
294
+ if (selected_cell_str_dup) {
295
+ struct zsvsheet_sheet_context *state = (struct zsvsheet_sheet_context *)ctx->subcommand_context;
296
+ struct zsvsheet_display_info *di = &state->display_info;
297
+ zsvsheet_check_buffer_worker_updates(buff, di->dimensions, NULL);
298
+ zsvsheet_handle_find_next(di, buff, selected_cell_str_dup,
299
+ 1, // find value in first column
300
+ 1, // exact
301
+ 1, // header_span
302
+ di->dimensions, &di->update_buffer, NULL);
303
+ }
304
+ }
305
+ }
306
+ }
307
+ // TO DO: add param to ext_sheet_open_file to set filename vs data_filename, and set buffer type or proc owner
308
+ // TO DO: add way to attach custom context, and custom context destructor, to the new buffer
309
+ // TO DO: add cell highlighting
310
+ }
311
+
312
+ zsv_sqlite3_db_delete(zdb);
313
+ if (sql_str)
314
+ sqlite3_free(sqlite3_str_finish(sql_str));
315
+ pivot_data_delete(pd);
316
+ free(selected_cell_str_dup);
317
+ return zst;
318
+ }
@@ -0,0 +1,134 @@
1
+ #include "procedure.h"
2
+
3
+ #if 0
4
+ #define proc_debug(...) fprintf(stderr, __VA_ARGS__)
5
+ #else
6
+ #define proc_debug(...) ((void)0)
7
+ #endif
8
+
9
+ #define MAX_PROCEDURES 512
10
+
11
+ /* Each procedure can be given a name and in the future argument specification
12
+ * so it can be typed from the procedureline. Simple procedure like call motion
13
+ * don't can omit a name meaning they can only be executed via key binding.
14
+ */
15
+ struct zsvsheet_procedure {
16
+ zsvsheet_proc_id_t id;
17
+ const char *name;
18
+ const char *description;
19
+ zsvsheet_proc_fn handler;
20
+ };
21
+
22
+ /* This array both stores procedures and works as a lookup table. */
23
+ static struct zsvsheet_procedure procedure_lookup[MAX_PROCEDURES] = {0};
24
+
25
+ static inline bool is_valid_proc_id(zsvsheet_proc_id_t id) {
26
+ return (0 < id && id < MAX_PROCEDURES);
27
+ }
28
+
29
+ struct zsvsheet_procedure *zsvsheet_find_procedure(zsvsheet_proc_id_t proc_id) {
30
+ struct zsvsheet_procedure *proc;
31
+ if (!is_valid_proc_id(proc_id))
32
+ return NULL;
33
+ proc = &procedure_lookup[proc_id];
34
+ if (proc->id == ZSVSHEET_PROC_INVALID)
35
+ return NULL;
36
+ assert(proc->id == proc_id);
37
+ return proc;
38
+ }
39
+
40
+ struct zsvsheet_procedure *zsvsheet_find_procedure_by_name(const char *name) {
41
+ struct zsvsheet_procedure *proc;
42
+ if (!name)
43
+ return NULL;
44
+ for (int i = 0; i < MAX_PROCEDURES; ++i) {
45
+ proc = &procedure_lookup[i];
46
+ if (is_valid_proc_id(proc->id) && proc->name && !strcmp(name, proc->name))
47
+ return proc;
48
+ }
49
+ return NULL;
50
+ }
51
+
52
+ static zsvsheet_proc_id_t zsvsheet_generate_proc_id(void) {
53
+ for (zsvsheet_proc_id_t id = MAX_PROCEDURES - 1; id > ZSVSHEET_PROC_INVALID; --id) {
54
+ if (!is_valid_proc_id(procedure_lookup[id].id))
55
+ return id;
56
+ }
57
+ return ZSVSHEET_PROC_INVALID;
58
+ }
59
+
60
+ zsvsheet_status zsvsheet_proc_invoke(zsvsheet_proc_id_t proc_id, struct zsvsheet_proc_context *ctx) {
61
+ proc_debug("invoke proc %d\n", proc_id);
62
+ struct zsvsheet_procedure *proc = zsvsheet_find_procedure(proc_id);
63
+ if (proc) {
64
+ proc_debug("call proc %d handler %p\n", proc->id, proc->handler);
65
+ return proc->handler(ctx);
66
+ }
67
+ return -1;
68
+ }
69
+
70
+ zsvsheet_status zsvsheet_proc_invoke_from_keypress(zsvsheet_proc_id_t proc_id, int ch, void *subcommand_context) {
71
+ struct zsvsheet_proc_context context = {
72
+ .proc_id = proc_id,
73
+ .invocation.type = zsvsheet_proc_invocation_type_keypress,
74
+ .invocation.interactive = true,
75
+ .invocation.u.keypress.ch = ch,
76
+ .subcommand_context = subcommand_context,
77
+ };
78
+ return zsvsheet_proc_invoke(proc_id, &context);
79
+ }
80
+
81
+ zsvsheet_status zsvsheet_proc_invoke_from_command(const char *command, struct zsvsheet_proc_context *context) {
82
+ char *toks[10] = {0};
83
+ char tokbuf[1024];
84
+ struct zsvsheet_lexer lexer;
85
+ char *proc_name;
86
+ struct zsvsheet_procedure *proc;
87
+
88
+ proc_debug("invoke from command: %s\n", command);
89
+ zsvsheet_lexer_init(&lexer, command, tokbuf, sizeof(tokbuf), toks, sizeof(toks) / sizeof(toks[0]));
90
+
91
+ if (zsvsheet_lexer_parse(&lexer) != zsvsheet_lexer_status_ok)
92
+ goto out;
93
+ if (lexer.num_toks == 0 || lexer.num_toks - 1 > ZSVSHEET_PROC_MAX_ARGS)
94
+ goto out;
95
+
96
+ proc_name = lexer.toks[0];
97
+ proc = zsvsheet_find_procedure_by_name(proc_name);
98
+ if (!proc)
99
+ goto out;
100
+
101
+ /* Prototypes can be added to procedures to specify what exact arguments they
102
+ * take. Here the arguments could be validated and typechecked against the
103
+ * prototype. For now we just pass the parameters as they are */
104
+ context->proc_id = proc->id;
105
+ context->num_params = lexer.num_toks - 1;
106
+ for (int i = 0; i < context->num_params; ++i)
107
+ context->params[i].u.string = lexer.toks[i + 1];
108
+
109
+ return zsvsheet_proc_invoke(proc->id, context);
110
+ out:
111
+ return zsvsheet_status_error;
112
+ }
113
+
114
+ static zsvsheet_proc_id_t zsvsheet_do_register_proc(struct zsvsheet_procedure *proc) {
115
+ proc_debug("register proc %d %s\n", proc->id, proc->name ? proc->name : "(unnamed)");
116
+ if (!is_valid_proc_id(proc->id))
117
+ return -1;
118
+ if (zsvsheet_find_procedure(proc->id))
119
+ return -1;
120
+ procedure_lookup[proc->id] = *proc;
121
+ return proc->id;
122
+ }
123
+
124
+ zsvsheet_proc_id_t zsvsheet_register_builtin_proc(zsvsheet_proc_id_t id, const char *name, const char *description,
125
+ zsvsheet_proc_fn handler) {
126
+ struct zsvsheet_procedure procedure = {.id = id, .name = name, .description = description, .handler = handler};
127
+ return zsvsheet_do_register_proc(&procedure);
128
+ }
129
+
130
+ zsvsheet_proc_id_t zsvsheet_register_proc(const char *name, const char *description, zsvsheet_proc_fn handler) {
131
+ struct zsvsheet_procedure procedure = {
132
+ .id = zsvsheet_generate_proc_id(), .name = name, .description = description, .handler = handler};
133
+ return zsvsheet_do_register_proc(&procedure);
134
+ }
@@ -0,0 +1,119 @@
1
+ #ifndef ZSVSHEET_PROCEDURE_H
2
+ #define ZSVSHEET_PROCEDURE_H
3
+ #include <stdbool.h>
4
+ #include <zsv/ext.h>
5
+
6
+ /* ID's of bulitin procedures, extensions can register more.
7
+ *
8
+ * TODO: What specific procedures are bulitin and what are their
9
+ * id's is not a concern of the procedure system. This should
10
+ * be defined by the registrar who defines those procedures,
11
+ * in this case sheet. move it out of here at some point.
12
+ */
13
+ enum {
14
+ zsvsheet_builtin_proc_unknown = 0,
15
+ zsvsheet_builtin_proc_quit,
16
+ zsvsheet_builtin_proc_escape,
17
+ zsvsheet_builtin_proc_move_bottom,
18
+ zsvsheet_builtin_proc_move_top,
19
+ zsvsheet_builtin_proc_move_first_col,
20
+ zsvsheet_builtin_proc_pg_down,
21
+ zsvsheet_builtin_proc_pg_up,
22
+ zsvsheet_builtin_proc_move_last_col,
23
+ zsvsheet_builtin_proc_move_up,
24
+ zsvsheet_builtin_proc_move_down,
25
+ zsvsheet_builtin_proc_move_left,
26
+ zsvsheet_builtin_proc_move_right,
27
+ zsvsheet_builtin_proc_filter,
28
+ zsvsheet_builtin_proc_filter_this,
29
+ zsvsheet_builtin_proc_sqlfilter,
30
+ zsvsheet_builtin_proc_find,
31
+ zsvsheet_builtin_proc_find_next,
32
+ zsvsheet_builtin_proc_goto_column,
33
+ zsvsheet_builtin_proc_open_file,
34
+ zsvsheet_builtin_proc_resize,
35
+ zsvsheet_builtin_proc_prompt,
36
+ zsvsheet_builtin_proc_subcommand,
37
+ zsvsheet_builtin_proc_help,
38
+ zsvsheet_builtin_proc_vim_g_key_binding_dmux,
39
+ zsvsheet_builtin_proc_newline,
40
+ zsvsheet_builtin_proc_pivot_expr,
41
+ zsvsheet_builtin_proc_pivot_cur_col,
42
+ zsvsheet_builtin_proc_errors,
43
+ zsvsheet_builtin_proc_errors_clear
44
+ };
45
+
46
+ #define ZSVSHEET_PROC_INVALID 0
47
+ #define ZSVSHEET_PROC_MAX_ARGS 5
48
+
49
+ /* Procedures perform various actions in the editor. Procedures can be invoked
50
+ * by key-bindings, prompt invocation, another procedure or script. */
51
+
52
+ enum zsvsheet_proc_invocation_type {
53
+ zsvsheet_proc_invocation_type_keypress,
54
+ zsvsheet_proc_invocation_type_proc,
55
+ /* Add more... */
56
+ };
57
+
58
+ struct zsvsheet_proc_context {
59
+ zsvsheet_proc_id_t proc_id;
60
+ /* Information about how this procedure was called i.e. through a keypress,
61
+ * command invocation, another procedure, a script etc... */
62
+ struct {
63
+ enum zsvsheet_proc_invocation_type type;
64
+
65
+ /* Can we prompt user to type-in parameters? If not prompt_get should fail. */
66
+ bool interactive;
67
+
68
+ /* Type specific info */
69
+ union {
70
+ struct {
71
+ int ch;
72
+ } keypress;
73
+ struct {
74
+ zsvsheet_proc_id_t id;
75
+ } proc;
76
+ } u;
77
+ } invocation;
78
+
79
+ int num_params;
80
+ struct {
81
+ /* TODO: typing */
82
+ union {
83
+ const char *string;
84
+ } u;
85
+ } params[ZSVSHEET_PROC_MAX_ARGS];
86
+
87
+ /* Within context of which subcommand has this proc been called? */
88
+ void *subcommand_context;
89
+ };
90
+
91
+ enum zsvsheet_proc_arg_type {
92
+ ZSVSHEET_PROC_ARG_TYPE_INVALID,
93
+ ZSVSHEET_PROC_ARG_TYPE_INT,
94
+ ZSVSHEET_PROC_ARG_TYPE_STRING,
95
+ };
96
+
97
+ typedef zsvsheet_status (*zsvsheet_proc_fn)(struct zsvsheet_proc_context *ctx);
98
+
99
+ /* Wrapper for procedure invocation from keypress */
100
+ zsvsheet_status zsvsheet_proc_invoke_from_keypress(zsvsheet_proc_id_t proc_id, int ch, void *subcommand_context);
101
+
102
+ /* Invoke a procedure based on subcommand/script statement. For script support
103
+ * this is likely too simple but its a nice simple API subcommand. */
104
+ zsvsheet_status zsvsheet_proc_invoke_from_command(const char *command, struct zsvsheet_proc_context *context);
105
+
106
+ /* Base proc invocation function */
107
+ zsvsheet_status zsvsheet_proc_invoke(zsvsheet_proc_id_t proc_id, struct zsvsheet_proc_context *ctx);
108
+
109
+ /* Register builtin procedure with fixed id */
110
+ zsvsheet_proc_id_t zsvsheet_register_builtin_proc(zsvsheet_proc_id_t id, const char *name, const char *description,
111
+ zsvsheet_proc_fn handler);
112
+
113
+ /* Dynamically register a procedure, returns a positive id or negative error */
114
+ zsvsheet_proc_id_t zsvsheet_register_proc(const char *name, const char *description, zsvsheet_proc_fn handler);
115
+
116
+ /* Find procedure by name */
117
+ struct zsvsheet_procedure *zsvsheet_find_procedure_by_name(const char *name);
118
+
119
+ #endif /* ZSVSHEET_PROCEDURE_H */