228 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			228 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <stdlib.h>
 | 
						|
 | 
						|
#include <applicat.h>
 | 
						|
#include <config.h>
 | 
						|
#include <utility.h>
 | 
						|
#include <scanner.h>
 | 
						|
 | 
						|
// questo sara' il principale, per ora non c'e'
 | 
						|
#define CONFIG_FILE        "prassi.ini"
 | 
						|
// file parametri studio (uno per studio, per ora e' il principale)
 | 
						|
#define CONFIG_FILE_STUDIO "prassis.ini"
 | 
						|
// file parametri ditta (uno per ditta)
 | 
						|
#define CONFIG_FILE_DITTA  "prassid.ini"
 | 
						|
 | 
						|
extern "C"
 | 
						|
{
 | 
						|
  int rename(const char*, const char*);
 | 
						|
};
 | 
						|
 | 
						|
bool TConfig::_read_paragraph()
 | 
						|
     // ritorna TRUE se il paragrafo c'era, FALSE altrimenti
 | 
						|
{
 | 
						|
  bool itwas = FALSE;
 | 
						|
  _data.destroy();
 | 
						|
  TScanner scan(_file);
 | 
						|
  if (scan.paragraph(_paragraph))
 | 
						|
    {
 | 
						|
      itwas = TRUE;
 | 
						|
      // populate array
 | 
						|
      TString l, key, val;
 | 
						|
      for (;;)
 | 
						|
	{
 | 
						|
	  l = scan.line();
 | 
						|
	  if (l[0] == '#') continue;
 | 
						|
	  if (l == "" || l[0] == '[') break;
 | 
						|
	  int ind = l.find('=');
 | 
						|
	  if (ind == -1) 
 | 
						|
	    {
 | 
						|
	      warning_box("Errore configurazione: file %s, vicino a riga %ud",
 | 
						|
			  (const char*)_file, scan.linenum());
 | 
						|
	      continue;
 | 
						|
	    }
 | 
						|
	  
 | 
						|
	  key = l.left(ind);  key.trim();
 | 
						|
	  val = l.mid(ind+1); val.trim();
 | 
						|
	  // sostituzione abilitata
 | 
						|
	  _data.add(key,val,TRUE);
 | 
						|
	}
 | 
						|
    }
 | 
						|
  return itwas;
 | 
						|
}
 | 
						|
 | 
						|
void TConfig::_write_paragraph(ofstream& out)
 | 
						|
{
 | 
						|
  _data.restart();            
 | 
						|
  TString cnf(16);
 | 
						|
  cnf << '[' << _paragraph << ']';
 | 
						|
  out << cnf << '\n';  
 | 
						|
  for (int i = 0; i < _data.items(); i++)
 | 
						|
    {
 | 
						|
      THash_object* o = _data.get_hashobj();
 | 
						|
      out << o->key() << "\t= " << (TString&)(o->obj()) << '\n';
 | 
						|
    }
 | 
						|
  out << '\n';
 | 
						|
}
 | 
						|
 | 
						|
