Files
bshell/bshell.runtime/verb.c
T
2026-05-30 19:51:29 +01:00

828 lines
18 KiB
C

#include <bshell/status.h>
#include <bshell/verb.h>
#include <fx/reflection/function.h>
#include <fx/reflection/property.h>
#include <fx/string.h>
#include <fx/vector.h>
struct bshell_verb_p {
enum bshell_verb_id v_id;
const char *v_name;
const char *v_alias_prefix;
const char *v_group;
const char *v_description;
};
bshell_verb *bshell_verb_create(
enum bshell_verb_id id,
const char *name,
const char *alias_prefix,
const char *group,
const char *description)
{
bshell_verb *verb = fx_object_create(BSHELL_TYPE_VERB);
if (!verb) {
return NULL;
}
struct bshell_verb_p *verb_p
= fx_object_get_private(verb, BSHELL_TYPE_VERB);
verb_p->v_id = id;
verb_p->v_name = name;
verb_p->v_alias_prefix = alias_prefix;
verb_p->v_group = group;
verb_p->v_description = description;
return verb;
}
static bool verb_is_reserved(const struct bshell_verb_p *verb)
{
return !strcmp(verb->v_group, "Reserved");
}
static enum bshell_verb_id verb_get_id(const struct bshell_verb_p *verb)
{
return verb->v_id;
}
static const char *verb_get_name(const struct bshell_verb_p *verb)
{
return verb->v_name;
}
bool bshell_verb_is_reserved(const bshell_verb *verb)
{
FX_CLASS_DISPATCH_STATIC_0(BSHELL_TYPE_VERB, verb_is_reserved, verb);
}
enum bshell_verb_id bshell_verb_get_id(const bshell_verb *verb)
{
FX_CLASS_DISPATCH_STATIC_0(BSHELL_TYPE_VERB, verb_get_id, verb);
}
const char *bshell_verb_get_name(const bshell_verb *verb)
{
FX_CLASS_DISPATCH_STATIC_0(BSHELL_TYPE_VERB, verb_get_name, verb);
}
static fx_status get_name(
const fx_value *verb_v,
const fx_property *prop,
fx_value *out)
{
bshell_verb *verb = NULL;
fx_value_get_object(verb_v, &verb);
struct bshell_verb_p *verb_p
= fx_object_get_private(verb, BSHELL_TYPE_VERB);
*out = FX_CSTR(verb_p->v_name);
return FX_SUCCESS;
}
static fx_status get_alias_prefix(
const fx_value *verb_v,
const fx_property *prop,
fx_value *out)
{
bshell_verb *verb = NULL;
fx_value_get_object(verb_v, &verb);
struct bshell_verb_p *verb_p
= fx_object_get_private(verb, BSHELL_TYPE_VERB);
*out = FX_CSTR(verb_p->v_alias_prefix);
return FX_SUCCESS;
}
static fx_status get_group(
const fx_value *verb_v,
const fx_property *prop,
fx_value *out)
{
bshell_verb *verb = NULL;
fx_value_get_object(verb_v, &verb);
struct bshell_verb_p *verb_p
= fx_object_get_private(verb, BSHELL_TYPE_VERB);
*out = FX_CSTR(verb_p->v_group);
return FX_SUCCESS;
}
static fx_status get_description(
const fx_value *verb_v,
const fx_property *prop,
fx_value *out)
{
bshell_verb *verb = NULL;
fx_value_get_object(verb_v, &verb);
struct bshell_verb_p *verb_p
= fx_object_get_private(verb, BSHELL_TYPE_VERB);
*out = FX_CSTR(verb_p->v_description);
return FX_SUCCESS;
}
static void verb_fini(fx_object *obj, void *priv)
{
struct bshell_verb_p *verb = priv;
}
FX_TYPE_CLASS_BEGIN(bshell_verb)
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = NULL;
FX_TYPE_VTABLE_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
FX_TYPE_PROPERTY("verb", get_name, NULL);
FX_TYPE_PROPERTY("alias_prefix", get_alias_prefix, NULL);
FX_TYPE_PROPERTY("group", get_group, NULL);
FX_TYPE_PROPERTY("description", get_description, NULL);
FX_TYPE_CONSTRUCTOR("create", bshell_verb_create, 0, FX_TYPE_VOID);
FX_TYPE_CLASS_END(bshell_verb)
FX_TYPE_DEFINITION_BEGIN(bshell_verb)
FX_TYPE_ID(0x90eb98eb, 0x5497, 0x47a7, 0x923c, 0x01538c070f21);
FX_TYPE_NAME("bshell.verb");
FX_TYPE_CLASS(bshell_verb_class);
FX_TYPE_INSTANCE_PRIVATE(struct bshell_verb_p);
FX_TYPE_INSTANCE_FINI(verb_fini);
FX_TYPE_DEFINITION_END(bshell_verb)
static fx_hashtable *all_verbs_by_name = NULL;
static bshell_verb *all_verbs_by_id[__BSHELL_VERB_MAX] = {};
#define PUT_VERB(id, name, prefix, group, desc) \
do { \
bshell_verb *verb = bshell_verb_create( \
BSHELL_VERB_##id, \
name, \
prefix, \
group, \
desc); \
if (!verb) { \
return BSHELL_ERR_NO_MEMORY; \
} \
all_verbs_by_id[BSHELL_VERB_##id] = verb; \
fx_string *name_lower = fx_string_create_from_cstr(name); \
fx_string_transform_lowercase(name_lower); \
fx_hashtable_put( \
all_verbs_by_name, \
&FX_VALUE_OBJECT(name_lower), \
&FX_VALUE_OBJECT(verb)); \
fx_string_unref(name_lower); \
bshell_verb_unref(verb); \
} while (0)
#define PUT_RESERVED_VERB(id, name, prefix) \
do { \
bshell_verb *verb = bshell_verb_create( \
BSHELL_VERB_##id, \
name, \
prefix, \
"Reserved", \
NULL); \
if (!verb) { \
return BSHELL_ERR_NO_MEMORY; \
} \
all_verbs_by_id[BSHELL_VERB_##id] = verb; \
fx_string *name_lower = fx_string_create_from_cstr(name); \
fx_string_transform_lowercase(name_lower); \
fx_hashtable_put( \
all_verbs_by_name, \
&FX_VALUE_OBJECT(name_lower), \
&FX_VALUE_OBJECT(verb)); \
fx_string_unref(name_lower); \
bshell_verb_unref(verb); \
} while (0)
enum bshell_status bshell_init_all_verbs(void)
{
all_verbs_by_name = fx_hashtable_create();
PUT_VERB(
ADD,
"Add",
"a",
"Common",
"Adds a resource to a container, or attaches an item to "
"another item");
PUT_VERB(
CLEAR,
"Clear",
"cl",
"Common",
"Removes all the resources from a container but does not "
"delete the container");
PUT_VERB(
CLOSE,
"Close",
"cs",
"Common",
"Changes the state of a resource to make it inaccessible, "
"unavailable, or unusable");
PUT_VERB(
COPY,
"Copy",
"cp",
"Common",
"Copies a resource to another name or to another container");
PUT_VERB(
ENTER,
"Enter",
"et",
"Common",
"Specifies an action that allows the user to move into a "
"resource");
PUT_VERB(
EXIT,
"Exit",
"ex",
"Common",
"Sets the current environment or context to the most recently "
"used context");
PUT_VERB(
FIND,
"Find",
"fd",
"Common",
"Looks for an object in a container that is unknown, implied, "
"optional, or specified");
PUT_VERB(
FORMAT,
"Format",
"f",
"Common",
"Arranges objects in a specified form or layout");
PUT_VERB(
GET,
"Get",
"g",
"Common",
"Specifies an action that retrieves a resource");
PUT_VERB(HIDE, "Hide", "h", "Common", "Makes a resource undetectable");
PUT_VERB(
JOIN,
"Join",
"j",
"Common",
"Combines resources into one resource");
PUT_VERB(LOCK, "Lock", "lk", "Common", "Secures a resource");
PUT_VERB(
MOVE,
"Move",
"m",
"Common",
"Moves a resource from one location to another");
PUT_VERB(NEW, "New", "n", "Common", "Creates a resource");
PUT_VERB(
OPEN,
"Open",
"op",
"Common",
"Changes the state of a resource to make it accessible, "
"available, or usable");
PUT_VERB(
OPTIMIZE,
"Optimize",
"om",
"Common",
"Increases the effectiveness of a resource");
PUT_VERB(
PUSH,
"Push",
"pu",
"Common",
"Adds an item to the top of a stack");
PUT_VERB(
POP,
"Pop",
"pop",
"Common",
"Removes an item from the top of a stack");
PUT_VERB(
REDO,
"Redo",
"re",
"Common",
"Resets a resource to the state that was undone");
PUT_VERB(
REMOVE,
"Remove",
"r",
"Common",
"Deletes a resource from a container");
PUT_VERB(
RENAME,
"Rename",
"rn",
"Common",
"Changes the name of a resource");
PUT_VERB(
RESET,
"Reset",
"rs",
"Common",
"Sets a resource back to its original state");
PUT_VERB(
RESIZE,
"Resize",
"rz",
"Common",
"Changes the size of a resource");
PUT_VERB(
SEARCH,
"Search",
"sr",
"Common",
"Creates a reference to a resource in a container");
PUT_VERB(
SELECT,
"Select",
"sc",
"Common",
"Locates a resource in a container");
PUT_VERB(
SET,
"Set",
"s",
"Common",
"Replaces data on an existing resource or creates a resource "
"that contains some data");
PUT_VERB(
SHOW,
"Show",
"sh",
"Common",
"Makes a resource visible to the user");
PUT_VERB(
SKIP,
"Skip",
"sk",
"Common",
"Bypasses one or more resources or points in a sequence");
PUT_VERB(
SPLIT,
"Split",
"sl",
"Common",
"Separates parts of a resource");
PUT_VERB(
STEP,
"Step",
"st",
"Common",
"Moves to the next point or resource in a sequence");
PUT_VERB(
SWITCH,
"Switch",
"sw",
"Common",
"Specifies an action that alternates between two resources, "
"such as to change between two locations, responsibilities, or "
"states");
PUT_VERB(
UNDO,
"Undo",
"un",
"Common",
"Sets a resource to its previous state");
PUT_VERB(
UNLOCK,
"Unlock",
"uk",
"Common",
"Releases a resource that was locked");
PUT_VERB(
WATCH,
"Watch",
"wc",
"Common",
"Continually inspects or monitors a resource for changes");
PUT_VERB(
CONNECT,
"Connect",
"cc",
"Communications",
"Creates a link between a source and a destination");
PUT_VERB(
DISCONNECT,
"Disconnect",
"dc",
"Communications",
"Breaks the link between a source and a destination");
PUT_VERB(
RECEIVE,
"Receive",
"rc",
"Communications",
"Accepts information sent from a source");
PUT_VERB(
READ,
"Read",
"rd",
"Communications",
"Acquires information from a source");
PUT_VERB(
SEND,
"Send",
"sd",
"Communications",
"Delivers information to a destination");
PUT_VERB(
WRITE,
"Write",
"wr",
"Communications",
"Adds information to a target");
PUT_VERB(
BACKUP,
"Backup",
"ba",
"Data",
"Stores data by replicating it");
PUT_VERB(
CHECKPOINT,
"Checkpoint",
"ch",
"Data",
"Creates a snapshot of the current state of the data or of its "
"configuration");
PUT_VERB(
COMPARE,
"Compare",
"cr",
"Data",
"Evaluates the data from one resource against the data from "
"another resource");
PUT_VERB(
COMPRESS,
"Compress",
"cm",
"Data",
"Compacts the data of a resource");
PUT_VERB(
CONVERT,
"Convert",
"cv",
"Data",
"Changes the data from one representation to another when the "
"cmdlet supports bidirectional conversion or when the cmdlet "
"supports conversion between multiple data types");
PUT_VERB(
CONVERTFROM,
"ConvertFrom",
"cf",
"Data",
"Converts one primary type of input (the cmdlet noun indicates "
"the input) to one or more supported output types");
PUT_VERB(
CONVERTTO,
"ConvertTo",
"ct",
"Data",
"Converts from one or more types of input to a primary output "
"type (the cmdlet noun indicates the output type)");
PUT_VERB(
DISMOUNT,
"Dismount",
"dm",
"Data",
"Detaches a named entity from a location");
PUT_VERB(
EDIT,
"Edit",
"ed",
"Data",
"Modifies existing data by adding or removing content");
PUT_VERB(
EXPAND,
"Expand",
"en",
"Data",
"Restores the data of a resource that has been compressed to "
"its original state");
PUT_VERB(
EXPORT,
"Export",
"ep",
"Data",
"Encapsulates the primary input into a persistent data store, "
"such as a file, or into an interchange format");
PUT_VERB(
GROUP,
"Group",
"gp",
"Data",
"Arranges or associates one or more resources");
PUT_VERB(
IMPORT,
"Import",
"ip",
"Data",
"Creates a resource from data that is stored in a persistent "
"data store (such as a file) or in an interchange format");
PUT_VERB(
INITIALIZE,
"Initialize",
"in",
"Data",
"Prepares a resource for use, and sets it to a default state");
PUT_VERB(
LIMIT,
"Limit",
"l",
"Data",
"Applies constraints to a resource");
PUT_VERB(
MERGE,
"Merge",
"mg",
"Data",
"Creates a single resource from multiple resources");
PUT_VERB(
MOUNT,
"Mount",
"mt",
"Data",
"Attaches a named entity to a location");
PUT_VERB(OUT, "Out", "o", "Data", "Sends data out of the environment");
PUT_VERB(
PUBLISH,
"Publish",
"pb",
"Data",
"Makes a resource available to others");
PUT_VERB(
RESTORE,
"Restore",
"rr",
"Data",
"Sets a resource to a predefined state, such as a state set by "
"Checkpoint");
PUT_VERB(SAVE, "Save", "sv", "Data", "Preserves data to avoid loss");
PUT_VERB(
SYNC,
"Sync",
"sy",
"Data",
"Assures that two or more resources are in the same state");
PUT_VERB(
UNPUBLISH,
"Unpublish",
"ub",
"Data",
"Makes a resource unavailable to others");
PUT_VERB(
UPDATE,
"Update",
"ud",
"Data",
"Brings a resource up-to-date to maintain its state, accuracy, "
"conformance, or compliance");
PUT_VERB(
DEBUG,
"Debug",
"db",
"Diagnostic",
"Examines a resource to diagnose operational problems");
PUT_VERB(
MEASURE,
"Measure",
"ms",
"Diagnostic",
"Identifies resources that are consumed by a specified "
"operation, or retrieves statistics about a resource");
PUT_VERB(
REPAIR,
"Repair",
"rp",
"Diagnostic",
"Restores a resource to a usable condition");
PUT_VERB(
RESOLVE,
"Resolve",
"rv",
"Diagnostic",
"Maps a shorthand representation of a resource to a more "
"complete representation");
PUT_VERB(
TEST,
"Test",
"t",
"Diagnostic",
"Verifies the operation or consistency of a resource");
PUT_VERB(
TRACE,
"Trace",
"tr",
"Diagnostic",
"Tracks the activities of a resource");
PUT_VERB(
APPROVE,
"Approve",
"ap",
"Lifecycle",
"Confirms or agrees to the status of a resource or process");
PUT_VERB(
ASSERT,
"Assert",
"as",
"Lifecycle",
"Affirms the state of a resource");
PUT_VERB(
BUILD,
"Build",
"bd",
"Lifecycle",
"Creates an artifact (usually a binary or document) out of "
"some set of input files (usually source code or declarative "
"documents)");
PUT_VERB(
COMPLETE,
"Complete",
"cmp",
"Lifecycle",
"Concludes an operation");
PUT_VERB(
CONFIRM,
"Confirm",
"cn",
"Lifecycle",
"Acknowledges, verifies, or validates the state of a resource "
"or process");
PUT_VERB(
DENY,
"Deny",
"dn",
"Lifecycle",
"Refuses, objects, blocks, or opposes the state of a resource "
"or process");
PUT_VERB(
DEPLOY,
"Deploy",
"dp",
"Lifecycle",
"Sends an application, website, or solution to a remote "
"target[s] in such a way that a consumer of that solution can "
"access it after deployment is complete");
PUT_VERB(
DISABLE,
"Disable",
"d",
"Lifecycle",
"Configures a resource to an unavailable or inactive state");
PUT_VERB(
ENABLE,
"Enable",
"e",
"Lifecycle",
"Configures a resource to an available or active state");
PUT_VERB(
INSTALL,
"Install",
"is",
"Lifecycle",
"Places a resource in a location, and optionally initializes "
"it");
PUT_VERB(
INVOKE,
"Invoke",
"i",
"Lifecycle",
"Performs an action, such as running a command or a method");
PUT_VERB(
REGISTER,
"Register",
"rg",
"Lifecycle",
"Creates an entry for a resource in a repository such as a "
"database");
PUT_VERB(
REQUEST,
"Request",
"rq",
"Lifecycle",
"Asks for a resource or asks for permissions");
PUT_VERB(
RESTART,
"Restart",
"rt",
"Lifecycle",
"Stops an operation and then starts it again");
PUT_VERB(
RESUME,
"Resume",
"ru",
"Lifecycle",
"Starts an operation that has been suspended");
PUT_VERB(START, "Start", "sa", "Lifecycle", "Initiates an operation");
PUT_VERB(STOP, "Stop", "sp", "Lifecycle", "Discontinues an activity");
PUT_VERB(
SUBMIT,
"Submit",
"sb",
"Lifecycle",
"Presents a resource for approval");
PUT_VERB(SUSPEND, "Suspend", "ss", "Lifecycle", "Pauses an activity");
PUT_VERB(
UNINSTALL,
"Uninstall",
"us",
"Lifecycle",
"Removes a resource from an indicated location");
PUT_VERB(
UNREGISTER,
"Unregister",
"ur",
"Lifecycle",
"Removes the entry for a resource from a repository");
PUT_VERB(
WAIT,
"Wait",
"w",
"Lifecycle",
"Pauses an operation until a specified event occurs");
PUT_VERB(
USE,
"Use",
"u",
"Other",
"Uses or includes a resource to do something");
PUT_VERB(
BLOCK,
"Block",
"bl",
"Security",
"Restricts access to a resource");
PUT_VERB(
GRANT,
"Grant",
"gr",
"Security",
"Allows access to a resource");
PUT_VERB(
PROTECT,
"Protect",
"pt",
"Security",
"Safeguards a resource from attack or loss");
PUT_VERB(
REVOKE,
"Revoke",
"rk",
"Security",
"Specifies an action that does not allow access to a resource");
PUT_VERB(
UNBLOCK,
"Unblock",
"ul",
"Security",
"Removes restrictions to a resource");
PUT_VERB(
UNPROTECT,
"Unprotect",
"up",
"Security",
"Removes safeguards from a resource that were added to prevent "
"it from attack or loss");
PUT_RESERVED_VERB(FOREACH, "ForEach", "foreach");
PUT_RESERVED_VERB(PING, "Ping", "pi");
PUT_RESERVED_VERB(SORT, "Sort", "sr");
PUT_RESERVED_VERB(TEE, "Tee", "te");
PUT_RESERVED_VERB(WHERE, "Where", "wh");
return BSHELL_SUCCESS;
}
enum bshell_status bshell_cleanup_all_verbs(void)
{
for (size_t i = 0; i < __BSHELL_VERB_MAX; i++) {
all_verbs_by_id[i] = NULL;
}
fx_hashtable_unref(all_verbs_by_name);
return BSHELL_SUCCESS;
}
fx_hashtable *bshell_get_all_verbs(void)
{
return all_verbs_by_name;
}
bshell_verb *bshell_verb_get_by_id(enum bshell_verb_id id)
{
if (id >= __BSHELL_VERB_MAX) {
return NULL;
}
return all_verbs_by_id[id];
}
bshell_verb *bshell_verb_get_by_name(const char *name)
{
const fx_value *val
= fx_hashtable_get(all_verbs_by_name, &FX_CSTR(name));
if (!val) {
return NULL;
}
bshell_verb *result = NULL;
fx_value_get_object(val, &result);
return result;
}