Improve config behaviour
This commit is contained in:
		
							parent
							
								
									5796f88e05
								
							
						
					
					
						commit
						0c13c03a73
					
				
					 11 changed files with 2571 additions and 37 deletions
				
			
		
							
								
								
									
										19
									
								
								emgauwa-core.conf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								emgauwa-core.conf
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					[core]
 | 
				
			||||||
 | 
					database = "emgauwa-core.sqlite"
 | 
				
			||||||
 | 
					content-dir = "/usr/share/webapps/emgauwa"
 | 
				
			||||||
 | 
					include = "./emgauwa-core.conf.d/"
 | 
				
			||||||
 | 
					not-found-file = "404.html"
 | 
				
			||||||
 | 
					not-found-file-mime = "text/html"
 | 
				
			||||||
 | 
					not-found-content = "404 - NOT FOUND"
 | 
				
			||||||
 | 
					not-found-content-type = "text/plain"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[ports]
 | 
				
			||||||
 | 
					server = 5000
 | 
				
			||||||
 | 
					# 4422 for testing; 4421 for dev-env; 4420 for testing-env; 4419 for prod-env
 | 
				
			||||||
 | 
					discovery = 4421
 | 
				
			||||||
 | 
					# 1886 for testing; 1885 for dev-env; 1884 for testing-env; 1883 for prod-env
 | 
				
			||||||
 | 
					mqtt = 1885
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[logging]
 | 
				
			||||||
 | 
					level = "debug"
 | 
				
			||||||
 | 
					file = "stdout"
 | 
				
			||||||
| 
						 | 
					@ -3,11 +3,10 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct cli
 | 
					typedef struct cli
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char *config_path;
 | 
					    const char *config_file;
 | 
				
			||||||
} cli_t;
 | 
					} cli_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
cli_parse(int argc, const char **argv, config_t *config);
 | 
					cli_parse(int argc, const char **argv, cli_t *cli);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* CORE_CLI_H */
 | 
					#endif /* CORE_CLI_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct
 | 
					typedef struct
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char *file;
 | 
					 | 
				
			||||||
    char *include;
 | 
					    char *include;
 | 
				
			||||||
    char *database;
 | 
					    char *database;
 | 
				
			||||||
    char *user;
 | 
					    char *user;
 | 
				
			||||||
