Logo Search packages:      
Sourcecode: vdrift version File versions

configfile.cpp

/* vim: set noexpandtab shiftwidth=8 cino=:
 ***************************************************************************
 *            configfile.cc
 *
 *  Sun Oct  2 18:34:08 2005
 *  Copyright  2005  Joe Venzon
 *  joe@venzon.net
 ****************************************************************************/

/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
 
#include "configfile.h"
#include <stdexcept>

CONFIGFILE::CONFIGFILE()
{
      vars = NULL;
      filename = "";
      SUPPRESS_ERROR = false;
}

CONFIGFILE::CONFIGFILE(string fname)
{
      vars = NULL;
      
      SUPPRESS_ERROR = false;
      
      Load(fname);
}

CONFIGFILE::~CONFIGFILE()
{
      Clear();
}

bool CONFIGFILE::GetParam(string param, int & outvar)
{
      CONFIGVARIABLE * cur = vars;
      bool found = false;
      while (cur != NULL)
      {
            //if the var section/name matches the param name, set outvar
            
            string pname = param;
            string psec = "";
            string::size_type ppos;
            ppos = param.find(".", 0);
            if (ppos < /*(int)*/ param.length())
            {
                  psec = param.substr(0, ppos);
                  ppos++;
                  pname = param.substr(ppos, param.length() - ppos);
            }
            
            if (pname == cur->name && psec == cur->section)
            {
                  found = true;
                  outvar = cur->val_i;
            }
            
            cur = cur->next;
      }
      
      if (!found && !SUPPRESS_ERROR)
      {
            cout << "CONFIGFILE::GetParam():  " << param << " not found in " << filename << endl;
      }
      
      return found;
}

bool CONFIGFILE::GetParam(string param, bool & outvar)
{
      CONFIGVARIABLE * cur = vars;
      bool found = false;
      while (cur != NULL)
      {
            //if the var section/name matches the param name, set outvar
            
            string pname = param;
            string psec = "";
            string::size_type ppos;
            ppos = param.find(".", 0);
            if (ppos < /*(int)*/ param.length())
            {
                  psec = param.substr(0, ppos);
                  ppos++;
                  pname = param.substr(ppos, param.length() - ppos);
            }
            
            if (pname == cur->name && psec == cur->section)
            {
                  found = true;
                  outvar = cur->val_b;
            }
            
            cur = cur->next;
      }
      
      if (!found && !SUPPRESS_ERROR)
      {
            cout << "CONFIGFILE::GetParam():  " << param << " not found in " << filename << endl;
      }
      
      return found;
}

bool CONFIGFILE::GetParam(string param, float & outvar)
{
      CONFIGVARIABLE * cur = vars;
      bool found = false;
      while (cur != NULL)
      {
            //if the var section/name matches the param name, set outvar
            
            string pname = param;
            string psec = "";
            string::size_type ppos;
            ppos = param.find(".", 0);
            if (ppos < /*(int)*/ param.length())
            {
                  psec = param.substr(0, ppos);
                  ppos++;
                  pname = param.substr(ppos, param.length() - ppos);
            }
            
            if (pname == cur->name && psec == cur->section)
            {
                  found = true;
                  outvar = cur->val_f;
            }
            
            cur = cur->next;
      }
      
      if (!found && !SUPPRESS_ERROR)
      {
            cout << "CONFIGFILE::GetParam():  " << param << " not found in " << filename << endl;
      }
      
      return found;
}

bool CONFIGFILE::GetParam(string param, float * outvar)
{
      CONFIGVARIABLE * cur = vars;
      bool found = false;
      while (cur != NULL)
      {
            //if the var section/name matches the param name, set outvar
            
            string pname = param;
            string psec = "";
            string::size_type ppos;
            ppos = param.find(".", 0);
            if (ppos < /*(int)*/ param.length())
            {
                  psec = param.substr(0, ppos);
                  ppos++;
                  pname = param.substr(ppos, param.length() - ppos);
            }
            
            if (pname == cur->name && psec == cur->section)
            {
                  found = true;
                  
                  int i;
                  for (i = 0; i < 3; i++)
                        outvar[i] = cur->val_v[i];
            }
            
            cur = cur->next;
      }
      
      if (!found && !SUPPRESS_ERROR)
      {
            cout << "CONFIGFILE::GetParam():  " << param << " not found in " << filename << endl;
      }
      
      return found;
}

