#include #include #include #include #include // 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(); }