campo-sirio/include/utility.cpp
guy 937fcbfe58 archives.cpp Aggiustate indentazioni
cfiles.cpp      Corretta costruzione della stringa __ptprf
                (senza doppi slash e controlslash consecutivi)
config.cpp      Megafigata: Dopo anni e anni le chiavi vengono salvate
                in ordine alfabetico e non in disordine hash!
execp.cpp       Aggiunti due flag al metodo TExternal_app::run
                Uno per specificare l'iconizzazione del programma chiamante
                e uno per la visibilita' del programma chiamato
prefix.cpp      Migliorata costruzione path dei dati
strings.cpp     Aggiunta #define della dimensione di default delle stringhe
		Corretto metodo TFilename::add
utility.cpp     Megafigata: Dopo anni e anni aggiunto il metodo fsize(const char*)


git-svn-id: svn://10.65.10.50/trunk@5498 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-10-30 16:14:49 +00:00

477 lines
12 KiB
C++
Executable File

#include <ctype.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef FOXPRO
#define STRICT
#define XVT_INCL_NATIVE
#include <xvt.h>
#endif
#include <xvtility.h>
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_WIN32
#include <direct.h>
#include <io.h>
#define F_OK 0
#undef DIRECTORY
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
// @doc EXTERNAL
// @func Permette di rimuovere un file (chiama unlink)
//
// @rdesc Ritorna il risultato dell'operazione
//
// @flag 0 | Se l'operazione ha successo
// @flag -1 | Se l'operazione non e' riuscita. Viene inoltre settata la variabile
// <p errno> con la causa dell'insuccesso
int remove(
const char* path) // @parm Nome del file da eliminare (non valgono i caratteri jolly)
{ return unlink(path); }
#endif
#define __UTILITY_CPP
#include <utility.h>
// @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
// 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 XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_WIN32
const char* const rflag = "rb";
const char* wflag = append ? "ab" : "wb";
#else
const char* const rflag = "r";
const char* wflag = append ? "a" : "w";
#endif
// Copia il file su se stesso?
if (stricmp(orig, dest) == 0)
return TRUE; // Or FALSE?
FILE* i = fopen(orig, rflag);
if (!i) return error_box("Impossibile leggere il file %s", orig);
FILE* o = fopen(dest, wflag);
if (!o)
{
fclose(i);
return error_box("Impossibile scrivere il file ", dest);
}
const word 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("Errore di scrittura: probabile disco pieno!");
fclose(o);
fclose(i);
return ok;
}
// @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 contrallarne l'esistenza
{
int err = access(file, F_OK);
if (err) // Se la access fallisce provo con la _lopen
{
HFILE hf = _lopen(file, READ);
if (hf != HFILE_ERROR)
{
_lclose(hf);
err = 0;
}
}
return err == 0;
}
long fsize(const char* name)
{
long s = 0;
if (name && *name)
{
FILE* f = fopen(name, "r");
if (f != NULL)
{
fseek(f, 0, SEEK_END);
s = ftell(f);
fclose(f);
}
}
return s;
}
// @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
{
int res =
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_WIN32
mkdir(dir);
#else
mkdir(dir, 0777);
#endif
return res == 0;
}
#ifndef FOXPRO
// @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
// della token string)
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
// @comm Per comodita' la lista desiderata vine anch'essa messa in <p filelist> in quanto e'
// gia' costruita
{
TWait_cursor hourglass;
TFilename dir(filelist);
for (int i = dir.len()-1; i >= 0; i--)
if (dir[i] == '/' || dir[i] == '\\' || dir[i] == ':') break;
TFilename mask(dir.mid(i+1));
dir.cut(i > 0 ? i+1 : 0);
xvt_fsys_save_dir();
if (dir.not_empty())
{
DIRECTORY directory; xvt_fsys_convert_str_to_dir(dir.get_buffer(), &directory);
BOOLEAN ok = xvt_fsys_set_dir(&directory);
if (!ok)
fatal_box ("Impossibile entrare in %s", (const char*)dir);
}
SLIST files = xvt_fsys_list_files("", mask.get_buffer(), 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))
{
char* f = xvt_slist_get(files, e, NULL);
if (dir.not_empty())
{
mask = dir;
mask.add(f);
result.add(mask);
}
else
result.add(f);
}
xvt_slist_destroy(files);
xvt_fsys_restore_dir();
return count;
}
#endif
// 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.
{
va_list pars;
va_start(pars, fmt);
const int tot = vsprintf(__tmp_string, fmt, pars);
va_end(pars);
CHECK(tot >= 0 && tot < sizeof(__tmp_string)-1, "Ue'! Ma quanto scrivi?");
return(__tmp_string);
}
// @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 app << " -0";
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";
return strcpy(__tmp_string, app);
}
///////////////////////////////////////////////////////////
// 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 Carattere da codificare
// @comm Viene utilizzata soprattuto in UNIX.
{
const char *s1 = s;
char *s2 = __tmp_string;
int base;
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 't' : *s2++ = '\t'; break;
default :
{
if (isdigit(*s1))
{
if (*s1 == '0')
{
s1++;
if (tolower(*s1) == 'x')
{
s1++;
base = 16;
}
else base = 8;
}
else base = 10;
*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(__tmp_string);
}
HIDDEN const char * const key = "QSECOFR-";
// @doc EXTERNAL
// @func Permette di criptare una parola
//
// @rdesc Ritorna la stringa criptata
const char * encode(
const char * data) // @parm Stringa da criptare
// @xref <f decode>
{
for (int i = 0; data[i]; i++)
__tmp_string[i] = data[i] + (i < 8 ? key[i] : data[i - 8]);
__tmp_string[i] = '\0';
return __tmp_string;
}
// @doc EXTERNAL
// @func Permette di decodificare una stringa criptata
//
// @rdesc Ritorna la stringa in chiaro
const char * decode(
const char * data) // @parm Stringa criptata da tradurre
// @xref <f encode>
{
for (int i = 0; data[i]; i++)
__tmp_string[i] = data[i] - (i < 8 ? key[i] : __tmp_string[i - 8]);
__tmp_string[i] = '\0';
return __tmp_string;
}
os_type get_os_type()
{
#if XVT_OS == XVT_OS_WIN
const WORD winver = LOWORD(GetVersion());
const BYTE majver = LOBYTE(winver);
const BYTE minver = HIBYTE(winver);
if (majver > 3 || (majver == 3 && minver > 11))
return os_Windows95;
const DWORD winflags = GetWinFlags();
if (winflags & 0x4000)
return os_WindowsNT;
return os_Windows;
#else
// #error Ricordati di Win32
return os_WindowsNT;
#endif
}