bool CONFIGFILE::GetParam(string param, string & outvar)
{
      CONFIGVARIABLE * cur = vars;
      bool found = false;
      while (cur != NULL)
      {
            //if the var section/name matches the param name, set outvar
            
            string pname = param;
            string psec = "";
            string::size_type ppos;
            ppos = param.find(".", 0);
            if (ppos < /*(int)*/ param.length())
            {
                  psec = param.substr(0, ppos);
                  ppos++;
                  pname = param.substr(ppos, param.length() - ppos);
            }
            
            if (pname == cur->name && psec == cur->section)
            {
                  found = true;
                  outvar = cur->val_s;
            }
            
            cur = cur->next;
      }
      
      if (!found && !SUPPRESS_ERROR)
      {
            cout << "CONFIGFILE::GetParam():  " << param << " not found in " << filename << endl;
      }
      
      return found;
}

void CONFIGFILE::Clear()
{
      int count = 0;
      
      //cout << "Clear " << filename << endl;
      
      CONFIGVARIABLE * cur = vars;
      while (cur != NULL)
      {
            count++;
            //cout << count << ": " << cur << ", " << cur->GetFullName() << endl;
            CONFIGVARIABLE * todel = cur;
            
            if (cur != 0)
                  cur = cur->next;

            delete todel;
      }
      
      vars = NULL;
}

void CONFIGFILE::Add(CONFIGVARIABLE * newvar)
{
      newvar->next = NULL;
      //check for dups
      CONFIGVARIABLE * cur = vars;
      bool isdup = false;
      while (cur != NULL)
      {
            if (cur->section == newvar->section && cur->name == newvar->name)
            {
                  isdup = true;
                  cur->Set(newvar->val_s);
            }
            
            cur = cur->next;
      }
      
      //go ahead and insert
      if (!isdup)
      {
            /*CONFIGVARIABLE * oldfirst = vars;
            
            vars = newvar;
            vars->next = oldfirst;*/

            cur = vars;
            CONFIGVARIABLE * last = vars;
            while (cur != NULL)
            {
                  last = cur;
                  cur = cur->next;
            }
            if (vars == NULL)
            {
                  vars = newvar;
                  vars->next = NULL;
            }
            else
            {
                  last->next = newvar;
                  last->next->next = cur;
            }
            //newvar->next = cur;
      }
      else
            delete newvar;
}

CONFIGVARIABLE::CONFIGVARIABLE()
{
      val_s = "";
      val_i = 0;
      val_f = 0;
      val_b = false;
      int i;
      for (i = 0; i < 3; i++)
            val_v[i] = 0;
      
      next = NULL;
}

string CONFIGVARIABLE::GetFullName()
{
      string outstr = "";
      
      if (section != "")
            outstr = outstr + section + ".";
      outstr = outstr + name;
      
      return outstr;
}

void CONFIGVARIABLE::Set(string newval)
{
      newval = strTrim(newval);
      
      val_i = atoi(newval.c_str());
      val_f = atof(newval.c_str());
      val_s = newval;
      
      val_b = false;
      if (val_i == 0)
            val_b = false;
      if (val_i == 1)
            val_b = true;
      if (strLCase(newval) == "true")
            val_b = true;
      if (strLCase(newval) == "false")
            val_b = false;
      if (strLCase(newval) == "on")
            val_b = true;
      if (strLCase(newval) == "off")
            val_b = false;
      
      //now process as vector information
      int pos = 0;
      int arraypos = 0;
      string::size_type nextpos = newval.find(",", pos);
      string frag;
      
      while (nextpos < /*(int)*/ newval.length() && arraypos < 3)
      {
            frag = newval.substr(pos, nextpos - pos);
            val_v[arraypos] = atof(frag.c_str());
            
            pos = nextpos+1;
            arraypos++;
            nextpos = newval.find(",", pos);
      }
      
      //don't forget the very last one
      if (arraypos < 3)
      {
            frag = newval.substr(pos, newval.length() - pos);
            val_v[arraypos] = atof(frag.c_str());
      }
}

void CONFIGVARIABLE::DebugPrint()
{
      if (section != "")
            cout << section << ".";
      cout << name << endl;
      cout << "string: " << val_s << endl;
      cout << "int: " << val_i << endl;
      cout << "float: " << val_f << endl;
      cout << "vector: (" << val_v[0] << "," << val_v[1] << "," << val_v[2] << ")" << endl;
      cout << "bool: " << val_b << endl;
      
      cout << endl;
}