| 
						 | 
					@ -46,10 +45,13 @@ config_free();
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
config_load_string(char **holder, const char *value);
 | 
					config_load_string(char **holder, const char *value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					void
 | 
				
			||||||
config_load(config_t *config);
 | 
					config_load(config_t *config, const char *cli_config_file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
config_load_directory(config_t *config, char *directory_name);
 | 
					config_load_file(config_t *config, const char *file_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					config_load_directory(config_t *config, const char *directory_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* CORE_CONFIG_H */
 | 
					#endif /* CORE_CONFIG_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PIFACE_GPIO_BASE 200
 | 
					#define PIFACE_GPIO_BASE 200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DEFAULT_CONFIG_PATH "emgauwa-core.toml"
 | 
					#define DEFAULT_CONFIG_PATH "emgauwa-core.conf"
 | 
				
			||||||
 | 
					#define DEFAULT_GLOBAL_CONFIG_PATH "/etc/emgauwa/core.conf"
 | 
				
			||||||
#define DEFAULT_DISCOVERY_PORT 4421
 | 
					#define DEFAULT_DISCOVERY_PORT 4421
 | 
				
			||||||
#define DEFAULT_MQTT_PORT 1885
 | 
					#define DEFAULT_MQTT_PORT 1885
 | 
				
			||||||
#define DEFAULT_SERVER_PORT 5000
 | 
					#define DEFAULT_SERVER_PORT 5000
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										15
									
								
								src/cli.c
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								src/cli.c
									
										
									
									
									
								
							| 
						 | 
					@ -5,25 +5,29 @@
 | 
				
			||||||
#include <argparse.h>
 | 
					#include <argparse.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <config.h>
 | 
					#include <config.h>
 | 
				
			||||||
 | 
					#include <cli.h>
 | 
				
			||||||
#include <logger.h>
 | 
					#include <logger.h>
 | 
				
			||||||
#include <helpers.h>
 | 
					#include <helpers.h>
 | 
				
			||||||
#include <version.h>
 | 
					#include <version.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cli_t *global_cli;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *const usage[] = {
 | 
					static const char *const usage[] = {
 | 
				
			||||||
    "core [options]",
 | 
					    "core [options]",
 | 
				
			||||||
    NULL,
 | 
					    NULL,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
cli_parse(int argc, const char **argv, config_t *config)
 | 
					cli_parse(int argc, const char **argv, cli_t *cli)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const char *config_file = NULL;
 | 
					    cli->config_file = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int version = 0;
 | 
					    int version = 0;
 | 
				
			||||||
    struct argparse_option options[] =
 | 
					    struct argparse_option options[] =
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        OPT_HELP(),
 | 
					        OPT_HELP(),
 | 
				
			||||||
        OPT_GROUP("Basic options"),
 | 
					        OPT_GROUP("Basic options"),
 | 
				
			||||||
        OPT_STRING('c', "config", &config_file, "path to config file", NULL, 0, OPT_NONEG),
 | 
					        OPT_STRING('c', "config", &cli->config_file, "path to config file", NULL, 0, OPT_NONEG),
 | 
				
			||||||
        OPT_BOOLEAN('v', "version", &version, "print version", NULL, 0, OPT_NONEG),
 | 
					        OPT_BOOLEAN('v', "version", &version, "print version", NULL, 0, OPT_NONEG),
 | 
				
			||||||
        OPT_END(),
 | 
					        OPT_END(),
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
| 
						 | 
					@ -37,11 +41,6 @@ cli_parse(int argc, const char **argv, config_t *config)
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
    argparse_parse(&argparse, argc, argv);
 | 
					    argparse_parse(&argparse, argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(config_file)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        config_load_string(&config->file, config_file);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if(version)
 | 
					    if(version)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        printf("%s\n", EMGAUWA_CORE_VERSION);
 | 
					        printf("%s\n", EMGAUWA_CORE_VERSION);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										80
									
								
								src/config.c
									
										
									
									
									
								
							
							
						
						
									
										80
									
								
								src/config.c
									
										
									
									
									
								
							| 
						 | 
					@ -200,7 +200,6 @@ config_init()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    global_config = calloc(1, sizeof(config_t));
 | 
					    global_config = calloc(1, sizeof(config_t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    config_load_string(&global_config->file, DEFAULT_CONFIG_PATH);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    global_config->ports.discovery = DEFAULT_DISCOVERY_PORT;
 | 
					    global_config->ports.discovery = DEFAULT_DISCOVERY_PORT;
 | 
				
			||||||
    global_config->ports.mqtt = DEFAULT_MQTT_PORT;
 | 
					    global_config->ports.mqtt = DEFAULT_MQTT_PORT;
 | 
				
			||||||
| 
						 | 
					@ -222,7 +221,6 @@ config_init()
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
config_free()
 | 
					config_free()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    free(global_config->file);
 | 
					 | 
				
			||||||
    free(global_config->include);
 | 
					    free(global_config->include);
 | 
				
			||||||
    free(global_config->database);
 | 
					    free(global_config->database);
 | 
				
			||||||
    free(global_config->user);
 | 
					    free(global_config->user);
 | 
				
			||||||
| 
						 | 
					@ -251,23 +249,64 @@ config_load_string(char **holder, const char *value)
 | 
				
			||||||
    *holder = new_holder;
 | 
					    *holder = new_holder;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					static int
 | 
				
			||||||
config_load(config_t *config)
 | 
					config_try_file(const char *path)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(access(path, F_OK) != 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LOGGER_DEBUG("'%s' does not exist\n", path);
 | 
				
			||||||
 | 
					        return 1; 
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(access(path, R_OK) != 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LOGGER_DEBUG("no read access for '%s'\n", path);
 | 
				
			||||||
 | 
					        return 1; 
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					config_load(config_t *config, const char *cli_config_file)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(cli_config_file)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(config_try_file(cli_config_file) == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            config_load_file(config, cli_config_file);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        LOGGER_CRIT("unable to open the passed config file '%s'\n", cli_config_file);
 | 
				
			||||||
 | 
					        exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(config_try_file(DEFAULT_CONFIG_PATH) == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        config_load_file(config, DEFAULT_CONFIG_PATH);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(config_try_file(DEFAULT_GLOBAL_CONFIG_PATH) == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        config_load_file(config, DEFAULT_GLOBAL_CONFIG_PATH);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					config_load_file(config_t *config, const char *file_name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    FILE *fp;
 | 
					    FILE *fp;
 | 
				
			||||||
    toml_table_t* config_toml;
 | 
					    toml_table_t* config_toml;
 | 
				
			||||||
    char errbuf[256];
 | 
					    char errbuf[256];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Open the file and parse content */
 | 
					    /* Open the file and parse content */
 | 
				
			||||||
    fp = fopen(global_config->file, "r");
 | 
					    fp = fopen(file_name, "r");
 | 
				
			||||||
    if(fp == NULL) {
 | 
					    if(fp == NULL) {
 | 
				
			||||||
        LOGGER_CRIT("unable to open config file '%s'\n", global_config->file);
 | 
					        LOGGER_CRIT("unable to open config file '%s'\n", file_name);
 | 
				
			||||||
        exit(1);
 | 
					        exit(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    config_toml = toml_parse_file(fp, errbuf, sizeof(errbuf));
 | 
					    config_toml = toml_parse_file(fp, errbuf, sizeof(errbuf));
 | 
				
			||||||
    fclose(fp);
 | 
					    fclose(fp);
 | 
				
			||||||
    if(config_toml == NULL) {
 | 
					    if(config_toml == NULL) {
 | 
				
			||||||
        LOGGER_CRIT("unable to parse config file '%s': %s\n", global_config->file, errbuf);
 | 
					        LOGGER_CRIT("unable to parse config file '%s': %s\n", file_name, errbuf);
 | 
				
			||||||
        exit(1);
 | 
					        exit(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -291,19 +330,19 @@ config_load(config_t *config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    toml_free(config_toml);
 | 
					    toml_free(config_toml);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    LOGGER_DEBUG("Loaded config from %s\n", file_name);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
config_load_directory(config_t *config, char *directory_name)
 | 
					config_load_directory(config_t *config, const char *directory_name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    struct dirent *pDirent;
 | 
					    struct dirent *directory_entry;
 | 
				
			||||||
    DIR *pDir;
 | 
					    DIR *directory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    (void)config;
 | 
					    (void)config;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pDir = opendir (directory_name);
 | 
					    directory = opendir(directory_name);
 | 
				
			||||||
    if(pDir == NULL)
 | 
					    if(directory == NULL)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        LOGGER_CRIT("cannot open directory '%s': %s\n", directory_name, strerror(errno));
 | 
					        LOGGER_CRIT("cannot open directory '%s': %s\n", directory_name, strerror(errno));
 | 
				
			||||||
        exit(1);
 | 
					        exit(1);
 | 
				
			||||||
| 
						 | 
					@ -311,12 +350,21 @@ config_load_directory(config_t *config, char *directory_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Process each entry.
 | 
					    // Process each entry.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while((pDirent = readdir(pDir)) != NULL)
 | 
					    while((directory_entry = readdir(directory)) != NULL)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        LOGGER_DEBUG("including: %s\n", pDirent->d_name);
 | 
					        struct stat sb;
 | 
				
			||||||
 | 
					        const char *entry_name = directory_entry->d_name;
 | 
				
			||||||
 | 
					        if(stat(entry_name, &sb))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            LOGGER_WARNING("failed to get info for '%s': %s\n", entry_name, strerror(errno));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if(S_ISREG(sb.st_mode))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            config_load_file(config, entry_name);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Close directory and exit.
 | 
					    // Close directory and exit.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    closedir(pDir);
 | 
					    closedir(directory);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,9 +59,10 @@ main(int argc, const char** argv)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    config_init();
 | 
					    config_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cli_parse(argc, argv, global_config);
 | 
					    cli_t cli;
 | 
				
			||||||
 | 
					    cli_parse(argc, argv, &cli);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    config_load(global_config);
 | 
					    config_load(global_config, cli.config_file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(global_config->logging.file == NULL)
 | 
					    if(global_config->logging.file == NULL)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					@ -73,8 +74,6 @@ main(int argc, const char** argv)
 | 
				
			||||||
        config_load_directory(global_config, global_config->include);
 | 
					        config_load_directory(global_config, global_config->include);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOGGER_DEBUG("Loaded config from %s\n", global_config->file);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /******************** SETUP CONNECTION ********************/
 | 
					    /******************** SETUP CONNECTION ********************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										18
									
								
								tests/emgauwa-core-testing.conf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								tests/emgauwa-core-testing.conf
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					[core]
 | 
				
			||||||
 | 
					database = "emgauwa-core.sqlite"
 | 
				
			||||||
 | 
					content-dir = "."
 | 
				
			||||||
 | 
					not-found-file = "404.html"
 | 
				
			||||||
 | 
					not-found-file-mime = "text/html"
 | 
				
			||||||
 | 
					not-found-content = "404 - NOT FOUND"
 | 
				
			||||||
 | 
					not-found-content-type = "text/plain"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[ports]
 | 
				
			||||||
 | 
					server = 5000
 | 
				
			||||||
 | 
					# 4422 for testing; 4421 for dev-env; 4420 for testing-env; 4419 for prod-env
 | 
				
			||||||
 | 
					discovery = 4422
 | 
				
			||||||
 | 
					# 1886 for testing; 1885 for dev-env; 1884 for testing-env; 1883 for prod-env
 | 
				
			||||||
 | 
					mqtt = 1886
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[logging]
 | 
				
			||||||
 | 
					level = "debug"
 | 
				
			||||||
 | 
					file = "stdout"
 | 
				
			||||||
| 
						 | 
					@ -41,7 +41,7 @@ touch $working_dir/index.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cp $1 $working_dir/core
 | 
					cp $1 $working_dir/core
 | 
				
			||||||
 | 
					
 | 
				
			||||||
valgrind_emgauwa $working_dir/core -c $source_dir/emgauwa-core-testing.toml >>$working_dir/core.log 2>&1 &
 | 
					valgrind_emgauwa $working_dir/core -c $source_dir/emgauwa-core-testing.conf >>$working_dir/core.log 2>&1 &
 | 
				
			||||||
core_id=$!
 | 
					core_id=$!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2274
									
								
								vendor/toml.c
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2274
									
								
								vendor/toml.c
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										175
									
								
								vendor/toml.h
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								vendor/toml.h
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,175 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  Copyright (c) 2017 - 2019 CK Tan
 | 
				
			||||||
 | 
					  https://github.com/cktan/tomlc99
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					  of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					  in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					  copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					  furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  The above copyright notice and this permission notice shall be included in all
 | 
				
			||||||
 | 
					  copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
				
			||||||
 | 
					  SOFTWARE.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#ifndef TOML_H
 | 
				
			||||||
 | 
					#define TOML_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					#define TOML_EXTERN extern "C"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define TOML_EXTERN extern
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct toml_timestamp_t toml_timestamp_t;
 | 
				
			||||||
 | 
					typedef struct toml_table_t toml_table_t;
 | 
				
			||||||
 | 
					typedef struct toml_array_t toml_array_t;
 | 
				
			||||||
 | 
					typedef struct toml_datum_t toml_datum_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Parse a file. Return a table on success, or 0 otherwise. 
 | 
				
			||||||
 | 
					 * Caller must toml_free(the-return-value) after use.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					TOML_EXTERN toml_table_t* toml_parse_file(FILE* fp, 
 | 
				
			||||||
 | 
															  char* errbuf,
 | 
				
			||||||
 | 
															  int errbufsz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Parse a string containing the full config. 
 | 
				
			||||||
 | 
					 * Return a table on success, or 0 otherwise.
 | 
				
			||||||
 | 
					 * Caller must toml_free(the-return-value) after use.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					TOML_EXTERN toml_table_t* toml_parse(char* conf, /* NUL terminated, please. */
 | 
				
			||||||
 | 
														 char* errbuf,
 | 
				
			||||||
 | 
														 int errbufsz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Free the table returned by toml_parse() or toml_parse_file(). Once 
 | 
				
			||||||
 | 
					 * this function is called, any handles accessed through this tab 
 | 
				
			||||||
 | 
					 * directly or indirectly are no longer valid.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					TOML_EXTERN void toml_free(toml_table_t* tab);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Timestamp types. The year, month, day, hour, minute, second, z 
 | 
				
			||||||
 | 
					 * fields may be NULL if they are not relevant. e.g. In a DATE
 | 
				
			||||||
 | 
					 * type, the hour, minute, second and z fields will be NULLs.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct toml_timestamp_t {
 | 
				
			||||||
 | 
						struct { /* internal. do not use. */
 | 
				
			||||||
 | 
							int year, month, day;
 | 
				
			||||||
 | 
							int hour, minute, second, millisec;
 | 
				
			||||||
 | 
							char z[10];
 | 
				
			||||||
 | 
						} __buffer;
 | 
				
			||||||
 | 
						int *year, *month, *day;
 | 
				
			||||||
 | 
						int *hour, *minute, *second, *millisec;
 | 
				
			||||||
 | 
						char* z;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*-----------------------------------------------------------------
 | 
				
			||||||
 | 
					 *  Enhanced access methods 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct toml_datum_t {
 | 
				
			||||||
 | 
						int ok;
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							toml_timestamp_t* ts; /* ts must be freed after use */
 | 
				
			||||||
 | 
							char*   s; /* string value. s must be freed after use */
 | 
				
			||||||
 | 
							int     b; /* bool value */
 | 
				
			||||||
 | 
							int64_t i; /* int value */
 | 
				
			||||||
 | 
							double  d; /* double value */
 | 
				
			||||||
 | 
						} u;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* on arrays: */
 | 
				
			||||||
 | 
					/* ... retrieve size of array. */
 | 
				
			||||||
 | 
					TOML_EXTERN int toml_array_nelem(const toml_array_t* arr);
 | 
				
			||||||
 | 
					/* ... retrieve values using index. */
 | 
				
			||||||
 | 
					TOML_EXTERN toml_datum_t toml_string_at(const toml_array_t* arr, int idx);
 | 
				
			||||||
 | 
					TOML_EXTERN toml_datum_t toml_bool_at(const toml_array_t* arr, int idx);
 | 
				
			||||||
 | 
					TOML_EXTERN toml_datum_t toml_int_at(const toml_array_t* arr, int idx);
 | 
				
			||||||
 | 
					TOML_EXTERN toml_datum_t toml_double_at(const toml_array_t* arr, int idx);
 | 
				
			||||||
 | 
					TOML_EXTERN toml_datum_t toml_timestamp_at(const toml_array_t* arr, int idx);
 | 
				
			||||||
 | 
					/* ... retrieve array or table using index. */
 | 
				
			||||||
 | 
					TOML_EXTERN toml_array_t* toml_array_at(const toml_array_t* arr, int idx);
 | 
				
			||||||
 | 
					TOML_EXTERN toml_table_t* toml_table_at(const toml_array_t* arr, int idx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* on tables: */
 | 
				
			||||||
 | 
					/* ... retrieve the key in table at keyidx. Return 0 if out of range. */
 | 
				
			||||||
 | 
					TOML_EXTERN const char* toml_key_in(const toml_table_t* tab, int keyidx);
 | 
				
			||||||
 | 
					/* ... retrieve values using key. */
 | 
				
			||||||
 | 
					TOML_EXTERN toml_datum_t toml_string_in(const toml_table_t* arr, const char* key);
 | 
				
			||||||
 | 
					TOML_EXTERN toml_datum_t toml_bool_in(const toml_table_t* arr, const char* key);
 | 
				
			||||||
 | 
					TOML_EXTERN toml_datum_t toml_int_in(const toml_table_t* arr, const char* key);
 | 
				
			||||||
 | 
					TOML_EXTERN toml_datum_t toml_double_in(const toml_table_t* arr, const char* key);
 | 
				
			||||||
 | 
					TOML_EXTERN toml_datum_t toml_timestamp_in(const toml_table_t* arr, const char* key);
 | 
				
			||||||
 | 
					/* .. retrieve array or table using key. */
 | 
				
			||||||
 | 
					TOML_EXTERN toml_array_t* toml_array_in(const toml_table_t* tab,
 | 
				
			||||||
 | 
															const char* key);
 | 
				
			||||||
 | 
					TOML_EXTERN toml_table_t* toml_table_in(const toml_table_t* tab,
 | 
				
			||||||
 | 
															const char* key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*-----------------------------------------------------------------
 | 
				
			||||||
 | 
					 * lesser used 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					/* Return the array kind: 't'able, 'a'rray, 'v'alue */
 | 
				
			||||||
 | 
					TOML_EXTERN char toml_array_kind(const toml_array_t* arr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* For array kind 'v'alue, return the type of values 
 | 
				
			||||||
 | 
					   i:int, d:double, b:bool, s:string, t:time, D:date, T:timestamp
 | 
				
			||||||
 | 
					   0 if unknown
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					TOML_EXTERN char toml_array_type(const toml_array_t* arr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Return the key of an array */
 | 
				
			||||||
 | 
					TOML_EXTERN const char* toml_array_key(const toml_array_t* arr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Return the number of key-values in a table */
 | 
				
			||||||
 | 
					TOML_EXTERN int toml_table_nkval(const toml_table_t* tab);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Return the number of arrays in a table */
 | 
				
			||||||
 | 
					TOML_EXTERN int toml_table_narr(const toml_table_t* tab);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Return the number of sub-tables in a table */
 | 
				
			||||||
 | 
					TOML_EXTERN int toml_table_ntab(const toml_table_t* tab);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Return the key of a table*/
 | 
				
			||||||
 | 
					TOML_EXTERN const char* toml_table_key(const toml_table_t* tab);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------
 | 
				
			||||||
 | 
					 * misc 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					TOML_EXTERN int toml_utf8_to_ucs(const char* orig, int len, int64_t* ret);
 | 
				
			||||||
 | 
					TOML_EXTERN int toml_ucs_to_utf8(int64_t code, char buf[6]);
 | 
				
			||||||
 | 
					TOML_EXTERN void toml_set_memutil(void* (*xxmalloc)(size_t),
 | 
				
			||||||
 | 
													  void	(*xxfree)(void*));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------
 | 
				
			||||||
 | 
					 *  deprecated 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					/* A raw value, must be processed by toml_rto* before using. */
 | 
				
			||||||
 | 
					typedef const char* toml_raw_t;
 | 
				
			||||||
 | 
					TOML_EXTERN toml_raw_t toml_raw_in(const toml_table_t* tab, const char* key);
 | 
				
			||||||
 | 
					TOML_EXTERN toml_raw_t toml_raw_at(const toml_array_t* arr, int idx);
 | 
				
			||||||
 | 
					TOML_EXTERN int toml_rtos(toml_raw_t s, char** ret);
 | 
				
			||||||
 | 
					TOML_EXTERN int toml_rtob(toml_raw_t s, int* ret);
 | 
				
			||||||
 | 
					TOML_EXTERN int toml_rtoi(toml_raw_t s, int64_t* ret);
 | 
				
			||||||
 | 
					TOML_EXTERN int toml_rtod(toml_raw_t s, double* ret);
 | 
				
			||||||
 | 
					TOML_EXTERN int toml_rtod_ex(toml_raw_t s, double* ret, char* buf, int buflen);
 | 
				
			||||||
 | 
					TOML_EXTERN int toml_rtots(toml_raw_t s, toml_timestamp_t* ret);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* TOML_H */
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue