unsigned char sysbench_cmdline_lua[] =
  "-- Copyright (C) 2017-2018 Alexey Kopytov <akopytov@gmail.com>\n"
  "\n"
  "-- This program is free software; you can redistribute it and/or modify\n"
  "-- it under the terms of the GNU General Public License as published by\n"
  "-- the Free Software Foundation; either version 2 of the License, or\n"
  "-- (at your option) any later version.\n"
  "\n"
  "-- This program is distributed in the hope that it will be useful,\n"
  "-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
  "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
  "-- GNU General Public License for more details.\n"
  "\n"
  "-- You should have received a copy of the GNU General Public License\n"
  "-- along with this program; if not, write to the Free Software\n"
  "-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n"
  "\n"
  "-- ----------------------------------------------------------------------\n"
  "-- Command line option handling\n"
  "-- ----------------------------------------------------------------------\n"
  "\n"
  "ffi = require(\"ffi\")\n"
  "\n"
  "ffi.cdef[[\n"
  "/* The following has been copied from sb_option.h */\n"
  "\n"
  "typedef enum\n"
  "{\n"
  "  SB_ARG_TYPE_NULL,\n"
  "  SB_ARG_TYPE_BOOL,\n"
  "  SB_ARG_TYPE_INT,\n"
  "  SB_ARG_TYPE_SIZE,\n"
  "  SB_ARG_TYPE_DOUBLE,\n"
  "  SB_ARG_TYPE_STRING,\n"
  "  SB_ARG_TYPE_LIST,\n"
  "  SB_ARG_TYPE_FILE,\n"
  "  SB_ARG_TYPE_MAX\n"
  "} sb_arg_type_t;\n"
  "\n"
  "/* Option validation function */\n"
  "typedef bool sb_opt_validate_t(const char *, const char *);\n"
  "\n"
  "/* Test option definition */\n"
  "typedef struct\n"
  "{\n"
  "  const char         *name;\n"
  "  const char         *desc;\n"
  "  const char         *value;\n"
  "  sb_arg_type_t      type;\n"
  "  sb_opt_validate_t  *validate;\n"
  "} sb_arg_t;\n"
  "\n"
  "int sb_lua_set_test_args(sb_arg_t *args, size_t len);\n"
  "]]\n"
  "\n"
  "sysbench.cmdline.ARG_NULL = ffi.C.SB_ARG_TYPE_NULL\n"
  "sysbench.cmdline.ARG_BOOL = ffi.C.SB_ARG_TYPE_BOOL\n"
  "sysbench.cmdline.ARG_INT = ffi.C.SB_ARG_TYPE_INT\n"
  "sysbench.cmdline.ARG_SIZE = ffi.C.SB_ARG_TYPE_SIZE\n"
  "sysbench.cmdline.ARG_DOUBLE = ffi.C.SB_ARG_TYPE_DOUBLE\n"
  "sysbench.cmdline.ARG_STRING = ffi.C.SB_ARG_TYPE_STRING\n"
  "sysbench.cmdline.ARG_LIST = ffi.C.SB_ARG_TYPE_LIST\n"
  "sysbench.cmdline.ARG_FILE = ffi.C.SB_ARG_TYPE_FILE\n"
  "sysbench.cmdline.ARG_MAX = ffi.C.SB_ARG_TYPE_MAX\n"
  "\n"
  "-- Attribute indicating that a custom command can be executed in parallel\n"
  "sysbench.cmdline.PARALLEL_COMMAND = true\n"
  "\n"
  "local arg_types = {\n"
  "   boolean = sysbench.cmdline.ARG_BOOL,\n"
  "   string = sysbench.cmdline.ARG_STRING,\n"
  "   number = sysbench.cmdline.ARG_DOUBLE,\n"
  "   table = sysbench.cmdline.ARG_LIST\n"
  "}\n"
  "\n"
  "local function __genOrderedIndex( t )\n"
  "   local orderedIndex = {}\n"
  "   for key in pairs(t) do\n"
  "      table.insert( orderedIndex, key )\n"
  "   end\n"
  "   table.sort( orderedIndex )\n"
  "   return orderedIndex\n"
  "end\n"
  "\n"
  "local function orderedNext(t, state)\n"
  "   local key = nil\n"
  "   if state == nil then\n"
  "      t.__orderedIndex = __genOrderedIndex( t )\n"
  "      key = t.__orderedIndex[1]\n"
  "   else\n"
  "      for i = 1,table.getn(t.__orderedIndex) do\n"
  "         if t.__orderedIndex[i] == state then\n"
  "            key = t.__orderedIndex[i+1]\n"
  "         end\n"
  "      end\n"
  "   end\n"
  "\n"
  "   if key then\n"
  "      return key, t[key]\n"
  "   end\n"
  "\n"
  "   t.__orderedIndex = nil\n"
  "   return\n"
  "end\n"
  "\n"
  "local function orderedPairs(t)\n"
  "   return orderedNext, t, nil\n"
  "end\n"
  "\n"
  "-- Parse command line options definitions, if present in the script as a\n"
  "-- 'sysbench.cmdline.options' table. If no such table exists, or if there a\n"
  "-- parsing error, return false. Return true on success. After parsing the\n"
  "-- command line arguments, option values are available as the sysbench.opt\n"
  "-- table.\n"
  "function sysbench.cmdline.read_cmdline_options()\n"
  "   if sysbench.cmdline.options == nil then\n"
  "      return true\n"
  "   end\n"
  "\n"
  "   local t = type(sysbench.cmdline.options)\n"
  "   assert(t == \"table\", \"wrong type for sysbench.cmdline.options: \" .. t)\n"
  "\n"
  "   local i = 0\n"
  "   for name, def in pairs(sysbench.cmdline.options) do\n"
  "      i = i+1\n"
  "   end\n"
  "\n"
  "   local args = ffi.new('sb_arg_t[?]', i)\n"
  "   i = 0\n"
  "\n"
  "   for name, def in orderedPairs(sysbench.cmdline.options) do\n"
  "      -- name\n"
  "      assert(type(name) == \"string\" and type(def) == \"table\",\n"
  "             \"wrong table structure in sysbench.cmdline.options\")\n"
  "      args[i].name = name\n"
  "\n"
  "      -- description\n"
  "      assert(def[1] ~= nil, \"nil description for option \" .. name)\n"
  "      args[i].desc = def[1]\n"
  "\n"
  "      if type(def[2]) == \"table\" then\n"
  "         assert(type(def[3]) == \"nil\" or\n"
  "                   type(def[3]) == sysbench.cmdline.ARG_LIST,\n"
  "                \"wrong type for list option \" .. name)\n"
  "         args[i].value = table.concat(def[2], ',')\n"
  "      else\n"
  "         if type(def[2]) == \"boolean\" then\n"
  "            args[i].value = def[2] and 'on' or 'off'\n"
  "         elseif type(def[2]) == \"number\" then\n"
  "            args[i].value = tostring(def[2])\n"
  "         else\n"
  "            args[i].value = def[2]\n"
  "         end\n"
  "      end\n"
  "\n"
  "      -- type\n"
  "      local t = def[3]\n"
  "      if t == nil then\n"
  "         if def[2] ~= nil then\n"
  "            -- Try to determine the type by the default value\n"
  "            t = arg_types[type(def[2])]\n"
  "         else\n"
  "            t = sysbench.cmdline.ARG_STRING\n"
  "         end\n"
  "      end\n"
  "\n"
  "      assert(t ~= nil, \"cannot determine type for option \" .. name)\n"
  "      args[i].type = t\n"
  "\n"
  "      -- validation function\n"
  "      args[i].validate = def[4]\n"
  "\n"
  "      i = i + 1\n"
  "   end\n"
  "\n"
  "   return ffi.C.sb_lua_set_test_args(args, i) == 0\n"
  "end\n"
  "\n"
  "function sysbench.cmdline.command_defined(name)\n"
  "   return type(sysbench.cmdline.commands) == \"table\" and\n"
  "      sysbench.cmdline.commands[name] ~= nil and\n"
  "      sysbench.cmdline.commands[name][1] ~= nil\n"
  "end\n"
  "\n"
  "function sysbench.cmdline.command_parallel(name)\n"
  "   return sysbench.cmdline.command_defined(name) and\n"
  "      sysbench.cmdline.commands[name][2] == sysbench.cmdline.PARALLEL_COMMAND\n"
  "end\n"
  "\n"
  "function sysbench.cmdline.call_command(name)\n"
  "   if not sysbench.cmdline.command_defined(name) then\n"
  "      return false\n"
  "   end\n"
  "\n"
  "   local rc = sysbench.cmdline.commands[name][1]()\n"
  "\n"
  "   if rc == nil then\n"
  "      -- handle the case when the command does not return and value as success\n"
  "      return true\n"
  "   else\n"
  "      -- otherwise return success for any returned value other than false\n"
  "      return rc and true or false\n"
  "   end\n"
  "end\n"
  "\n"
  "ffi.cdef[[\n"
  "void sb_print_test_options(void);\n"
  "]]\n"
  "\n"
  "-- ----------------------------------------------------------------------\n"
  "-- Print descriptions of command line options, if defined by\n"
  "-- sysbench.cmdline.options\n"
  "-- ----------------------------------------------------------------------\n"
  "function sysbench.cmdline.print_test_options()\n"
  "   ffi.C.sb_print_test_options()\n"
  "end\n"
;
size_t sysbench_cmdline_lua_len = sizeof(sysbench_cmdline_lua) - 1;