string CONFIGVARIABLE::strLTrim(string instr)
{
      return instr.erase(0, instr.find_first_not_of(" \t"));
}

string CONFIGVARIABLE::strRTrim(string instr)
{
      try {
            return instr.erase(instr.find_last_not_of(" \t") + 1);
      } catch(std::out_of_range) {
            return instr;
      }
}

string CONFIGVARIABLE::strTrim(string instr)
{
      return strLTrim(strRTrim(instr));
}

void CONFIGFILE::Load(string fname)
{
      filename = fname;
      
      string cursection = "";
      
      //work string
      string ws;
      const int MAXIMUMCHAR = 1024;
      char trashchar[MAXIMUMCHAR];
      
      ifstream f;
      f.open(fname.c_str());
      
      if (!f && !SUPPRESS_ERROR)
      {
            cout << "CONFIGFILE.Load: Couldn't find file:  " << fname << endl;
      }
            
      while (f && !f.eof())
      {
            f.getline(trashchar, MAXIMUMCHAR, '\n');
            ProcessLine(cursection, trashchar);
      }
      
      f.close();
      
      //DebugPrint();
}

string CONFIGFILE::Trim(string instr)
{
      CONFIGVARIABLE trimmer;
      string outstr = trimmer.strTrim(instr);
      return outstr;
}

void CONFIGFILE::ProcessLine(string & cursection, string linestr)
{
      linestr = Trim(linestr);
      linestr = Strip(linestr, '\r');
      linestr = Strip(linestr, '\n');
      
      //remove comments
      string::size_type commentpos = linestr.find("#", 0);
      if (commentpos < /*(int)*/ linestr.length())
      {
            linestr = linestr.substr(0, commentpos);
      }
      
      linestr = Trim(linestr);
      
      //only continue if not a blank line or comment-only line
      if (linestr.length() > 0)
      {
            if (linestr.find("=", 0) < linestr.length())
            {
                  //find the name part
                  string::size_type equalpos = linestr.find("=", 0);
                  string name = linestr.substr(0, equalpos);
                  equalpos++;
                  string val = linestr.substr(equalpos, linestr.length() - equalpos);
                  name = Trim(name);
                  val = Trim(val);
                  
                  //only continue if valid
                  if (name.length() > 0 && val.length() > 0)
                  {
                        CONFIGVARIABLE * newvar;
                        newvar = new CONFIGVARIABLE;
                        newvar->section = cursection;
                        newvar->name = name;
                        newvar->Set(val);
                        newvar->next = NULL;
                        
                        Add(newvar);
                  }
            }
            else
            {
                  //section header
                  linestr = Strip(linestr, '[');
                  linestr = Strip(linestr, ']');
                  linestr = Trim(linestr);
                  cursection = linestr;
            }
      }
}

string CONFIGFILE::Strip(string instr, char stripchar)
{
      string::size_type pos = 0;
      string outstr = "";
      
      while (pos < /*(int)*/ instr.length())
      {
            if (instr.c_str()[pos] != stripchar)
                  outstr = outstr + instr.substr(pos, 1);
            
            pos++;
      }
      
      return outstr;
}

void CONFIGFILE::DebugPrint()
{
      CONFIGVARIABLE * cur = vars;
      cout << "*** " << filename << " ***" << endl << endl;
      while (cur != NULL)
      {
            cur->DebugPrint();
            
            cur = cur->next;
      }
}

string CONFIGVARIABLE::strLCase(string instr)
{
      char tc[2];
      tc[1] = '\0';
      string outstr = "";
      
      string::size_type pos = 0;
      while (pos < /*(int)*/ instr.length())
      {
            if (instr.c_str()[pos] <= 90 && instr.c_str()[pos] >= 65)
            {
                  tc[0] = instr.c_str()[pos] + 32;
                  string tstr = tc;
                  outstr = outstr + tc;
            }
            else
                  outstr = outstr + instr.substr(pos, 1);
            
            pos++;
      }
      
      return outstr;
}

string CONFIGFILE::LCase(string instr)
{
      CONFIGVARIABLE lcaser;
      string outstr = lcaser.strLCase(instr);
      return outstr;
}

bool CONFIGFILE::SetParam(string param, int invar)
{
      char tc[256];
      
      sprintf(tc, "%i", invar);
      
      string tstr = tc;
      
      return SetParam(param, tstr);
}

