You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

286 lines
6.6 KiB
C++

#ifndef PARSER_H
#define PARSER_H
#include <stdarg.h>
#include <string>
#include <list>
#include <stdlib.h>
#include <stdint.h>
#include <typeinfo>
#include <libconfig.h++>
#include <string.h>
#include <iostream>
#include <fstream>
namespace srsenb {
using namespace libconfig;
class parser
{
public:
class field_itf
{
public:
virtual ~field_itf(){}
virtual int parse(Setting &root) = 0;
virtual const char* get_name() = 0;
};
template<class T>
class field_enum_str : public field_itf
{
public:
field_enum_str(const char* name_, T *store_ptr_, const char (*value_str_)[20], uint32_t nof_items_, bool *enabled_value_ = NULL)
{
name = name_;
store_ptr = store_ptr_;
value_str = value_str_;
nof_items = nof_items_;
enabled_value = enabled_value_;
}
const char* get_name() {
return name;
}
int parse(Setting &root)
{
std::string val;
if (root.exists(name)) {
if (enabled_value) {
*enabled_value = true;
}
if (root.lookupValue(name, val)) {
bool found = false;
// find value
for (uint32_t i=0;i<nof_items && !found;i++) {
if (!strcmp(value_str[i], val.c_str())) {
*store_ptr = (T) i;
found = true;
}
}
if (!found) {
fprintf(stderr, "Invalid option: %s for field %s\n", val.c_str(), name);
fprintf(stderr, "Valid options: %s", value_str[0]);
for (uint32_t i=1;i<nof_items;i++) {
fprintf(stderr, ", %s", value_str[i]);
}
fprintf(stderr, "\n");
return -1;
}
return 0;
} else {
return -1;
}
} else {
if (enabled_value) {
*enabled_value = false;
return 0;
} else {
return -1;
}
}
}
private:
const char* name;
T *store_ptr;
const char (*value_str)[20];
uint32_t nof_items;
bool *enabled_value;
};
template<class T, class S>
class field_enum_num : public field_itf
{
public:
field_enum_num(const char* name_, T *store_ptr_, const S *value_str_, uint32_t nof_items_, bool *enabled_value_ = NULL)
{
name = name_;
store_ptr = store_ptr_;
value_str = value_str_;
nof_items = nof_items_;
enabled_value = enabled_value_;
}
const char* get_name() {
return name;
}
int parse(Setting &root)
{
S val;
if (root.exists(name)) {
if (enabled_value) {
*enabled_value = true;
}
if (parser::lookupValue(root, name, &val)) {
bool found = false;
// find value
for (uint32_t i=0;i<nof_items && !found;i++) {
if (value_str[i] == val) {
*store_ptr = (T) i;
found = true;
}
}
if (!found) {
std::cout << "Invalid option: " << +val << " for field " << name << std::endl;
std::cout << "Valid options: ";
for (uint32_t i=0;i<nof_items;i++) {
std::cout << +value_str[i] << ", ";
}
std::cout << std::endl;
return -1;
}
return 0;
} else {
return -1;
}
} else {
if (enabled_value) {
*enabled_value = false;
return 0;
} else {
return -1;
}
}
}
private:
const char* name;
T *store_ptr;
const S *value_str;
uint32_t nof_items;
bool *enabled_value;
};
template<class T>
class field : public field_itf
{
public:
field(const char* name_, T *store_ptr_, bool *enabled_value_ = NULL)
{
name = name_;
store_ptr = store_ptr_;
enabled_value = enabled_value_;
}
const char* get_name() {
return name;
}
int parse(Setting &root)
{
if (root.exists(name)) {
if (enabled_value) {
*enabled_value = true;
}
if (!parser::lookupValue(root, name, store_ptr)) {
return -1;
} else {
return 0;
}
} else {
if (enabled_value) {
*enabled_value = false;
return 0;
} else {
return -1;
}
}
}
private:
const char* name;
T *store_ptr;
bool *enabled_value;
};
class section
{
public:
section(std::string name);
~section();
void set_optional(bool *enabled_value);
void add_subsection(section *s);
void add_field(field_itf *f);
int parse(Setting &root);
private:
std::string name;
bool *enabled_value;
std::list<section*> sub_sections;
std::list<field_itf*> fields;
};
parser(std::string filename);
int parse();
void add_section(section *s);
static int parse_section(std::string filename, section *s);
static bool lookupValue(Setting &root, const char *name, std::string *val) {
return root.lookupValue(name, *val);
}
static bool lookupValue(Setting &root, const char *name, uint8_t *val) {
uint32_t t;
bool r = root.lookupValue(name, t);
*val = (uint8_t) t;
return r;
}
static bool lookupValue(Setting &root, const char *name, uint16_t *val) {
uint32_t t;
bool r = root.lookupValue(name, t);
*val = (uint16_t) t;
return r;
}
static bool lookupValue(Setting &root, const char *name, uint32_t *val) {
uint32_t t;
bool r = root.lookupValue(name, t);
*val = t;
return r;
}
static bool lookupValue(Setting &root, const char *name, int8_t *val) {
int32_t t;
bool r = root.lookupValue(name, t);
*val = (int8_t) t;
return r;
}
static bool lookupValue(Setting &root, const char *name, int16_t *val) {
int32_t t;
bool r = root.lookupValue(name, t);
*val = (int16_t) t;
return r;
}
static bool lookupValue(Setting &root, const char *name, int32_t *val) {
int32_t t;
bool r = root.lookupValue(name, t);
*val = t;
return r;
}
static bool lookupValue(Setting &root, const char *name, double *val) {
double t;
bool r = root.lookupValue(name, t);
*val = t;
return r;
}
static bool lookupValue(Setting &root, const char *name, bool *val) {
bool t;
bool r = root.lookupValue(name, t);
*val = t;
return r;
}
private:
std::list<section*> sections;
std::string filename;
};
}
#endif // PARSER_H