DSL
config2_ini.cpp
1 #include <drift/dslcore.h>
2 #include <drift/config.h>
3 #include <drift/config2.h>
4 #include <drift/GenLib.h>
5 #include <math.h>
6 
10 bool ConfigINI::loadFromString(const char ** pconfig, size_t& line, const char * fn) {
11  bool long_comment = false;
12  char buf[256] = { 0 };
13 
14  const char * config = *pconfig;
15  while (*config != 0) {
16  const char * eol = strchr(config, '\n');
17  if (eol != NULL) {
18  size_t len = eol - config + 1;
19  strlcpy(buf, config, len);
20  config += len;
21  } else {
22  sstrcpy(buf, config);
23  config += strlen(config);
24  }
25  line++;
26  strtrim(buf, " \t\r\n "); // first, trim the string of unwanted chars
27  if (strlen(buf) < 3) {
28  // the minimum meaningful line would be 3 chars long, specifically [x] or x=y
29  continue;
30  }
31 
32  str_replaceA(buf, sizeof(buf), "\t", " "); // turn tabs into spaces
33  while (strstr(buf, " ")) {
34  str_replaceA(buf, sizeof(buf), " ", " "); // turn double-spaces into spaces
35  }
36 
37  //printf("line: %s\n",buf);
38 
39  if (long_comment) {
40  if (!strcmp(buf, "*/")) {
41  long_comment = false;
42  }
43  continue;
44  }
45 
46  if (!strncmp(buf, "/*", 2)) {
47  long_comment = true;
48  continue;
49  }
50 
51  if (strnicmp(buf, "#include ", 9) == 0) {
52  char * p = &buf[9];
53  p = strchr(p, '\"');
54  if (p) {
55  p++;
56  char *q = strchr(p, '\"');
57  if (q) {
58  q[0] = 0;
59  string data;
60  if (file_get_contents(p, data)) {
61  const char * tmpc = data.c_str();
62  size_t tmpln = 0;
63  if (!loadFromString(&tmpc, tmpln, p)) {
64  printf("ERROR: Error loading #included file '%s'\n", p);
65  break;
66  }
67  } else {
68  printf("ERROR: Error reading #included file '%s'\n", p);
69  break;
70  }
71  } else {
72  printf("ERROR: Syntax is #include \"filename\"\n");
73  break;
74  }
75  } else {
76  printf("ERROR: Syntax is #include \"filename\"\n");
77  break;
78  }
79  continue;
80  }
81 
82  if (buf[0] == '#' || !strncmp(buf, "//", 2)) {
83  continue;
84  }
85 
86  if (buf[0] == '[' && buf[strlen(buf)-1] == ']') { // open a new section
87  buf[strlen(buf) - 1] = 0;
88  ConfigINI * sub;
89  if (parent != NULL) {
90  sub = parent->FindOrAddSection(&buf[1]);
91  } else {
92  sub = FindOrAddSection(&buf[1]);
93  }
94  if (sub == NULL) {
95  printf("ERROR: Error finding or creating section '%s'\n", &buf[1]);
96  break;
97  }
98  if (!sub->loadFromString(&config, line, fn)) {
99  break;
100  }
101  continue;
102  }
103 
104  char * value = strchr(buf, '=');
105  if (value == NULL) {
106  continue;
107  }
108  *value++ = 0;
109  strtrim(buf);
110  strtrim(value);
111  if (buf[0] && value[0]) {
112  auto x = values.find(buf);
113  if (x != values.end()) {
114  x->second->ParseString(value);
115  } else {
116  auto tmpv = new ConfigValue();
117  tmpv->ParseString(value);
118  _values[buf] = tmpv;
119  }
120  continue;
121  }
122 
123  printf("Unrecognized line at %s:%zu -> %s\n", fn, line, buf);
124  // some unknown line here
125  }
126 
127  *pconfig = config;
128  return true;
129 }
130 
131 void ConfigINI::writeSection(stringstream& sstr, int level, bool single) const {
132  sstr << "[" << name << "]\n";
133 
134  for (auto& x : values) {
135  sstr << x.first << " = " << x.second->AsString() << "\n";
136  };
137 
138  sstr << "\n";
139 }
140 
141 ConfigINI * ConfigINI::FindOrAddSection(const string& name) {
142  auto sec = GetSection(name);
143  if (sec != NULL) {
144  ConfigINI * ret = dynamic_cast<ConfigINI *>(sec);
145  if (ret != NULL) {
146  return ret;
147  }
148  return NULL;
149  }
150 
151  auto * s = new ConfigINI();
152  s->name = name;
153  s->parent = this;
154  _sections[name] = s;
155  return s;
156 }
virtual bool loadFromString(const char **config, size_t &line, const char *fn)
Definition: config2_ini.cpp:10
DSL_API size_t DSL_CC strlcpy(char *dst, const char *src, size_t siz)
Definition: GenLib.cpp:905
DSL_API_CLASS int DSL_CC str_replaceA(char *Str, size_t BufSize, const char *FindStr, const char *ReplStr)
Simple string replacement.
Definition: GenLib.cpp:592
#define sstrcpy(x, y)
Definition: GenLib.h:102
DSL_API char *DSL_CC strtrim(char *buf, const char *trim="\r\n\t ", uint8 sides=TRIM_BOTH)
Definition: GenLib.cpp:294
DSL_API_CLASS bool DSL_CC file_get_contents(const string &fn, vector< uint8 > &data, int64 maxSize=INT32_MAX)
Definition: GenLib.cpp:972