00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "configfile.h"
00027 #include <stdexcept>
00028
00029 CONFIGFILE::CONFIGFILE()
00030 {
00031 vars = NULL;
00032 filename = "";
00033 SUPPRESS_ERROR = false;
00034 }
00035
00036 CONFIGFILE::CONFIGFILE(string fname)
00037 {
00038 vars = NULL;
00039
00040 SUPPRESS_ERROR = false;
00041
00042 Load(fname);
00043 }
00044
00045 CONFIGFILE::~CONFIGFILE()
00046 {
00047 Clear();
00048 }
00049
00050 bool CONFIGFILE::GetParam(string param, int & outvar)
00051 {
00052 CONFIGVARIABLE * cur = vars;
00053 bool found = false;
00054 while (cur != NULL)
00055 {
00056
00057
00058 string pname = param;
00059 string psec = "";
00060 string::size_type ppos;
00061 ppos = param.find(".", 0);
00062 if (ppos < param.length())
00063 {
00064 psec = param.substr(0, ppos);
00065 ppos++;
00066 pname = param.substr(ppos, param.length() - ppos);
00067 }
00068
00069 if (pname == cur->name && psec == cur->section)
00070 {
00071 found = true;
00072 outvar = cur->val_i;
00073 }
00074
00075 cur = cur->next;
00076 }
00077
00078 if (!found && !SUPPRESS_ERROR)
00079 {
00080 cout << "CONFIGFILE::GetParam(): " << param << " not found in " << filename << endl;
00081 }
00082
00083 return found;
00084 }
00085
00086 bool CONFIGFILE::GetParam(string param, bool & outvar)
00087 {
00088 CONFIGVARIABLE * cur = vars;
00089 bool found = false;
00090 while (cur != NULL)
00091 {
00092
00093
00094 string pname = param;
00095 string psec = "";
00096 string::size_type ppos;
00097 ppos = param.find(".", 0);
00098 if (ppos < param.length())
00099 {
00100 psec = param.substr(0, ppos);
00101 ppos++;
00102 pname = param.substr(ppos, param.length() - ppos);
00103 }
00104
00105 if (pname == cur->name && psec == cur->section)
00106 {
00107 found = true;
00108 outvar = cur->val_b;
00109 }
00110
00111 cur = cur->next;
00112 }
00113
00114 if (!found && !SUPPRESS_ERROR)
00115 {
00116 cout << "CONFIGFILE::GetParam(): " << param << " not found in " << filename << endl;
00117 }
00118
00119 return found;
00120 }
00121
00122 bool CONFIGFILE::GetParam(string param, float & outvar)
00123 {
00124 CONFIGVARIABLE * cur = vars;
00125 bool found = false;
00126 while (cur != NULL)
00127 {
00128
00129
00130 string pname = param;
00131 string psec = "";
00132 string::size_type ppos;
00133 ppos = param.find(".", 0);
00134 if (ppos < param.length())
00135 {
00136 psec = param.substr(0, ppos);
00137 ppos++;
00138 pname = param.substr(ppos, param.length() - ppos);
00139 }
00140
00141 if (pname == cur->name && psec == cur->section)
00142 {
00143 found = true;
00144 outvar = cur->val_f;
00145 }
00146
00147 cur = cur->next;
00148 }
00149
00150 if (!found && !SUPPRESS_ERROR)
00151 {
00152 cout << "CONFIGFILE::GetParam(): " << param << " not found in " << filename << endl;
00153 }
00154
00155 return found;
00156 }
00157
00158 bool CONFIGFILE::GetParam(string param, float * outvar)
00159 {
00160 CONFIGVARIABLE * cur = vars;
00161 bool found = false;
00162 while (cur != NULL)
00163 {
00164
00165
00166 string pname = param;
00167 string psec = "";
00168 string::size_type ppos;
00169 ppos = param.find(".", 0);
00170 if (ppos < param.length())
00171 {
00172 psec = param.substr(0, ppos);
00173 ppos++;
00174 pname = param.substr(ppos, param.length() - ppos);
00175 }
00176
00177 if (pname == cur->name && psec == cur->section)
00178 {
00179 found = true;
00180
00181 int i;
00182 for (i = 0; i < 3; i++)
00183 outvar[i] = cur->val_v[i];
00184 }
00185
00186 cur = cur->next;
00187 }
00188
00189 if (!found && !SUPPRESS_ERROR)
00190 {
00191 cout << "CONFIGFILE::GetParam(): " << param << " not found in " << filename << endl;
00192 }
00193
00194 return found;
00195 }
00196
00197 bool CONFIGFILE::GetParam(string param, string & outvar)
00198 {
00199 CONFIGVARIABLE * cur = vars;
00200 bool found = false;
00201 while (cur != NULL)
00202 {
00203
00204
00205 string pname = param;
00206 string psec = "";
00207 string::size_type ppos;
00208 ppos = param.find(".", 0);
00209 if (ppos < param.length())
00210 {
00211 psec = param.substr(0, ppos);
00212 ppos++;
00213 pname = param.substr(ppos, param.length() - ppos);
00214 }
00215
00216 if (pname == cur->name && psec == cur->section)
00217 {
00218 found = true;
00219 outvar = cur->val_s;
00220 }
00221
00222 cur = cur->next;
00223 }
00224
00225 if (!found && !SUPPRESS_ERROR)
00226 {
00227 cout << "CONFIGFILE::GetParam(): " << param << " not found in " << filename << endl;
00228 }
00229
00230 return found;
00231 }
00232
00233 void CONFIGFILE::Clear()
00234 {
00235 int count = 0;
00236
00237
00238
00239 CONFIGVARIABLE * cur = vars;
00240 while (cur != NULL)
00241 {
00242 count++;
00243
00244 CONFIGVARIABLE * todel = cur;
00245
00246 if (cur != 0)
00247 cur = cur->next;
00248
00249 delete todel;
00250 }
00251
00252 vars = NULL;
00253 }
00254
00255 void CONFIGFILE::Add(CONFIGVARIABLE * newvar)
00256 {
00257 newvar->next = NULL;
00258
00259 CONFIGVARIABLE * cur = vars;
00260 bool isdup = false;
00261 while (cur != NULL)
00262 {
00263 if (cur->section == newvar->section && cur->name == newvar->name)
00264 {
00265 isdup = true;
00266 cur->Set(newvar->val_s);
00267 }
00268
00269 cur = cur->next;
00270 }
00271
00272
00273 if (!isdup)
00274 {
00275
00276
00277
00278
00279
00280 cur = vars;
00281 CONFIGVARIABLE * last = vars;
00282 while (cur != NULL)
00283 {
00284 last = cur;
00285 cur = cur->next;
00286 }
00287 if (vars == NULL)
00288 {
00289 vars = newvar;
00290 vars->next = NULL;
00291 }
00292 else
00293 {
00294 last->next = newvar;
00295 last->next->next = cur;
00296 }
00297
00298 }
00299 else
00300 delete newvar;
00301 }
00302
00303 CONFIGVARIABLE::CONFIGVARIABLE()
00304 {
00305 val_s = "";
00306 val_i = 0;
00307 val_f = 0;
00308 val_b = false;
00309 int i;
00310 for (i = 0; i < 3; i++)
00311 val_v[i] = 0;
00312
00313 next = NULL;
00314 }
00315
00316 string CONFIGVARIABLE::GetFullName()
00317 {
00318 string outstr = "";
00319
00320 if (section != "")
00321 outstr = outstr + section + ".";
00322 outstr = outstr + name;
00323
00324 return outstr;
00325 }
00326
00327 void CONFIGVARIABLE::Set(string newval)
00328 {
00329 newval = strTrim(newval);
00330
00331 val_i = atoi(newval.c_str());
00332 val_f = atof(newval.c_str());
00333 val_s = newval;
00334
00335 val_b = false;
00336 if (val_i == 0)
00337 val_b = false;
00338 if (val_i == 1)
00339 val_b = true;
00340 if (strLCase(newval) == "true")
00341 val_b = true;
00342 if (strLCase(newval) == "false")
00343 val_b = false;
00344 if (strLCase(newval) == "on")
00345 val_b = true;
00346 if (strLCase(newval) == "off")
00347 val_b = false;
00348
00349
00350 int pos = 0;
00351 int arraypos = 0;
00352 string::size_type nextpos = newval.find(",", pos);
00353 string frag;
00354
00355 while (nextpos < newval.length() && arraypos < 3)
00356 {
00357 frag = newval.substr(pos, nextpos - pos);
00358 val_v[arraypos] = atof(frag.c_str());
00359
00360 pos = nextpos+1;
00361 arraypos++;
00362 nextpos = newval.find(",", pos);
00363 }
00364
00365
00366 if (arraypos < 3)
00367 {
00368 frag = newval.substr(pos, newval.length() - pos);
00369 val_v[arraypos] = atof(frag.c_str());
00370 }
00371 }
00372
00373 void CONFIGVARIABLE::DebugPrint()
00374 {
00375 if (section != "")
00376 cout << section << ".";
00377 cout << name << endl;
00378 cout << "string: " << val_s << endl;
00379 cout << "int: " << val_i << endl;
00380 cout << "float: " << val_f << endl;
00381 cout << "vector: (" << val_v[0] << "," << val_v[1] << "," << val_v[2] << ")" << endl;
00382 cout << "bool: " << val_b << endl;
00383
00384 cout << endl;
00385 }
00386
00387 string CONFIGVARIABLE::strLTrim(string instr)
00388 {
00389 return instr.erase(0, instr.find_first_not_of(" \t"));
00390 }
00391
00392 string CONFIGVARIABLE::strRTrim(string instr)
00393 {
00394 try {
00395 return instr.erase(instr.find_last_not_of(" \t") + 1);
00396 } catch(std::out_of_range) {
00397 return instr;
00398 }
00399 }
00400
00401 string CONFIGVARIABLE::strTrim(string instr)
00402 {
00403 return strLTrim(strRTrim(instr));
00404 }
00405
00406 void CONFIGFILE::Load(string fname)
00407 {
00408 filename = fname;
00409
00410 string cursection = "";
00411
00412
00413 string ws;
00414 const int MAXIMUMCHAR = 1024;
00415 char trashchar[MAXIMUMCHAR];
00416
00417 ifstream f;
00418 f.open(fname.c_str());
00419
00420 if (!f && !SUPPRESS_ERROR)
00421 {
00422 cout << "CONFIGFILE.Load: Couldn't find file: " << fname << endl;
00423 }
00424
00425 while (f && !f.eof())
00426 {
00427 f.getline(trashchar, MAXIMUMCHAR, '\n');
00428 ProcessLine(cursection, trashchar);
00429 }
00430
00431 f.close();
00432
00433
00434 }
00435
00436 string CONFIGFILE::Trim(string instr)
00437 {
00438 CONFIGVARIABLE trimmer;
00439 string outstr = trimmer.strTrim(instr);
00440 return outstr;
00441 }
00442
00443 void CONFIGFILE::ProcessLine(string & cursection, string linestr)
00444 {
00445 linestr = Trim(linestr);
00446 linestr = Strip(linestr, '\r');
00447 linestr = Strip(linestr, '\n');
00448
00449
00450 string::size_type commentpos = linestr.find("#", 0);
00451 if (commentpos < linestr.length())
00452 {
00453 linestr = linestr.substr(0, commentpos);
00454 }
00455
00456 linestr = Trim(linestr);
00457
00458
00459 if (linestr.length() > 0)
00460 {
00461 if (linestr.find("=", 0) < linestr.length())
00462 {
00463
00464 string::size_type equalpos = linestr.find("=", 0);
00465 string name = linestr.substr(0, equalpos);
00466 equalpos++;
00467 string val = linestr.substr(equalpos, linestr.length() - equalpos);
00468 name = Trim(name);
00469 val = Trim(val);
00470
00471
00472 if (name.length() > 0 && val.length() > 0)
00473 {
00474 CONFIGVARIABLE * newvar;
00475 newvar = new CONFIGVARIABLE;
00476 newvar->section = cursection;
00477 newvar->name = name;
00478 newvar->Set(val);
00479 newvar->next = NULL;
00480
00481 Add(newvar);
00482 }
00483 }
00484 else
00485 {
00486
00487 linestr = Strip(linestr, '[');
00488 linestr = Strip(linestr, ']');
00489 linestr = Trim(linestr);
00490 cursection = linestr;
00491 }
00492 }
00493 }
00494
00495 string CONFIGFILE::Strip(string instr, char stripchar)
00496 {
00497 string::size_type pos = 0;
00498 string outstr = "";
00499
00500 while (pos < instr.length())
00501 {
00502 if (instr.c_str()[pos] != stripchar)
00503 outstr = outstr + instr.substr(pos, 1);
00504
00505 pos++;
00506 }
00507
00508 return outstr;
00509 }
00510
00511 void CONFIGFILE::DebugPrint()
00512 {
00513 CONFIGVARIABLE * cur = vars;
00514 cout << "*** " << filename << " ***" << endl << endl;
00515 while (cur != NULL)
00516 {
00517 cur->DebugPrint();
00518
00519 cur = cur->next;
00520 }
00521 }
00522
00523 string CONFIGVARIABLE::strLCase(string instr)
00524 {
00525 char tc[2];
00526 tc[1] = '\0';
00527 string outstr = "";
00528
00529 string::size_type pos = 0;
00530 while (pos < instr.length())
00531 {
00532 if (instr.c_str()[pos] <= 90 && instr.c_str()[pos] >= 65)
00533 {
00534 tc[0] = instr.c_str()[pos] + 32;
00535 string tstr = tc;
00536 outstr = outstr + tc;
00537 }
00538 else
00539 outstr = outstr + instr.substr(pos, 1);
00540
00541 pos++;
00542 }
00543
00544 return outstr;
00545 }
00546
00547 string CONFIGFILE::LCase(string instr)
00548 {
00549 CONFIGVARIABLE lcaser;
00550 string outstr = lcaser.strLCase(instr);
00551 return outstr;
00552 }
00553
00554 bool CONFIGFILE::SetParam(string param, int invar)
00555 {
00556 char tc[256];
00557
00558 sprintf(tc, "%i", invar);
00559
00560 string tstr = tc;
00561
00562 return SetParam(param, tstr);
00563 }
00564
00565 bool CONFIGFILE::SetParam(string param, bool invar)
00566 {
00567
00568
00569
00570
00571 string tstr = "off";
00572
00573 if (invar)
00574 tstr = "on";
00575
00576 return SetParam(param, tstr);
00577 }
00578
00579 bool CONFIGFILE::SetParam(string param, float invar)
00580 {
00581 char tc[256];
00582
00583 sprintf(tc, "%f", invar);
00584
00585 string tstr = tc;
00586
00587 return SetParam(param, tstr);
00588 }
00589
00590 bool CONFIGFILE::SetParam(string param, float * invar)
00591 {
00592 char tc[256];
00593
00594 sprintf(tc, "%f,%f,%f", invar[0], invar[1], invar[2]);
00595
00596 string tstr = tc;
00597
00598 return SetParam(param, tstr);
00599 }
00600
00601 bool CONFIGFILE::SetParam(string param, string invar)
00602 {
00603 CONFIGVARIABLE * newvar;
00604 newvar = new CONFIGVARIABLE;
00605
00606 newvar->name = param;
00607 newvar->section = "";
00608 string::size_type ppos;
00609 ppos = param.find(".", 0);
00610 if (ppos < param.length())
00611 {
00612 newvar->section = param.substr(0, ppos);
00613 ppos++;
00614 newvar->name = param.substr(ppos, param.length() - ppos);
00615 }
00616
00617 newvar->Set(invar);
00618 newvar->next = NULL;
00619
00620 Add(newvar);
00621
00622 return true;
00623 }
00624
00625 bool CONFIGFILE::Write(bool with_brackets)
00626 {
00627 return Write(with_brackets, filename);
00628 }
00629
00630 bool CONFIGFILE::Write(bool with_brackets, string save_as)
00631 {
00632 ofstream f;
00633 f.open(save_as.c_str());
00634
00635 if (f)
00636 {
00637
00638 CONFIGVARIABLE * cur = vars;
00639 while (cur != NULL)
00640 {
00641 cur->written = false;
00642 cur = cur->next;
00643 }
00644
00645
00646 bool nosection = false;
00647 cur = vars;
00648 while (cur != NULL)
00649 {
00650 if (cur->section == "")
00651 {
00652 f << cur->name << " = " << cur->val_s << endl;
00653
00654 nosection = true;
00655
00656 cur->written = true;
00657 }
00658
00659 cur = cur->next;
00660 }
00661
00662 if (nosection)
00663 f << endl;
00664
00665
00666 cur = vars;
00667 while (cur != NULL)
00668 {
00669 if (!cur->written)
00670 {
00671 if (with_brackets)
00672 f << "[ " << cur->section << " ]" << endl;
00673 else
00674 f << cur->section << endl;
00675
00676 CONFIGVARIABLE * sub = vars;
00677 while (sub != NULL)
00678 {
00679 if (!sub->written && cur->section == sub->section)
00680 {
00681 f << sub->name << " = " << sub->val_s << endl;
00682
00683 sub->written = true;
00684 }
00685
00686 sub = sub->next;
00687 }
00688
00689 f << endl;
00690
00691 cur->written = true;
00692 }
00693
00694 cur = cur->next;
00695 }
00696
00697 f.close();
00698 return true;
00699 }
00700 else
00701 return false;
00702 }
00703
00704 bool CONFIGFILE::Write()
00705 {
00706 Write(true);
00707 return true;
00708 }
00709
00710 bool CONFIGFILE::ClearParam(string param)
00711 {
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723 CONFIGVARIABLE * cur = vars;
00724 CONFIGVARIABLE * prev = vars;
00725 bool found = false;
00726 while (cur != NULL)
00727 {
00728
00729
00730 string pname = param;
00731 string psec = "";
00732 string::size_type ppos;
00733 ppos = param.find(".", 0);
00734 if (ppos < param.length())
00735 {
00736 psec = param.substr(0, ppos);
00737 ppos++;
00738 pname = param.substr(ppos, param.length() - ppos);
00739 }
00740
00741 if (pname == cur->name && psec == cur->section)
00742 {
00743 found = true;
00744
00745 CONFIGVARIABLE * todel = cur;
00746 if (cur == vars)
00747 {
00748 vars = vars->next;
00749 prev = vars;
00750 cur = vars;
00751 }
00752 else
00753 {
00754 cur = cur->next;
00755 prev->next = cur;
00756 }
00757
00758 delete todel;
00759 }
00760 else
00761 {
00762 prev = cur;
00763 cur = cur->next;
00764 }
00765 }
00766
00767
00768
00769
00770
00771
00772
00773 return found;
00774 }