Skip to content
This repository has been archived by the owner on Oct 15, 2024. It is now read-only.

Commit

Permalink
kdb-cli: add new main.c
Browse files Browse the repository at this point in the history
and add command.h containing helpful macros and a struct def that is
needed later
  • Loading branch information
hannes99 committed Sep 16, 2022
1 parent e3c31c7 commit b2604b5
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 263 deletions.
6 changes: 4 additions & 2 deletions src/tools/kdb/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
include (LibAddMacros)

file (GLOB HDR_FILES *.hpp gen/*.hpp gen/*/*.hpp)
file (GLOB HDR_FILES *.h *.hpp gen/*.hpp gen/*/*.hpp)
add_headers (HDR_FILES)
add_cppheaders (HDR_FILES)
add_toolheaders (HDR_FILES)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})

file (GLOB SRC_FILES *.cpp gen/*.cpp gen/*/*.cpp)
file (GLOB SRC_FILES *.c *.cpp gen/*.cpp gen/*/*.cpp)
list (REMOVE_ITEM SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/gen/templates/collect.cpp")
set (SOURCES ${SRC_FILES} ${HDR_FILES})

add_compile_definitions(CLI_BASE_KEY="/cli/kdb")

add_subdirectory (gen/templates)

if (BUILD_SHARED OR BUILD_FULL)
Expand Down
50 changes: 50 additions & 0 deletions src/tools/kdb/command.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* @file
*
* @brief
*
* @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
*/

#ifndef COMMAND_H
#define COMMAND_H

#include <kdb.h>

#define ADD_BASIC_OPTIONS(baseSpec, baseKeyName) \
ksAppendKey (baseSpec, keyNew (baseKeyName "/debug", KEY_META, "description", \
"Give debug information or ask debug questions (in interactive mode).", KEY_META, "opt", "d", \
KEY_META, "opt/long", "debug", KEY_META, "opt/arg", "none", KEY_END)); \
ksAppendKey (baseSpec, keyNew (baseKeyName "/verbose", KEY_META, "description", "Explain what is happening.", KEY_META, "opt", \
"v", KEY_META, "opt/long", "verbose", KEY_META, "opt/arg", "none", KEY_END)); \
ksAppendKey (baseSpec, keyNew (baseKeyName "/version", KEY_META, "description", "Print version info.", KEY_META, "opt", "V", \
KEY_META, "opt/long", "version", KEY_META, "opt/arg", "none", KEY_END)); \
ksAppendKey (baseSpec, keyNew (baseKeyName "/profile", KEY_META, "description", "Use a different profile for kdb configuration.", \
KEY_META, "opt", "p", KEY_META, "opt/arg/help", "NAME", KEY_META, "opt/long", "profile", KEY_META, \
"opt/arg", "required", KEY_END)); \
ksAppendKey (baseSpec, keyNew (baseKeyName "/color", KEY_META, "description", "Print never/auto(default)/always colored output.", \
KEY_META, "opt", "c", KEY_META, "opt/arg/help", "WHEN", KEY_META, "opt/long", "color", KEY_META, \
"opt/arg", "required", KEY_END)); \
ksAppendKey (baseSpec, \
keyNew (baseKeyName "/nonewline", KEY_META, "description", "Suppress the newline at the end of the output.", \
KEY_META, "opt", "n", KEY_META, "opt/long", "no-newline", KEY_META, "opt/arg", "none", KEY_END));


#define GET_OPT(options, key) keyString (ksLookupByName (options, "proc:" key, 0))
#define OR(value, def) \
void * tmp = value; \
tmp == NULL ? (def) : tmp
#define GET_ERR(errorKey) keyString (keyGetMeta (errorKey, "error/reason"))
#define COMMAND_BASE_KEY(name) CLI_BASE_KEY "/" name
#define COMMAND_SPEC_KEY(name) "spec:" COMMAND_BASE_KEY (name)

typedef struct command
{
const char * name;
void (*addSpec) (KeySet * spec);
int (*exec) (KeySet * options, Key * errorKey);
int (*checkArgs) (KeySet * options, Key * errorKey);
} command;


#endif // COMMAND_H
105 changes: 105 additions & 0 deletions src/tools/kdb/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/**
* @file
*
* @brief
*
* @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
*/

#include <command.h>
#include <kdb.h>
#include <kdbhelper.h>
#include <kdbopts.h>
#include <stdio.h>
#include <stdlib.h>

#define CLI_SPEC_KEY "spec:" CLI_BASE_KEY

extern char ** environ;

command subcommands[] = {};

void printWarnings (Key * errorKey)
{
const char * warnings = keyString (keyGetMeta (errorKey, "warnings"));
warnings = warnings[1] == '_' ? warnings + 2 : warnings + 1;

int warningsCount = atoi (warnings);
char buff[8 + 1 + 1 + 11 + 1 + 6 + 1];
for (int i = 0; i <= warningsCount; ++i)
{
snprintf (buff, sizeof buff, "warnings/#%d/reason", i);
const char * warning = keyString (keyGetMeta (errorKey, buff));
printf ("WARNING: %s\n", warning);
}
}

int main (int argc, char ** argv)
{
KeySet * options = ksNew (1,
keyNew (CLI_SPEC_KEY, KEY_META, "command", "", KEY_META, "description",
"kdb is a program to manage Elektra's key database.", KEY_END),
KS_END);

for (unsigned long i = 0; i < sizeof (subcommands) / sizeof (subcommands[0]); ++i)
{
subcommands[i].addSpec (options);
}

Key * errorKey = keyNew (CLI_SPEC_KEY, KEY_END);

int result = elektraGetOpts (options, argc, (const char **) argv, (const char **) environ, errorKey);
if (result == -1)
{
// there was an error
fprintf (stderr, "ERROR: %s\n", keyString (keyGetMeta (errorKey, "error/reason")));
keyDel (errorKey);
ksDel (options);
return 1;
}

const char * subcommand = keyString (ksLookupByName (options, CLI_BASE_KEY, 0));
if (elektraStrCmp (subcommand, "") == 0)
{
fprintf (stderr, "kdb is a program to manage Elektra's key database. For more information use --help.\n\n");
}

if (result == 1)
{
// '--help' option was used
char * help = elektraGetOptsHelpMessage (errorKey, NULL, NULL);
fprintf (stderr, "%s\n", help);
elektraFree (help);
keyDel (errorKey);
ksDel (options);
return 0;
}
keyDel (errorKey);
for (unsigned long i = 0; i < sizeof (subcommands) / sizeof (subcommands[0]); ++i)
{
if (elektraStrCmp (subcommand, subcommands[i].name) == 0)
{
errorKey = keyNew (CLI_SPEC_KEY, KEY_END);
result = subcommands[i].checkArgs (options, errorKey);
if (result != 0)
{
fprintf (stderr, "ARG ERROR: %s\n", GET_ERR (errorKey));
keyDel (errorKey);
ksDel (options);
return 1;
}
result = subcommands[i].exec (options, errorKey);
if (result != 0)
{
fprintf (stderr, "ERROR: %s\n", GET_ERR (errorKey));
}
printWarnings (errorKey);
keyDel (errorKey);
ksDel (options);
return result;
}
}
keyDel (errorKey);
ksDel (options);
return 0;
}
Loading

0 comments on commit b2604b5

Please sign in to comment.