diff --git a/include/array.h b/include/array.h index 32fae8eaf..95990c755 100755 --- a/include/array.h +++ b/include/array.h @@ -9,8 +9,6 @@ #define NULL 0L #endif -class TArray; - // @doc EXTERNAL // // @type COMPARE_FUNCTION | Prototipo funzione di confronto tra elementi della diff --git a/include/ccommon.h b/include/ccommon.h index fe63f3b13..97a6f7af4 100755 --- a/include/ccommon.h +++ b/include/ccommon.h @@ -32,7 +32,6 @@ #include #include #include -#include #else #ifdef __cplusplus #include @@ -61,7 +60,12 @@ #endif #endif +#ifdef __LONGDOUBLE__ +typedef unsigned int word; +#define ELLIPSES ... +#else #include +#endif #if !defined(__MSHELL_H) && !defined(FOXPRO) #include "mshell.h" @@ -245,9 +249,11 @@ extern "C" { void CInitProg(void ); void CEndProg(void ); int execprog(int ,char *, ELLIPSES); - + +#ifndef __LONGDOUBLE__ void CEditDec(DEC *,int ,int ,char *); void CConvDec(char *,DEC *); +#endif int CIOResult(void ); TDitta *CGetDitta(char *); diff --git a/include/cfiles.c b/include/cfiles.c index 10229ba76..df2891757 100755 --- a/include/cfiles.c +++ b/include/cfiles.c @@ -1,1390 +1,1392 @@ -#define __CFILES_C /* fv */ - -#include "cfiles.h" -#include "fldtypes.h" - -int hashfun(char *); -void setdec(char *, int); -char *prefname(void); - -HIDDEN BOOLEAN pathpread = FALSE; - -BOOLEAN dispferr = TRUE; -int dirfl[2] = {0, 0}, recfl[2] = {0, 0} ; -char __ptprf[80] = ""; - -/* - @(#) COpenDir FILES - - @(ID) - Apre il file directory di una ditta. - @(FD) - - @(ISV) - name = percorso per il file di direttorio. - - Versione DOS e XENIX. - @(FSV) - - @(IN) - NON UTILIZZARE !!. - - Se si utilizza spiegare dettagliatamente il motivo. - @(FN) - */ - -void COpenDir(lockmode, dirflg) - int lockmode; /* modo di apertura */ - int dirflg; /* flag per file comuni */ - -{ - PathSt name; - - if (dirfl[dirflg]++) return; -#ifndef DOS - if ((excllock(CInsPref(glockname, dirflg), (lockmode == ExclLock)) == -1) - && (errno == EACCES)) - fatal_box("Locked Directory. Error number : %d ", errno); -#endif - strcpy(name, CInsPref(directory, dirflg)) ; - COpen(&fdir[dirflg], name, sizeof(FileDes), 0, lockmode) ; - if (fdir[dirflg].IOR != NoErr) - fatal_box("Can't open Directory. Error number : %d ", fdir[dirflg].IOR); -} - -/* - @(#) CCloseDir FILES - - @(ID) - Chiude il file di direttorio di una ditta. - @(FD) - - @(ISV) - Versione DOS e XENIX. - @(FSV) - - @(IN) - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo. - @(FN) - */ - -void CCloseDir(dirflg) - int dirflg; /* flag per file comuni */ - -{ -#ifndef DOS - exclunlock(CInsPref(glockname, dirflg), (fdir[dirflg].LockMode == ExclLock)); -#endif - if (dirfl[dirflg]) dirfl[dirflg]--; - if (!dirfl[dirflg]) CClose(&fdir[dirflg]) ; -} - -/* - @(#) COpenFile FILES - - @(ID) - Legge i dati di un archivio dal Direttorio. - @(FD) - - @(ISV) - junk = variabile spazzatura per la chiamata della funzione "sleep". - - s = stringa contenente messaggio di attesa. - - w = descrittore finestra di attesa. - - Versione DOS e XENIX. - @(FSV) - - @(IN) - Sostituisce l'eventuale simbolo "$" con il prefisso corrente. - - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo. - @(FN) - */ - -void COpenFile(logicname,filed,lockmode,dirflg) - int logicname; /* numero logico file */ - FileDes *filed; /* puntatore alla struttura che contiene i dati letti dal direttorio */ - int lockmode; /* tipo di lock effettuato sul record */ - int dirflg; /* flag per file comuni */ - -{ - do - { - CRead(&fdir[dirflg],(RecType) filed,(long) logicname, lockmode); - - if (TESTLOCK(fdir[dirflg].IOR)) - message_box("Sono in attesa della directory n.ro %d", logicname); - } while TESTLOCK(fdir[dirflg].IOR) ; - strcpy(filed->SysName, CAddPref(filed->SysName)) ; -} - -/* - @(#) CCloseFile FILES - - @(ID) - Chiude e Riscrive i dati di un file sul direttorio. - @(FD) - - @(ISV) - wd = descrittore di una riga di direttorio. - - junk = variabile spazzatura per la chiamata della funzione "sleep". - - s = messaggio di attesa. - - w = descrittore della finestra di attesa. - @(FSV) - - @(IN) - ATTENZIONE : questa funzione aggiorna esclusivamente i campi EOD e Flags . - - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo. - @(FN) - */ - -void CCloseFile(logicname,filed,dirflg) - int logicname; /* numero logico file */ - FileDes *filed; /* puntatore al descrittore di un archivio */ - int dirflg; /* flag per file comuni */ - -{ - FileDes wd; - - CRead(&fdir[dirflg],(RecType) &wd,(long) logicname, NoLock); - wd.EOD = filed->EOD; - wd.Flags = filed->Flags; - CWrite(&fdir[dirflg],(RecType) &wd,(long) logicname, UnLock); -} -/* - @($) CGetFile FILES - - @(ID) - Legge i dati relativi ad un archivio nel direttorio. - Non sostituisce con il prefisso l'eventuale carattere "$". - @(FD) - - @(ISV) - junk = variabile spazzatura per la chiamata della funzione "sleep". - - s = messaggio di attesa. - - w = descrittore finestra di attesa. - - Versione DOS e XENIX. - @(FSV) - - @(IN) - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo. - @(FN) - */ - -void CGetFile(logicname,filed,lockmode,dirflg) - int logicname; /* numero logico file */ - FileDes *filed; /* puntatore al descrittore archivio nel direttorio */ - int lockmode; /* tipo di lock sul record */ - int dirflg; /* flag per file comuni */ -{ - - do - { - CRead(&fdir[dirflg],(RecType) filed,(long) logicname, lockmode); - if (TESTLOCK(fdir[dirflg].IOR)) - message_box("Sono in attesa della directory n.ro %d", logicname); - } - while TESTLOCK(fdir[dirflg].IOR) ; -} - -/* - @($) CPutFile FILES - - @(ID) - Chiude il direttorio e Riscrive i dati relativi ad un archivo. - Aggiorna tutti i campi. - @(FD) - - @(IN) - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo. - @(FN) - */ - -void CPutFile(logicname,filed,dirflg) - int logicname; /* numero logico file */ - FileDes *filed; /* puntatore al descrittore dell'archivio */ - int dirflg; /* flag per file comuni */ - -{ - CWrite(&fdir[dirflg],(RecType) filed,(long) logicname, UnLock); -} - -/* - @($) zerofdes FILES - - @(ID) - Azzera un descrittore di directory. - @(FD) - - @(IN) - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo. - @(FN) - */ - - -void zerofdes(d) - FileDes *d; /* puntatore al descrittore di un archivio nella direttorio */ - -{ - strcpy(d->SysName, ""); - d->EOD = 0; - d->EOX = 0; - d->LenR = 0; - d->Flags = 0; - strcpy(d->Des, ""); - strcpy(d->FCalc, ""); - strcpy(d->GenPrompt, ""); -} - -/* - @(#) COpenRecDir FILES - - @(ID) - Apre l'Archivio dei Tracciati Record. - @(FD) - - @(ISV) - name = nome dell'archivio dei Tracciati Record. - - Versione DOS e XENIX. - @(FSV) - - @(IN) - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo. - @(FN) - */ - -void COpenRecDir(lockmode,dirflg) - int lockmode; /* modo di apertura */ - int dirflg; /* flag per file comuni */ - -{ - PathSt name; - - if (recfl[dirflg]++) return; - strcpy(name, CInsPref(ntrrec, dirflg)) ; - COpen(&rdir[dirflg], name, sizeof(RecDes), 0, lockmode) ; - if (rdir[dirflg].IOR != NoErr) - fatal_box("Can't open record description file. Error number : %d ", rdir[dirflg].IOR); - -} - -/* - @(#) CCloseRecDir FILES - - @(ID) - Chiude l'Archivio dei Tracciati Record - @(FD) - - @(IN) - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo - @(FN) - */ - -void CCloseRecDir(dirflg) - int dirflg; /* flag per file comuni */ - -{ - if (recfl[dirflg]) recfl[dirflg]--; - if (!recfl[dirflg]) CClose(&rdir[dirflg]) ; -} - -/* - @(#) CGetRec FILES - - @(ID) - Legge il tracciato record del file "logicname" e lo mette in "recd". - @(FD) - - @(IN) - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo. - @(FN) - */ - -void CGetRec(logicname,recd,dirflg) - int logicname; /* numero file */ - RecDes *recd; /* descrittore record */ - int dirflg; /* flag per file comuni */ - -{ - CRead(&rdir[dirflg],(RecType) recd,(long) logicname, NoLock); -} - - -/* - @($) CPutRec FILES - - @(ID) - Aggiorna il file dei Tracciati Record. - @(FD) - - */ - -void CPutRec(logicname,recd,dirflg) - int logicname; /* numero file */ - RecDes *recd; /* descrittore record */ - int dirflg; /* flag per file comuni */ - -{ - CWrite(&rdir[dirflg],(RecType) recd,(long) logicname, NoLock); -} - -/* - @($) zerodes FILES - - @(ID) - Azzera il Tracciato Record "r". - @(FD) - - @(ISV) - i,j = contatori. - @(FSV) - - @(IN) - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo. - @(FN) - */ - -void zerordes(r) - RecDes *r; /* descrittore record */ - -{ - int i,j ; - - r->NFields = 0; - for (i = 0; i < MaxFields; i++) - { - strcpy(r->Fd[i].Name, ""); - r->Fd[i].TypeF = NullF; - r->Fd[i].Len = 0; - r->Fd[i].Dec = 0; - r->Fd[i].RecOff = 0; - } - for (i = 0; i < MaxFields; i++) r->SortFd[i] = INVFLD; - r->NKeys = 0; - for (i = 1; i < MaxKeys; i++) - { - r->Ky[i].DupKeys = FALSE; - r->Ky[i].NkFields = 0; - for (j = 0; j < MKFields; j++) r->Ky[i].FieldSeq[j] = INVFLD; - for (j = 0; j < MKFields; j++) r->Ky[i].FromCh[j] = INVFLD; - for (j = 0; j < MKFields; j++) r->Ky[i].ToCh[j] = INVFLD; - } -} - -/* - @($) setrdes FILES - - @(ID) - Dato il tracciato record crea la struttura HASH (sortFd) per l'accesso veloce - ai campi. - @(FD) - - @(ISV) - pos = indirizzo Hash. - - i = contatore. - - nf = variabile di lavoro. - - tmppos = indirizzo hash per l'accesso ai campi. - @(FSV) - - @(IN) - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo. - @(FN) - */ - -word setrdes(r) - RecDes *r; /* descrittore record */ - -{ - int pos, tmppos, nf, i; - - for (i = 0; i < MaxFields; i++) r->SortFd[i] = INVFLD; - if (r->NFields) - { - for (i = 0; i < r->NFields; i++) - { - nf = i; - pos = hashfun(r->Fd[nf].Name); - while (TRUE) - { - if (r->SortFd[pos] == INVFLD) - { - r->SortFd[pos] = (byte) nf; - break; - } - else - { - if (strcmp(r->Fd[r->SortFd[pos]].Name, r->Fd[nf].Name) <= 0) - { - pos++; - if (pos >= MaxFields) - pos = 0; - } - else - { - tmppos = r->SortFd[pos]; - r->SortFd[pos] = (byte) nf; - nf = tmppos; - } - } - } - } - r->Fd[0].RecOff = 1; - for (i = 1; i < r->NFields; i++) - r->Fd[i].RecOff = r->Fd[i - 1].RecOff + r->Fd[i - 1].Len; - return(r->Fd[r->NFields - 1].RecOff + r->Fd[r->NFields - 1].Len); - } - return(0); -} - -/* - @(SHF) Funzioni per la gestione dei campi dei record - @($) setdec FILES - - @(ID) - Data la stringa "s" (contenente un numero) Aggiusta il numero dei decimali in - base a "dec". - @(FD) - - @(ISV) - s1 = stringa di lavoro. - - i = contatore. - - l = lunghezza stringa s1. - - carry = eventuale riporto approssimazione. - - @(FSV) - - @(IN) - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo. - @(FN) - */ - -void setdec(s,dec) - char *s; /* stringa che deve contenere un numero */ - int dec; /* numero di decimali che deve avere il numero */ - -{ - char *s1; - int i, l, carry; - - if (LENGTH(s) == 0) strcpy(s, "0"); - if ((s1 = strchr(s, ',')) != NULL) *s1 = '.'; - s1 = strchr(s, '.'); - if ((dec) && (s1 == NULL)) - { - strcat(s, "."); - s1 = strchr(s, '.'); - } - else - if (!dec) - { - if (s1 == NULL) return ; - l = LENGTH(s1); /* occhio verificare */ - carry = (s1[1] >= '5'); - *s1 = '\0'; - while (carry) - { - s1--; - if (*s1 == '-') break; - if (*s1 == '9') - { - *s1 = '0'; - if (s == s1) break; - } - else - { - (*s1)++; - carry = FALSE; - } - } - if (carry) - { - for (i = l; i > (*s1 == '-'); i--) s[i] = s[i - 1]; - s[(*s1 == '-')] = '1'; - } - return; - } - s1++; - l = LENGTH(s1); - if (l > dec) - { - carry = (s1[dec] >= '5'); - s1[dec] = '\0'; - while (carry) - { - dec--; - if (s1[dec] == '9') - { - s1[dec] = '0'; - if (!dec) break; - } - else - { - s1[dec]++; - carry = FALSE; - } - } - s1--; - while (carry) - { - s1--; - if (*s1 == '-') break; - if (*s1 == '9') - { - *s1 = '0'; - if (s == s1) break; - } - else - { - (*s1)++; - carry = FALSE; - } - } - if (carry) - { - for (i = l; i > (*s1 == '-'); i--) s[i] = s[i - 1]; - s[(*s1 == '-')] = '1'; - } - } - else - while (l++ < dec) strcat(s1, "0"); -} - -/* - @($) hashfun FILES - - @(ID) - Data la stringa "s" costruisce la chiave Hash. - @(FD) - - @(ISV) - l = lunghezza della stringa "s". - - w[82] = copia di lavoro della stringa "s". - - temp = variabile di lavoro. - - pw = puntatore ai caratteri della stringa. - - Utilizza l'operatore OR Esclusivo. - @(FSV) - - @(IN) - Restituisce l'indirizzo HASH. - @(FN) - */ - -int hashfun(s) - char *s; /* stringa da eleborare */ - -{ - int l; - char w[82]; - unsigned short temp = 0, *pw = (unsigned short *) w; - - strcpy(w, s); - if (ODD(LENGTH(s))) strcat(w, " "); - l = LENGTH(s); - while ((char *) pw < w + l) - { - temp ^= *pw; - pw++; - } - l = (short) (temp % (MaxFields - 3)); - if (l < 0) l = -l; - return(l); -} - -/* - @($) findfld FILES - - @(ID) - Ricerca all'interno di un record il campo di nome "s". - @(FD) - - @(ISV) - i= variabile di lavoro. - startp = variabile di lavoro. - cmp = variabile di lavoro. - @(FSV) - */ - -int findfld(recd,s) - RecDes *recd; /* Descrittore record Tracciato Record */ - char *s; /* stringa contenente il nome del campo */ - -{ - int i, cmp, startp; - - i = hashfun(s); - startp = i; - if (recd->SortFd[i] == INVFLD) return(-1); - do - { - if (!(cmp = strcmp(recd->Fd[recd->SortFd[i]].Name, s))) - return((int) (recd->SortFd[i])); - else - if (cmp > 0) return(-1); - else - if (++i >= MaxFields) i = 0; - if (recd->SortFd[i] == INVFLD) return(-1); - } - while (i != startp) ; - return(-1); -} - -/* - @(#) CFieldSize FILES - - @(ID) - Restituisce la lunghezza del campo. - @(FD) - - @(ISV) - p = puntatore al campo. - @(FSV) - */ - -unsigned int CFieldSize(fieldname,recd) - char *fieldname; /* nome del campo */ - RecDes *recd; /* descrittore record */ - -{ - int p; - - if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].Len); - else return(0); -} - -/* - @(#) CFieldDec FILES - - @(ID) - Restituisce il numero di decimali presenti nel campo. - @(FD) - - @(ISV) - p = puntatore al campo. - @(FSV) - */ - -unsigned int CFieldDec(fieldname,recd) - char *fieldname; /* nome del campo */ - RecDes *recd; /* descrittore record */ - -{ - int p; - - if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].Dec); - else return(0); -} - -/* - @(#) CFieldType FILES - - @(ID) - Restituisce un intero rappresentante il tipo del campo. - @(FD) - - @(ISV) - p = posizione all'interno del record del campo. - @(FSV) - */ - -int CFieldType(fieldname,recd) - char *fieldname; /* nome del campo */ - RecDes *recd; /* descrittore record */ - -{ - int p; - - if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].TypeF); - else return(NullF); -} - -/* - @($) getfrmt FILES - - @(ID) - Prepara il il formato per dsprintf per il campo "nf" del tracciato record "recd". - @(FD) - - @(ISV) - len = lunghezza del campo. - - dec = numero di decimali presenti nel campo. - @(FSV) - */ - -void getfrmt(recd,nf,frm) - RecDes *recd; /* descrittore record */ - int nf; /* numero campo */ - char *frm; /* stringa in formato per dsprintf */ - -{ - int len, dec; - - strcpy(frm, ""); - len = recd->Fd[nf].Len; - dec = recd->Fd[nf].Dec; - if (recd->Fd[nf].TypeF == IntF) sprintf(frm, "%%%dd", len); - else - if (recd->Fd[nf].TypeF == Int4F) sprintf(frm, "%%%dld", len); - else - if (recd->Fd[nf].TypeF == RealF) sprintf(frm, "%%%d.%dt",len, dec); - /*cambiare */ - else - if (recd->Fd[nf].TypeF == WordF) sprintf(frm, "%%%du", len); - else - if (recd->Fd[nf].TypeF == ZeroF) sprintf(frm, "%%0%dd", len); - else - if (recd->Fd[nf].TypeF == EZeroF) sprintf(frm, "%%0%dld", len); -} - -/* - @(#) CGetField FILES - - @(ID) - Estrae il valore di un campo dal record e lo pone in "fout". - - Restituisce un eventuale codice errore. - @(FD) - - @(ISV) - r = variabile che contiene l'eventuale codice errore. - - p = variabile per la chiamata di "findfld". - - s = puntatore alla zona di memoria allocata. - - frm= stringa per contenere un formato per la dsprintf. - @(FSV) - - @(IN) - Si osservi che "fout" deve essere un puntatore a una variabile di tipo coerente con il campo da leggere. - @(FN) - */ - -#ifndef FOXPRO - -/* - @(#) CPutField FILES - - @(ID) - Scrive il contenuto della variabile puntata da "fin" nel campo "fieldname" del record. - - Restituisce un eventuale codice errore. - @(FD) - - @(ISV) - r = variabile che contiene l'eventuale codice errore. - - p = variabile per la chiamata di "findfld". - - s = puntatore alla zona di memoria allocata. - - frm= stringa per contenere un formato per la dsprintf. - @(FSV) - - @(IN) - Si osservi che "fin" deve essere un puntatore a una variabile di tipo coerente con il campo da leggere. - @(FN) - */ - -int CPutField(fieldname,recd,fin,recout) - char *fieldname; /* nome del campo */ - RecDes *recd; /* descrittore record */ - void *fin; /* puntatore al valore da scrivere */ - RecType recout; /* buffer contenetnte il record */ - -{ - int p; - char s[256], frm[30]; - - strcpy(s, ""); - p = findfld(recd, fieldname); - getfrmt(recd, p, frm); - if (recd->Fd[p].TypeF == AlfaF) strcpy(s, (char *) fin); - else - if ((recd->Fd[p].TypeF == IntF) || (recd->Fd[p].TypeF == ZeroF)) - sprintf(s, frm, *((int *) fin)); - else - if ((recd->Fd[p].TypeF == Int4F) || (recd->Fd[p].TypeF == EZeroF)) - sprintf(s, frm, *((long *) fin)) ; - else - if (recd->Fd[p].TypeF == RealF) dsprintf(s, frm, (DEC *) fin); - else - if (recd->Fd[p].TypeF == WordF) sprintf(s, frm, *((unsigned *) fin)) ; - else - if (recd->Fd[p].TypeF == CharF) - { - s[0] = *((char *) fin); - s[1] = '\0'; - } - else - if (recd->Fd[p].TypeF == BoolF) - { - s[0] = *((BOOLEAN*) fin) ? 'X' : ' '; - s[1] = '\0'; - } - return CPutFieldBuff(fieldname, recd, s, recout); -} - -#endif /* FOXPRO */ - -/* - @(#) CGetFieldBuff FILES - - @(ID) - Estrae il valore di un campo dal record e lo pone nella stringa "s". - - Restituisce un eventuale codice errore. - @(FD) - - @(ISV) - p = puntatore al campo. - - i = contatore. - - Off = offest in byte all'interno del record per il campo in oggetto. - - len = lunghezza campo. - - s1 = stringa di lavoro. - - d = data in formato stringa. - @(FSV) - - @(IN) - Utilizzato per il Data Entry. - @(FN) - */ - -int CGetFieldBuff(fieldname,recd,recin,s) - char *fieldname; /* nome del campo */ - RecDes *recd; /* descrittore record */ - RecType recin; /* buffer contenente il record */ - char *s; /* stringa per l'output */ - -{ - int p, i; - char *s1; - - if ((p = findfld(recd, fieldname)) != -1) - { - const int tipo = recd->Fd[p].TypeF; - unsigned int off = recd->Fd[p].RecOff; - byte len = recd->Fd[p].Len; - - if ((tipo != AlfaF) && (tipo != DateF) && (tipo != ZeroF) && (tipo != EZeroF)) - { - while ((recin[off] == ' ') && (len)) - { - off++; - len--; - } - if ((tipo != RealF) && (tipo != CharF)) - { - while ((recin[off] == '0') && (len)) - { - off++; - len--; - } - } - } - else - if ((tipo == ZeroF) || (tipo == EZeroF)) - { - char* c = &recin[off]; - for (i = 0; i < len; i++, c++) - { - if (*c == ' ') - *c = '0'; - else - if (*c != '0') - break; - } - if (i == len) - { - off += len; - len = 0; - } - } - if (len) - { - s1 = recin + off; - for (i = 0; i < len; i++) s[i] = s1[i]; - s[len] = '\0'; - while ((len) && (s[len - 1] == ' ')) s[--len] = '\0'; - } - else strcpy(s, ""); - - if ((tipo == RealF)) - if ((s1 = strchr(s, ',')) != NULL) *s1 = '.'; - return(0); - } - else - { - strcpy(s, ""); - return(-1); - } -} - -/* - @(#) CPutFieldBuff FILES - - @(ID) - Scrive il contenuto della stringa "s" nel campo "fieldname" del record. - - Restituisce un eventuale codice errore. - @(FD) - - @(ISV) - p = puntatore al campo. - - i = contatore. - - l = variabile di lavoro. - - off = offest in byte all'interno del record per il campo in oggetto. - - len = lunghezza campo. - - s1,s2 = stringa di lavoro. - - d = data in formato stringa. - @(FSV) - - @(IN) - Utilizzato per il Data Entry - @(FN) - */ - -int CPutFieldBuff(fieldname,recd,s,recout) - char *fieldname; /* nome del campo */ - RecDes *recd; /* descrittore record */ - char *s; /* stringa contenente il valore da scrivere nel campo */ - RecType recout; /* buffer contenente il record */ - -{ - int p, off, len, l, i; - char *s1; - /* - char *s2; - s2 = malloc(256); - */ - char s2[256]; - - strcpy(s2, s); - if ((p = findfld(recd, fieldname)) != -1) - { - off = recd->Fd[p].RecOff; - len = recd->Fd[p].Len; - if (recd->Fd[p].TypeF == RealF) setdec(s2, recd->Fd[p].Dec); - l = LENGTH(s2); - if (l > len) - { - /* free(s2); */ - return(-1); - } - s1 = recout + off ; - for (i = 0; i < l ; i++) s1[i] = s2[i] ; - if ((recd->Fd[p].TypeF == IntF) || - (recd->Fd[p].TypeF == Int4F) || - (recd->Fd[p].TypeF == WordF) || - (recd->Fd[p].TypeF == RealF) || - (recd->Fd[p].TypeF == ZeroF) || - (recd->Fd[p].TypeF == EZeroF)) - { - char c; - if ((recd->Fd[p].TypeF == ZeroF) || - (recd->Fd[p].TypeF == EZeroF)) - c = '0'; - else c = ' '; - if (l == 0) s1[l++] = '0'; - while (l < len) - { - for (i = l; i > 0; i--) s1[i] = s1[i - 1]; - s1[0] = c; - l++; - } - } - else - while (l < len) s1[l++] = ' '; - /* free(s2); */ - return(0); - } - else - { - strcpy(s, ""); - /* free(s2); */ - return(-1); - } -} - - -/* - @(#) CZeroField FILES - - @(ID) - Azzera un campo. - @(FD) - - @(ISV) - p = puntatore al campo. - - s = stringa messaggio. - @(FSV) - */ - -int CZeroField(fieldname,recd,recout) - char *fieldname; /* nonme del campo */ - RecDes *recd; /* descrittore record */ - RecType recout; /* buffer contenente il record */ - -{ - int p; - - if ((p = findfld(recd, fieldname)) != -1) - { - if (recd->Fd[p].TypeF == DateF) - memset(recout + recd->Fd[p].RecOff, '0', recd->Fd[p].Len); - else - { - memset(recout + recd->Fd[p].RecOff, Blank, recd->Fd[p].Len); - if ((recd->Fd[p].TypeF == IntF) || - (recd->Fd[p].TypeF == Int4F) || - (recd->Fd[p].TypeF == WordF)) - { - *(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - 1) = '0'; - } - else - if (recd->Fd[p].TypeF == RealF) - { - if (recd->Fd[p].Dec) - { - memset(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - - recd->Fd[p].Dec - 2, '0', recd->Fd[p].Dec + 2); - *(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - - recd->Fd[p].Dec - 1) = '.'; - } - else *(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - 1) = '0'; - } - return(NoErr); - } - } - else return(-1); - return(NoErr); -} - -/* - @(#) CZeroRec FILES - - @(ID) - Azzera tutto il record. - @(FD) - - @(ISV) - i = contatore. - - junk = variabile spazzatura per la chiamata di CZeroField. - @(FSV) - */ - -void CZeroRec(recd,recout) - RecDes *recd; /* descrittore record */ - RecType recout; /* buffer contenente il record */ - -{ - int i, junk; - - IRecallRec(recout) ; - for (i = 0; i < recd->NFields; i++) junk = CZeroField(recd->Fd[i].Name, - recd, recout); -} - - -/* - @($) prefname FILES - - @(ID) - Restituisce il nome del file che contiene il prefisso corrente. - @(FD) - - @(ISV) - s,s1 = stringhe di lavoro. - - Versione DOS e XENIX. - @(FSV) - */ - -#ifndef FOXPRO - -char *prefname() - -{ - static PathSt s; -#ifdef DOS - char *s1 = getenv("PREFPATH"); - if (s1 == NULL) s1 = "prefix.txt"; - strcpy(s, s1); -#else - sprintf(s, "prefix.%-d", getuid()); -#endif - return(s) ; -} - -#endif - -/* - @(#) CGetPref FILES - - @(ID) - Legge dal file prefisso il prefisso dati corrente. - @(FD) - - @(ISV) - f = puntatore al file. - @(FSV) - - @(IN) - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo. - @(FN) - */ - -char *CGetPref() - -{ - const char* p = prefname(); - FILE *f = fopen(p, "r"); - - if (f == NULL) - { - strcpy(cprefix, ""); - } - else - { - if (fgets(cprefix, 42, f) != NULL) - { - const int len = LENGTH(cprefix)-1; - if (len >= 0 && cprefix[len] <= ' ') cprefix[len] = '\0'; - } - else - *cprefix = '\0'; - fclose(f); - } - if (!pathpread) - { - const char* p = "pathpref.ini"; - FILE* f = fopen(p, "r"); - pathpread = TRUE; - if (f != NULL) - { - if (fgets(__ptprf, 42, f) != NULL) - { - const int len = LENGTH(__ptprf)-1; - if (len >= 0 && __ptprf[len] <= ' ') - { - __ptprf[len] = '\0'; - if (len > 0) strcat(__ptprf, "/"); - } - } - else - *__ptprf = '\0'; - fclose(f); - } - } - if (*__ptprf) - { - char ws[200]; - sprintf(ws, "%s%s", __ptprf, cprefix); - strcpy(cprefix, ws); - } - return(cprefix); -} - -/* - @($) CPutPref FILES - - @(ID) - Aggiorna sul file prefisso il prefisso dati corrente. - @(FD) - - @(ISV) - f = puntatore a file. - @(FSV) - - @(IN) - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo. - @(FN) - */ - -void CPutPref(pref) - char *pref; /* stringa contenente il nuovo prefisso */ - -{ - FILE *f; - const int l = strlen(__ptprf); - - if (l && strncmp(pref, __ptprf, l) == 0) pref += l; - if ((f = fopen(prefname(), "w")) == NULL) - fatal_box("Put prefix. Error number : %d ", errno); - fprintf(f, "%s\n", pref); - fclose(f); -} - -/* - @($) CAddPref FILES - - @(ID) - Cerca il carattere "$" nel nome file e lo sostituisce con il prefisso corrente. - @(FD) - - @(ISV) - s = stringa che contiene il nome. - @(FSV) - - @(IN) - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo. - @(FN) - */ - -char *CAddPref(name) - char *name; /* nome file */ - -{ - static PathSt s; - - if (*name == '$') - { - name++; - return(CInsPref(name, NORDIR)) ; - } - else - if (*name == '%') - { - name++; - return(CInsPref(name, COMDIR)) ; - } - else - { - sprintf(s, "%s%s", __ptprf, name); - return(s); - } -} - -/* - @($) CInsPref FILES - - @(ID) - Aggiunge (a sinistra) il prefisso corrente. - @(FD) - - @(ISV) - s = stringa di lavoro. - @(FSV) - - @(IN) - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo. - @(FN) - */ - -char *CInsPref(name,dirflg) - char *name; /* nome del file cui aggiungere il prefisso */ - int dirflg; /* flag per file comuni */ - -{ - static PathSt s; - - if (dirflg == NORDIR) - { - if (LENGTH(cprefix) == 0) sprintf(s,"%s", name); - else sprintf(s,"%s%c%s",cprefix, DIRSEP, name); - } - else sprintf(s,"%scom%c%s", __ptprf, DIRSEP, name); - return(s); -} - -/* - @(#) CGetIdxName FILES - - @(ID) - Dato un nome file costruisce il nome del file indice corrispondente. - @(FD) - - @(ISV) - fdst,s1,s2 = stringhe di lavoro. - @(FSV) - - @(IN) - NON UTILIZZARE !!. - - Se si utilizza spiegarne dettagliatamente il motivo. - - L' estensione dei file indice e' ndx; e' quindi vietato utilizzare un nome - di file che abbia tale estensione. L' estensione dei file dati e' dta. - @(FN) - */ - -char *CGetIdxName(s) - char *s; /* stringa contenente il nome file */ - -{ - static PathSt fdst; - char *s1, *s2; - - strcpy(fdst, s) ; - s1 = strrchr(fdst,DIRSEP) ; - if (s1 == NULL) s1 = fdst; - s2 = strchr(s1,'.') ; - if (s2 != NULL) s2[0] = '\0' ; - s1 = strcat(fdst, ".ndx") ; - return(fdst) ; -} +#define __CFILES_C /* fv */ + +#include "cfiles.h" +#include "fldtypes.h" + +int hashfun(char *); +void setdec(char *, int); +char *prefname(void); + +HIDDEN BOOLEAN pathpread = FALSE; + +BOOLEAN dispferr = TRUE; +int dirfl[2] = {0, 0}, recfl[2] = {0, 0} ; +char __ptprf[80] = ""; + +/* + @(#) COpenDir FILES + + @(ID) + Apre il file directory di una ditta. + @(FD) + + @(ISV) + name = percorso per il file di direttorio. + + Versione DOS e XENIX. + @(FSV) + + @(IN) + NON UTILIZZARE !!. + + Se si utilizza spiegare dettagliatamente il motivo. + @(FN) + */ + +void COpenDir(lockmode, dirflg) + int lockmode; /* modo di apertura */ + int dirflg; /* flag per file comuni */ + +{ + PathSt name; + + if (dirfl[dirflg]++) return; +#ifndef DOS + if ((excllock(CInsPref(glockname, dirflg), (lockmode == ExclLock)) == -1) + && (errno == EACCES)) + fatal_box("Locked Directory. Error number : %d ", errno); +#endif + strcpy(name, CInsPref(directory, dirflg)) ; + COpen(&fdir[dirflg], name, sizeof(FileDes), 0, lockmode) ; + if (fdir[dirflg].IOR != NoErr) + fatal_box("Can't open Directory. Error number : %d ", fdir[dirflg].IOR); +} + +/* + @(#) CCloseDir FILES + + @(ID) + Chiude il file di direttorio di una ditta. + @(FD) + + @(ISV) + Versione DOS e XENIX. + @(FSV) + + @(IN) + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo. + @(FN) + */ + +void CCloseDir(dirflg) + int dirflg; /* flag per file comuni */ + +{ +#ifndef DOS + exclunlock(CInsPref(glockname, dirflg), (fdir[dirflg].LockMode == ExclLock)); +#endif + if (dirfl[dirflg]) dirfl[dirflg]--; + if (!dirfl[dirflg]) CClose(&fdir[dirflg]) ; +} + +/* + @(#) COpenFile FILES + + @(ID) + Legge i dati di un archivio dal Direttorio. + @(FD) + + @(ISV) + junk = variabile spazzatura per la chiamata della funzione "sleep". + + s = stringa contenente messaggio di attesa. + + w = descrittore finestra di attesa. + + Versione DOS e XENIX. + @(FSV) + + @(IN) + Sostituisce l'eventuale simbolo "$" con il prefisso corrente. + + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo. + @(FN) + */ + +void COpenFile(logicname,filed,lockmode,dirflg) + int logicname; /* numero logico file */ + FileDes *filed; /* puntatore alla struttura che contiene i dati letti dal direttorio */ + int lockmode; /* tipo di lock effettuato sul record */ + int dirflg; /* flag per file comuni */ + +{ + do + { + CRead(&fdir[dirflg],(RecType) filed,(long) logicname, lockmode); + + if (TESTLOCK(fdir[dirflg].IOR)) + message_box("Sono in attesa della directory n.ro %d", logicname); + } while TESTLOCK(fdir[dirflg].IOR) ; + strcpy(filed->SysName, CAddPref(filed->SysName)) ; +} + +/* + @(#) CCloseFile FILES + + @(ID) + Chiude e Riscrive i dati di un file sul direttorio. + @(FD) + + @(ISV) + wd = descrittore di una riga di direttorio. + + junk = variabile spazzatura per la chiamata della funzione "sleep". + + s = messaggio di attesa. + + w = descrittore della finestra di attesa. + @(FSV) + + @(IN) + ATTENZIONE : questa funzione aggiorna esclusivamente i campi EOD e Flags . + + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo. + @(FN) + */ + +void CCloseFile(logicname,filed,dirflg) + int logicname; /* numero logico file */ + FileDes *filed; /* puntatore al descrittore di un archivio */ + int dirflg; /* flag per file comuni */ + +{ + FileDes wd; + + CRead(&fdir[dirflg],(RecType) &wd,(long) logicname, NoLock); + wd.EOD = filed->EOD; + wd.Flags = filed->Flags; + CWrite(&fdir[dirflg],(RecType) &wd,(long) logicname, UnLock); +} +/* + @($) CGetFile FILES + + @(ID) + Legge i dati relativi ad un archivio nel direttorio. + Non sostituisce con il prefisso l'eventuale carattere "$". + @(FD) + + @(ISV) + junk = variabile spazzatura per la chiamata della funzione "sleep". + + s = messaggio di attesa. + + w = descrittore finestra di attesa. + + Versione DOS e XENIX. + @(FSV) + + @(IN) + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo. + @(FN) + */ + +void CGetFile(logicname,filed,lockmode,dirflg) + int logicname; /* numero logico file */ + FileDes *filed; /* puntatore al descrittore archivio nel direttorio */ + int lockmode; /* tipo di lock sul record */ + int dirflg; /* flag per file comuni */ +{ + + do + { + CRead(&fdir[dirflg],(RecType) filed,(long) logicname, lockmode); + if (TESTLOCK(fdir[dirflg].IOR)) + message_box("Sono in attesa della directory n.ro %d", logicname); + } + while TESTLOCK(fdir[dirflg].IOR) ; +} + +/* + @($) CPutFile FILES + + @(ID) + Chiude il direttorio e Riscrive i dati relativi ad un archivo. + Aggiorna tutti i campi. + @(FD) + + @(IN) + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo. + @(FN) + */ + +void CPutFile(logicname,filed,dirflg) + int logicname; /* numero logico file */ + FileDes *filed; /* puntatore al descrittore dell'archivio */ + int dirflg; /* flag per file comuni */ + +{ + CWrite(&fdir[dirflg],(RecType) filed,(long) logicname, UnLock); +} + +/* + @($) zerofdes FILES + + @(ID) + Azzera un descrittore di directory. + @(FD) + + @(IN) + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo. + @(FN) + */ + + +void zerofdes(d) + FileDes *d; /* puntatore al descrittore di un archivio nella direttorio */ + +{ + strcpy(d->SysName, ""); + d->EOD = 0; + d->EOX = 0; + d->LenR = 0; + d->Flags = 0; + strcpy(d->Des, ""); + strcpy(d->FCalc, ""); + strcpy(d->GenPrompt, ""); +} + +/* + @(#) COpenRecDir FILES + + @(ID) + Apre l'Archivio dei Tracciati Record. + @(FD) + + @(ISV) + name = nome dell'archivio dei Tracciati Record. + + Versione DOS e XENIX. + @(FSV) + + @(IN) + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo. + @(FN) + */ + +void COpenRecDir(lockmode,dirflg) + int lockmode; /* modo di apertura */ + int dirflg; /* flag per file comuni */ + +{ + PathSt name; + + if (recfl[dirflg]++) return; + strcpy(name, CInsPref(ntrrec, dirflg)) ; + COpen(&rdir[dirflg], name, sizeof(RecDes), 0, lockmode) ; + if (rdir[dirflg].IOR != NoErr) + fatal_box("Can't open record description file. Error number : %d ", rdir[dirflg].IOR); + +} + +/* + @(#) CCloseRecDir FILES + + @(ID) + Chiude l'Archivio dei Tracciati Record + @(FD) + + @(IN) + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo + @(FN) + */ + +void CCloseRecDir(dirflg) + int dirflg; /* flag per file comuni */ + +{ + if (recfl[dirflg]) recfl[dirflg]--; + if (!recfl[dirflg]) CClose(&rdir[dirflg]) ; +} + +/* + @(#) CGetRec FILES + + @(ID) + Legge il tracciato record del file "logicname" e lo mette in "recd". + @(FD) + + @(IN) + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo. + @(FN) + */ + +void CGetRec(logicname,recd,dirflg) + int logicname; /* numero file */ + RecDes *recd; /* descrittore record */ + int dirflg; /* flag per file comuni */ + +{ + CRead(&rdir[dirflg],(RecType) recd,(long) logicname, NoLock); +} + + +/* + @($) CPutRec FILES + + @(ID) + Aggiorna il file dei Tracciati Record. + @(FD) + + */ + +void CPutRec(logicname,recd,dirflg) + int logicname; /* numero file */ + RecDes *recd; /* descrittore record */ + int dirflg; /* flag per file comuni */ + +{ + CWrite(&rdir[dirflg],(RecType) recd,(long) logicname, NoLock); +} + +/* + @($) zerodes FILES + + @(ID) + Azzera il Tracciato Record "r". + @(FD) + + @(ISV) + i,j = contatori. + @(FSV) + + @(IN) + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo. + @(FN) + */ + +void zerordes(r) + RecDes *r; /* descrittore record */ + +{ + int i,j ; + + r->NFields = 0; + for (i = 0; i < MaxFields; i++) + { + strcpy(r->Fd[i].Name, ""); + r->Fd[i].TypeF = NullF; + r->Fd[i].Len = 0; + r->Fd[i].Dec = 0; + r->Fd[i].RecOff = 0; + } + for (i = 0; i < MaxFields; i++) r->SortFd[i] = INVFLD; + r->NKeys = 0; + for (i = 1; i < MaxKeys; i++) + { + r->Ky[i].DupKeys = FALSE; + r->Ky[i].NkFields = 0; + for (j = 0; j < MKFields; j++) r->Ky[i].FieldSeq[j] = INVFLD; + for (j = 0; j < MKFields; j++) r->Ky[i].FromCh[j] = INVFLD; + for (j = 0; j < MKFields; j++) r->Ky[i].ToCh[j] = INVFLD; + } +} + +/* + @($) setrdes FILES + + @(ID) + Dato il tracciato record crea la struttura HASH (sortFd) per l'accesso veloce + ai campi. + @(FD) + + @(ISV) + pos = indirizzo Hash. + + i = contatore. + + nf = variabile di lavoro. + + tmppos = indirizzo hash per l'accesso ai campi. + @(FSV) + + @(IN) + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo. + @(FN) + */ + +word setrdes(r) + RecDes *r; /* descrittore record */ + +{ + int pos, tmppos, nf, i; + + for (i = 0; i < MaxFields; i++) r->SortFd[i] = INVFLD; + if (r->NFields) + { + for (i = 0; i < r->NFields; i++) + { + nf = i; + pos = hashfun(r->Fd[nf].Name); + while (TRUE) + { + if (r->SortFd[pos] == INVFLD) + { + r->SortFd[pos] = (byte) nf; + break; + } + else + { + if (strcmp(r->Fd[r->SortFd[pos]].Name, r->Fd[nf].Name) <= 0) + { + pos++; + if (pos >= MaxFields) + pos = 0; + } + else + { + tmppos = r->SortFd[pos]; + r->SortFd[pos] = (byte) nf; + nf = tmppos; + } + } + } + } + r->Fd[0].RecOff = 1; + for (i = 1; i < r->NFields; i++) + r->Fd[i].RecOff = r->Fd[i - 1].RecOff + r->Fd[i - 1].Len; + return(r->Fd[r->NFields - 1].RecOff + r->Fd[r->NFields - 1].Len); + } + return(0); +} + +/* + @(SHF) Funzioni per la gestione dei campi dei record + @($) setdec FILES + + @(ID) + Data la stringa "s" (contenente un numero) Aggiusta il numero dei decimali in + base a "dec". + @(FD) + + @(ISV) + s1 = stringa di lavoro. + + i = contatore. + + l = lunghezza stringa s1. + + carry = eventuale riporto approssimazione. + + @(FSV) + + @(IN) + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo. + @(FN) + */ + +void setdec(s,dec) + char *s; /* stringa che deve contenere un numero */ + int dec; /* numero di decimali che deve avere il numero */ + +{ + char *s1; + int i, l, carry; + + if (LENGTH(s) == 0) strcpy(s, "0"); + if ((s1 = strchr(s, ',')) != NULL) *s1 = '.'; + s1 = strchr(s, '.'); + if ((dec) && (s1 == NULL)) + { + strcat(s, "."); + s1 = strchr(s, '.'); + } + else + if (!dec) + { + if (s1 == NULL) return ; + l = LENGTH(s1); /* occhio verificare */ + carry = (s1[1] >= '5'); + *s1 = '\0'; + while (carry) + { + s1--; + if (*s1 == '-') break; + if (*s1 == '9') + { + *s1 = '0'; + if (s == s1) break; + } + else + { + (*s1)++; + carry = FALSE; + } + } + if (carry) + { + for (i = l; i > (*s1 == '-'); i--) s[i] = s[i - 1]; + s[(*s1 == '-')] = '1'; + } + return; + } + s1++; + l = LENGTH(s1); + if (l > dec) + { + carry = (s1[dec] >= '5'); + s1[dec] = '\0'; + while (carry) + { + dec--; + if (s1[dec] == '9') + { + s1[dec] = '0'; + if (!dec) break; + } + else + { + s1[dec]++; + carry = FALSE; + } + } + s1--; + while (carry) + { + s1--; + if (*s1 == '-') break; + if (*s1 == '9') + { + *s1 = '0'; + if (s == s1) break; + } + else + { + (*s1)++; + carry = FALSE; + } + } + if (carry) + { + for (i = l; i > (*s1 == '-'); i--) s[i] = s[i - 1]; + s[(*s1 == '-')] = '1'; + } + } + else + while (l++ < dec) strcat(s1, "0"); +} + +/* + @($) hashfun FILES + + @(ID) + Data la stringa "s" costruisce la chiave Hash. + @(FD) + + @(ISV) + l = lunghezza della stringa "s". + + w[82] = copia di lavoro della stringa "s". + + temp = variabile di lavoro. + + pw = puntatore ai caratteri della stringa. + + Utilizza l'operatore OR Esclusivo. + @(FSV) + + @(IN) + Restituisce l'indirizzo HASH. + @(FN) + */ + +int hashfun(s) + char *s; /* stringa da eleborare */ + +{ + int l; + char w[82]; + unsigned short temp = 0, *pw = (unsigned short *) w; + + strcpy(w, s); + if (ODD(LENGTH(s))) strcat(w, " "); + l = LENGTH(s); + while ((char *) pw < w + l) + { + temp ^= *pw; + pw++; + } + l = (short) (temp % (MaxFields - 3)); + if (l < 0) l = -l; + return(l); +} + +/* + @($) findfld FILES + + @(ID) + Ricerca all'interno di un record il campo di nome "s". + @(FD) + + @(ISV) + i= variabile di lavoro. + startp = variabile di lavoro. + cmp = variabile di lavoro. + @(FSV) + */ + +int findfld(recd,s) + RecDes *recd; /* Descrittore record Tracciato Record */ + char *s; /* stringa contenente il nome del campo */ + +{ + int i, cmp, startp; + + i = hashfun(s); + startp = i; + if (recd->SortFd[i] == INVFLD) return(-1); + do + { + if (!(cmp = strcmp(recd->Fd[recd->SortFd[i]].Name, s))) + return((int) (recd->SortFd[i])); + else + if (cmp > 0) return(-1); + else + if (++i >= MaxFields) i = 0; + if (recd->SortFd[i] == INVFLD) return(-1); + } + while (i != startp) ; + return(-1); +} + +/* + @(#) CFieldSize FILES + + @(ID) + Restituisce la lunghezza del campo. + @(FD) + + @(ISV) + p = puntatore al campo. + @(FSV) + */ + +unsigned int CFieldSize(fieldname,recd) + char *fieldname; /* nome del campo */ + RecDes *recd; /* descrittore record */ + +{ + int p; + + if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].Len); + else return(0); +} + +/* + @(#) CFieldDec FILES + + @(ID) + Restituisce il numero di decimali presenti nel campo. + @(FD) + + @(ISV) + p = puntatore al campo. + @(FSV) + */ + +unsigned int CFieldDec(fieldname,recd) + char *fieldname; /* nome del campo */ + RecDes *recd; /* descrittore record */ + +{ + int p; + + if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].Dec); + else return(0); +} + +/* + @(#) CFieldType FILES + + @(ID) + Restituisce un intero rappresentante il tipo del campo. + @(FD) + + @(ISV) + p = posizione all'interno del record del campo. + @(FSV) + */ + +int CFieldType(fieldname,recd) + char *fieldname; /* nome del campo */ + RecDes *recd; /* descrittore record */ + +{ + int p; + + if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].TypeF); + else return(NullF); +} + +/* + @($) getfrmt FILES + + @(ID) + Prepara il il formato per dsprintf per il campo "nf" del tracciato record "recd". + @(FD) + + @(ISV) + len = lunghezza del campo. + + dec = numero di decimali presenti nel campo. + @(FSV) + */ + +void getfrmt(recd,nf,frm) + RecDes *recd; /* descrittore record */ + int nf; /* numero campo */ + char *frm; /* stringa in formato per dsprintf */ + +{ + int len, dec; + + strcpy(frm, ""); + len = recd->Fd[nf].Len; + dec = recd->Fd[nf].Dec; + if (recd->Fd[nf].TypeF == IntF) sprintf(frm, "%%%dd", len); + else + if (recd->Fd[nf].TypeF == Int4F) sprintf(frm, "%%%dld", len); + else + if (recd->Fd[nf].TypeF == RealF) sprintf(frm, "%%%d.%dt",len, dec); + /*cambiare */ + else + if (recd->Fd[nf].TypeF == WordF) sprintf(frm, "%%%du", len); + else + if (recd->Fd[nf].TypeF == ZeroF) sprintf(frm, "%%0%dd", len); + else + if (recd->Fd[nf].TypeF == EZeroF) sprintf(frm, "%%0%dld", len); +} + +/* + @(#) CGetField FILES + + @(ID) + Estrae il valore di un campo dal record e lo pone in "fout". + + Restituisce un eventuale codice errore. + @(FD) + + @(ISV) + r = variabile che contiene l'eventuale codice errore. + + p = variabile per la chiamata di "findfld". + + s = puntatore alla zona di memoria allocata. + + frm= stringa per contenere un formato per la dsprintf. + @(FSV) + + @(IN) + Si osservi che "fout" deve essere un puntatore a una variabile di tipo coerente con il campo da leggere. + @(FN) + */ + +#ifndef FOXPRO + +/* + @(#) CPutField FILES + + @(ID) + Scrive il contenuto della variabile puntata da "fin" nel campo "fieldname" del record. + + Restituisce un eventuale codice errore. + @(FD) + + @(ISV) + r = variabile che contiene l'eventuale codice errore. + + p = variabile per la chiamata di "findfld". + + s = puntatore alla zona di memoria allocata. + + frm= stringa per contenere un formato per la dsprintf. + @(FSV) + + @(IN) + Si osservi che "fin" deve essere un puntatore a una variabile di tipo coerente con il campo da leggere. + @(FN) + */ + +int CPutField(fieldname,recd,fin,recout) + char *fieldname; /* nome del campo */ + RecDes *recd; /* descrittore record */ + void *fin; /* puntatore al valore da scrivere */ + RecType recout; /* buffer contenetnte il record */ + +{ + int p; + char s[256], frm[30]; + + strcpy(s, ""); + p = findfld(recd, fieldname); + getfrmt(recd, p, frm); + if (recd->Fd[p].TypeF == AlfaF) strcpy(s, (char *) fin); + else + if ((recd->Fd[p].TypeF == IntF) || (recd->Fd[p].TypeF == ZeroF)) + sprintf(s, frm, *((int *) fin)); + else + if ((recd->Fd[p].TypeF == Int4F) || (recd->Fd[p].TypeF == EZeroF)) + sprintf(s, frm, *((long *) fin)) ; + else +#ifndef __LONGDOUBLE__ + if (recd->Fd[p].TypeF == RealF) dsprintf(s, frm, (DEC *) fin); + else +#endif + if (recd->Fd[p].TypeF == WordF) sprintf(s, frm, *((unsigned *) fin)) ; + else + if (recd->Fd[p].TypeF == CharF) + { + s[0] = *((char *) fin); + s[1] = '\0'; + } + else + if (recd->Fd[p].TypeF == BoolF) + { + s[0] = *((BOOLEAN*) fin) ? 'X' : ' '; + s[1] = '\0'; + } + return CPutFieldBuff(fieldname, recd, s, recout); +} + +#endif /* FOXPRO */ + +/* + @(#) CGetFieldBuff FILES + + @(ID) + Estrae il valore di un campo dal record e lo pone nella stringa "s". + + Restituisce un eventuale codice errore. + @(FD) + + @(ISV) + p = puntatore al campo. + + i = contatore. + + Off = offest in byte all'interno del record per il campo in oggetto. + + len = lunghezza campo. + + s1 = stringa di lavoro. + + d = data in formato stringa. + @(FSV) + + @(IN) + Utilizzato per il Data Entry. + @(FN) + */ + +int CGetFieldBuff(fieldname,recd,recin,s) + char *fieldname; /* nome del campo */ + RecDes *recd; /* descrittore record */ + RecType recin; /* buffer contenente il record */ + char *s; /* stringa per l'output */ + +{ + int p, i; + char *s1; + + if ((p = findfld(recd, fieldname)) != -1) + { + const int tipo = recd->Fd[p].TypeF; + unsigned int off = recd->Fd[p].RecOff; + byte len = recd->Fd[p].Len; + + if ((tipo != AlfaF) && (tipo != DateF) && (tipo != ZeroF) && (tipo != EZeroF)) + { + while ((recin[off] == ' ') && (len)) + { + off++; + len--; + } + if ((tipo != RealF) && (tipo != CharF)) + { + while ((recin[off] == '0') && (len)) + { + off++; + len--; + } + } + } + else + if ((tipo == ZeroF) || (tipo == EZeroF)) + { + char* c = &recin[off]; + for (i = 0; i < len; i++, c++) + { + if (*c == ' ') + *c = '0'; + else + if (*c != '0') + break; + } + if (i == len) + { + off += len; + len = 0; + } + } + if (len) + { + s1 = recin + off; + for (i = 0; i < len; i++) s[i] = s1[i]; + s[len] = '\0'; + while ((len) && (s[len - 1] == ' ')) s[--len] = '\0'; + } + else strcpy(s, ""); + + if ((tipo == RealF)) + if ((s1 = strchr(s, ',')) != NULL) *s1 = '.'; + return(0); + } + else + { + strcpy(s, ""); + return(-1); + } +} + +/* + @(#) CPutFieldBuff FILES + + @(ID) + Scrive il contenuto della stringa "s" nel campo "fieldname" del record. + + Restituisce un eventuale codice errore. + @(FD) + + @(ISV) + p = puntatore al campo. + + i = contatore. + + l = variabile di lavoro. + + off = offest in byte all'interno del record per il campo in oggetto. + + len = lunghezza campo. + + s1,s2 = stringa di lavoro. + + d = data in formato stringa. + @(FSV) + + @(IN) + Utilizzato per il Data Entry + @(FN) + */ + +int CPutFieldBuff(fieldname,recd,s,recout) + char *fieldname; /* nome del campo */ + RecDes *recd; /* descrittore record */ + char *s; /* stringa contenente il valore da scrivere nel campo */ + RecType recout; /* buffer contenente il record */ + +{ + int p, off, len, l, i; + char *s1; + /* + char *s2; + s2 = malloc(256); + */ + char s2[256]; + + strcpy(s2, s); + if ((p = findfld(recd, fieldname)) != -1) + { + off = recd->Fd[p].RecOff; + len = recd->Fd[p].Len; + if (recd->Fd[p].TypeF == RealF) setdec(s2, recd->Fd[p].Dec); + l = LENGTH(s2); + if (l > len) + { + /* free(s2); */ + return(-1); + } + s1 = recout + off ; + for (i = 0; i < l ; i++) s1[i] = s2[i] ; + if ((recd->Fd[p].TypeF == IntF) || + (recd->Fd[p].TypeF == Int4F) || + (recd->Fd[p].TypeF == WordF) || + (recd->Fd[p].TypeF == RealF) || + (recd->Fd[p].TypeF == ZeroF) || + (recd->Fd[p].TypeF == EZeroF)) + { + char c; + if ((recd->Fd[p].TypeF == ZeroF) || + (recd->Fd[p].TypeF == EZeroF)) + c = '0'; + else c = ' '; + if (l == 0) s1[l++] = '0'; + while (l < len) + { + for (i = l; i > 0; i--) s1[i] = s1[i - 1]; + s1[0] = c; + l++; + } + } + else + while (l < len) s1[l++] = ' '; + /* free(s2); */ + return(0); + } + else + { + strcpy(s, ""); + /* free(s2); */ + return(-1); + } +} + + +/* + @(#) CZeroField FILES + + @(ID) + Azzera un campo. + @(FD) + + @(ISV) + p = puntatore al campo. + + s = stringa messaggio. + @(FSV) + */ + +int CZeroField(fieldname,recd,recout) + char *fieldname; /* nonme del campo */ + RecDes *recd; /* descrittore record */ + RecType recout; /* buffer contenente il record */ + +{ + int p; + + if ((p = findfld(recd, fieldname)) != -1) + { + if (recd->Fd[p].TypeF == DateF) + memset(recout + recd->Fd[p].RecOff, '0', recd->Fd[p].Len); + else + { + memset(recout + recd->Fd[p].RecOff, Blank, recd->Fd[p].Len); + if ((recd->Fd[p].TypeF == IntF) || + (recd->Fd[p].TypeF == Int4F) || + (recd->Fd[p].TypeF == WordF)) + { + *(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - 1) = '0'; + } + else + if (recd->Fd[p].TypeF == RealF) + { + if (recd->Fd[p].Dec) + { + memset(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - + recd->Fd[p].Dec - 2, '0', recd->Fd[p].Dec + 2); + *(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - + recd->Fd[p].Dec - 1) = '.'; + } + else *(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - 1) = '0'; + } + return(NoErr); + } + } + else return(-1); + return(NoErr); +} + +/* + @(#) CZeroRec FILES + + @(ID) + Azzera tutto il record. + @(FD) + + @(ISV) + i = contatore. + + junk = variabile spazzatura per la chiamata di CZeroField. + @(FSV) + */ + +void CZeroRec(recd,recout) + RecDes *recd; /* descrittore record */ + RecType recout; /* buffer contenente il record */ + +{ + int i, junk; + + IRecallRec(recout) ; + for (i = 0; i < recd->NFields; i++) junk = CZeroField(recd->Fd[i].Name, + recd, recout); +} + + +/* + @($) prefname FILES + + @(ID) + Restituisce il nome del file che contiene il prefisso corrente. + @(FD) + + @(ISV) + s,s1 = stringhe di lavoro. + + Versione DOS e XENIX. + @(FSV) + */ + +#ifndef FOXPRO + +char *prefname() + +{ + static PathSt s; +#ifdef DOS + char *s1 = getenv("PREFPATH"); + if (s1 == NULL) s1 = "prefix.txt"; + strcpy(s, s1); +#else + sprintf(s, "prefix.%-d", getuid()); +#endif + return(s) ; +} + +#endif + +/* + @(#) CGetPref FILES + + @(ID) + Legge dal file prefisso il prefisso dati corrente. + @(FD) + + @(ISV) + f = puntatore al file. + @(FSV) + + @(IN) + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo. + @(FN) + */ + +char *CGetPref() + +{ + const char* p = prefname(); + FILE *f = fopen(p, "r"); + + if (f == NULL) + { + strcpy(cprefix, ""); + } + else + { + if (fgets(cprefix, 42, f) != NULL) + { + const int len = LENGTH(cprefix)-1; + if (len >= 0 && cprefix[len] <= ' ') cprefix[len] = '\0'; + } + else + *cprefix = '\0'; + fclose(f); + } + if (!pathpread) + { + const char* p = "pathpref.ini"; + FILE* f = fopen(p, "r"); + pathpread = TRUE; + if (f != NULL) + { + if (fgets(__ptprf, 42, f) != NULL) + { + const int len = LENGTH(__ptprf)-1; + if (len >= 0 && __ptprf[len] <= ' ') + { + __ptprf[len] = '\0'; + if (len > 0) strcat(__ptprf, "/"); + } + } + else + *__ptprf = '\0'; + fclose(f); + } + } + if (*__ptprf) + { + char ws[200]; + sprintf(ws, "%s%s", __ptprf, cprefix); + strcpy(cprefix, ws); + } + return(cprefix); +} + +/* + @($) CPutPref FILES + + @(ID) + Aggiorna sul file prefisso il prefisso dati corrente. + @(FD) + + @(ISV) + f = puntatore a file. + @(FSV) + + @(IN) + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo. + @(FN) + */ + +void CPutPref(pref) + char *pref; /* stringa contenente il nuovo prefisso */ + +{ + FILE *f; + const int l = strlen(__ptprf); + + if (l && strncmp(pref, __ptprf, l) == 0) pref += l; + if ((f = fopen(prefname(), "w")) == NULL) + fatal_box("Put prefix. Error number : %d ", errno); + fprintf(f, "%s\n", pref); + fclose(f); +} + +/* + @($) CAddPref FILES + + @(ID) + Cerca il carattere "$" nel nome file e lo sostituisce con il prefisso corrente. + @(FD) + + @(ISV) + s = stringa che contiene il nome. + @(FSV) + + @(IN) + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo. + @(FN) + */ + +char *CAddPref(name) + char *name; /* nome file */ + +{ + static PathSt s; + + if (*name == '$') + { + name++; + return(CInsPref(name, NORDIR)) ; + } + else + if (*name == '%') + { + name++; + return(CInsPref(name, COMDIR)) ; + } + else + { + sprintf(s, "%s%s", __ptprf, name); + return(s); + } +} + +/* + @($) CInsPref FILES + + @(ID) + Aggiunge (a sinistra) il prefisso corrente. + @(FD) + + @(ISV) + s = stringa di lavoro. + @(FSV) + + @(IN) + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo. + @(FN) + */ + +char *CInsPref(name,dirflg) + char *name; /* nome del file cui aggiungere il prefisso */ + int dirflg; /* flag per file comuni */ + +{ + static PathSt s; + + if (dirflg == NORDIR) + { + if (LENGTH(cprefix) == 0) sprintf(s,"%s", name); + else sprintf(s,"%s%c%s",cprefix, DIRSEP, name); + } + else sprintf(s,"%scom%c%s", __ptprf, DIRSEP, name); + return(s); +} + +/* + @(#) CGetIdxName FILES + + @(ID) + Dato un nome file costruisce il nome del file indice corrispondente. + @(FD) + + @(ISV) + fdst,s1,s2 = stringhe di lavoro. + @(FSV) + + @(IN) + NON UTILIZZARE !!. + + Se si utilizza spiegarne dettagliatamente il motivo. + + L' estensione dei file indice e' ndx; e' quindi vietato utilizzare un nome + di file che abbia tale estensione. L' estensione dei file dati e' dta. + @(FN) + */ + +char *CGetIdxName(s) + char *s; /* stringa contenente il nome file */ + +{ + static PathSt fdst; + char *s1, *s2; + + strcpy(fdst, s) ; + s1 = strrchr(fdst,DIRSEP) ; + if (s1 == NULL) s1 = fdst; + s2 = strchr(s1,'.') ; + if (s2 != NULL) s2[0] = '\0' ; + s1 = strcat(fdst, ".ndx") ; + return(fdst) ; +} diff --git a/include/expr.cpp b/include/expr.cpp index 047773720..38b8256e2 100755 --- a/include/expr.cpp +++ b/include/expr.cpp @@ -273,23 +273,23 @@ void TExpression::eval() { o2 = (real&) evalstack.pop(); o1 = (real&) evalstack.pop(); - evalstack.push(o1 + o2); + evalstack.push(real(o1 + o2)); } break; case _minus: o2 = (real&) evalstack.pop(); o1 = (real&) evalstack.pop(); - evalstack.push(o1 - o2); + evalstack.push(real(o1 - o2)); break; case _multiply: o2 = (real&) evalstack.pop(); o1 = (real&) evalstack.pop(); - evalstack.push(o1 * o2); + evalstack.push(real(o1 * o2)); break; case _divide: o2 = (real&) evalstack.pop(); o1 = (real&) evalstack.pop(); - evalstack.push(o1 / o2); + evalstack.push(real(o1 / o2)); break; case _chgs: o1 = (real&) evalstack.pop(); @@ -417,31 +417,31 @@ void TExpression::eval() } break; case _sqrt: - evalstack.push(sqrt((real&) evalstack.pop())); + evalstack.push(real(sqrt((real&) evalstack.pop()))); break; case _sqr: - evalstack.push(sqr((real&) evalstack.pop())); + evalstack.push(real(sqr((real&) evalstack.pop()))); break; case _exp10: - evalstack.push(exp10((real&) evalstack.pop())); + evalstack.push(real(exp10((real&) evalstack.pop()))); break; case _exp: - evalstack.push(exp((real&) evalstack.pop())); + evalstack.push(real(exp((real&) evalstack.pop()))); break; case _log10: - evalstack.push(log10((real&) evalstack.pop())); + evalstack.push(real(log10((real&) evalstack.pop()))); break; case _log: - evalstack.push(log((real&) evalstack.pop())); + evalstack.push(real(log((real&) evalstack.pop()))); break; case _sin: - evalstack.push(sin((real&) evalstack.pop())); + evalstack.push(real(sin((real&) evalstack.pop()))); break; case _cos: - evalstack.push(cos((real&) evalstack.pop())); + evalstack.push(real(cos((real&) evalstack.pop()))); break; case _tan: - evalstack.push(tan((real&) evalstack.pop())); + evalstack.push(real(tan((real&) evalstack.pop()))); break; case _left: o2 = (real&) evalstack.pop(); @@ -467,16 +467,17 @@ void TExpression::eval() case _pow: o2 = (real&) evalstack.pop(); o1 = (real&) evalstack.pop(); - evalstack.push(pow(o1, o2)); + evalstack.push(real(pow(o1, o2))); break; + case _min: o2 = (real&)evalstack.pop(); o1 = (real&)evalstack.pop(); - evalstack.push(fnc_min(o1, o2)); + evalstack.push(real(fnc_min(o1, o2))); break; case _max: o2 = (real&) evalstack.pop(); o1 = (real&) evalstack.pop(); - evalstack.push(fnc_min(o1, o2)); + evalstack.push(real(fnc_max(o1, o2))); break; case _upper: s1 = (TString&) evalstack.pop(); diff --git a/include/isam.cpp b/include/isam.cpp index 3e4fdd12c..8f03c6b38 100755 --- a/include/isam.cpp +++ b/include/isam.cpp @@ -2322,8 +2322,10 @@ bool TRectype::get_memo(const char* fieldname, TTextfile& txt) const TDate TRectype::get_date(const char* fieldname) const { - const TRecfield f((TRectype&)*this, fieldname); - return (TDate) f; + if (CGetFieldBuff((char*) fieldname, rec_des(), _rec, _isam_string) == -1) + UNKNOWN_FIELD(num(), fieldname); + TDate d(_isam_string); + return d; } #ifndef FOXPRO @@ -2372,16 +2374,14 @@ void TRectype::put(const char* fieldname, word val) } void TRectype::put(const char* fieldname, const real& val) - { - if (CPutField((char*) fieldname, rec_des(), val.ptr(), _rec) == -1) + if (CPutFieldBuff((char*) fieldname, rec_des(), (char*)(const char*)val.string(), _rec) == -1) UNKNOWN_FIELD(num(), fieldname); setempty(FALSE); } void TRectype::put(const char* fieldname, const TDate& val) - -{ +{ TRecfield f(*this, fieldname); f = val.string(full); setempty(FALSE); @@ -2824,9 +2824,8 @@ TRecfield::operator const real() const TRecfield::operator TDate() const { - static TDate d; - __getfieldbuff( _len, _type, _p, _isam_string); - d = _isam_string; + __getfieldbuff(_len, _type, _p, _isam_string); + TDate d(_isam_string); return d; } diff --git a/include/libdefs.h b/include/libdefs.h index 8fc2c993b..75a31e7de 100755 --- a/include/libdefs.h +++ b/include/libdefs.h @@ -30,19 +30,6 @@ @(H) 2.3.01.130 08/10/92 Bonazzi Corretto algoritmo lettura caratteri per >128 */ -typedef union -{ - BOOLEAN b; /*tipo BL*/ - int i; /*tipo I*/ - word w; /*tipo U*/ - byte by; /*tipo BY*/ - long l; /*tipo E*/ - DEC r; /*tipo R*/ - char c; /*tipo C*/ - TrDate d; /*tipo D*/ - Str80 s; /*tipo A*/ -} conftype; - #ifndef DOS struct capentry { /* @(!) 2.3.01.130 */ @@ -63,7 +50,6 @@ struct keybar { /* @(:) 2.3.01.223 */ }; -extern conftype _int_cf; extern char _int_res[513]; extern uchar _int_s1[256]; /* @(!) 2.3.01.temp */ @@ -122,6 +108,5 @@ int gettdef ( char *, uchar *); /* @(:) 2.3.01.130 */ void initctab(struct capentry *); void createaut (struct capentry *); -void putconf(int, conftype *); Word Hl_Port(Word); Word getser(void); diff --git a/include/maskfld.cpp b/include/maskfld.cpp index 181206461..6977a8339 100755 --- a/include/maskfld.cpp +++ b/include/maskfld.cpp @@ -2403,7 +2403,7 @@ word TBoolean_field::class_id() const void TBoolean_field::create(WINDOW parent) { - wincreate(WC_CHECKBOX, _prompt.len()+4, 1, _prompt, parent, 0); + wincreate(WC_CHECKBOX, _prompt.len()+3, 1, _prompt, parent, 0); } void TBoolean_field::set_back_color(COLOR c) const diff --git a/include/maskfld.h b/include/maskfld.h index 07eacedfc..9e7360cec 100755 --- a/include/maskfld.h +++ b/include/maskfld.h @@ -252,7 +252,7 @@ public: void disable() { enable(FALSE); } // @cmember Controlla se un campo e' abilitato - bool enabled() const + virtual bool enabled() const { return _flags.enabled; } // @cmember Rimette lo stato di dis/abilitazione del campo a seconda di come era settato sul file void enable_default(); diff --git a/include/msksheet.cpp b/include/msksheet.cpp index ebf4857ff..fe14c5abb 100755 --- a/include/msksheet.cpp +++ b/include/msksheet.cpp @@ -1824,8 +1824,8 @@ void TSheet_field::highlight() const if (rows > 0) { _sheet->_firstfocus = FALSE; - if (_sheet->_edit_field == NULL) - _sheet->set_focus_cell(0, 1); + _sheet->set_focus_cell(_sheet->rec2row(selected()), 1); + _sheet->str2mask(selected()); } #endif } @@ -1835,6 +1835,11 @@ void TSheet_field::enable(bool on) _sheet->activate(on); } +bool TSheet_field::enabled() const +{ + return items() > 0; +} + void TSheet_field::enable_column(int column, bool on) { _sheet->enable_column(column, on); diff --git a/include/msksheet.h b/include/msksheet.h index 1dc688823..381edc35a 100755 --- a/include/msksheet.h +++ b/include/msksheet.h @@ -79,6 +79,8 @@ public: virtual void reset(); // @cmember Abilita/disabilita tutto lo spreadsheet (vedi ) virtual void enable(bool on); + // @cmember Ritorna lo stato di abilitazione dello spreadsheet (vedi ) + virtual bool enabled() const; // @cmember Aggiorna le righe dello spreadsheet con i valori salvati una volta che non ci sono // piu' processi attivi diff --git a/include/printapp.cpp b/include/printapp.cpp index 2248c2a0f..583262181 100755 --- a/include/printapp.cpp +++ b/include/printapp.cpp @@ -1,7 +1,9 @@ #include #include +#ifndef __LONGDOUBLE__ #include +#endif #include #include @@ -39,11 +41,11 @@ const word IGNORE_FILL = 0x2000; class _Transfield:public TObject { friend class TPrint_application; - TString _from, // "from" value - _to, // "to" value - _fn; // field name + TString _from, // "from" value + _to, // "to" value + _fn; // field name - int _lognum; // logical number + int _lognum; // logical number public: _Transfield (int l, const char *fn, const char *from, const char *to): @@ -102,13 +104,13 @@ class _FieldTok : public _Token friend class TPrint_application; int _size, _dec; char _align; - TString _fld; // field description + TString _fld; // field description - word _flags; // all you need to know + word _flags; // all you need to know public: _FieldTok (int rw, char *fld, word flags, char align = 'l', - int size = -1, int dec = -1): + int size = -1, int dec = -1): _fld (20) { tag (1); @@ -152,9 +154,9 @@ void TPrint_application::_reset_tree(link_item * head) if (head) { if (head->_brother) - _reset_tree (head->_brother); + _reset_tree (head->_brother); if (head->_son) - _reset_tree (head->_son); + _reset_tree (head->_son); delete head; } } @@ -163,20 +165,20 @@ void TPrint_application::_reset_tree(link_item * head) // // @rdesc Ritorna il nodo a cui agganciarsi link_item *TPrint_application::_look_print_node ( - link_item * head, // @parm Nodo per cui effettuare la ricerca - int logicnum) // @parm Numero logico del file + link_item * head, // @parm Nodo per cui effettuare la ricerca + int logicnum) // @parm Numero logico del file // @comm E' necessario che non esistano piu' nodi per lo stesso file/alias, altrimenti la -// la ricerca termina alla proma occorrenza incontrata +// la ricerca termina alla proma occorrenza incontrata { link_item *s; while (head) { if (head->_logicnum == logicnum) - return head; + return head; else if (head->_son) - if ((s = _look_print_node (head->_son, logicnum)) != NULL) - return s; + if ((s = _look_print_node (head->_son, logicnum)) != NULL) + return s; head = head->_brother; } return NULL; @@ -187,11 +189,11 @@ link_item *TPrint_application::_look_print_node ( // @rdesc Ritorna il numero identificatore il segnalibro creato int TPrint_application::set_bookmark( const char* txt, // @parm Testo del segnalibro - int father) // @parm Identificatore del segnalibro padre (default -1) + int father) // @parm Identificatore del segnalibro padre (default -1) // @comm L'aggiunta dei segnalibri causa la comparsa del menu 'Indice' nella viswin, -// con la lista dei segnalibri inseriti; questi possono essere legati ad albero n-ario -// specificando il bookmark padre, in tal caso il menu sara' gerarchico a sua volta. +// con la lista dei segnalibri inseriti; questi possono essere legati ad albero n-ario +// specificando il bookmark padre, in tal caso il menu sara' gerarchico a sua volta. // Nella prossima release di XVT il menu indice sara' pop-up nella finestra { @@ -205,9 +207,9 @@ void TPrint_application::add_file (const char *tab, int from) // @mfunc Aggiunge un file del cursore nell'albero di stampa void TPrint_application::add_file ( - int file, // @parm Numero logico del file da aggiungere - int from) // @parm Posizione nell'albero di stampa nel quale aggiungere il file - // @parm const char* | tab | Nome del del file da aggiungere + int file, // @parm Numero logico del file da aggiungere + int from) // @parm Posizione nell'albero di stampa nel quale aggiungere il file + // @parm const char* | tab | Nome del del file da aggiungere // @syntax add_file(int file, int from = 0); // @syntax add_file(const char* tab, int from = 0); @@ -231,7 +233,7 @@ void TPrint_application::add_file ( { fr = fr->_son; while (fr->_brother) - fr = fr->_brother; + fr = fr->_brother; fr->_brother = nw; } else @@ -267,9 +269,9 @@ int TPrint_application::find_link( // // @rdesc Ritorna l'ID del link ipertestuale di cui sono stati abilitati i colori int TPrint_application::enable_link( - const char *descr, // @parm Testo del link da abilitare - char fg, // @parm Colore del carattere - char bg) // @parm Colore dello sfondo (default 'w') + const char *descr, // @parm Testo del link da abilitare + char fg, // @parm Colore del carattere + char bg) // @parm Colore dello sfondo (default 'w') // @comm Quando si vogliono abilitare determinati colori come indicatori di legame ipertestuale, // si faccia enable_link nella create. L' ID ritornato viene passato a process_link @@ -300,20 +302,20 @@ void TPrint_application::disable_link (char fg, char bg) const char f = *(t.get(1)); const char b = *(t.get()); if (f == fg && b == bg) - { + { printer().links().remove(i, TRUE); - break; - } + break; + } } } // @mfunc Abilita/disabilita pił link per la void TPrint_application::set_multiple_link ( - bool on) // @parm Indica se effettuare il link con tutti gli elementi selezioanti della riga + bool on) // @parm Indica se effettuare il link con tutti gli elementi selezioanti della riga // @comm Se si setta

