Telodendria/src/include/Config.h

209 lines
7.4 KiB
C
Raw Normal View History

/*
* Copyright (C) 2022 Jordan Bancino <@jordan:bancino.net>
*
* 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
2022-07-28 16:00:52 +00:00
* included in all copies or 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.
*/
2022-07-29 16:32:52 +00:00
/*
* Config.h: A heavily-modified version of Conifer2, a configuration
* file format specification and C parsing library written by Jordan
* Bancino. This library differs from Conifer2 in that the function
* naming convention has been updated to be consistent with Telodendria,
* and the underlying data structures have been overhauled to use the
* data structure libraries provided by Telodendria.
*
* Conifer2 was originally a learning project. It was very thoroughly
* debugged, however, and the configuration syntax was elegant,
* certainly more elegant than using JSON for a configuration file,
* so it was chosen to be the format for Telodendria's configuration
* file. The original Conifer2 project is now dead; Conifer2 lives on
* only as Telodendria's Config parsing library.
*/
2022-07-23 00:19:12 +00:00
#ifndef TELODENDRIA_CONFIG_H
#define TELODENDRIA_CONFIG_H
#include <stdio.h>
#include <HashMap.h>
#include <Array.h>
2022-07-29 16:32:52 +00:00
/*
* A configuration directive is a single key that may have at least one
* value, and any number of children.
*/
2022-07-23 00:19:12 +00:00
typedef struct ConfigDirective ConfigDirective;
2022-07-29 16:32:52 +00:00
/*
* The parser returns a parse result object. This stores whether or
* not the parse was successful, and then also additional information
* about the parse, such as the line number on which parsing failed,
* or the collection of directives if the parsing succeeded.
*
* There are a number of ConfigParseResult methods that can be used
* to query the result of parsing.
*/
2022-07-23 00:19:12 +00:00
typedef struct ConfigParseResult ConfigParseResult;
2022-07-29 16:32:52 +00:00
/*
* Parse a configuration file, and generate the structures needed to
* make it easy to read.
*
* Params:
*
* (FILE *) The input stream to read from.
*
* Return: A ConfigParseResult, which can be used to check whether or
* not the parsing was successful. If the parsing was sucessful, then
* this object contains the root directive, which can be used to
* retrieve configuration values out of. If the parsing failed, then
* this object contains the line number at which the parsing was
* aborted.
*/
2022-07-23 00:19:12 +00:00
extern ConfigParseResult *
2022-07-29 16:32:52 +00:00
ConfigParse(FILE *);
2022-07-23 00:19:12 +00:00
2022-07-29 16:32:52 +00:00
/*
* Get whether or not a parse result indicates that parsing was
* successful or not. This function should be used to determine what
* to do next. If the parsing failed, your program should terminate
* with an error, otherwise, you can proceed to parse the configuration
* file.
*
* Params:
*
* (ConfigParseResult *) The output of ConfigParse() to check.
*
* Return: 0 if the configuration file is malformed, or otherwise
* could not be parsed. Any non-zero return value indicates that the
* configuration file was successfully parsed.
*/
2022-07-23 00:19:12 +00:00
extern unsigned int
2022-07-29 16:32:52 +00:00
ConfigParseResultOk(ConfigParseResult *);
2022-07-23 00:19:12 +00:00
2022-07-29 16:32:52 +00:00
/*
* If, and only if, the configuration file parsing failed, then this
* function can be used to get the line number it failed at. Typically,
* this will be reported to the user and then the program will be
* terminated.
*
* Params:
*
* (ConfigParseResult *) The output of ConfigParse() to get the
* line number from.
*
* Return: The line number on which the configuration file parser
* choked, or 0 if the parsing was actually successful.
*/
2022-07-23 00:19:12 +00:00
extern size_t
2022-07-29 16:32:52 +00:00
ConfigParseResultLineNumber(ConfigParseResult *);
2022-07-23 00:19:12 +00:00
2022-07-29 16:32:52 +00:00
/*
* Convert a ConfigParseResult into a HashMap containing the entire
* configuration file, if, and only if, the parsing was successful.
*
* Params:
*
* (ConfigParseResult *) The output of ConfigParse() to get the
* actual configuration data from.
*
* Return: A HashMap containing all the configuration data, or NULL
* if the parsing was not successful. This HashMap is a map of string
* keys to ConfigDirective objects. Use the standard HashMap methods
* to get ConfigDirectives, and then use the ConfigDirective functions
* to get information out of them.
*/
2022-07-23 00:19:12 +00:00
extern HashMap *
2022-07-29 16:32:52 +00:00
ConfigParseResultGet(ConfigParseResult *);
2022-07-23 00:19:12 +00:00
2022-07-29 16:32:52 +00:00
/*
* Free the memory being used by the given ConfigParseResult. Note that
* it is safe to free the ConfigParseResult immediately after you have
* retrieved either the line number or the configuration data from it.
* Freeing the parse result does not free the configuration data.
*
* Params:
*
* (ConfigParseResult *) The output of ConfigParse() to free. This
* object will be invalidated, but pointers to
* the actual configuration data will still be
* valid.
*/
2022-07-23 00:19:12 +00:00
extern void
2022-07-29 16:32:52 +00:00
ConfigParseResultFree(ConfigParseResult *);
2022-07-23 00:19:12 +00:00
2022-07-29 16:32:52 +00:00
/*
* Get an array of values associated with the given configuration
* directive. Directives can have any number of values, which are
* made accessible via the Array API.
*
* Params:
*
* (ConfigDirective *) The configuration directive to get the values
* for.
*
* Return: An array that contains at least 1 value. Configuration files
* cannot have value-less directives. If the passed directive is NULL,
* or there is an error allocating memory for an array, then NULL is
* returned.
*/
2022-07-23 00:19:12 +00:00
extern Array *
2022-07-29 16:32:52 +00:00
ConfigValuesGet(ConfigDirective *);
2022-07-23 00:19:12 +00:00
2022-07-29 16:32:52 +00:00
/*
* Get a map of children associated with the given configuration
* directive. Configuration files can recurse with no practical limit,
* so directives can have any number of child directives.
*
* Params:
*
* (ConfigDirective *) The configuratio ndirective to get the
* children of.
*
* Return: A HashMap containing child directives, or NULL if the passed
* directive is NULL or has no children.
*/
2022-07-23 00:19:12 +00:00
extern HashMap *
2022-07-29 16:32:52 +00:00
ConfigChildrenGet(ConfigDirective *);
2022-07-23 00:19:12 +00:00
2022-07-29 16:32:52 +00:00
/*
* Free all the memory associated with the given configuration hash
* map. Note: this will free *everything*. All Arrays, HashMaps,
* ConfigDirectives, and even strings will be invalidated. As such,
* this should be done after you either copy the values you want, or
* are done using them. It is highly recommended to use this function
* near the end of your program's execution during cleanup, otherwise
* copy any values you need into your own buffers.
*
* Note that this should only be run on the root configuration object,
* not any children. Running on children will produce undefined
* behavior. This function is recursive; it will get all the children
* under it.
*
* Params:
*
* (HashMap *) The configuration data to free.
*
*/
2022-07-23 00:19:12 +00:00
extern void
2022-07-29 16:32:52 +00:00
ConfigFree(HashMap *);
2022-07-23 00:19:12 +00:00
2022-07-29 16:32:52 +00:00
#endif