// SPDX-FileCopyrightText: 2024 Redict Contributors // SPDX-FileCopyrightText: 2024 Salvatore Sanfilippo // // SPDX-License-Identifier: BSD-3-Clause // SPDX-License-Identifier: LGPL-3.0-only #include "redictmodule.h" #define UNUSED(V) ((void) V) int cmd_set(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) { UNUSED(argv); UNUSED(argc); RedictModule_ReplyWithSimpleString(ctx, "OK"); return REDICTMODULE_OK; } int cmd_get(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) { UNUSED(argv); if (argc > 4) /* For testing */ return RedictModule_WrongArity(ctx); RedictModule_ReplyWithSimpleString(ctx, "OK"); return REDICTMODULE_OK; } int cmd_get_fullname(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) { UNUSED(argv); UNUSED(argc); const char *command_name = RedictModule_GetCurrentCommandName(ctx); RedictModule_ReplyWithSimpleString(ctx, command_name); return REDICTMODULE_OK; } int RedictModule_OnLoad(RedictModuleCtx *ctx, RedictModuleString **argv, int argc) { REDICTMODULE_NOT_USED(argv); REDICTMODULE_NOT_USED(argc); if (RedictModule_Init(ctx, "subcommands", 1, REDICTMODULE_APIVER_1) == REDICTMODULE_ERR) return REDICTMODULE_ERR; /* Module command names cannot contain special characters. */ RedictModule_Assert(RedictModule_CreateCommand(ctx,"subcommands.char\r",NULL,"",0,0,0) == REDICTMODULE_ERR); RedictModule_Assert(RedictModule_CreateCommand(ctx,"subcommands.char\n",NULL,"",0,0,0) == REDICTMODULE_ERR); RedictModule_Assert(RedictModule_CreateCommand(ctx,"subcommands.char ",NULL,"",0,0,0) == REDICTMODULE_ERR); if (RedictModule_CreateCommand(ctx,"subcommands.bitarray",NULL,"",0,0,0) == REDICTMODULE_ERR) return REDICTMODULE_ERR; RedictModuleCommand *parent = RedictModule_GetCommand(ctx,"subcommands.bitarray"); if (RedictModule_CreateSubcommand(parent,"set",cmd_set,"",0,0,0) == REDICTMODULE_ERR) return REDICTMODULE_ERR; /* Module subcommand names cannot contain special characters. */ RedictModule_Assert(RedictModule_CreateSubcommand(parent,"char|",cmd_set,"",0,0,0) == REDICTMODULE_ERR); RedictModule_Assert(RedictModule_CreateSubcommand(parent,"char@",cmd_set,"",0,0,0) == REDICTMODULE_ERR); RedictModule_Assert(RedictModule_CreateSubcommand(parent,"char=",cmd_set,"",0,0,0) == REDICTMODULE_ERR); RedictModuleCommand *subcmd = RedictModule_GetCommand(ctx,"subcommands.bitarray|set"); RedictModuleCommandInfo cmd_set_info = { .version = REDICTMODULE_COMMAND_INFO_VERSION, .key_specs = (RedictModuleCommandKeySpec[]){ { .flags = REDICTMODULE_CMD_KEY_RW | REDICTMODULE_CMD_KEY_UPDATE, .begin_search_type = REDICTMODULE_KSPEC_BS_INDEX, .bs.index.pos = 1, .find_keys_type = REDICTMODULE_KSPEC_FK_RANGE, .fk.range = {0,1,0} }, {0} } }; if (RedictModule_SetCommandInfo(subcmd, &cmd_set_info) == REDICTMODULE_ERR) return REDICTMODULE_ERR; if (RedictModule_CreateSubcommand(parent,"get",cmd_get,"",0,0,0) == REDICTMODULE_ERR) return REDICTMODULE_ERR; subcmd = RedictModule_GetCommand(ctx,"subcommands.bitarray|get"); RedictModuleCommandInfo cmd_get_info = { .version = REDICTMODULE_COMMAND_INFO_VERSION, .key_specs = (RedictModuleCommandKeySpec[]){ { .flags = REDICTMODULE_CMD_KEY_RO | REDICTMODULE_CMD_KEY_ACCESS, .begin_search_type = REDICTMODULE_KSPEC_BS_INDEX, .bs.index.pos = 1, .find_keys_type = REDICTMODULE_KSPEC_FK_RANGE, .fk.range = {0,1,0} }, {0} } }; if (RedictModule_SetCommandInfo(subcmd, &cmd_get_info) == REDICTMODULE_ERR) return REDICTMODULE_ERR; /* Get the name of the command currently running. */ if (RedictModule_CreateCommand(ctx,"subcommands.parent_get_fullname",cmd_get_fullname,"",0,0,0) == REDICTMODULE_ERR) return REDICTMODULE_ERR; /* Get the name of the subcommand currently running. */ if (RedictModule_CreateCommand(ctx,"subcommands.sub",NULL,"",0,0,0) == REDICTMODULE_ERR) return REDICTMODULE_ERR; RedictModuleCommand *fullname_parent = RedictModule_GetCommand(ctx,"subcommands.sub"); if (RedictModule_CreateSubcommand(fullname_parent,"get_fullname",cmd_get_fullname,"",0,0,0) == REDICTMODULE_ERR) return REDICTMODULE_ERR; /* Sanity */ /* Trying to create the same subcommand fails */ RedictModule_Assert(RedictModule_CreateSubcommand(parent,"get",NULL,"",0,0,0) == REDICTMODULE_ERR); /* Trying to create a sub-subcommand fails */ RedictModule_Assert(RedictModule_CreateSubcommand(subcmd,"get",NULL,"",0,0,0) == REDICTMODULE_ERR); return REDICTMODULE_OK; }