a TRUE anziche' la descrizione del testo selezionato -// viene passata a una tokenstring con tutti i -// 'bottoni' dello stesso colore presenti sulla riga. +// viene passata a una tokenstring con tutti i +// 'bottoni' dello stesso colore presenti sulla riga. { printer().setmultiplelink (on); @@ -347,34 +349,34 @@ void TPrint_application::_pp_footer (TPrinter &) for (int i = 0; i <= ii; i++) if (prapp._footer.objptr(i) != NULL) printer().setfooterline (i, - new TPrintrow ((TPrintrow &) (prapp._footer)[i])); + new TPrintrow ((TPrintrow &) (prapp._footer)[i])); } // @mfunc Permette di stampare sullo sfondo e per variarne gli attributi void TPrint_application::set_background ( - const char *bgdesc) // @parm Stringa contente i codici per la stampa (vedi descrizione) + const char *bgdesc) // @parm Stringa contente i codici per la stampa (vedi descrizione) // @comm Occorre passare una stringa che contiene codici per stampare box, linee, bitmap -// sullo sfondo, e per variarne gli attributi: se NULL lo azzera. -// Il background e' stampato sia su che su stampante, e riguarda -// una PAGINA fisica e non le righe o le "pages" relative al cursore; +// sullo sfondo, e per variarne gli attributi: se NULL lo azzera. +// Il background e' stampato sia su che su stampante, e riguarda +// una PAGINA fisica e non le righe o le "pages" relative al cursore; // viene replicato ad ogni nuova pagina fisica a meno che non venga cancellato // o ridefinito in una qualcosaprocessqualcos'altro(). // CODICI BACKGROUND -// Una stringa con n codici, opzionalmente separati da spazi o tab +// Una stringa con n codici, opzionalmente separati da spazi o tab // SETTINGS -// @flag Pn | Setta pen style (n = codice XVT) -// @flag Bn | Setta brush style (idem) -// @flag Wn | Altezza della linea in pixel -// @flag Cn | Colore della penna (codice colore solito) +// @flag Pn | Setta pen style (n = codice XVT) +// @flag Bn | Setta brush style (idem) +// @flag Wn | Altezza della linea in pixel +// @flag Cn | Colore della penna (codice colore solito) // @comm DRAWING COMMANDS -// @flag i{string,x1,y1,x2,y2} | Disegna la bitmap

