diff --git a/include/cfiles.c b/include/cfiles.c index df2891757..dd0d3f9dc 100755 --- a/include/cfiles.c +++ b/include/cfiles.c @@ -1,1392 +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 -#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) ; -} +#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) ; +}