mirror of
https://github.com/onyx-and-iris/vmrcli.git
synced 2026-04-08 09:53:32 +00:00
add support for long options
update README minor bump
This commit is contained in:
26
README.md
26
README.md
@@ -27,19 +27,19 @@
|
|||||||
|
|
||||||
### Command Line Options
|
### Command Line Options
|
||||||
|
|
||||||
| Option | Description | Example |
|
| Option | Long Option | Description | Example |
|
||||||
|--------|-------------|----------|
|
|--------|-------------|-------------|---------|
|
||||||
| `-h` | Print help message | `vmrcli.exe -h` |
|
| `-h` | `--help` | Print help message | `vmrcli.exe -h` |
|
||||||
| `-v` | Show version information | `vmrcli.exe -v` |
|
| `-v` | `--version` | Show version information | `vmrcli.exe -v` |
|
||||||
| `-i` | Enable interactive mode | `vmrcli.exe -i` |
|
| `-i` | `--interactive` | Enable interactive mode | `vmrcli.exe -i` |
|
||||||
| `-I` | Interactive mode without prompt | `vmrcli.exe -I` |
|
| `-I` | `--no-prompt` | Interactive mode without prompt | `vmrcli.exe -I` |
|
||||||
| `-f` | Don't split input on spaces | `vmrcli.exe -f` |
|
| `-f` | `--full-line` | Don't split input on spaces | `vmrcli.exe -f` |
|
||||||
| `-k <type>` | Launch Voicemeeter GUI | `-kbasic`, `-kbanana`, `-kpotato` |
|
| `-k <type>` | `--kind <type>` | Launch Voicemeeter GUI | `--kind basic`, `--kind banana`, `--kind potato` |
|
||||||
| `-l <level>` | Set log level | `-lDEBUG`, `-lINFO`, `-lWARN` |
|
| `-l <level>` | `--log-level <level>` | Set log level | `--log-level DEBUG`, `--log-level WARN` |
|
||||||
| `-e` | Enable extra console output | `vmrcli.exe -e` |
|
| `-e` | `--extra-output` | Enable extra console output | `vmrcli.exe -e` |
|
||||||
| `-c <path>` | Load user configuration | `-c "C:\config.txt"` |
|
| `-c <path>` | `--config <path>` | Load user configuration | `--config "C:\config.txt"` |
|
||||||
| `-m` | Launch MacroButtons app | `vmrcli.exe -m` |
|
| `-m` | `--macrobuttons` | Launch MacroButtons app | `vmrcli.exe -m` |
|
||||||
| `-s` | Launch StreamerView app | `vmrcli.exe -s` |
|
| `-s` | `--streamerview` | Launch StreamerView app | `vmrcli.exe -s` |
|
||||||
|
|
||||||
> **Note:** When using interactive mode (`-i`), command line API commands are ignored.
|
> **Note:** When using interactive mode (`-i`), command line API commands are ignored.
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* @author Vincent Burel, Onyx and Iris (code@onyxandiris.online)
|
* @author Vincent Burel, Onyx and Iris (code@onyxandiris.online)
|
||||||
* @brief Functions for initializing the iVMR interface.
|
* @brief Functions for initializing the iVMR interface.
|
||||||
* Defines a single public function that returns a pointer to the interface.
|
* Defines a single public function that returns a pointer to the interface.
|
||||||
* @version 0.13.0
|
* @version 0.14.0
|
||||||
* @date 2024-07-06
|
* @date 2024-07-06
|
||||||
*
|
*
|
||||||
* @copyright Vincent Burel(c)2015-2021 All Rights Reserved
|
* @copyright Vincent Burel(c)2015-2021 All Rights Reserved
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @file util.c
|
* @file util.c
|
||||||
* @author Onyx and Iris (code@onyxandiris.online)
|
* @author Onyx and Iris (code@onyxandiris.online)
|
||||||
* @brief Utility functions.
|
* @brief Utility functions.
|
||||||
* @version 0.13.0
|
* @version 0.14.0
|
||||||
* @date 2024-07-06
|
* @date 2024-07-06
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2024
|
* @copyright Copyright (c) 2024
|
||||||
|
|||||||
134
src/vmrcli.c
134
src/vmrcli.c
@@ -2,7 +2,7 @@
|
|||||||
* @file vmrcli.c
|
* @file vmrcli.c
|
||||||
* @author Onyx and Iris (code@onyxandiris.online)
|
* @author Onyx and Iris (code@onyxandiris.online)
|
||||||
* @brief A Voicemeeter Remote Command Line Interface
|
* @brief A Voicemeeter Remote Command Line Interface
|
||||||
* @version 0.13.0
|
* @version 0.14.0
|
||||||
* @date 2024-07-06
|
* @date 2024-07-06
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2024
|
* @copyright Copyright (c) 2024
|
||||||
@@ -22,22 +22,23 @@
|
|||||||
|
|
||||||
#define USAGE "Usage: .\\vmrcli.exe [-h] [-v] [-i|-I] [-f] [-k] [-l] [-e] [-c] [-m] [-s] <api commands>\n" \
|
#define USAGE "Usage: .\\vmrcli.exe [-h] [-v] [-i|-I] [-f] [-k] [-l] [-e] [-c] [-m] [-s] <api commands>\n" \
|
||||||
"Where: \n" \
|
"Where: \n" \
|
||||||
"\th: Print the help message\n" \
|
"\t-h, --help: Print the help message\n" \
|
||||||
"\tv: Print the version number\n" \
|
"\t-v, --version: Print the version number\n" \
|
||||||
"\ti: Enable interactive mode, use (-I) to disable the '>>' prompt\n" \
|
"\t-i, --interactive: Enable interactive mode\n" \
|
||||||
"\tf: Do not split input on spaces\n" \
|
"\t-I, --no-prompt: Enable interactive mode without the '>>' prompt\n" \
|
||||||
"\tk: The kind of Voicemeeter (basic, banana, potato)\n" \
|
"\t-f, --full-line: Do not split input on spaces\n" \
|
||||||
"\tl: Set log level, must be one of TRACE, DEBUG, INFO, WARN, ERROR, or FATAL\n" \
|
"\t-k, --kind: The kind of Voicemeeter (basic, banana, potato)\n" \
|
||||||
"\te: Enable extra console output (toggle, set messages)\n" \
|
"\t-l, --log-level: Set log level, must be one of TRACE, DEBUG, INFO, WARN, ERROR, or FATAL\n" \
|
||||||
"\tc: Load a user configuration (give the full file path)\n" \
|
"\t-e, --extra-output: Enable extra console output (toggle, set messages)\n" \
|
||||||
"\tm: Launch the MacroButtons application\n" \
|
"\t-c, --config: Load a user configuration (give the full file path)\n" \
|
||||||
"\ts: Launch the StreamerView application"
|
"\t-m, --macrobuttons: Launch the MacroButtons application\n" \
|
||||||
|
"\t-s, --streamerview: Launch the StreamerView application"
|
||||||
#define OPTSTR ":hvk:msc:iIfl:e"
|
#define OPTSTR ":hvk:msc:iIfl:e"
|
||||||
#define MAX_LINE 4096 /* Size of the input buffer */
|
#define MAX_LINE 4096 /* Size of the input buffer */
|
||||||
#define RES_SZ 512 /* Size of the buffer passed to VBVMR_GetParameterStringW */
|
#define RES_SZ 512 /* Size of the buffer passed to VBVMR_GetParameterStringW */
|
||||||
#define COUNT_OF(x) (sizeof(x) / sizeof(x[0]))
|
#define COUNT_OF(x) (sizeof(x) / sizeof(x[0]))
|
||||||
#define DELIMITERS " \t;,"
|
#define DELIMITERS " \t;,"
|
||||||
#define VERSION "0.13.0"
|
#define VERSION "0.14.0"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum The kind of values a get call may return.
|
* @enum The kind of values a get call may return.
|
||||||
@@ -73,28 +74,55 @@ static void parse_input(PT_VMR vmr, char *input, char *delimiters);
|
|||||||
static void parse_command(PT_VMR vmr, char *command);
|
static void parse_command(PT_VMR vmr, char *command);
|
||||||
static void get(PT_VMR vmr, char *command, struct result *res);
|
static void get(PT_VMR vmr, char *command, struct result *res);
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
struct config_t {
|
||||||
{
|
bool mflag;
|
||||||
bool iflag = false,
|
bool sflag;
|
||||||
mflag = false,
|
bool cflag;
|
||||||
sflag = false,
|
|
||||||
cflag = false,
|
|
||||||
fflag = false,
|
|
||||||
with_prompt = true;
|
|
||||||
int opt;
|
|
||||||
int log_level = LOG_WARN;
|
|
||||||
char *cvalue;
|
char *cvalue;
|
||||||
enum kind kind = BANANAX64;
|
bool iflag;
|
||||||
|
bool with_prompt;
|
||||||
|
bool fflag;
|
||||||
|
int log_level;
|
||||||
|
enum kind kind;
|
||||||
|
};
|
||||||
|
|
||||||
|
int get_options(struct config_t *config, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
static const struct option options[] =
|
||||||
|
{
|
||||||
|
{"help", no_argument, 0, 'h'},
|
||||||
|
{"version",no_argument, 0, 'v'},
|
||||||
|
{"kind", required_argument, 0, 'k'},
|
||||||
|
{"macrobuttons", no_argument, 0, 'm'},
|
||||||
|
{"streamerview", no_argument, 0, 's'},
|
||||||
|
{"config", required_argument, 0, 'c'},
|
||||||
|
{"interactive", no_argument, 0, 'i'},
|
||||||
|
{"no-prompt", no_argument, 0, 'I'},
|
||||||
|
{"full-line", no_argument, 0, 'f'},
|
||||||
|
{"log-level", required_argument,0, 'l'},
|
||||||
|
{"extra-output", no_argument, 0, 'e'},
|
||||||
|
{NULL, 0, NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
config->iflag = false;
|
||||||
|
config->mflag = false;
|
||||||
|
config->sflag = false;
|
||||||
|
config->cflag = false;
|
||||||
|
config->fflag = false;
|
||||||
|
config->with_prompt = true;
|
||||||
|
config->log_level = LOG_WARN;
|
||||||
|
config->kind = BANANAX64;
|
||||||
|
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
{
|
{
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
log_set_level(log_level);
|
log_set_level(config->log_level);
|
||||||
|
|
||||||
opterr = 0;
|
opterr = 0;
|
||||||
while ((opt = getopt(argc, argv, OPTSTR)) != -1)
|
int opt;
|
||||||
|
while ((opt = getopt_long(argc, argv, OPTSTR, options, NULL)) != -1)
|
||||||
{
|
{
|
||||||
switch (opt)
|
switch (opt)
|
||||||
{
|
{
|
||||||
@@ -102,37 +130,37 @@ int main(int argc, char *argv[])
|
|||||||
printf("vmrcli version %s\n", VERSION);
|
printf("vmrcli version %s\n", VERSION);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
case 'k':
|
case 'k':
|
||||||
kind = set_kind(optarg);
|
config->kind = set_kind(optarg);
|
||||||
if (kind == UNKNOWN)
|
if (config->kind == UNKNOWN)
|
||||||
{
|
{
|
||||||
log_fatal("Unknown Voicemeeter kind '%s'", optarg);
|
log_fatal("Unknown Voicemeeter kind '%s'", optarg);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
mflag = true;
|
config->mflag = true;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
sflag = true;
|
config->sflag = true;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
cflag = true;
|
config->cflag = true;
|
||||||
cvalue = optarg;
|
config->cvalue = optarg;
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
with_prompt = false;
|
config->with_prompt = false;
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case 'i':
|
case 'i':
|
||||||
iflag = true;
|
config->iflag = true;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
fflag = true;
|
config->fflag = true;
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
log_level = log_level_from_string(optarg);
|
config->log_level = log_level_from_string(optarg);
|
||||||
if (log_level != -1)
|
if (config->log_level != -1)
|
||||||
{
|
{
|
||||||
log_set_level(log_level);
|
log_set_level(config->log_level);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -160,6 +188,20 @@ int main(int argc, char *argv[])
|
|||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return optind;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct config_t config;
|
||||||
|
int optind = get_options(&config, argc, argv);
|
||||||
|
|
||||||
|
if (argc == 1)
|
||||||
|
{
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
log_set_level(config.log_level);
|
||||||
|
|
||||||
PT_VMR vmr = create_interface();
|
PT_VMR vmr = create_interface();
|
||||||
if (vmr == NULL)
|
if (vmr == NULL)
|
||||||
@@ -167,7 +209,7 @@ int main(int argc, char *argv[])
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
long rep = login(vmr, kind);
|
long rep = login(vmr, config.kind);
|
||||||
if (rep != 0)
|
if (rep != 0)
|
||||||
{
|
{
|
||||||
if (rep == -2)
|
if (rep == -2)
|
||||||
@@ -176,36 +218,36 @@ int main(int argc, char *argv[])
|
|||||||
terminate(vmr, "Error logging into the Voicemeeter API");
|
terminate(vmr, "Error logging into the Voicemeeter API");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mflag)
|
if (config.mflag)
|
||||||
{
|
{
|
||||||
run_voicemeeter(vmr, MACROBUTTONS);
|
run_voicemeeter(vmr, MACROBUTTONS);
|
||||||
log_info("MacroButtons app launched");
|
log_info("MacroButtons app launched");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sflag)
|
if (config.sflag)
|
||||||
{
|
{
|
||||||
run_voicemeeter(vmr, STREAMERVIEW);
|
run_voicemeeter(vmr, STREAMERVIEW);
|
||||||
log_info("StreamerView app launched");
|
log_info("StreamerView app launched");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cflag)
|
if (config.cflag)
|
||||||
{
|
{
|
||||||
set_parameter_string(vmr, "command.load", cvalue);
|
set_parameter_string(vmr, "command.load", config.cvalue);
|
||||||
log_info("Profile %s loaded", cvalue);
|
log_info("Profile %s loaded", config.cvalue);
|
||||||
Sleep(300);
|
Sleep(300);
|
||||||
clear(vmr, is_pdirty);
|
clear(vmr, is_pdirty);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *delimiter_ptr = DELIMITERS;
|
char *delimiter_ptr = DELIMITERS;
|
||||||
if (fflag)
|
if (config.fflag)
|
||||||
{
|
{
|
||||||
delimiter_ptr++; /* skip space delimiter */
|
delimiter_ptr++; /* skip space delimiter */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iflag)
|
if (config.iflag)
|
||||||
{
|
{
|
||||||
puts("Interactive mode enabled. Enter 'Q' to exit.");
|
puts("Interactive mode enabled. Enter 'Q' to exit.");
|
||||||
interactive(vmr, with_prompt, delimiter_ptr);
|
interactive(vmr, config.with_prompt, delimiter_ptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @file wrapper.c
|
* @file wrapper.c
|
||||||
* @author Onyx and Iris (code@onyxandiris.online)
|
* @author Onyx and Iris (code@onyxandiris.online)
|
||||||
* @brief Provides public functions that wrap the iVMR calls
|
* @brief Provides public functions that wrap the iVMR calls
|
||||||
* @version 0.13.0
|
* @version 0.14.0
|
||||||
* @date 2024-07-06
|
* @date 2024-07-06
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2024
|
* @copyright Copyright (c) 2024
|
||||||
|
|||||||
Reference in New Issue
Block a user