(nome file) alle coordinate indicate +// @flag i{string,x1,y1,x2,y2} | Disegna la bitmap

(nome file) alle coordinate indicate // @flag l{x1,y1,x2,y2} | Linea da/a (la resa delle oblique dipende dalla stampante) -// @flag b{x1,y1,x2,y2} | Box -// @flag r{x1,y1,x2,y2} | Rounded box -// @flag t{text,x,y} | Testo text a

,

+// @flag b{x1,y1,x2,y2} | Box +// @flag r{x1,y1,x2,y2} | Rounded box +// @flag t{text,x,y} | Testo text a

,

{ printer().setbackground (bgdesc); @@ -421,16 +423,16 @@ TString& fill_str (TString & t, char f) for (int kk = t.len () - 1; kk >= 0; kk--) { if (t[kk] == ' ') - t[kk] = f; + t[kk] = f; else - break; + break; } for (kk = 0; kk < t.len (); kk++) { if (t[kk] == ' ') - t[kk] = f; + t[kk] = f; else - break; + break; } return t; } @@ -464,11 +466,11 @@ TCursor* TPrint_application::get_cursor (int c) // // @rdesc Ritorna l'identificatore del cursore aggiunto int TPrint_application::add_cursor ( - TCursor * c) // @parm Cursore da aggiungere all'albero + TCursor * c) // @parm Cursore da aggiungere all'albero // @comm Nel caso sia passato NULL a