void TConfig::_write_file()
 | 
						|
{
 | 
						|
  ifstream in(_file);       
 | 
						|
  TFilename temp;
 | 
						|
  temp.temp("__tmp__.cnf");
 | 
						|
  ofstream out(temp);
 | 
						|
  
 | 
						|
  TFixed_string l(__tmp_string, sizeof(__tmp_string)); 
 | 
						|
  TString cnf(16);
 | 
						|
  cnf << '[' << _paragraph << ']';
 | 
						|
  bool skip = FALSE, done = FALSE;
 | 
						|
 | 
						|
  while (!in.eof())
 | 
						|
    {
 | 
						|
      in.getline(__tmp_string,sizeof(__tmp_string)-1);
 | 
						|
      l.trim();
 | 
						|
 | 
						|
      if (cnf == l)
 | 
						|
	    {
 | 
						|
	      // write paragraph and all variables
 | 
						|
	      _write_paragraph(out);
 | 
						|
	      skip = TRUE; done = TRUE;
 | 
						|
	    }
 | 
						|
      else 
 | 
						|
       { 
 | 
						|
      	  if (skip)  skip = l[0] != '[';
 | 
						|
      	  if (!skip) out << l << '\n';
 | 
						|
       }
 | 
						|
    }
 | 
						|
  // new paragraph
 | 
						|
  if (!done) _write_paragraph(out);
 | 
						|
 | 
						|
  out.close(); in.close();
 | 
						|
  TFilename bak(_file); bak.ext("bak");
 | 
						|
  rename(_file,bak);
 | 
						|
  fcopy(temp,_file);
 | 
						|
  remove(temp);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TConfig::_check_paragraph(const char* section)
 | 
						|
{
 | 
						|
 if (section != NULL && section != _paragraph)
 | 
						|
    {
 | 
						|
      if (_dirty) _write_file();
 | 
						|
      _paragraph = section; 
 | 
						|
      _dirty = FALSE;
 | 
						|
      _read_paragraph();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
TString& TConfig::get(const char* var, const char* section, int index)
 | 
						|
{
 | 
						|
  // ritorna valore di variabile nella sezione corrente o in
 | 
						|
  // quella specificata
 | 
						|
  static TFixed_string s(__tmp_string, 256);
 | 
						|
  TString vvar(var); if (index != -1) vvar << '(' << index << ')';
 | 
						|
 
 | 
						|
 _check_paragraph(section);
 | 
						|
 | 
						|
  if (_data.is_key(vvar)) 
 | 
						|
    s = (TString&)_data[vvar];
 | 
						|
  else 
 | 
						|
  {
 | 
						|
#ifdef DBG
 | 
						|
    error_box("Can't find '%s' in section '%s' of '%s'", 
 | 
						|
              var, (const char*)_paragraph, (const char*)_file);
 | 
						|
#endif  
 | 
						|
    s = "";
 | 
						|
  }  
 | 
						|
 | 
						|
  return s;
 | 
						|
}
 | 
						|
 | 
						|
long TConfig::get_long(const char* var, const char* section, int index)
 | 
						|
{ 
 | 
						|
  return atol(get(var,section,index)); 
 | 
						|
}
 | 
						|
 | 
						|
bool TConfig::get_bool(const char* var, const char* section, int index)
 | 
						|
{
 | 
						|
  const TString& s = get(var, section, index).upper();
 | 
						|
  return s != "" && (s == "X" || s == "ON" || s == "YES" || s == "OK" || s == "TRUE");
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TConfig::set(const char* var, const char* value, const char* section, 
 | 
						|
		  bool force, int index)
 | 
						|
{
 | 
						|
  // setta variabile nella sezione corrente o specificata
 | 
						|
  // se force == TRUE crea la variabile se non esiste; altrimenti
 | 
						|
  // da' errore; ritorna TRUE se la variabile c'era, FALSE diversamente
 | 
						|
 | 
						|
 _check_paragraph(section);
 | 
						|
 TString vvar(var); if (index != -1) vvar << '(' << index << ')';
 | 
						|
 | 
						|
  bool itwas = _data.is_key(vvar);
 | 
						|
 
 | 
						|
  if (itwas && !force)
 | 
						|
    warning_box("Tentativo di ridefinizione simbolo: %s", (const char*)vvar);
 | 
						|
  else
 | 
						|
    {
 | 
						|
      _dirty = TRUE;
 | 
						|
      _data.add(vvar, new TString(value), force);
 | 
						|
    }
 | 
						|
  return itwas;
 | 
						|
}
 | 
						|
 | 
						|
bool TConfig::set(const char* var, long value, const char* section, 
 | 
						|
		  bool force, int index)
 | 
						|
{
 | 
						|
  TString t; t << value;
 | 
						|
  return set(var,t,section,force,index);
 | 
						|
}
 | 
						|
 | 
						|
word TConfig::items(const char* var, const char* section)
 | 
						|
{
 | 
						|
  _check_paragraph(section);
 | 
						|
  TString vvar(16);
 | 
						|
  for (int cnt = 0; /* uncazzo */ ;cnt++)
 | 
						|
    {
 | 
						|
      vvar = var; vvar << '(' << cnt << ')';
 | 
						|
      if (!_data.is_key(var))
 | 
						|
	break;
 | 
						|
    }
 | 
						|
  return cnt;
 | 
						|
}
 | 
						|
 | 
						|
TConfig::TConfig(int which_config, const char* paragraph) : 
 | 
						|
                 _paragraph(paragraph), _dirty(FALSE), _ispresent(FALSE)
 | 
						|
                 
 | 
						|
{
 | 
						|
  if (which_config < CONFIG_STUDIO) _file = CONFIG_FILE;
 | 
						|
  else
 | 
						|
  	if (which_config == CONFIG_STUDIO) _file = CONFIG_FILE_STUDIO;
 | 
						|
  	else
 | 
						|
  	{
 | 
						|
  		 _file.format("%s/%s", MainApp()->get_firm_dir(), CONFIG_FILE_DITTA);
 | 
						|
  		 if (!fexist(_file))
 | 
						|
  		 {
 | 
						|
  		 	fcopy(CONFIG_FILE_DITTA, _file);   
 | 
						|
  		 	if (!fexist(_file))
 | 
						|
  		 	 fatal_box("Impossibile aprire la configurazione %s", 
 | 
						|
  									which_config < CONFIG_STUDIO ? "generale" :
 | 
						|
  									which_config == CONFIG_STUDIO ? "di studio" : "della ditta");
 | 
						|
  		 }
 | 
						|
  	}	  
 | 
						|
  if (_paragraph.empty())
 | 
						|
    {
 | 
						|
      _paragraph = MainApp()->name();
 | 
						|
      _paragraph.cut(2);
 | 
						|
    }
 | 
						|
 _ispresent = _read_paragraph();
 | 
						|
}
 | 
						|
 | 
						|
TConfig::~TConfig()
 | 
						|
{
 | 
						|
  // il distruttore riscrive il file con le modifiche se necessario 
 | 
						|
  if (_dirty) _write_file();
 | 
						|
}
 | 
						|
 |