#ifndef WS_CONFIG_SERVERCONFIG_H
#define WS_CONFIG_SERVERCONFIG_H
#include <cx/linked_list.h>
#include <cx/hash_map.h>
#include <cx/mempool.h>
#include <cx/string.h>
#include <stdbool.h>
#include "conf.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CFG_NODE_ADD(list_begin, list_end, elm) \
cx_linked_list_add((
void**)list_begin, (
void**)list_end, offsetof(ConfigNode, prev), offsetof(ConfigNode, next), elm)
typedef struct ServerConfig ServerConfig;
typedef struct ConfigNode ConfigNode;
typedef struct CFGToken CFGToken;
typedef struct ConfigParser2 ConfigParser2;
typedef enum ConfigNodeType ConfigNodeType;
typedef enum CFGTokenType CFGTokenType;
struct ServerConfig {
CxMempool *mp;
ConfigNode *root;
cxstring tab;
};
enum ConfigNodeType {
CONFIG_NODE_SPACE =
0,
CONFIG_NODE_COMMENT,
CONFIG_NODE_OBJECT,
CONFIG_NODE_DIRECTIVE,
CONFIG_NODE_OPEN_OBJECT,
CONFIG_NODE_CLOSE_OBJECT
};
struct ConfigNode {
cxmutstr text_begin;
cxmutstr text_end;
ConfigNodeType type;
cxmutstr name;
ConfigParam *args;
ConfigNode *children_begin;
ConfigNode *children_end;
ConfigNode *prev;
ConfigNode *next;
};
typedef struct ConfigNodeStack ConfigNodeStack;
struct ConfigNodeStack {
ConfigNode *node;
ConfigNodeStack *next;
};
enum CFGTokenType {
CFG_NO_TOKEN =
0,
CFG_TOKEN_COMMENT,
CFG_TOKEN_SPACE,
CFG_TOKEN_NEWLINE,
CFG_TOKEN
};
struct CFGToken {
cxstring content;
CFGTokenType type;
};
enum ConfigParserError {
CONFIG_PARSER_OOM =
0,
CONFIG_PARSER_IO_ERROR,
CONFIG_PARSER_SYNTAX_ERROR
};
typedef int(*CfgValidateNodeFunc)(ConfigParser2 *parser, ConfigNode *node);
struct ConfigParser2 {
CxMempool *mp;
const char *filename;
int linenum;
int linepos;
enum ConfigParserError error;
const char *delim;
int io_errno;
CfgValidateNodeFunc validateObjBegin;
CfgValidateNodeFunc validateObjEnd;
CfgValidateNodeFunc validateDirective;
bool allow_hierarchy;
};
ServerConfig* serverconfig_load(
const char *file);
ConfigNode* serverconfig_load_file(ConfigParser2 *parser,
const char *file);
ConfigNode* serverconfig_parse(ConfigParser2 *parser, cxstring content);
void serverconfig_free(ServerConfig *cfg);
ConfigNode* serverconfig_get_node(ConfigNode *parent, ConfigNodeType type, cxstring name);
CxList* serverconfig_get_node_list(ConfigNode *parent, ConfigNodeType type, cxstring name);
cxstring serverconfig_object_directive_value(ConfigNode *obj, cxstring directive_name);
cxstring serverconfig_directive_get_arg(ConfigNode *directive, cxstring param_name);
int serverconfig_validate_directive_name(
ConfigNode *directive,
const char *names[],
size_t numnames,
size_t *nameindex);
int serverconfig_check_param_names(ConfigNode *directive, ConfigParam **err);
ConfigNode* serverconfig_previous_dir_or_obj(ConfigNode *node);
size_t serverconfig_children_count(ConfigNode *node, ConfigNodeType type);
#ifdef __cplusplus
}
#endif
#endif