non viene utilizzato nessun file, ma la -// viene chaiamta e le iterazione sono valoutate da -// pre_ e post_ process. +// viene chaiamta e le iterazione sono valoutate da +// pre_ e post_ process. { if (c == NULL) @@ -486,10 +488,10 @@ void TPrint_application::reset_row (int r) { _Token *t = (_Token *) (_rows.objptr (j)); if (t) - { - if (t->row () == r) - _rows.add (NULL, j); - } + { + if (t->row () == r) + _rows.add (NULL, j); + } } _rows.pack (); if (_maxrow == r && _maxrow > 0) @@ -505,9 +507,9 @@ void TPrint_application::reset_print () // @mfunc Permette di definire l'header della stampa void TPrint_application::set_header ( - int r, // @parm Numero della riga nella quale stampare l'header - const char *fmt, // @parm Testo dell'header da stampare - ...) // @parmvar Uno o piu' parametri corrispondenti ai codici in

+ int r, // @parm Numero della riga nella quale stampare l'header + const char *fmt, // @parm Testo dell'header da stampare + ...) // @parmvar Uno o piu' parametri corrispondenti ai codici in

{ CHECK (r >= 1, "Header rows start at 1"); @@ -527,9 +529,9 @@ void TPrint_application::set_header ( // @mfunc Permette di definire il footer della stampa void TPrint_application::set_footer ( - int r, // @parm Numero della riga nella quale stampare il footer - const char *fmt, // @parm Testo del footer da stampare - ...) // @parmvar Uno o piu' parametri corrispondenti ai codici in

+ int r, // @parm Numero della riga nella quale stampare il footer + const char *fmt, // @parm Testo del footer da stampare + ...) // @parmvar Uno o piu' parametri corrispondenti ai codici in

{ CHECK (r >= 1, "Footer rows start at 1"); @@ -582,9 +584,9 @@ void TPrint_application::merge_export_file(const char* file, bool header, bool d // @mfunc Permette di settare una riga di stampa void TPrint_application::set_row ( - int r, // @parm Numero della riga da settare - const char *frmt, // @parm Contenuto della riga da stampare - ...) // @parmvar Uno o piu' parametri corrispondenti ai codici in

+ int r, // @parm Numero della riga da settare + const char *frmt, // @parm Contenuto della riga da stampare + ...) // @parmvar Uno o piu' parametri corrispondenti ai codici in

// @comm COME SETTARE LE RIGHE DI STAMPA // Questa funzione si usa come una printf per settare le righe di stampa @@ -704,260 +706,266 @@ void TPrint_application::set_row ( while ((ch = *fmt++) != '\0') { if (ch == '@') - { - // check for pending string - if (strind) - { - strbuf[strind] = '\0'; - _rows.add (new _PrintfTok (_currow, strbuf)); - strind = 0; - } - ch = *fmt++; - if (isdigit (ch)) - { - int i = 0; - digbuf[i++] = ch; + { + // check for pending string + if (strind) + { + strbuf[strind] = '\0'; + _rows.add (new _PrintfTok (_currow, strbuf)); + strind = 0; + } + ch = *fmt++; + if (isdigit (ch)) + { + int i = 0; + digbuf[i++] = ch; while (isdigit (ch = *fmt++)) - digbuf[i++] = ch; - digbuf[i] = '\0'; - size = atoi (digbuf); - flags |= PAD_FLAG; - if (ch == '.') - { - // decimal size follows - i = 0; - digbuf[i++] = ch; - while (isdigit (ch = *fmt++)) - digbuf[i] = ch; - digbuf[i] = '\0'; - dec = atoi (digbuf); - flags |= DEC_FLAG; - // ch = *fmt++; - } - else if (ch == ',') - { - // aligment spec follows - align = (ch = *fmt++); - CHECK (ch == 'l' || ch == 'r' || ch == 'c', - "TPrint_application::set_row: invalid alignment spec"); - flags |= ALIGN_FLAG; - ch = *fmt++; - } - } - switch (ch) - { - // modifiers - case 'l': - case 'L': - flags |= LONG_FLAG; - ch = *fmt++; - break; - case 'p': - case 'P': - flags |= PICTURE_FLAG; - ch = *fmt++; - break; - } - switch (ch) - { - // codes - case '@': - _rows.add (new _PrintfTok (_currow, "@")); - break; - case 'b': - case 'i': - case 'u': + digbuf[i++] = ch; + digbuf[i] = '\0'; + size = atoi (digbuf); + flags |= PAD_FLAG; + if (ch == '.') + { + // decimal size follows + i = 0; + digbuf[i++] = ch; + while (isdigit (ch = *fmt++)) + digbuf[i] = ch; + digbuf[i] = '\0'; + dec = atoi (digbuf); + flags |= DEC_FLAG; + // ch = *fmt++; + } + else if (ch == ',') + { + // aligment spec follows + align = (ch = *fmt++); + CHECK (ch == 'l' || ch == 'r' || ch == 'c', + "TPrint_application::set_row: invalid alignment spec"); + flags |= ALIGN_FLAG; + ch = *fmt++; + } + } + switch (ch) + { + // modifiers + case 'l': + case 'L': + flags |= LONG_FLAG; + ch = *fmt++; + break; + case 'p': + case 'P': + flags |= PICTURE_FLAG; + ch = *fmt++; + break; + } + switch (ch) + { + // codes + case '@': + _rows.add (new _PrintfTok (_currow, "@")); + break; + case 'b': + case 'i': + case 'u': case 'r': - { - char *xxxx = new char[2]; - xxxx[0] = ch; - xxxx[1] = '\0'; - _rows.add (new _FieldTok (_currow, xxxx, FONT_FLAG)); - } - break; - case 'g': - case 'j': - { - const char *xxx = format ("%c %d", ch, size); - char *xxxx = new char[strlen (xxx) + 1]; - strcpy (xxxx, xxx); - _rows.add (new _FieldTok (_currow, xxxx, JUMP_FLAG)); - } - break; - case 'T': - flags |= IGNORE_FILL; - case 't': - flags |= TRANS_FLAG; - break; + { + char *xxxx = new char[2]; + xxxx[0] = ch; + xxxx[1] = '\0'; + _rows.add (new _FieldTok (_currow, xxxx, FONT_FLAG)); + } + break; + case 'g': + case 'j': + { + const char *xxx = format ("%c %d", ch, size); + char *xxxx = new char[strlen (xxx) + 1]; + strcpy (xxxx, xxx); + _rows.add (new _FieldTok (_currow, xxxx, JUMP_FLAG)); + } + break; + case 'T': + flags |= IGNORE_FILL; + case 't': + flags |= TRANS_FLAG; + break; case 'D': - flags |= IGNORE_FILL; - case 'd': - flags |= DATE_FLAG; - break; - case 'F': - flags |= IGNORE_FILL; - case 'f': - flags |= BOOLEAN_FLAG; - break; + flags |= IGNORE_FILL; + case 'd': + flags |= DATE_FLAG; + break; + case 'F': + flags |= IGNORE_FILL; + case 'f': + flags |= BOOLEAN_FLAG; + break; case 'S': - flags |= IGNORE_FILL; - case 's': - flags |= STRING_FLAG; - break; - case 'C': - flags |= IGNORE_FILL; - case 'c': - flags |= RECNO_FLAG; - break; - case 'N': - flags |= IGNORE_FILL; - case 'n': - flags |= NUMBER_FLAG; - break; - default: - CHECK (0, "TPrint_application::set_row: invalid @ code"); - break; - } - if (flags & NUMBER_FLAG || - flags & DATE_FLAG || - flags & TRANS_FLAG || - flags & BOOLEAN_FLAG || - flags & STRING_FLAG) - { - char *xxx = va_arg (params, char *); - _rows.add (new _FieldTok (_currow, xxx, - flags, align, size, dec)); - } - flags = 0x0000; - align = 'l'; - } + flags |= IGNORE_FILL; + case 's': + flags |= STRING_FLAG; + break; + case 'C': + flags |= IGNORE_FILL; + case 'c': + flags |= RECNO_FLAG; + break; + case 'N': + flags |= IGNORE_FILL; + case 'n': + flags |= NUMBER_FLAG; + break; + default: + CHECK (0, "TPrint_application::set_row: invalid @ code"); + break; + } + if (flags & NUMBER_FLAG || + flags & DATE_FLAG || + flags & TRANS_FLAG || + flags & BOOLEAN_FLAG || + flags & STRING_FLAG) + { + char *xxx = va_arg (params, char *); + _rows.add (new _FieldTok (_currow, xxx, + flags, align, size, dec)); + } + flags = 0x0000; + align = 'l'; + } else - { - TString t; - switch (ch) - { - case '#': - case '%': - { - char ccc = ch; - // check for pending string - if (strind) - { - strbuf[strind] = '\0'; - _rows.add (new _PrintfTok (_currow, strbuf)); - strind = 0; - } - if ((ch = *fmt++) == ccc) - _rows.add (new _PrintfTok (_currow, ccc == '%' ? "%" : "#")); - else - { - // read format - t << ccc; - bool islong = FALSE; - while (strchr (printf_types, ch) == NULL) - { - t << ch; - if (ch == 'l') - islong = TRUE; - ch = *fmt++; - if (ch == '\0') - fatal_box ("sorry, zer's samzing vruong" - " uitz ioar format."); - } - if (isupper (ch)) - { - ch = tolower (ch); - fill = ' '; - } - if (ch == 't' || ch == 'a') - t << 's'; - else if (ch == 'r') - t << 't'; - else - t << ch; - if (ccc == '%') - { - TString q (60); - switch (ch) - { - case 'd': - case 'i': - case 'u': - case 'o': - case 'x': - case 'X': - q.format (t, islong ? va_arg (params, long) : - va_arg (params, int)); - break; - case 'f': - case 'e': - case 'E': - case 'G': - q.format (t, islong ? va_arg (params, double) : - va_arg (params, float)); - break; - case 'c': - q.format (t, va_arg (params, char)); - break; - case 's': - q.format (t, va_arg (params, char *)); - break; - case 't': // TString + { + TString t; + switch (ch) + { + case '#': + case '%': + { + char ccc = ch; + // check for pending string + if (strind) + { + strbuf[strind] = '\0'; + _rows.add (new _PrintfTok (_currow, strbuf)); + strind = 0; + } + if ((ch = *fmt++) == ccc) + _rows.add (new _PrintfTok (_currow, ccc == '%' ? "%" : "#")); + else + { + // read format + t << ccc; + bool islong = FALSE; + while (strchr (printf_types, ch) == NULL) + { + t << ch; + if (ch == 'l') + islong = TRUE; + ch = *fmt++; + if (ch == '\0') + fatal_box ("sorry, zer's samzing vruong" + " uitz ioar format."); + } + if (isupper (ch)) + { + ch = tolower (ch); + fill = ' '; + } + if (ch == 't' || ch == 'a') + t << 's'; + else if (ch == 'r') +#ifdef __LONGDOUBLE + t << "Lf"; +#else + t << 't'; +#endif + else + t << ch; + if (ccc == '%') + { + TString q (60); + switch (ch) + { + case 'd': + case 'i': + case 'u': + case 'o': + case 'x': + case 'X': + q.format (t, islong ? va_arg (params, long) : + va_arg (params, int)); + break; + case 'f': + case 'e': + case 'E': + case 'G': + q.format (t, islong ? va_arg (params, double) : + va_arg (params, float)); + break; + case 'c': + q.format (t, va_arg (params, char)); + break; + case 's': + q.format (t, va_arg (params, char *)); + break; + case 't': // TString - q.format (t, (const char *) - (TString) * ((va_arg (params, TString *)))); - break; - case 'a': // TParagraph_string + q.format (t, (const char *) + (TString) * ((va_arg (params, TString *)))); + break; + case 'a': // TParagraph_string - q.format (t, (const char *) - (TParagraph_string) * ((va_arg (params, TParagraph_string *)))); - break; - case 'r': // Real + q.format (t, (const char *) + (TParagraph_string) * ((va_arg (params, TParagraph_string *)))); + break; + case 'r': // Real - { - real *rrr = va_arg (params, real *); - if (t.len () == 2 && *_picture) - { - // no format specifications - // use default picture - q = rrr->string(_picture); - } - else - { - char *fff = (char *) ((const char *) t); - // dsprintf(__tmp_string, fff, - // (DEC*)(*rrr)); - dsprintf (__tmp_string, fff, rrr->ptr ()); - q = __tmp_string; - } - if (rrr->is_zero () && !_print_zero) - q.fill (' '); - } - break; - default: - break; - } - if (fill != ' ') - q = fill_str (q, fill); - fill = _fillchar; - _rows.add (new _PrintfTok (_currow, q)); - } - else - _rows.add (new _PrintfRef (_currow, t, ch, - va_arg (params, void *))); - } - } - break; - case '\n': // ignore - break; - default: - // add to string - strbuf[strind++] = ch; - if (!ch) - fmt--; - break; - } - } + { + const real& rrr = * va_arg (params, real *); + if (t.len () == 2 && *_picture) + { + // no format specifications + // use default picture + q = rrr.string(_picture); + } + else + { +#ifdef __LONGDOUBLE__ + sprintf (__tmp_string, t, (long double)rrr); +#else + char *fff = (char*)(const char *)t; + dsprintf (__tmp_string, fff, rrr.ptr()); +#endif + q = __tmp_string; + } + if (rrr.is_zero () && !_print_zero) + q.fill (' '); + } + break; + default: + break; + } + if (fill != ' ') + q = fill_str (q, fill); + fill = _fillchar; + _rows.add (new _PrintfTok (_currow, q)); + } + else + _rows.add (new _PrintfRef (_currow, t, ch, + va_arg (params, void *))); + } + } + break; + case '\n': // ignore + break; + default: + // add to string + strbuf[strind++] = ch; + if (!ch) + fmt--; + break; + } + } } if (strind) { @@ -970,16 +978,16 @@ void TPrint_application::set_row ( // @mfunc Setta i valori di traduzione dei campi void TPrint_application::set_translation ( - int lognum, // @parm Numero logido del file condenete il campo da tradurre - const char *field, // @parm Campo di cui effettuare la straduzione - const char *from, // @parm Valore da tradurre - const char *to) // @parm Valore che assume il campo + int lognum, // @parm Numero logido del file condenete il campo da tradurre + const char *field, // @parm Campo di cui effettuare la straduzione + const char *from, // @parm Valore da tradurre + const char *to) // @parm Valore che assume il campo // @comm Questa funzione occorre che sia chiamata per ogni traduzione da effettuare. -// Esempio: set_translation(12,"STATOCIV","1","Celibe") provoca la stampa -// automatica di stringhe al posto di determinati valori dei campi se e' dato -// il codice @t. -// Il posto giusto per chiamarla e' nella . +// Esempio: set_translation(12,"STATOCIV","1","Celibe") provoca la stampa +// automatica di stringhe al posto di determinati valori dei campi se e' dato +// il codice @t. +// Il posto giusto per chiamarla e' nella . { _transtab.add (new _Transfield (lognum, field, from, to)); } @@ -1008,50 +1016,50 @@ void TPrint_application::print() { //************************************************ while (nc--) - { - - int cnt = 0; - bool ok = TRUE; - do - { - if (preprocess_print (0, cnt)) - { - int cnt2 = 0; - do - { - if (preprocess_page (0, cnt2)) - { - set_page (0, cnt2); - ok = print_one (0); - } - } - while (ok && postprocess_page (0, cnt2++) == REPEAT_PAGE); - } - } - while (ok && postprocess_print (0, cnt++) == REPEAT_PAGE); - // ***************************************************** - } + { + + int cnt = 0; + bool ok = TRUE; + do + { + if (preprocess_print (0, cnt)) + { + int cnt2 = 0; + do + { + if (preprocess_page (0, cnt2)) + { + set_page (0, cnt2); + ok = print_one (0); + } + } + while (ok && postprocess_page (0, cnt2++) == REPEAT_PAGE); + } + } + while (ok && postprocess_print (0, cnt++) == REPEAT_PAGE); + // ***************************************************** + } } else { // cursor exists ********************************************* while (nc--) - { - (*_cur) = 0l; - _cur->freeze (TRUE); - - if (_cur->items () >= _wthr && - (_force_progind || printer ().printtype () != screenvis)) - _prind = new TProgind (_cur->items (), _wmess, _wcancel, _wbar, 35); - print_tree (_pr_tree); - _cur->freeze (FALSE); - - if (_prind) - { - delete _prind;; - _prind = NULL; - } - } + { + (*_cur) = 0l; + _cur->freeze (TRUE); + + if (_cur->items () >= _wthr && + (_force_progind || printer ().printtype () != screenvis)) + _prind = new TProgind (_cur->items (), _wmess, _wcancel, _wbar, 35); + print_tree (_pr_tree); + _cur->freeze (FALSE); + + if (_prind) + { + delete _prind;; + _prind = NULL; + } + } // **************************************************************** } if (!_repeat_print) @@ -1065,7 +1073,7 @@ void TPrint_application::print() postclose_print (); } else - printer().formfeed(); + printer().formfeed(); } bool TPrint_application::print_tree (link_item * head) @@ -1075,38 +1083,38 @@ bool TPrint_application::print_tree (link_item * head) { head->_cnt = 0; if (_cur->is_first_match (head->_logicnum)) - { - do - { - if (!preprocess_print (head->_logicnum, head->_cnt)) - break; - do - { - // set print rows according to current file - if (_force_setpage || _cur_file != head->_logicnum - || !_print_defined) - { - reset_print (); - set_page(head->_logicnum, head->_cnt); - _cur_file = head->_logicnum; - } - int cnt2 = 0; - do - { - if (!preprocess_page (head->_logicnum, cnt2)) - break; - go = print_one (head->_logicnum); - if (go && head->_son) - go = print_tree (head->_son); - } - while (go && postprocess_page (head->_logicnum, cnt2++) == - REPEAT_PAGE); - } - while (go && _cur->next_match (head->_logicnum)); - } - while (go && postprocess_print (head->_logicnum, head->_cnt++) - == REPEAT_PAGE); - } + { + do + { + if (!preprocess_print (head->_logicnum, head->_cnt)) + break; + do + { + // set print rows according to current file + if (_force_setpage || _cur_file != head->_logicnum + || !_print_defined) + { + reset_print (); + set_page(head->_logicnum, head->_cnt); + _cur_file = head->_logicnum; + } + int cnt2 = 0; + do + { + if (!preprocess_page (head->_logicnum, cnt2)) + break; + go = print_one (head->_logicnum); + if (go && head->_son) + go = print_tree (head->_son); + } + while (go && postprocess_page (head->_logicnum, cnt2++) == + REPEAT_PAGE); + } + while (go && _cur->next_match (head->_logicnum)); + } + while (go && postprocess_print (head->_logicnum, head->_cnt++) + == REPEAT_PAGE); + } if (!go) break; go = TRUE; @@ -1151,285 +1159,287 @@ bool TPrint_application::print_one ( for (i = 0; i <= _maxrow; i++) for (int j = 0; j < _rows.items (); j++) { - _Token *t = (_Token *) & (_rows[j]); - if (!t) - continue; // should not happen + _Token *t = (_Token *) & (_rows[j]); + if (!t) + continue; // should not happen - if (t->row () == i) - { - char pic[36], fn[17]; - int ch, ln, from, to; + if (t->row () == i) + { + char pic[36], fn[17]; + int ch, ln, from, to; - if (t->tag () == 1) - { - // it's a _FieldTok - _FieldTok *ft = (_FieldTok *) t; - TString toprint; - from = to = -1; + if (t->tag () == 1) + { + // it's a _FieldTok + _FieldTok *ft = (_FieldTok *) t; + TString toprint; + from = to = -1; - if (ft->_flags & FONT_FLAG) - { - TPrintstyle st = normalstyle; - switch (((const char *) (ft->_fld))[0]) - { - case 'u': - st = underlinedstyle; - break; - case 'b': - st = boldstyle; - break; - case 'i': - st = italicstyle; - break; - case 'r': - st = normalstyle; - break; - } - ((TPrintrow *) (&rw[ft->row ()]))->set_style (st); - } - else if (ft->_flags & JUMP_FLAG) - { - char ch; - int p; + if (ft->_flags & FONT_FLAG) + { + TPrintstyle st = normalstyle; + switch (((const char *) (ft->_fld))[0]) + { + case 'u': + st = underlinedstyle; + break; + case 'b': + st = boldstyle; + break; + case 'i': + st = italicstyle; + break; + case 'r': + st = normalstyle; + break; + } + ((TPrintrow *) (&rw[ft->row ()]))->set_style (st); + } + else if (ft->_flags & JUMP_FLAG) + { + char ch; + int p; - ch = ft->_fld[0]; - p = atoi (((const char *) ft->_fld) + 2); - if (ch == 'g') - // go to - pos[ft->row ()] = p; - else - // jump ahead - pos[ft->row ()] = - ((TPrintrow *) (&rw[ft->row ()]))-> - lastpos () + p; - } - else - { - if ((*(const char *) (ft->_fld)) == 'p') - { - // picture - TToken_string ttt (ft->_fld, '|'); - ch = (ttt.get ())[0]; - ln = atoi ((const char *) ttt.get ()); - strcpy (fn, (const char *) ttt.get ()); - strcpy (pic, (const char *) ttt.get ()); - } - else - { - TToken_string ttt (ft->_fld, '|'); - ch = (ttt.get ())[0]; - ln = atoi ((const char *) ttt.get ()); - strcpy (fn, (const char *) ttt.get ()); - from = atoi ((const char *) ttt.get ()); - to = atoi ((const char *) ttt.get ()); - } - // get field val - TLocalisamfile &f = _cur->file(ln); - if (ft->_flags & TRANS_FLAG) - { - _Transfield *tr = NULL; - // look up field value in translation table - for (int i = 0; i < _transtab.items (); i++) - { - tr = (_Transfield *) & _transtab[i]; - if (tr->_fn == fn && tr->_lognum == ln) - { - // check value - if (tr->_from == f.get (fn)) - break; - } - } - if (i == _transtab.items ()) - toprint = ""; - else - toprint = tr->_to; - } - else if (ft->_flags & DATE_FLAG) - { - const TDate d(f.get(fn)); - toprint = d.string (ft->_flags & LONG_FLAG ? full : brief); - if (toprint.empty ()) - { - toprint = (ft->_flags & LONG_FLAG ? - " - - " : - " - - "); - } - } - else if (ft->_flags & BOOLEAN_FLAG) - { - toprint = f.get(fn) == "X" ? "Si" : "No"; - } - else if (ft->_flags & NUMBER_FLAG) - { - TString pict (0); - real r(f.get (fn)); + ch = ft->_fld[0]; + p = atoi (((const char *) ft->_fld) + 2); + if (ch == 'g') + // go to + pos[ft->row ()] = p; + else + // jump ahead + pos[ft->row ()] = + ((TPrintrow *) (&rw[ft->row ()]))-> + lastpos () + p; + } + else + { + if ((*(const char *) (ft->_fld)) == 'p') + { + // picture + TToken_string ttt (ft->_fld, '|'); + ch = (ttt.get ())[0]; + ln = atoi ((const char *) ttt.get ()); + strcpy (fn, (const char *) ttt.get ()); + strcpy (pic, (const char *) ttt.get ()); + } + else + { + TToken_string ttt (ft->_fld, '|'); + ch = (ttt.get ())[0]; + ln = atoi ((const char *) ttt.get ()); + strcpy (fn, (const char *) ttt.get ()); + from = atoi ((const char *) ttt.get ()); + to = atoi ((const char *) ttt.get ()); + } + // get field val + TLocalisamfile &f = _cur->file(ln); + if (ft->_flags & TRANS_FLAG) + { + _Transfield *tr = NULL; + // look up field value in translation table + for (int i = 0; i < _transtab.items (); i++) + { + tr = (_Transfield *) & _transtab[i]; + if (tr->_fn == fn && tr->_lognum == ln) + { + // check value + if (tr->_from == f.get (fn)) + break; + } + } + if (i == _transtab.items ()) + toprint = ""; + else + toprint = tr->_to; + } + else if (ft->_flags & DATE_FLAG) + { + const TDate d(f.get(fn)); + toprint = d.string (ft->_flags & LONG_FLAG ? full : brief); + if (toprint.empty ()) + { + toprint = (ft->_flags & LONG_FLAG ? + " - - " : + " - - "); + } + } + else if (ft->_flags & BOOLEAN_FLAG) + { + toprint = f.get(fn) == "X" ? "Si" : "No"; + } + else if (ft->_flags & NUMBER_FLAG) + { + TString pict (0); + real r(f.get (fn)); - bool isreal = f.curr ().type (fn) == _realfld; + bool isreal = f.curr ().type (fn) == _realfld; - if (ft->_flags & PICTURE_FLAG) - pict = pic; - else if (!(ft->_flags & DEC_FLAG) && *_picture - && isreal) - pict = _picture; + if (ft->_flags & PICTURE_FLAG) + pict = pic; + else if (!(ft->_flags & DEC_FLAG) && *_picture + && isreal) + pict = _picture; - if (pict.len () > 0) - toprint = r.string (pict); - else if (ft->_flags & DEC_FLAG) - toprint = r.string (ft->_size, ft->_dec); - else - toprint = r.string (); + if (pict.len () > 0) + toprint = r.string (pict); + else if (ft->_flags & DEC_FLAG) + toprint = r.string (ft->_size, ft->_dec); + else + toprint = r.string (); - if (r.is_zero () && !_print_zero) - toprint.fill (' '); - } - else if (ft->_flags & STRING_FLAG) - { - toprint = f.curr().get (fn); - // perform string extraction - if (from != -1) - toprint = toprint.sub (from, to); - else if (to != -1) - toprint = toprint.left (to); - } - } - // adjust size and set fill char - if (ft->_flags & PAD_FLAG) - { - if (!(ft->_flags & NUMBER_FLAG)) - { - if (ft->_size < toprint.len ()) - toprint.cut (ft->_size); - else - toprint.left_just (ft->_size); - } - if (ft->_flags & ALIGN_FLAG) - { - if (ft->_align == 'r') - toprint.right_just (ft->_size); - else if (ft->_align == 'c') - toprint.center_just (ft->_size); - else if (ft->_align == 'l') - toprint.left_just (ft->_size); - } - } - if (_fillchar != ' ' && !(ft->_flags & IGNORE_FILL)) - toprint = fill_str (toprint, _fillchar); - // add to print row - ((TPrintrow *) (&rw[ft->row ()]))->put (toprint, - pos[ft->row ()]); - if (pos[ft->row ()] != -1) - pos[ft->row ()] += toprint.len (); - } + if (r.is_zero () && !_print_zero) + toprint.fill (' '); + } + else if (ft->_flags & STRING_FLAG) + { + toprint = f.curr().get (fn); + // perform string extraction + if (from != -1) + toprint = toprint.sub (from, to); + else if (to != -1) + toprint = toprint.left (to); + } + } + // adjust size and set fill char + if (ft->_flags & PAD_FLAG) + { + if (!(ft->_flags & NUMBER_FLAG)) + { + if (ft->_size < toprint.len ()) + toprint.cut (ft->_size); + else + toprint.left_just (ft->_size); + } + if (ft->_flags & ALIGN_FLAG) + { + if (ft->_align == 'r') + toprint.right_just (ft->_size); + else if (ft->_align == 'c') + toprint.center_just (ft->_size); + else if (ft->_align == 'l') + toprint.left_just (ft->_size); + } + } + if (_fillchar != ' ' && !(ft->_flags & IGNORE_FILL)) + toprint = fill_str (toprint, _fillchar); + // add to print row + ((TPrintrow *) (&rw[ft->row ()]))->put (toprint, + pos[ft->row ()]); + if (pos[ft->row ()] != -1) + pos[ft->row ()] += toprint.len (); + } - else if (t->tag () == 0) - { - // it's a _PrintfTok - _PrintfTok *pt = (_PrintfTok *) t; - TString v = pt->_val; - ((TPrintrow *) (&rw[pt->row ()]))->put (v, pos[pt->row ()]); - if (pos[pt->row ()] != -1) - { - pos[pt->row ()] += v.len (); - const char* s = v; - while (*s && strncmp(s, "$[", 2) == 0) - { - while (*s && *s != ']') - { - pos[pt->row()]--; - s++; - } - if (*s) - pos[pt->row()]--; - while (*s && *s != '$') s++; - } - } - } - else - if (t->tag () == 2) - { - // printf by reference - _PrintfRef *pr = (_PrintfRef *) t; - TString ps; - TParagraph_string * para_str = NULL; - bool islong = (pr->_fmt).find ('l') != -1; - switch (pr->_type) - { - case 'd': - case 'i': - case 'u': - case 'o': - case 'x': - case 'X': - ps.format (pr->_fmt, islong ? *((long *) (pr->_what)) : - *((int *) (pr->_what))); - break; - case 'f': - case 'e': - ps.format (pr->_fmt, islong ? *((double *) (pr->_what)) : - *((float *) (pr->_what))); - break; - case 'c': - ps.format (pr->_fmt, *((char *) (pr->_what))); - break; - case 's': - ps.format (pr->_fmt, (char *) (pr->_what)); - break; - case 't': - ps.format (pr->_fmt, (const char *) - (*((TString *) (pr->_what)))); - break; - case 'a': - { - para_str = ((TParagraph_string *) (pr->_what)); - const char * s = para_str->get(); - - if (s != NULL) - ps.format (pr->_fmt, s); - break; - } - case 'r': - { - real *rrr = (real *) pr->_what; - if (pr->_fmt.len () == 2 && *_picture) - { - strcpy (__tmp_string, rrr->string (_picture)); - } - else - { - char *fff = (char *) ((const char *) pr->_fmt); - dsprintf (__tmp_string, fff, - // (DEC*)*((real*)(pr->_what))); - ((real *) pr->_what)->ptr ()); - } - ps = __tmp_string; - if (rrr->is_zero () && !_print_zero) - ps.fill (' '); - break; - } - } + else if (t->tag () == 0) + { + // it's a _PrintfTok + _PrintfTok *pt = (_PrintfTok *) t; + TString v = pt->_val; + ((TPrintrow *) (&rw[pt->row ()]))->put (v, pos[pt->row ()]); + if (pos[pt->row ()] != -1) + { + pos[pt->row ()] += v.len (); + const char* s = v; + while (*s && strncmp(s, "$[", 2) == 0) + { + while (*s && *s != ']') + { + pos[pt->row()]--; + s++; + } + if (*s) + pos[pt->row()]--; + while (*s && *s != '$') s++; + } + } + } + else + if (t->tag () == 2) + { + // printf by reference + _PrintfRef *pr = (_PrintfRef *) t; + TString ps; + TParagraph_string * para_str = NULL; + bool islong = (pr->_fmt).find ('l') != -1; + switch (pr->_type) + { + case 'd': + case 'i': + case 'u': + case 'o': + case 'x': + case 'X': + ps.format (pr->_fmt, islong ? *((long *) (pr->_what)) : + *((int *) (pr->_what))); + break; + case 'f': + case 'e': + ps.format (pr->_fmt, islong ? *((double *) (pr->_what)) : + *((float *) (pr->_what))); + break; + case 'c': + ps.format (pr->_fmt, *((char *) (pr->_what))); + break; + case 's': + ps.format (pr->_fmt, (char *) (pr->_what)); + break; + case 't': + ps.format (pr->_fmt, (const char *) + (*((TString *) (pr->_what)))); + break; + case 'a': + { + para_str = ((TParagraph_string *) (pr->_what)); + const char * s = para_str->get(); + + if (s != NULL) + ps.format (pr->_fmt, s); + break; + } + case 'r': + { + const real& rrr = *(real*)pr->_what; + if (pr->_fmt.len () == 2 && *_picture) + { + strcpy (__tmp_string, rrr.string (_picture)); + } + else + { + const char* fff = pr->_fmt; +#ifdef __LONGDOUBLE__ + sprintf(__tmp_string, fff, (long double)rrr); +#else + dsprintf(__tmp_string, (char*)fff, rrr.ptr()); +#endif + } + ps = __tmp_string; + if (rrr.is_zero () && !_print_zero) + ps.fill (' '); + break; + } + } - ps = fill_str (ps, _fillchar); - ((TPrintrow *) (&rw[pr->row ()]))->put (ps, pos[pr->row ()]); - if (para_str != NULL) - { - const char * s = para_str->get(); - int row = pr->row(); - - while (s != NULL) - { - ps.format (pr->_fmt, s); - ps = fill_str (ps, _fillchar); - row++; - if (rw.objptr(row) == NULL) - rw.add(new TPrintrow ()); - ((TPrintrow *) (&rw[row]))->put(ps, pos[pr->row()]); - s = para_str->get(); - } - } - if (pos[pr->row ()] != -1) - pos[pr->row ()] += ps.len (); - } - } + ps = fill_str (ps, _fillchar); + ((TPrintrow *) (&rw[pr->row ()]))->put (ps, pos[pr->row ()]); + if (para_str != NULL) + { + const char * s = para_str->get(); + int row = pr->row(); + + while (s != NULL) + { + ps.format (pr->_fmt, s); + ps = fill_str (ps, _fillchar); + row++; + if (rw.objptr(row) == NULL) + rw.add(new TPrintrow ()); + ((TPrintrow *) (&rw[row]))->put(ps, pos[pr->row()]); + s = para_str->get(); + } + } + if (pos[pr->row ()] != -1) + pos[pr->row ()] += ps.len (); + } + } } // print! @@ -1439,7 +1449,7 @@ bool TPrint_application::print_one ( { TPrintrow *pr = (TPrintrow *) & rw[i]; if (!(printer().print(*pr))) - break; + break; } if (_auto_ff && last /* _maxrox */ < printer().formlen ()) printer().formfeed (); @@ -1471,8 +1481,8 @@ bool TPrint_application::create() printer().setlinkhandler (_pp_link); if (user_create()) { - dispatch_e_menu (_last_choice); - return TRUE; + dispatch_e_menu (_last_choice); + return TRUE; } else return FALSE; } diff --git a/include/real.cpp b/include/real.cpp index c8b896ba5..4faa63a32 100755 --- a/include/real.cpp +++ b/include/real.cpp @@ -1,5 +1,300 @@ #include #include + +#include + +HIDDEN char __string[80]; +const real ZERO (0.0); + +#ifdef __LONGDOUBLE__ + +#include +#include + +// @doc EXTERNAL + +real::real () : _dec(0.0) +{ } + +real::real (const real& b) : _dec(b._dec) +{ } + +real::real (long double a) : _dec(a) +{ } + +bool real::is_real (const char *s) +{ + if (s && *s) + { + const long double n = _atold(s); + if (n == 0.0) + { + for(; *s; s++) if (*s != '0' && *s != ' ' && *s != '.') + return FALSE; + } + } + return TRUE; +} + + +real::real (const char *s) +{ + _dec = (s && *s) ? _atold(s) : 0.0; +} + +real& real::operator = (const real& b) +{ + _dec = b._dec; + return *this; +} + +real& real::operator = (long double b) +{ + _dec = b; + return *this; +} + +real& real::operator += (long double b) +{ + _dec += b; + return *this; +} + +real& real::operator -= (long double b) +{ + _dec -= b; + return *this; +} + +real& real::operator *= (long double b) +{ + _dec *= b; + return *this; +} + +real& real::operator /= (long double b) +{ + _dec /= b; + return *this; +} + +// @mfunc Ritorna il segno del reale +// +// @rdesc Ritorna i seguenti valori: +// +// @flag 0 | Se il numero e' minore di 0 +// @flag = 0 | Se il numero e' uguale a 0 +// @flag 0 | Se il numero e' maggiore di 0 +int real::sign () const +{ + const int s = _dec > 0.0 ? +1 : (_dec < 0.0 ? -1 : 0); + return s; +} + +real real::operator - () const +{ + real n(-_dec); + return n; +} + +long real::integer () const +{ + return (long)floorl(_dec); +} + +// Certified 91% +// @mfunc Trasforma un reale in stringa +// +// @rdesc Ritorna la stringa nella lunghezza richiesta +char *real::string ( + int len, // @parm Lunghezza della stringa (compreso decimali) + int dec, // @parm Numero di decimali (default UNDEFINED) + char pad) const // @parm Carattere di riempimento (default ' ') + // @parm char * | picture | Formato della stringa + + // @syntax string (int len, int dec, char pad); + // @syntax string (const char *picture); + // + // @comm Nel primo caso ritorna una stringa lunga

con

decimali e + // inserisce nella stringa stessa il carattere

nel caso la + // lunghezza richiesta sia maggiore di quella che risulterebbe per la + // completa rappresentazione del reale. + // Nel secondo caso ritorna la stringa con il formato stabilito in + //

. + +{ + if (dec != UNDEFINED) + { + if (len != 0) + sprintf(__string, "%*.*Lf", len, dec, _dec); + else + sprintf(__string, "%.*Lf", dec, _dec); + } + else + { + if (len != 0) + sprintf(__string, "%*Lf", len, _dec); + else + sprintf(__string, "%Lf", _dec); + + if (strchr(__string, '.') != NULL) + { + int cut = strlen (__string); + for (int i = cut-1; i >= 0; i--) + { + if (__string[i] == '0') + cut--; + else + { + if(__string[i] == '.') + cut--; + break; + } + } + __string[cut] = '\0'; + } + } + const int lun = strlen (__string); + if (lun < len) + { + const int delta = len - lun; + for (int i = lun; i >= 0; i--) + __string[i + delta] = __string[i]; + for (i = 0; i < delta; i++) + __string[i] = pad; + } + + return __string; +} + +// @mfunc real& | real | round | Arrotonda al numero di decimali passati +real& real::round ( + int prec) // @parm Numero di decimali a cui arrotondare il numero (default 0) + + // @comm Nel caso

sia: + // + // @flag 0 | Arrotonda al decimale + // @flag = 0 | Arrotonda all'intero + // @flag 0 | Arrotonda al valore passato (es. -3 arrotonda alle mille) +{ + long double p = 1.0; + if (prec != 0) + { + p = powl (10.0, prec); + _dec *= p; + } + _dec = floorl(_dec + 0.5); + if (prec != 0) + _dec /= p; + + return *this; +} + +real& real::ceil (int prec) +{ + long double p = 1.0; + if (prec != 0) + { + p = powl(10.0, prec); + _dec *= p; + } + _dec = ceill(_dec); + if (prec != 0) + _dec /= p; + + return *this; +} + +real& real::trunc(int prec) +{ + long double p = 1.0; + if (prec != 0) + { + p = powl(10.0, prec); + _dec *= p; + } + _dec = floorl(_dec); + if (prec != 0) + _dec /= p; + return *this; +} + + +// @func Scambia il numero reale

con il numero real

+void swap ( + real& a, // @parm Primo numero da scambiare + real& b) // @parm Secondo numero da scambiare + +{ + const real n = a; + a = b; + b = n; +} + +long double operator%(const real& a, const real& b) +{ + const long double times = floorl(a / b); + const long double resto = a - b * times; + return resto; +} + +long double sqrt(long double a) +{ + return sqrtl(a); +} + +long double sqr(long double a) +{ + return a*a; +} + +long double exp10(long double a) +{ + return powl(10.0, a); +} + +long double pow(long double a, long double b) +{ + return powl(a, b); +} + +long double exp(long double a) +{ + return expl(a); +} + +long double log10(long double a) +{ + return log10l(a); +} + +long double log(long double a) +{ + return logl(a); +} + +long double sin(long double a) +{ + return sinl(a); +} + +long double cos(long double a) +{ + return cosl(a); +} + +long double tan(long double a) +{ + return tanl(a); +} + +long double abs(long double a) +{ + return fabsl(a); +} + +#else + #include extern "C" @@ -7,12 +302,8 @@ extern "C" double pow (double, double); } // Should be #include -#include -#include HIDDEN real __tmp_real; -HIDDEN char __string[80]; -const real ZERO (0.0); // @doc EXTERNAL @@ -39,40 +330,6 @@ void real::trail( ) deltrz (ptr (), ptr () ); // Delete Trailing zeroes } -char *real::eng2ita (char *s) -{ - if (s) - { - char *dot = strchr (s, '.'); - if (dot) - *dot = ','; - } - return s; -} - -char *real::ita2eng (const char *s) -{ - int j = 0; - if (s) - for (int i = 0; s[i]; i++) - { - switch (s[i]) - { - case ' ': - case '.': - break; - case ',': - __string[j++] = '.'; - break; - default: - __string[j++] = s[i]; - break; - } - } - __string[j] = '\0'; - return __string; -} - bool real::is_real (const char *s) { bool ok = FALSE; @@ -86,26 +343,6 @@ bool real::is_real (const char *s) return ok; } -bool real::is_natural (const char *s) -{ - bool ok = s && *s != '\0'; - if (ok) - { - while (*s == ' ') - s++; // Remove leading spaces before - - if (*s) - { - while (isdigit(*s)) - s++; - ok = *s == '\0'; - } - else ok = FALSE; - - } - return ok; -} - real::real (const char *s) { if (s) @@ -118,48 +355,48 @@ real::real (const char *s) dzero (ptr ()); } -real & real::operator = (const real & b) +real& real::operator =(const real & b) { dcpy (ptr (), b.ptr ()); return *this; } -real & real::operator = (double a) +real& real::operator =(double a) { const real n (a); operator = (n); return *this; } -real & real::operator += (const real & b) +real& real::operator += (const real & b) { dadd (ptr (), ptr (), b.ptr ()); trail( ); return *this; } -real & real::operator += (double a) +real& real::operator += (double a) { adddfd (ptr (), ptr (), a); trail( ); return *this; } -real & real::operator -= (const real & b) +real& real::operator -= (const real & b) { dsub (ptr (), ptr (), b.ptr ()); trail( ); return *this; } -real & real::operator *= (const real & b) +real& real::operator *= (const real & b) { dmul (ptr (), ptr (), b.ptr ()); trail( ); return *this; } -real & real::operator /= (const real & b) +real& real::operator /= (const real & b) { const DEC *dst = ddiv (ptr (), ptr (), b.ptr ()); @@ -174,11 +411,6 @@ real & real::operator /= (const real & b) return *this; } -TObject *real:: dup () const -{ - return new real (*this); -} - bool real::is_zero () const { return diszero (ptr ()); @@ -252,212 +484,6 @@ char *real::string ( return __string; } -// Certified 99% -char *real ::stringa (int len, int dec, char pad) const - -{ - string (len, dec, pad); - if (dec > 0 || dec == UNDEFINED) - eng2ita (__string); - return __string; -} - -// Certified 75% -char *real ::literals () const -{ - const char *primi20[] = - {"", "uno", "due", "tre", "quattro", - "cinque", "sei", "sette", "otto", - "nove", "dieci", "undici", "dodici", - "tredici", "quattordici", "quindici", "sedici", - "diciassette", "diciotto", "diciannove"}; - const char *decine[] = - {"zero", "dieci", "venti", "trenta", "quaranta", - "cinquanta", "sessanta", "settanta", "ottanta", - "novanta", "cento"}; - const char *uni[] = - {"uno", "mille", "unmilione", "unmiliardo"}; - - const char *potenze[] = - {"", "mila", "milioni", "miliardi"}; - - __tmp_real = *this; - __tmp_real.round (0); - TString80 r (__tmp_real.string (0, 0)); - const bool negativo = r[0] == '-'; - if (negativo) - r.ltrim (1); - - TFixed_string risultato (__string, 80); - risultato.cut (0); - - TString80 centinaia; - - for (int migliaia = 0;; migliaia++) - { - int v = r.len () - 3; - if (v < -2) - break; - - if (v < 0) - v = 0; - const int val = atoi (&r[v]); - r.cut (v); // Elimina ultimi 3 caratteri - - v = val; - if (v >= 100) - { - const int c = v / 100; - if (c > 1) - centinaia = primi20[c]; - else - centinaia.cut(0); - v -= c * 100; - centinaia << "cento"; - } else centinaia.cut(0); - const int d = v / 10; - if (d > 1) - { - centinaia << decine[d]; - v -= d * 10; - } - - if (val > 0) - { - if (v != 1) - { - centinaia << primi20[v] << potenze[migliaia]; - } - else if (val > 1) - { - if (d > 1) - centinaia.cut (centinaia.len() - 1); - centinaia << "un" << (migliaia ? potenze[migliaia] : "o"); - } - else - centinaia = uni[migliaia]; - } - - risultato.insert(centinaia, 0); - } - - if (negativo) - risultato.insert ("meno", 0); - return __string; -} - -// Certified 75% -char *real ::points (int dec) const -{ - const char *str = stringa (0, dec); - const int neg = (*str == '-') ? 1 : 0; - TFixed_string n ((char *) str, 24); - int i; - - int dot = n.find (','); - if (dot < 0) - dot = n.len (); - - if (dec > 0) - { - if (n[dot] == '\0') - n << ','; - const int d = strlen (str + dot + 1); // Decimals already there - - if (d <= dec) - for (i = d; i < dec; i++) - n << '0'; - else - n.cut (dot + dec + 1); - } - - for (i = dot - 3; i > neg; i -= 3) - n.insert (".", i); - - return __string; -} - - -HIDDEN int get_picture_decimals (const TString& picture) -{ - int decimali = 0; - const int virgola = picture.find (','); - if (virgola >= 0) - { - const int len = picture.len (); - for (int i = virgola + 1; i < len; i++) - if (strchr ("#@~", picture[i])) - decimali++; - } - return decimali; -} - - -char *real ::string (const char *picture) - const -{ - if (*picture == '\0') - return string (); - if (*picture == '.') - return points (atoi (picture + 1)); - if (strcmp (picture, "LETTERE") == 0) - return literals (); - - TString80 v (string()); - TString80 f (picture); - - const int voluti = get_picture_decimals (f); - const int virgola = v.find ('.'); - int decimali = (virgola >= 0) ? v.len () - virgola - 1 : 0; - - for (; voluti > decimali; decimali++) - v << '@'; - if (voluti < decimali) - v.cut (virgola + voluti + (voluti > 0)); - - int j = v.len () - 1; - for (int i = f.len () - 1; i >= 0 && j >= 0; i--) - { - char &z = f[i]; - if (strchr ("#@^", z)) - { - char c = v[j--]; - if (j >= 0 && v[j] == '.') - j--; - if (z == '^') - c = ' '; - else - { - if (c == '@') - c = (z == '@') ? '0' : ' '; - else - if (c == '-' && f[i+1] == '.') - { - f[i+1] = '-'; - c = ' '; - } - } - - z = c; - } - } - for (; i >= 0; i--) - switch (f[i]) - { - case '#': - case '^': - case '.': - f[i] = ' '; - break; - case '@': - f[i] = '0'; - break; - default: - break; - } - return strcpy (__string, f); -} - // @func ostream& | operator | Permette di reindirizzare il numero // reale per la stampa @@ -822,11 +848,12 @@ bool operator != (double a, const real & b) // // @rdesc Ritorna il resto della divisione tra due numeri real operator % ( - const real & a, // @parm Primo membro della divisione - const long b) // @parm Secondo membro della divisione + const real& a, // @parm Primo membro della divisione + const real& b) // @parm Secondo membro della divisione -{ - dmodl (__tmp_real.ptr (), a.ptr (), b); +{ + const long l = b.integer(); + dmodl (__tmp_real.ptr (), a.ptr (), l); return __tmp_real; } @@ -957,6 +984,274 @@ real abs ( return __tmp_real; } +#endif + +// Funzioni comuni dei due real + +TObject* real::dup () const +{ + return new real(*this); +} + +char *real::eng2ita (char *s) +{ + if (s) + { + char *dot = strchr (s, '.'); + if (dot) + *dot = ','; + } + return s; +} + +char *real::ita2eng (const char *s) +{ + int j = 0; + if (s) + for (int i = 0; s[i]; i++) + { + switch (s[i]) + { + case ' ': + case '.': + break; + case ',': + __string[j++] = '.'; + break; + default: + __string[j++] = s[i]; + break; + } + } + __string[j] = '\0'; + return __string; +} + +bool real::is_natural (const char *s) +{ + bool ok = s && *s != '\0'; + if (ok) + { + while (*s == ' ') + s++; // Remove leading spaces before + + if (*s) + { + while (isdigit(*s)) + s++; + ok = *s == '\0'; + } + else ok = FALSE; + + } + return ok; +} + +// Certified 75% +char *real ::literals () const +{ + const char *primi20[] = + {"", "uno", "due", "tre", "quattro", + "cinque", "sei", "sette", "otto", + "nove", "dieci", "undici", "dodici", + "tredici", "quattordici", "quindici", "sedici", + "diciassette", "diciotto", "diciannove"}; + const char *decine[] = + {"zero", "dieci", "venti", "trenta", "quaranta", + "cinquanta", "sessanta", "settanta", "ottanta", + "novanta", "cento"}; + const char *uni[] = + {"uno", "mille", "unmilione", "unmiliardo"}; + + const char *potenze[] = + {"", "mila", "milioni", "miliardi"}; + + real tmp_real = *this; + tmp_real.round(); + + TString80 r (tmp_real.string (0, 0)); + const bool negativo = r[0] == '-'; + if (negativo) + r.ltrim (1); + + TFixed_string risultato (__string, 80); + risultato.cut (0); + + TString80 centinaia; + + for (int migliaia = 0;; migliaia++) + { + int v = r.len () - 3; + if (v < -2) + break; + + if (v < 0) + v = 0; + const int val = atoi (&r[v]); + r.cut (v); // Elimina ultimi 3 caratteri + + v = val; + if (v >= 100) + { + const int c = v / 100; + if (c > 1) + centinaia = primi20[c]; + else + centinaia.cut(0); + v -= c * 100; + centinaia << "cento"; + } else centinaia.cut(0); + const int d = v / 10; + if (d > 1) + { + centinaia << decine[d]; + v -= d * 10; + } + + if (val > 0) + { + if (v != 1) + { + centinaia << primi20[v] << potenze[migliaia]; + } + else if (val > 1) + { + if (d > 1) + centinaia.cut (centinaia.len() - 1); + centinaia << "un" << (migliaia ? potenze[migliaia] : "o"); + } + else + centinaia = uni[migliaia]; + } + + risultato.insert(centinaia, 0); + } + + if (negativo) + risultato.insert ("meno", 0); + return __string; +} + +// Certified 75% +char* real::points (int dec) const +{ + const char *str = stringa (0, dec); + const int neg = (*str == '-') ? 1 : 0; + TFixed_string n ((char *)str, 24); + int i; + + int dot = n.find (','); + if (dot < 0) + dot = n.len (); + + if (dec > 0) + { + if (n[dot] == '\0') + n << ','; + const int d = strlen (str + dot + 1); // Decimals already there + + if (d <= dec) + for (i = d; i < dec; i++) + n << '0'; + else + n.cut (dot + dec + 1); + } + + for (i = dot - 3; i > neg; i -= 3) + n.insert (".", i); + + return __string; +} + + +HIDDEN int get_picture_decimals (const TString& picture) +{ + int decimali = 0; + const int virgola = picture.find (','); + if (virgola >= 0) + { + const int len = picture.len (); + for (int i = virgola + 1; i < len; i++) + if (strchr ("#@~", picture[i])) + decimali++; + } + return decimali; +} + +char* real::string(const char *picture) const +{ + if (*picture == '\0') + return string (); + if (*picture == '.') + return points (atoi (picture + 1)); + if (strcmp (picture, "LETTERE") == 0) + return literals (); + + TString80 v (string()); + TString80 f (picture); + + const int voluti = get_picture_decimals (f); + const int virgola = v.find ('.'); + int decimali = (virgola >= 0) ? v.len () - virgola - 1 : 0; + + for (; voluti > decimali; decimali++) + v << '@'; + if (voluti < decimali) + v.cut (virgola + voluti + (voluti > 0)); + + int j = v.len () - 1; + for (int i = f.len () - 1; i >= 0 && j >= 0; i--) + { + char &z = f[i]; + if (strchr ("#@^", z)) + { + char c = v[j--]; + if (j >= 0 && v[j] == '.') + j--; + if (z == '^') + c = ' '; + else + { + if (c == '@') + c = (z == '@') ? '0' : ' '; + else + if (c == '-' && f[i+1] == '.') + { + f[i+1] = '-'; + c = ' '; + } + } + + z = c; + } + } + for (; i >= 0; i--) + switch (f[i]) + { + case '#': + case '^': + case '.': + f[i] = ' '; + break; + case '@': + f[i] = '0'; + break; + default: + break; + } + return strcpy (__string, f); +} + +// Certified 99% +char *real ::stringa (int len, int dec, char pad) const + +{ + string (len, dec, pad); + if (dec > 0 || dec == UNDEFINED) + eng2ita (__string); + return __string; +} + /////////////////////////////////////////////////////////// // Distrib // Oggetto per dividere un real in varie sue percentuali diff --git a/include/real.h b/include/real.h index b547b4095..ce5567733 100755 --- a/include/real.h +++ b/include/real.h @@ -1,21 +1,127 @@ #ifndef __REAL_H #define __REAL_H -#ifndef GMDOTH -#include -#include +#ifndef __STRINGS_H +#include #endif +#ifdef __LONGDOUBLE__ + +// @doc EXTERNAL + +// @class real | Classe per la gestione dei numeri reali +// +// @base public | TObject +class real : public TObject +{ + // @access Private Member + + // @cmember Numero reale + long double _dec; + + // @access Protected Member +protected: + // @cmember Duplica il numero reale (vedi classe ) + virtual TObject* dup() const; + // @cmember Traduce in lettere il numero reale + char* literals() const; + // @cmember Inserisce i punti separatori delle migliaia e riempe i decimali + // alla lunghezza passata (es: 3.000,20) + char* points(int decimals = 0) const; + + // @access Public Member +public: + operator long double () const { return _dec; } + + // @cmember Trasforma un numero dal formato inglese (decimali con punto) in + // formato italiano (decimali con virgola) + static char* eng2ita(char* s); + // @cmember Trasforma un numero dal formato italiano (decimali con virgola) in + // formato inglese (decimali con punto) + static char* ita2eng(const char* s); + // @cmember Controlla se si tratta di un numero reale (TRUE se vero) + static bool is_real(const char* n); + // @cmember Controlla se si tratta di un numero naturale intero (TRUE se vero) + static bool is_natural(const char* n); + + // @cmember Trasforma un reale in stringa + char* string(int len = 0, int dec = UNDEFINED, char pad = ' ') const; + // @cmember Trasforma un reale in stringa (chiama ), ma + // ritorna il formato italiano + char* stringa(int len = 0, int dec = UNDEFINED, char pad = ' ') const; + // @cmember Ritorna la stringa con il formato passato + char* string(const char* picture) const; + + // @cmember Controlla se si tratta di un reale uguale 0 (TRUE se 0) + bool is_zero() const + { return _dec == 0.0; } + // @cmember Ritorna il segno del reale + int sign() const; + // @cmember Trasforma il reale in intero (operator int era troppo pericoloso) + long integer() const; + + // @cmember Arrotonda al numero di decimali passati + real& round(int prec = 0) ; + // @cmember Tronca al numero di decimali passati (default 0) + real& trunc(int prec = 0) ; + // @cmember Arrotonda al numero successivo (della precisione passata) + real& ceil(int prec = 0); + // @cmember Assegna un reale + real& operator = (const real& a); + // @cmember Assegna un reale + real& operator =(long double a); + real& operator +=(long double a); + // @cmember Sottrae ad un reale il valore passato (passato per indirizzo) + real& operator -=(long double b); + // @cmember Moltiplica un reale per il valore passato (passato per indirizzo) + real& operator *=(long double b); + // @cmember Divide un reale per il valore passato (passato per indirizzo) + real& operator /=(long double b); + // @cmember Ritorna la negazione di un reale (TRUE se 0, altrimenti FALSE) + bool operator !() const + { return _dec == 0.0; } + // @cmember Ritorna il risultato della differenza tra due reali + real operator -() const; + + // @cmember Costruttore + real(); + // @cmember Costruttore + real(const real& b); + // @cmember Costruttore + real(long double a); + // @cmember Costruttore + real(const char* s); + // @cmember Distruttore + virtual ~real() + {} +}; + +inline long double fnc_min(long double a, long double b) { return a < b ? a : b; } +inline long double fnc_max(long double a, long double b) { return a > b ? a : b; } + +long double operator%(const real& a, const real& b); +void swap(real& a, real& b) ; +long double sqrt(long double) ; +long double sqr(long double) ; +long double exp10(long double) ; +long double pow(long double, long double) ; +long double exp(long double a) ; +long double log10(long double a) ; +long double log(long double a) ; +long double sin(long double a) ; +long double cos(long double a) ; +long double tan(long double a) ; +long double abs(long double a) ; + +#else + #ifndef __IOSTREAM_H #include #endif -#ifndef __STDTYPES_H -#include -#endif - -#ifndef __STRINGS_H -#include +#ifndef GMDOTH +#include +#include #endif // @doc EXTERNAL @@ -158,7 +264,7 @@ inline bool operator >=(const real& a, double b) { return operator <=(b, a); } inline bool operator ==(const real& a, double b) { return operator ==(b, a); } inline bool operator !=(const real& a, double b) { return operator !=(b, a); } -real operator %(const real& a, const long b) ; +real operator %(const real& a, const real& b) ; void swap(real& a, real& b) ; const real& fnc_min(const real& a, const real& b) ; const real& fnc_max(const real& a, const real& b) ; @@ -173,6 +279,11 @@ real sin(const real& a) ; real cos(const real& a) ; real tan(const real& a) ; real abs(const real& a) ; + +#endif + +// TReal implementato coi maledetti DEC + extern const real ZERO; // @class TDistrib | Classe per dividere un real in varie sue percentuali