campo-sirio/include/utility.cpp
bonazzi 7078caba13 Patch level : 10.0 pers
Files correlati     :  ca2.exe ca2500a.msk
Ricompilazione Demo : [ ]
Commento            :

Aggiunto programma di invio a Board

git-svn-id: svn://10.65.10.50/branches/R_10_00@23200 c028cbd2-c16b-5b4b-a496-9718f37d4682
2016-06-20 07:27:53 +00:00

695 lines
16 KiB
C++
Executable File

#include <xvt.h>
#include <statbar.h>
#include <diction.h>
#include <dongle.h>
#include <progind.h>
#include <utility.h>
///////////////////////////////////////////////////////////
// TPerformance_profiler
///////////////////////////////////////////////////////////
#ifdef DBG
static int _depth = 0;
#endif
TPerformance_profiler::TPerformance_profiler(const char* desc, bool trc)
: _desc(desc), _trc(trc)
{
#ifdef DBG
_depth++;
_start = clock();
while (true)
{
const clock_t clk = clock();
if (clk != _start)
{
_start = clk;
break;
}
}
#endif
}
void TPerformance_profiler::show() const
{
#ifdef DBG
const double s = double(clock() - _start) / CLOCKS_PER_SEC;
if (s > 0.1 && (_trc || _depth <= 1)) //visualizzo solo tempi significativi
{
int hour = 0, min = 0;
int sec = int(s);
const int cent = int((s - sec)*100);
if (sec >= 3600)
{
hour = sec / 3600;
sec -= hour * 3600;
}
if (sec >= 60)
{
min = sec / 60;
sec -= min * 60;
}
TString256 msg = _desc;
msg.format("%s %02d:%02d:%02d.%02d", (const char*)_desc, hour, min, sec, cent);
if (_trc)
__trace(msg);
statbar_set_title(TASK_WIN, msg);
}
#endif
}
TPerformance_profiler::~TPerformance_profiler()
{
show();
#ifdef DBG
_depth--;
#endif
}
// @doc EXTERNAL
// @func Permette di copiare un file
//
// @rdesc Ritorna il risultato dell'operazione:
//
// @flag TRUE | Se l'operazione e' stata effettuata con successo
// @flag FALSE | Se l'operazione non e' stata effettuata con successo
bool fcopy(
const char* orig, // @parm Nome del file di origine
const char* dest, // @parm Nome del file di destinazione
bool append, // @parm Controllo per aggiungere il contenuto del
bool advanced) // @parm Controllo per utilizzare la xvt_fsys_fcopy
// file <p dest> in coda al file <p orig> (default FALSE)
// @comm Nel caso vengano ravvisati degli errori durante l'operazione vengono
// creati dei box di comunicazione che indicano la causa del problema
{
CHECK(orig && *orig && dest && *dest, "fcopy: Invalid file name");
if (append || !advanced)
{
const char* const rflag = "rb";
const char* wflag = append ? "ab" : "wb";
// Copia il file su se stesso?
if (xvt_str_same(orig, dest))
return true; // Or FALSE?
FILE* i = NULL; fopen_s(&i, orig, rflag);
if (i == NULL)
return error_box(FR("Impossibile leggere il file '%s'\nda copiare in '%s'\nErrore %d"), orig, dest, errno);
if (!append)
xvt_fsys_remove_file(dest);
FILE* o = NULL; fopen_s(&o, dest, wflag);
if (o == NULL)
{
fclose(i);
if (append)
return error_box(FR("Impossibile aprire il file '%s'\nper accodare il file '%s'\nErrore %d"), dest, orig, errno);
else
return error_box(FR("Impossibile scrivere il file '%s'\nper copiare il file '%s'\nErrore %d"), dest, orig, errno);
}
const int size = 16*1024;
TString buffer(size);
bool ok = true;
while (ok)
{
const word letti = fread(buffer.get_buffer(), 1, size, i);
ok = fwrite(buffer.get_buffer(), 1, letti, o) == letti;
if (letti < size) break;
}
if (!ok)
error_box(FR("Errore di scrittura: controllare lo spazio libero sul disco!"));
fclose(o);
fclose(i);
return ok;
}
return xvt_fsys_fcopy(orig, dest) != 0 ;
}
// @doc EXTERNAL
// @func Controlla l'esistenza di un file
//
// @rdesc Ritrona i seguenti valori:
//
// @flag TRUE | Se il file esiste
// @flag FALSE | Se il file non esiste
bool fexist(
const char* file) // @parm Nome del file di cui contrallare l'esistenza
{
return file && *file && xvt_fsys_file_exists(file) != 0;
}
bool dexist(
const char* file) // @parm Nome del file di cui contrallare l'esistenza
{
return file && *file && xvt_fsys_dir_exists(file) != 0;
}
long fsize(const char* name)
{
return (name && *name) ? xvt_fsys_file_attr(name, XVT_FILE_ATTR_SIZE) : 0L;
}
// @doc EXTERNAL
// @func Permette di creare una directory
//
// @rdesc Ritorna il risultato dell'operazione
//
// @flag TRUE | Se l'operazione e' avvenuta con successo
// @flag FALSE | Se l'operazione non e' riuscita
bool make_dir(const char* dir) // @parm Nome della directory da creare
{
return xvt_fsys_mkdir(dir) != 0;
}
// @doc EXTERNAL
// @func Cancella un file
//
// @rdesc Ritorna il risultato dell'operazione
//
// @flag TRUE | Se l'operazione e' avvenuta con successo
// @flag FALSE | Se l'operazione non e' riuscita
bool remove_file(const char* file) // @parm Nome del file da cancellare
{
return xvt_fsys_remove_file(file) != 0;
}
int remove_files(const char* path, bool subdirs) // @parm maschera files da cancellare, es: "c:\temp\*.tmp"
{
TFilename dir(path);
if (dir.find('*') < 0 && dir.find('?') < 0 && dexist(dir))
dir.add("*.*");
SLIST files = xvt_fsys_list_files("", dir, subdirs);
const int count = xvt_slist_count(files);
if (count > 0)
{
dir = dir.path();
// Windows XP doesn't support multi file deletion ...
if (xvt_fsys_files_remove(dir, files) <= 0)
{
dir.insert(TR("Cancellazione cartella ")); // ... do it manually
TProgress_monitor bar(count, dir);
for (SLIST_ELT e = xvt_slist_get_first(files); e; e = xvt_slist_get_next(files, e))
{
const char* n = xvt_slist_get(files, e, NULL);
if (dexist(n))
xvt_fsys_rmdir(n);
else
xvt_fsys_remove_file(n);
bar.add_status();
}
}
}
xvt_slist_destroy(files);
return count;
}
int count_files(const char* dir, bool subdirs)
{
TFilename d(dir);
if (d.find('*') < 0 && d.find('?') < 0)
d.add("*.*");
SLIST files = xvt_fsys_list_files("", d, subdirs);
const int count = xvt_slist_count(files);
xvt_slist_destroy(files);
return count;
}
// @doc EXTERNAL
// @func Ritorna la lista dei file il cui nome corrisponde alla stringa (con caratteri
// jolly) passata.
//
// @rdesc Ritorna il numero di file che soddisfano la condizione passata (numero di elementi
// di result)
int list_files(
const char* filelist, // @parm Stringa contenente la maschera di estrazione
TString_array& result) // @parm Array da riempire con la lista dei file
{
TString mask(filelist);
mask.replace('\\', '/');
SLIST files = xvt_fsys_list_files("", mask, FALSE);
const int count = xvt_slist_count(files);
for (SLIST_ELT e = xvt_slist_get_first(files); e; e = xvt_slist_get_next(files, e))
result.add(xvt_slist_get(files, e, NULL));
xvt_slist_destroy(files);
return count;
}
bool input_filename(TFilename& file)
{
DIRECTORY dir; xvt_fsys_get_dir(&dir);
FILE_SPEC fs;
xvt_fsys_convert_str_to_fspec(file, &fs);
const bool good = xvt_dm_post_file_open(&fs, TR("Selezionare il file")) == FL_OK;
xvt_fsys_set_dir(&dir);
if (good)
xvt_fsys_convert_fspec_to_str(&fs, file.get_buffer(), file.size());
return good;
}
// Certified 99%
// @doc EXTERNAL
// @func Permette di ritornare una stringa formattata
//
// @rdesc Ritorna la stringa desiderata
char* format(
const char* fmt, // @parm Formato che deve essere dato alla stringa
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
// @comm Il funzionamento e' come la <f sprintf> del C, solo che non e' necessario passare la
// stringa di destinazione alla funzione.
{
char buf[512];
va_list pars;
va_start(pars, fmt);
const int tot = _vsnprintf(buf, sizeof(buf), fmt, pars);
va_end(pars);
CHECK(tot < 512, "Ue'! Ma quanto scrivi?");
TString& tmp = get_tmp_string();
tmp = buf;
return tmp.get_buffer();
}
void log_message(const char* fmt, ...)
{
static FILE* flog = NULL;
if (flog == NULL)
{
const char* const f = "campo.log";
const TDate oggi(TODAY);
if (oggi.day() <= 3 && fsize(f) > 1024*1024)
flog = fopen(f, "w");
else
flog = fopen(f, "a");
}
if (fmt && *fmt)
{
TString80 str;
time_t t; time(&t);
str << ctime(&t);
str.rtrim() << ' ';
fprintf(flog, (const char*)str);
va_list pars;
va_start(pars, fmt);
const int tot = vfprintf(flog, fmt, pars);
va_end(pars);
}
fputc('\n', flog);
}
// @doc EXTERNAL
// @func Converte la coppia nome-parametro in una stringa che identifica il programma
//
// @rdesc Ritorna la stringa identificante il programma
const char* cmd2name(
const char* argv0, // @parm Nome del programma
const char* argv1) // @parm Nome del parametro (default "")
{
TFilename app(argv0);
app = app.name();
if (argv1 && *argv1)
app << ' ' << argv1;
else
{
const char* space = strchr(argv0, ' ');
if (space != NULL)
app << space;
}
app.lower();
const int par = app.find(" -");
const int num = par > 0 ? atoi(app.mid(par+2))+1 : 1;
const char c = (num > 9) ? ('a'+num-10) : ('0'+num);
app.cut(3);
app << c << "00";
TString& tmp = get_tmp_string();
tmp = app;
return tmp;
}
///////////////////////////////////////////////////////////
// Conversione in cifre romane
///////////////////////////////////////////////////////////
HIDDEN const char * cifre_romane = "IVXLCDM@";
HIDDEN const int valori_cifre [] = { 1, 5, 10, 50, 100, 500, 1000, -1 };
HIDDEN int ctoi(char c)
{
if (c == '\0') return 0;
c = toupper(c);
for (int i = 0; cifre_romane[i]; i++)
if (cifre_romane[i] == c) return valori_cifre[i];
return -1;
}
// @doc EXTERNAL
// @func Converte una cifra romana in intero normale
//
// @rdesc Ritorna l'equivalente in numeri della cifra romane
int rtoi(
const char * val) // @parm Stringa contenente la cifra scritta in numeri romani
{
if (val == NULL) return 0;
int tot = 0;
int value = ctoi (val[0]);
for (int i = 1; value > 0; i++)
{
const int next_val = ctoi(val[i]);
if (value < next_val) tot -= value;
else tot += value;
value = next_val;
}
return (value == 0) ? tot : -1;
}
// @doc EXTERNAL
// @func Converte un numero intero nell'equivalente cifra romana
//
// @rdesc Ritorna una stringa contenente la cifra romana
const char* itor(
int num) // @parm Intero da convertire in cifra romana
{
HIDDEN char roman_string[16];
int cifra = 0;
for (int pos = 7; pos--;)
{
int val = valori_cifre[pos];
int quanti = num / val;
if (quanti < 4)
{
if ((pos & 1) && quanti == 1 && (num/valori_cifre[pos-1]) == 9)
{
roman_string[cifra++] = cifre_romane[pos-1];
roman_string[cifra++] = cifre_romane[pos+1];
val = valori_cifre[pos-1];
quanti = 9;
}
else for (int i = 0; i < quanti; i++)
roman_string[cifra++] = cifre_romane[pos];
}
else
{
roman_string[cifra++] = cifre_romane[pos];
roman_string[cifra++] = cifre_romane[pos+1];
}
num -= quanti * val;
}
roman_string[cifra] = '\0';
return roman_string;
}
// @doc EXTERNAL
// @func Permette di codificare i caratteri di escape
//
// @rdesc Ritorna il carattere codificato
const char* esc(
const char* s) // @parm Stringa da codificare
{
const char *s1 = s == NULL ? "" : s;
char* encoded = get_tmp_string().get_buffer(strlen(s));
char* s2 = encoded;
while (*s1)
{
if (*s1 == '\\')
{
s1++;
switch (tolower(*s1))
{
case 'b' : *s2++ = '\b'; break;
case 'e' : *s2++ = '\033'; break;
case 'f' : *s2++ = '\f'; break;
case 'n' : *s2++ = '\n'; break;
case 'r' : *s2++ = '\r'; break;
case 's' : *s2++ = ' '; break;
case 't' : *s2++ = '\t'; break;
default :
{
if (isdigit(*s1))
{
int base = 10;
if (*s1 == '0')
{
s1++;
if (tolower(*s1) == 'x')
{
s1++;
base = 16;
}
else
base = 8;
}
*s2 = 0;
char c = tolower(*s1);
while (isdigit(c) || (base == 16 && c >= 'a' && c <= 'f'))
{
*s2 *= base;
if (isdigit(*s1)) *s2 += (*s1 - 48);
else *s2 += (*s1 - 'a' + 10) & 0x0F;
s1++;
c = tolower(*s1);
}
s2++; s1--;
}
else *s2++ = *s1;
}
}
}
else
if (*s1 == '^')
{
s1++;
*s2++ = (tolower(*s1) - 'a' + 1);
}
else *s2++ = *s1 ;
s1++;
}
*s2 = '\0';
return encoded;
}
const char* unesc(
const char* s) // @parm Stringa da decodificare
{
char *decoded = get_tmp_string().get_buffer(strlen(s)*4);
char* s2 = decoded;
for (const char *s1 = s; *s1; s1++)
{
const char& c = *s1;
if (c >= '\0' && c < ' ')
{
switch(c)
{
case '\n':
*s2++ = '\\'; *s2++ = 'n';
break;
case '\r':
*s2++ = '\\'; *s2++ = 'r';
break;
case '\t':
*s2++ = '\\'; *s2++ = 't';
break;
default:
*s2++ = '\\'; *s2++ = '0'; *s2++ = 'x';
sprintf(s2, "%02x", int(c)); s2 += 2;
break;
}
}
else
*s2++ = c;
}
*s2 = '\0';
return decoded;
}
// @doc EXTERNAL
// @func Permette di criptare una parola
// @rdesc Ritorna la stringa criptata
const char * encode(const char* data)
{
char* tmp = get_tmp_string(strlen(data)).get_buffer();
xvt_str_encode(data, tmp, 0);
return tmp;
}
// @doc EXTERNAL
// @func Permette di decodificare una stringa criptata
// @rdesc Ritorna la stringa in chiaro
const char* decode(const char* data)
{
char* tmp = get_tmp_string(strlen(data)).get_buffer();
xvt_str_decode(data, tmp, 0);
return tmp;
}
//salta gli spazi bianchi ad inizio file
istream & eatwhite(istream & i)
{
#if defined(WIN32) && (_MSC_VER <= 1300)
i.eatwhite();
#else
char c;
while (i.get(c))
{
if (!isspace(c))
{
i.putback(c);
break;
}
}
#endif
return i;
}
const TString& get_hostname()
{
TString& tmp = get_tmp_string(50);
xvt_sys_get_host_name(tmp.get_buffer(), tmp.size());
return tmp;
}
long daytime()
{
const struct tm * timeloc = xvt_time_now();
return timeloc->tm_sec + timeloc->tm_min * 100L + timeloc->tm_hour * 10000L;
}
// DON'T cache this bool because hostname can be local or server
static bool is_sirio_station(const char* hostname)
{
const char* const ranger[] = { "NBKCORRADIW81", "KLINGON", "MOBILE", "PCTRUFFELLI", "SPOCK", "ARCHIMEDE", NULL };
for (int i = 0; ranger[i]; i++)
if (xvt_str_same(hostname, ranger[i]))
return true;
return false;
}
bool is_power_station()
{
static BOOLEAN ps = -1;
if (ps < 0)
{
const TDongle& d = dongle();
if (d.local())
ps = is_sirio_station(get_hostname());
else
ps = is_sirio_station(d.server_name());
}
return ps != 0;
}
bool is_power_reseller(bool power_user_only)
{
if (power_user_only && !is_power_station())
return false;
return xvt_sys_get_oem_int("OEM", 1) == 0;
}
bool expand_sys_vars(TString& str)
{
bool found = false;
TString value(_MAX_PATH);
int i = 0;
while ((i = str.find("$(")) >= 0)
{
value.cut(0);
int j = str.find(')', i);
if (j < 0) j = i+2;
const TString& name = str.sub(i+2, j);
if (name.compare("HostName", -1, true) == 0)
{
value = get_hostname();
} else
if (name.compare("UserName", -1, true) == 0)
{
value = user();
} else
if (name.compare("LoginName", -1, true) == 0)
{
xvt_sys_get_user_name(value.get_buffer(), value.len());
} else
if (name.compare("Session", -1, true) == 0)
{
value << xvt_sys_get_session_id();
} else
if (name.compare("DateAnsi", -1, true) == 0)
{
const TDate oggi(TODAY);
value << oggi.date2ansi();
} else
if (name.compare("TimeAnsi", -1, true) == 0)
{
value.format("%06ld", daytime());
}
const TString& before = str.left(i);
const TString& after = str.mid(j + 1);
str.cut(0) << before << value << after;
found = true;
}
return found;
}
void quoted_string(TString& query, const char* val)
{
query << '\'';
for (const char* c = val; *c; c++)
{
if (*c == '\'')
query << *c;
query << *c;
}
query << '\'';
}