bool CONFIGFILE::SetParam(string param, bool invar)
{
      //char tc[256];
      
      //sprintf(tc, "%i", invar);
      
      string tstr = "off";
      
      if (invar)
            tstr = "on";
      
      return SetParam(param, tstr);
}

bool CONFIGFILE::SetParam(string param, float invar)
{
      char tc[256];
      
      sprintf(tc, "%f", invar);
      
      string tstr = tc;
      
      return SetParam(param, tstr);
}

bool CONFIGFILE::SetParam(string param, float * invar)
{
      char tc[256];
      
      sprintf(tc, "%f,%f,%f", invar[0], invar[1], invar[2]);
      
      string tstr = tc;
      
      return SetParam(param, tstr);
}

bool CONFIGFILE::SetParam(string param, string invar)
{
      CONFIGVARIABLE * newvar;
      newvar = new CONFIGVARIABLE;
      
      newvar->name = param;
      newvar->section = "";
      string::size_type ppos;
      ppos = param.find(".", 0);
      if (ppos < /*(int)*/ param.length())
      {
            newvar->section = param.substr(0, ppos);
            ppos++;
            newvar->name = param.substr(ppos, param.length() - ppos);
      }
      
      newvar->Set(invar);
      newvar->next = NULL;
      
      Add(newvar);
      
      return true;
}

bool CONFIGFILE::Write(bool with_brackets)
{
      return Write(with_brackets, filename);
}

bool CONFIGFILE::Write(bool with_brackets, string save_as)
{
      ofstream f;
      f.open(save_as.c_str());
      
      if (f)
      {
            //clear out written flags
            CONFIGVARIABLE * cur = vars;
            while (cur != NULL)
            {
                  cur->written = false;
                  cur = cur->next;
            }
            
            //write non-section variables first
            bool nosection = false;
            cur = vars;
            while (cur != NULL)
            {
                  if (cur->section == "")
                  {
                        f << cur->name << " = " << cur->val_s << endl;
                        
                        nosection = true;
                        
                        cur->written = true;
                  }
                  
                  cur = cur->next;
            }
            
            if (nosection)
                  f << endl;
            
            //write variables by section
            cur = vars;
            while (cur != NULL)
            {
                  if (!cur->written)
                  {
                        if (with_brackets)
                              f << "[ " << cur->section << " ]" << endl;
                        else
                              f << cur->section << endl;
                        
                        CONFIGVARIABLE * sub = vars;
                        while (sub != NULL)
                        {
                              if (!sub->written && cur->section == sub->section)
                              {
                                    f << sub->name << " = " << sub->val_s << endl;
                                    
                                    sub->written = true;
                              }
                              
                              sub = sub->next;
                        }
                        
                        f << endl;
                        
                        cur->written = true;
                  }
                  
                  cur = cur->next;
            }
            
            f.close();
            return true;
      }
      else
            return false;
}

bool CONFIGFILE::Write()
{
      Write(true);
      return true;
}

bool CONFIGFILE::ClearParam(string param)
{
      /*CONFIGVARIABLE * cur = vars;
      while (cur != NULL)
      {
            CONFIGVARIABLE * todel = cur;
            cur = cur->next;
            
            delete todel;
      }
      
      vars = NULL;*/
      
      CONFIGVARIABLE * cur = vars;
      CONFIGVARIABLE * prev = vars;
      bool found = false;
      while (cur != NULL)
      {
            //if the var section/name matches the param name, set outvar
            
            string pname = param;
            string psec = "";
            string::size_type ppos;
            ppos = param.find(".", 0);
            if (ppos < /*(int)*/ param.length())
            {
                  psec = param.substr(0, ppos);
                  ppos++;
                  pname = param.substr(ppos, param.length() - ppos);
            }
            
            if (pname == cur->name && psec == cur->section)
            {
                  found = true;

                  CONFIGVARIABLE * todel = cur;
                  if (cur == vars)
                  {
                        vars = vars->next;
                        prev = vars;
                        cur = vars;
                  }
                  else
                  {
                        cur = cur->next;
                        prev->next = cur;
                  }
                  
                  delete todel;
            }
            else
            {           
                  prev = cur;
                  cur = cur->next;
            }
      }

      /*    
      if (!found && !SUPPRESS_ERROR)
      {
            cout << "CONFIGFILE::GetParam():  " << param << " not found in " << filename << endl;
      }*/
      
      return found;
}

Generated by  Doxygen 1.6.0   Back to index