The libparamset is a software development kit, written in plain C, for handling command-line parameters and program tasks. Parameters can be read from command line and a task can be extracted that matches with the given input. Process is covered with error detection and functions that generates helpful feedback messages to the user.
libparamset
The libparamset provides the following functionality:
- Works on Linux and Windows.
- Parameters can be parsed from command line, read from configuration file or inserted from the code.
- Short and long parameters (
-a and --long).
- Concatenating of flags with length
1 (-ab instead of -a -b).
- One alias for the parameter name (e.g.
--load and -l or --version and --VERSION).
- Individual parsing options for parameters:
- Parameter with multiple coexisting values (
-a v1 -a v2 ... -a vn, where -a = {v1, v2, ..., vn}).
- Parameter that never takes a value (
-a v1 -a -a, where -a = {NULL, NULL, NULL} and v1 is unknown token).
- Parameter that always takes a value (
-a -a, where -a = {-a}).
- Existing parameter break that takes next token as it's value only if it's not an existing parameter.
- Possible parameter break that takes next token as it's value only if it does not look like possible parameter (
-a v1 -a -b, where -a = {v1, NULL}).
- Parameter value sequence with (existing or possible) parameter break (
-a v1 v2 ... vn -b, where -a = {v1, v2, ..., vn}).
- Parameter that is hidden from the command line but can be inserted from the code or configuration file.
- Parameter that does not generate any typo errors (useful when hiding a parameter from command line).
- Value collectors:
- Parameter
--, that will redirect every next token to a specified parameter(s).
- Parameter that collects values that are not bound with any parameter (
-i x y ..., where x is bound with -i but y is not).
- Parameter that collects all unknown parameters (
--unknown unknown, where --unknown is collected and unknown is unknown token).
- Individual collector count limiters (e.g. no more than
5 values).
- Values can be filtered by, name (e.g.
-i as i and --long as long), source (e.g. default), priority (e.g. 3) and index (0 - n).
- Values can be counted by name, source and priority (e.g.
3).
- Values can be filtered as the last or the first with the highest or the lowest priority.
- Values can be counted as the highest or the lowest priority.
- Parameter default name that is shown in error messages (print name) can be replaced with custom string (constant or generated).
- Auto-generated typo suggestions (e.g. Did You mean
--long instead of --song?).
- Auto-generated unknown parameter error messages.
- Abstract format and content check functionality with auto-generated error messages.
- Abstract parameter transformation or repair functionality.
- Abstract Wildcard expander (can be used to make
-i * work on Windows).
- Implemented wildcards for Windows file system.
- Abstract object parsing functionality (e.g. extract double or file).
- Multiple parameter sets can be merged.
- Task set, composed of multiple tasks, where from a task can be extracted by specified parameter set.
- Auto-generated suggestions between multiple tasks for the user when it is not possible to resolve which task the user wants to perform.
- Auto-generated suggestions how to fix the task user tries to perform.
- Parameters can be bound with description and formatted to human readable list for help text.
Main objects
PARAM_SET contains user defined parameters that can be parsed from command line, read from configuration file or added from the code.
TASK_SET contains multiple task definitions (parameters that are mandatory, ignored or restricted for defined task) that can be analyzed against specified PARAM_SET to extract a signle consistent task that matches the input.
TASK is object returned by successful TASK_SET analyze that contains the matching task ID and PARAM_SET object.
Memory Management
The memory management obeys the following rules:
- Every object you create, belongs to you.
- Every object you own, must be freed by you.
- Using free function on
NULL does nothing and won't crash.
- Input strings are copied and freed by parent object.
Workflow
Code examples
Example 1
A basic example that illustrates just how to parse the command-line options without any error handling and do the task. See Example 2 for more advanced use case.
#include <stdio.h>
int main(int argc, char** argv) {
char buf[0xffff];
printf( "Usage:\n"
" util -i file [-r -o file][--dump]\n"
" util --debug\n\n");
printf(
"Options:\n%s",
PARAM_SET_helpToString(
set,
"i,o,r,h,dump,debug", 2, 10, 80, buf,
sizeof(buf)));
printf("Dump File.\n");
printf("Reverse File.\n");
} else {
printf("Unknown task. Use -h to get some help.\n");
}
}
Example 2
A simple example of a command-line tool that uses libparamset to specify parameter set and task set, parse the command line, handle errors and give some feedback to help get things working.
#include <stdio.h>
#ifdef _WIN32
#endif
enum {
VALUE_OK = 0,
VALUE_IS_NULL = 0x01,
VALUE_IS_EMPTY = 0x02,
VALUE_FILE_DOES_NOT_EXIST = 0x03,
};
int convertRepair_path(const char* arg, char* buf, unsigned len);
int isContentOk_path(const char* fname);
int isFormatOk_path(const char* fname);
const char *parameter_error_to_string(int err);
int main(int argc, char** argv, char **envp) {
char buf[1024];
char debug[0xffff];
PARAM_SET_setHelpText(
set,
"i",
"File input. To specify multiple input files, use -i multiple times or use wildcards.");
#ifdef _WIN32
#else
#endif
TASK_SET_add(task_set, 1,
"Only Dump file",
"i,dump", NULL,
"h,r,o,debug",NULL);
TASK_SET_add(task_set, 2,
"Reverse file",
"i,r,o", NULL,
"h,debug", NULL);
TASK_SET_add(task_set, 3,
"Debug",
"debug", NULL,
"h", NULL);
goto cleanup;
goto cleanup;
}
goto cleanup;
}
if (pTask == NULL) {
int ID;
} else {
}
goto cleanup;
}
case 0:
printf( "Usage:\n"
" util -i file [-r -o file][--dump]\n"
" util --debug\n\n");
printf(
"Options:\n%s",
PARAM_SET_helpToString(
set,
"i,o,r,h,dump,debug", 2, 10, 80, buf,
sizeof(buf)));
break;
case 1:
printf("Dump File.\n");
break;
case 2:
printf("Reverse File.\n");
break;
case 3:
break;
default:
printf("Error.\n");
break;
}
cleanup:
}
const char *parameter_error_to_string(int err) {
switch(err) {
case VALUE_OK: return "OK";
case VALUE_IS_NULL: return "Parameter must have value";
case VALUE_IS_EMPTY: return "Parameter must have content";
case VALUE_FILE_DOES_NOT_EXIST: return "File does not exist";
default: return "Unknown error";
}
}
int isFormatOk_path(const char* fname) {
if (fname == NULL) return VALUE_IS_NULL;
else if (*fname == '\0');
else return VALUE_OK;
}
int isContentOk_path(const char* fname) {
int result = 1;
FILE *f = NULL;
f = fopen(fname, "r");
result = f == NULL ? VALUE_FILE_DOES_NOT_EXIST : 0;
if (f != NULL) fclose(f);
return result;
}
int convertRepair_path(const char* arg, char* buf, unsigned len){
char *toBeReplaced = NULL;
strncpy(buf, arg, len - 1);
toBeReplaced = buf;
while ((toBeReplaced = strchr(toBeReplaced, '\\')) != NULL){
*toBeReplaced = '/';
toBeReplaced++;
}
}
Third party components
The SDK is using the following third party components: