#include #include #include #include #include HIDDEN const char * files[] = {"prassi.ini", "prassis.ini", "prassid.ini", "fconv.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 alla 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(); } } bool TConfig::exist(const char* var, int index) { TString80 vvar(var); if (index != -1) vvar << '(' << index << ')'; return _data.is_key(vvar); } 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) { TString16 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; } void TConfig::init(const char *fn, const char* pa) { _file = fn; _paragraph = pa; _dirty = FALSE; if (!fexist(_file)) fatal_box("Impossibile aprire il file di configurazione %s", fn ); if (_paragraph.empty()) { _paragraph = main_app().name(); _paragraph.cut(2); } _ispresent = _read_paragraph(); } TConfig::TConfig(int which_config, const char* paragraph) : _file(files[which_config]) { if (which_config == CONFIG_DITTA) { _file.insert(format("%s/", main_app().get_firm_dir())); if (!fexist(_file)) fcopy(files[CONFIG_DITTA], _file); } if (!fexist(_file)) fatal_box("Impossibile aprire la configurazione %s", which_config == CONFIG_GENERAL ? "generale" : which_config == CONFIG_STUDIO ? "di studio" : which_config == CONFIG_DITTA ? "della ditta": "per la conversione archivi"); init( _file, paragraph ); } TConfig::TConfig(const char *fn, const char* pa) { init(fn, pa); } TConfig::~TConfig() { // il distruttore riscrive il file con le modifiche se necessario if (_dirty) _write_file(); }