From 32761e46b5f96f8e06f63a8d0400f26e124998ec Mon Sep 17 00:00:00 2001 From: guy Date: Tue, 9 May 1995 13:33:34 +0000 Subject: [PATCH] Velocizzati spreadsheet MOdificata gestione chiave 1 della relapp git-svn-id: svn://10.65.10.50/trunk@1333 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- include/cisam.c | 3409 +++++++++++++++++++++--------------------- include/default.url | 2 +- include/isam.cpp | 36 +- include/isam.h | 6 +- include/mask.cpp | 20 +- include/maskfld.cpp | 15 +- include/msksheet.cpp | 45 +- include/printapp.cpp | 6 +- include/real.cpp | 10 + include/real.h | 6 +- include/relapp.cpp | 34 +- include/scanner.cpp | 12 +- include/scanner.h | 2 +- include/sheet.cpp | 20 +- include/sheet.h | 3 +- include/xvtility.cpp | 22 +- 16 files changed, 1831 insertions(+), 1817 deletions(-) diff --git a/include/cisam.c b/include/cisam.c index fbc8b4ad9..01159c05f 100755 --- a/include/cisam.c +++ b/include/cisam.c @@ -1,1699 +1,1710 @@ -/* - * - @(SH) Funzioni per la gestione dei file ISAM - @(C$) PRIVATE - logname : nome del file di LOG (GIORNALE) - INTTLOCK : costante che indica alla funzione di lettura che e' stata chaimata dalla funzione di scrittura e quindi deve solo controllare lo stato di lock del record - ISLOCKED : costante che indica che il record e' bloccato - @(VG$) PRIVATE - KSv, PosSv : variabili di lavoro - PagSv, IndSv : variabili di lavoro - IndActive : stato indici - TRUE = Aggiornati ad ogni modifica, FALSE = aggiorna solo i dati - isstate : Stato transazione corrente - win,wisfd : variabili di lavoro - isjournal : TRUE scrive il giornale - openf : array di TUTTI i puntatori ai descrittori dei file ISAM aperti - ------------------------------------------------------------------------------- - */ -#include "cisam.h" -#include "libdefs.h" -#include "checks.h" -#ifdef __WATCOMC__ -#include -#else -#include -#endif -#define logname "log.gen" -#define INTTLOCK 0xF000 -#define ISLOCKED 225 -#define NOALLOC (char **) -1 -TKey KSv; -int PosSv; -RecNoType PagSv,IndSv; -BOOLEAN IndActive = TRUE; -int isstate = NOTRANS ; -int wln = -1; -isfdptr wisfd; -extern BOOLEAN isjournal; -/* Guy moved them here from extcdecl.h */ -Str80 cprefix; -isfdptr* openf; -void savekeystat(isdef *); -void restkeystat(isdef *,int ); -int addkeys(isdef *,RecType ,int ,int *); -int delkeys(isdef *,RecType ,int ,int *); -int replkeys(isdef *,RecType ,RecType ,int ,int *); -#ifndef DOS -void writeundo(int ,isdef *,RecType); -void writelog(int ,isdef *,RecType); -char *undoname(void); -void getopenf(int ,RecType *); -#endif -/* - @($) savekeystat ISAM - @(ID) - Salva la chiave corrente. - @(FD) - */ -void savekeystat(isfd) - isfdptr isfd; /* descrittore del file ISAM */ -{ - strcpy(KSv,isfd->i.Key); - IndSv = isfd->i.Ind; - PosSv = isfd->i.Pos; - PagSv = isfd->i.CurPag; -} -/* - @($) restkeystat ISAM - @(ID) - Ripristina la chiave corrente. - @(FD) - */ -void restkeystat(isfd,knum) - isfdptr isfd; /* descrittore del file ISAM */ - int knum; /* numero della chiave */ -{ - isfd->i.PN = knum - 1; - strcpy(isfd->i.Key,KSv); - isfd->i.Ind = IndSv; - isfd->i.Pos = PosSv; - isfd->i.CurPag = PagSv; -} -/* - @($) relisfd ISAM - @(ID) - Vuota il descrittore del file . - @(FD) - */ -void relisfd(isfd) - isfdptr *isfd; /* descrittore del file ISAM */ -{ - free((char *) (*isfd)->d); - free((char *) (*isfd)->r); - free((char *) (*isfd)); -} -/* - @($) getisfd ISAM - @(ID) - Alloca e carica il descrittore del file con numero logico "logicname". - @(FD) - */ -void getisfd(isfd, logicname) - isdef **isfd; /* descrittore del file ISAM */ - int logicname; /* numero logico del file */ -{ - (*isfd) = (isfdptr) malloc(sizeof(**isfd)); - (*isfd)->d = (FileDes *) malloc(sizeof(*((*isfd)->d))); - (*isfd)->r = (RecDes *) malloc(sizeof(*((*isfd)->r))); - COpenDir(ManuLock, NORDIR); - CGetFile(logicname, (*isfd)->d, NoLock, NORDIR); - if ((!(STREMPTY((*isfd)->d->SysName))) && ((*isfd)->d->SysName[0] != '$')) - (*isfd)->ft = COMDIR; - else - (*isfd)->ft = NORDIR; - CCloseDir(NORDIR); - COpenDir(ManuLock, (*isfd)->ft); - COpenFile(logicname, (*isfd)->d, NoLock, (*isfd)->ft); - CCloseDir((*isfd)->ft); - COpenRecDir(ManuLock, (*isfd)->ft); - CGetRec(logicname,(*isfd)->r, (*isfd)->ft); - CCloseRecDir((*isfd)->ft); -} -/*void dump(s,l) - RecType s; - int l; - { - message_box("dump : record: %s ", &s[1]); - }*/ -/* - @(#) cisupdflags ISAM - @(ID) - Aggiorna all'interno del direttorio i campi EOD e Flags. - Ritorna il codice di errore. - @(FD) - @(ISV) - wd = riga relativa al file ISAM in oggetto nel Direttorio. - fdir = identificatore del file direttorio. - - Versione DOS e XENIX - @(FSV) - @(IN) - Il campo Flags viene aggiornato comunque, mentre EOD viene aggiornato solo - se il parametro di input "updateeod" e' TRUE. - @(FN) - */ -int cisupdflags(isfd,err,updateeod) - isdef *isfd; /* puntatore al descrittore del file ISAM */ - int *err; /* codice di errore */ - BOOLEAN updateeod; /* se TRUE si aggiorna anche EOD */ - -{ - FileDes wd; - - *err = NoErr ; - if (isfd->ln <= 0) return(*err) ; - COpenDir( ManuLock, isfd->ft); - COpenFile(isfd->ln, &wd, Lock, isfd->ft); - if ((*err = fdir[isfd->ft].IOR) == NoErr) - { - wd.Flags = isfd->d->Flags; - /* #ifdef DOS - if (updateeod) wd.EOD = isfd->d->EOD; - #else */ - if ((updateeod) && (isfd->f.LockMode == ExclLock)) wd.EOD = isfd->d->EOD; - /* #endif */ - CCloseFile(isfd->ln, &wd, isfd->ft); - } - CCloseDir(isfd->ft); - return(*err); -} - -/* - @(#) cisgeteod ISAM - - @(ID) - Ritorna l' EOD del file. - @(FD) - - @(ISV) - - - Versione DOS e XENIX - @(FSV) - - */ - -RecNoType cisgeteod(isfd,err) - isfdptr isfd; /* puntatore al descrittore del file ISAM */ - int *err; /* codice di errore */ - -{ - - *err = NoErr ; - if (isfd->ln > 0) - { - COpenDir( ManuLock , isfd->ft); - COpenFile(isfd->ln, isfd->d, NoLock, isfd->ft); - CCloseDir(isfd->ft); - } - return(isfd->d->EOD) ; -} - -/* - @(#) cisopen ISAM - - @(ID) - Apre un file ISAM e alloca il buffer per un record a attiva la chiave 1 (uno). - Ritorna il codice di errore. - @(FD) - - @(ISV) - werr = variabile di lavoro che raccoglie il codice errore proveniente dalla CBCloseFile. - - s = stringa di lavoro per messaggi di errore. - - - Versione DOS e XENIX - @(FSV) - - @(IN) - @(FN) - */ - -int cisopen (isfd,logicname,record,mode,err) - isfdptr *isfd; /* puntatore al descrittore del file */ - int logicname; /* numero logico */ - RecType *record; /* buffer per contenere un record */ - unsigned int mode; /* modo di apertura (lock) */ - int *err; /* codice di errore */ - -{ - *err = NoErr; - if (openf[logicname - 1] != NULL) - fatal_box("File n. %d already open", logicname); -#ifndef DOS - if ((excllock(CInsPref(glockname, NORDIR), FALSE) == -1) && (errno == EACCES)) - fatal_box("Can't open directory : Error n. %d ", errno); -#endif - getisfd (isfd,logicname); - COpen(&((*isfd)->f), (*isfd)->d->SysName, (*isfd)->d->LenR, 0, mode); - if (*err = (*isfd)->f.IOR) - { - Str80 name; strcpy(name, (*isfd)->d->SysName); - relisfd(isfd); - if (err == EACCESS && mode == ExclLock) - return (*err); - fatal_box("Can't open file n. %d (%s): error %d ", - logicname, name, *err); - } - if ((*isfd)->r->NKeys) - { - Str80 name; strcpy(name, CGetIdxName((*isfd)->d->SysName)); - CBOpenFile (&((*isfd)->i), name, mode, err); - if (*err) - { - CClose(&((*isfd)->f)); - relisfd(isfd); - if (err == EACCESS && mode == ExclLock) - return (*err); - fatal_box("Can't open file n. %d (%s): error %d ", - logicname, name, *err); - } -#ifndef DOS - else - if (mode == ExclLock) - { - CBLockFile(&((*isfd)->i), err); - if (*err) - { - int werr; - CClose(&((*isfd)->f)); - CBCloseFile(&((*isfd)->i), &werr); - relisfd(isfd); - fatal_box("Can't open exclusively file n. %d: error %d ", logicname, *err); - } - } -#endif - } - if (record != NOALLOC) - *record = (RecType) malloc((*isfd)->d->LenR); - (*isfd)->ln = logicname; - openf[logicname - 1] = *isfd; - if ((*isfd)->r->NKeys) (*isfd)->i.PN = 0; - return (*err); -} - -/* - @(#) ciscopyrec ISAM - - @(ID) - Copia un record dati da un record ad un altro. - Ritorna il codice di errore. - @(FD) - - @(ISV) - d = riga del direttorio corrispondente al file in esame. - @(FSV) - - @(IN) - @(FN) - */ - -int ciscopyrec(logicname,recdest, recsrc ,err) - int logicname; /* numero logico del file ISAM */ - RecType recdest; /* buffer destinazione */ - RecType recsrc; /* buffer sorgente */ - int *err; /* codice di errore */ - -{ - FileDes d; - int ft; - - *err = NoErr; - if (logicname < 0) logicname = -logicname; - if (openf[logicname - 1] != NULL) d = *(openf[logicname - 1]->d); -{ - COpenDir(ManuLock, NORDIR); - CGetFile(logicname, &d, NoLock, NORDIR); - if ((!(STREMPTY(d.SysName))) && (d.SysName[0] != '$')) ft = COMDIR; - else ft = NORDIR; - CCloseDir(NORDIR); - COpenDir(ManuLock, ft); - COpenFile(logicname, &d, NoLock, ft); - CCloseDir(ft); -} -memcpy(recdest, recsrc, d.LenR); -return(*err); -} - -/* - @(#) cisallocrec ISAM - - @(ID) - Alloca il buffer per un record. - Ritorna il codice di errore. - @(FD) - - @(ISV) - d = riga del direttorio corrispondente al file in esame. - @(FSV) - - @(IN) - @(FN) - */ - -int cisallocrec(logicname,record,err) - int logicname; /* numero logico del file ISAM */ - RecType *record; /* buffer per il record */ - int *err; /* codice di errore */ - -{ - FileDes d; - int ft; - - *err = NoErr; - if (logicname < 0) logicname = -logicname; - if (openf[logicname - 1] != NULL) d = *(openf[logicname - 1]->d); - else - { - COpenDir(ManuLock, NORDIR); - CGetFile(logicname, &d, NoLock, NORDIR); - if ((!(STREMPTY(d.SysName))) && (d.SysName[0] != '$')) ft = COMDIR; - else ft = NORDIR; - CCloseDir(NORDIR); - COpenDir(ManuLock, ft); - COpenFile(logicname, &d, NoLock, ft); - CCloseDir(ft); - } - *record = (RecType) malloc(d.LenR); - if (*record == ((RecType) NULL)) return(ENOMEM); - else return(*err); -} - -/* - @(#) cisclose ISAM - - @(ID) - Chiude un file ISAM e libera il buffer del record. - Ritorna il codice di errore. - @(FD) - - @(ISV) - werr = variabile di lavoro che raccoglie il codice errore proveniente dalla CBCloseFile. - - s[20] = stringa di lavoro per messaggi di errore. - - - Versione DOS e XENIX - @(FSV) - - @(IN) - Restituisce il codice di errore - @(FN) - */ - -int cisclose(isfd,rec,err) - isdef **isfd; /* puntatore al descrittore del file */ - RecType *rec; /* buffer per il record */ - int *err; /* codice di errore */ - -{ - int werr = NoErr; - - *err = NoErr; - if (((*isfd)->ln > 0) && ((*isfd == NULL) || (openf[(*isfd)->ln - 1] == NULL))) - { - if (*isfd != NULL) - error_box("File n. % isclose : Error n. %d ", (*isfd)->ln, IsNotOpen); - else - error_box("isclose : errore n. %d ", IsNotOpen); - } - CClose(&((*isfd)->f)); - *err = ((*isfd)->f.IOR); - if ((*isfd)->r->NKeys) - { - CBCloseFile(&((*isfd)->i), &werr); - if (werr != NoErr ) *err = werr; - } - if ((*isfd)->ln > 0) - openf[(*isfd)->ln - 1] = NULL ; - if ((rec != NULL) && (*rec != NULL)) - free(*rec); - relisfd(isfd); -#ifndef DOS - exclunlock(CInsPref(glockname, NORDIR), FALSE); -#endif - if (*err) - fatal_box("isclose : Error n. %d ", *err); - return (*err); -} - -/* - @(#) cisstart ISAM - - @(ID) - Esegue una lettura cambiando il numero di chiave attiva. - Ritorna il codice di errore. - @(FD) - - @(IN) - La variabile record in input contiene i campi necessari per la ricerca, - in output contiene il record letto. - - La variabile mode e' formata da un comando di lock + comando di posizionamento - . Se non si utilizza ISEQUAL o ISGREAT o ISGTEQ, il valore della variabile - record non ha nessuna importanza. - @(FN) - */ - -int cisstart(isfd,keynum,record,mode,err) - isfdptr isfd; /* descrittore del file ISAM */ - int keynum; /* numero della chiave */ - RecType record; /* buffer per il record */ - unsigned int mode; /* comando di lettura */ - int *err; /* codice di errore */ - -{ - if(isfd == ((isfdptr) NULL)) return ((*err = IsNotOpen)); - *err = NoErr; - if(!(keynum >= 1) && (keynum <= isfd->r->NKeys)) - return((*err = BTrPathErr)); - isfd->i.PN = keynum - 1; - *err = cisread(isfd,record,mode,err); - return(*err); -} - -/* - @(#) cisread ISAM - - @(ID) - Esegue una lettura utilizzando la chiave attiva. - Ritorna il codice di errore. - @(FD) - - @(ISV) - rmode = variabile che contiene il tipo lettura utilizzato. - - lmode = varibaile dhe contiene il tipo lock utilizzato. - - knum = numero chiave attiva. - - junk = variabile spazzatura per la chiamata alla funzione "sleep". - - times = variabile di lavoro. - - s = stringa contenente messaggio. - - w = descrittore finestra . - - internaltlock = flag che verifica se la isread e' stata chiamata da iswrite per testare l' esistenza di un record. - - @(FSV) - - @(IN) - La variabile record in input contiene i campi necessari per la ricerca, - in output contiene il record letto. - - La variabile mode e' formata da un comando di lock + comando di posizionamento - . Se non si utilizza ISEQUAL o ISGREAT o ISGTEQ, il valore della variabile - record non ha nessuna importanza. - @(FN) - */ - -int cisread(isfd,record,mode,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecType record;/* buffer per il record */ - unsigned int mode; /* modo di lettura */ - int *err; /* codice di errore */ - -{ - unsigned int rmode = (mode & READTYPES), - lmode = (mode & RecLockTypes), - knum = (isfd->i.PN+1); - int junk,times = 1; - TKey key,key1,key2; - /* char s[120]; */ - BOOLEAN internaltlock = (lmode == INTTLOCK); - - if (internaltlock) lmode = ShareLock; - *err = NoErr ; - if (isfd == ((isfdptr) NULL)) return ((*err = IsNotOpen)); - if (rmode & (IsPrevN + IsNextN)) - { - times = rmode & BYTEMASK; - if (rmode & IsPrevN) rmode = IsPrev; - else rmode = IsNext; - } - if (rmode == IsCurr) - { - if (!isfd->RecNo) return((*err = IsNotCurr)); - } - else - { - if (rmode == IsNext) - { - while ((times--) && (!*err)) - { - CBNext(&isfd->i,knum,key1,&isfd->RecNo,err); - } - } - else - { - if (rmode == IsPrev) - { - while ((times--) && (!*err)) - { - CBPrev(&isfd->i,knum,key1,&isfd->RecNo,err); - } - } - else - { - if (rmode == IsFirst) MinKey(CCalcLenKey(isfd->r,knum),key); - else - if (rmode == IsLast) MaxKey(CCalcLenKey(isfd->r,knum),key); - else - CBuildKey(isfd->r,knum,record,key); - CBRead(&isfd->i,knum,key,key1,&isfd->RecNo,err); - if ((rmode == IsGreat) && (!*err)) - while ((strcmp(key,key1) == 0) && (!*err)) - CBNext (&isfd->i,knum,key1,&isfd->RecNo,err); - } - } - } - do - { - if (((*err) && (rmode == IsEqual)) || - ((*err == BTrEOF) && (rmode == IsGreat))) - CRead(&isfd->f,record,isfd->RecNo,NoLock); - else - CRead(&isfd->f,record,isfd->RecNo,lmode); - if (TESTLOCK(isfd->f.IOR)) - { - if (lmode == ShareLock) - { - if (!*err) *err = ISLOCKED; - break; - } - message_box("Codice %s in uso da parte\ndi un altro utente.", key1); - if (rmode != IsCurr) - { - CBReRead(&isfd->i,knum,key1,key2,isfd->RecNo,&isfd->RecNo,&junk); - if (junk) strcpy(key1, key2) ; - } - } - else - if (!*err) *err = isfd->f.IOR; - } while (TESTLOCK(isfd->f.IOR)) ; - if (((rmode == IsFirst) || (rmode == IsLast)) && (*err != BTrEmptyTree)) - *err = NoErr; - if ((rmode == IsGtEq) && (*err != BTrEOF) && (*err != BTrEmptyTree)) - *err = NoErr ; - if (DEADLOCK(*err)) return(*err = IsDeadLock); - if (rmode == IsCurr) - { - CBuildKey(isfd->r,knum,record,key); - CBReRead(&isfd->i,knum,key,key1,isfd->RecNo,&isfd->RecNo,&junk); - } - if (*err == BTrEmptyTree) CZeroRec(isfd->r, record); - return(*err); -} - -/* - @($) addkeys ISAM - - @(ID) - Aggiunge all'indice le chiavi contenute nel record. - Ritorna il codice di errore. - @(FD) - - @(ISV) - i,j = contatori. - - werr = codice errore restituito dalla CBDelete. - - key = valore delle chiavi. - @(FSV) - - @(IN) - @(FN) - */ - -int addkeys (isfd,record,knum,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecType record; /* buffer per il record */ - int knum; /* numero chiave corrente */ - int *err; /* codice errore */ - -{ - int i,j,werr; - TKey key; - - for (i = 1;(i <= isfd->r->NKeys) && (!*err);i++) - { - CBuildKey(isfd->r,i,record,key); - CBWrite(&isfd->i,i,key,isfd->RecNo,err); - if (i == knum) savekeystat(isfd); - } - if (*err) - { - if (i == 2 && *err == BTrDupKeysNotAll) *err = IsReInsert; - for (j = 1; (j < i); j++) - { - CBuildKey(isfd->r,j,record,key); - CBDelete(&isfd->i,j,key,isfd->RecNo,&werr); - } - } - else restkeystat(isfd,knum); - return(*err); -} - -/* - @(#) ciswrite ISAM - - @(ID) - Aggiunge un nuovo record al file ISAM. - Ritorna il codice di errore. - @(FD) - - @(ISV) - werr = codice errore restituito. - - knum = numero chiave attiva. - - junk = variabile di lavoro per la chiamata di varie funzioni. - - wrec = buffer di lavoro. - @(FSV) - - @(IN) - La variabile record in input contiene il record da aggiungere. - @(FN) - */ - -int ciswrite (isfd,record,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecType record; /* buffer per il record */ - int *err; /* codice di errore */ - -{ - int knum = (isfd->i.PN+1), werr, junk; - RecNoType neweox; - - *err = NoErr; - if(isfd == ((isfdptr) NULL)) return((*err = IsNotOpen)); - if (isfd->ln > 0) - { - COpenDir (ManuLock, isfd->ft); - COpenFile(isfd->ln,isfd->d, NoLock, isfd->ft); - } - if (isfd->d->EOD == isfd->d->EOX) - { - neweox = isfd->d->EOX / 20 + 1; - if (neweox < 10) neweox = 10; - if (demoflag) - *err = IsFileFull; - else - { - neweox += isfd->d->EOX; - cisextend(isfd, isfd->ln, neweox, err); - } - if (*err == NoErr) - { - if (isfd->ln > 0) - { - COpenFile(isfd->ln,isfd->d, NoLock, isfd->ft); - for (junk = 0; junk < isfd->r->NKeys; junk++) - isfd->i.Base[junk].PEOX = neweox; - } - else - { - isfd->d->EOX = neweox; - if (isfd->f.LockMode == ExclLock) - for (junk = 0; junk < isfd->r->NKeys; junk++) - isfd->i.Base[junk].PEOX = neweox; - } - } - else - { - if (isfd->ln > 0) - CCloseDir(isfd->ft); - isfd->RecNo = 0; - if (DEADLOCK(*err)) *err = IsDeadLock; - return((*err ? *err : (*err = IsFileFull))); - } - } - IRecallRec(record); - if (/* test_share() && */ isfd->f.LockMode != ExclLock) - { - RecType wrec = malloc(isfd->d->LenR); - memcpy(wrec, record, isfd->d->LenR); - savekeystat(isfd); - junk = cisstart(isfd, 1, wrec, NoLock+IsEqual, &junk); - restkeystat(isfd, knum); - free(wrec); - - if ((junk == NoErr) || (junk == ISLOCKED)) - { - *err = IsReInsert; - if (isfd->ln > 0) - CCloseDir(isfd->ft); - isfd->RecNo = 0; - return(*err); - } - } - if (isfd->ln > 0) - { - COpenFile(isfd->ln,isfd->d, Lock, isfd->ft); - } - isfd->RecNo = (++isfd->d->EOD); - if ((isfd->r->NKeys) && IndActive) - { - if(/* test_share() && */ isfd->f.LockMode != ExclLock) - CBLockFile(&isfd->i,err) ; - if (!addkeys(isfd, record, knum, err)) - { - CWrite(&isfd->f,record,isfd->RecNo,NoLock); - if ((*err = isfd->f.IOR)) - { - isfd->RecNo = 0; - junk = delkeys(isfd, record, knum, &werr); - } - /* else - if (isfd->ln > 0) - CCloseFile(isfd->ln,isfd->d, isfd->ft) ; */ - } - else isfd->d->EOD-- ; - if (isfd->ln > 0) - { - CCloseFile(isfd->ln,isfd->d, isfd->ft) ; - } - if(/* test_share() && */ isfd->f.LockMode != ExclLock) - CBUnLockFile(&isfd->i, &werr) ; - } - else - { - CWrite(&isfd->f,record,isfd->RecNo,NoLock); - if ((*err = isfd->f.IOR)) isfd->RecNo = 0; - else CCloseFile(isfd->ln,isfd->d, isfd->ft) ; - } - if (!(*err)) - { -#ifndef DOS - if (isstate == NOTRANS) writelog(FNWRITE, isfd, record); - else writeundo(FNWRITE, isfd, record); -#endif - } - if (isfd->ln > 0) - CCloseDir(isfd->ft); - /* if (test_share()) */ -{ - junk = cisunlock(isfd, &junk); - if (isstate == NOTRANS) - CLockRec(&isfd->f,isfd->RecNo,UnLock); - if (DEADLOCK(*err)) *err = IsDeadLock; -} -return(*err); -} - -/* - @($) delkeys ISAM - - @(ID) - Cancella le chiavi contenute nel record dall'indice. - Ritorna il codice di errore. - @(FD) - - @(ISV) - i,j = contatori. - - werr = codice errore da CBWrite. - - key = valori chiave. - @(FSV) - - @(IN) - @(FN) - */ - -int delkeys (isfd,record,knum,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecType record; /* buffer per il record */ - int knum; /* numero della chiave attuale */ - int *err; /* codice di errore */ - -{ - int i,j,werr; - TKey key; - - for (i = 1;(i <= isfd->r->NKeys)&&(!*err);i++) - { - CBuildKey(isfd->r,i,record,key); - CBDelete(&isfd->i,i,key,isfd->RecNo,err); - } - if (*err) - { - for (j = 1;(j < i);j++) - { - CBuildKey(isfd->r,j,record,key); - CBWrite(&isfd->i,j,key,isfd->RecNo,&werr); - } - } - else restkeystat(isfd,knum); - return(*err); -} - -/* - @(#) cisdelete ISAM - - @(ID) - Cancella un record da un file ISAM. - Ritorna il codice di errore. - @(FD) - - @(ISV) - knum = numero chiave successiva a quella attiva. - - werr = codice errore da CBUnLockFile. - - key1,key = valori chiave. - - - Versione DOS e XENIX - @(FSV) - - @(IN) - La variabile record in input contiene il record da cancellare. - @(FN) - */ - -int cisdelete(isfd,record,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecType record; /* buffer per il record */ - int *err; /* codice di errore */ - -{ - int knum = (isfd->i.PN+1), werr; - TKey key,key1; - - if(isfd == ((isfdptr) NULL)) return((*err = IsNotOpen)); - *err = NoErr; - savekeystat(isfd); - CBuildKey(isfd->r,1,record,key); - *err = NoErr ; - CBRead(&isfd->i,1,key,key1,&isfd->RecNo,err); - if (*err) - { - restkeystat(isfd,knum); - return(*err); - } - CRead(&isfd->f, record, isfd->RecNo, NoLock); - if ((*err = isfd->f.IOR)) - { - restkeystat(isfd,knum); - return(*err); - } - if ((isfd->r->NKeys) && IndActive) - { - if( /* test_share() && */ isfd->f.LockMode != ExclLock) - CBLockFile(&isfd->i,err) ; - delkeys(isfd, record, knum, err) ; - } - IDeleteRec(record); - CWrite(&isfd->f,record,isfd->RecNo,UnLock); - if((*err = isfd->f.IOR)) - { - IRecallRec(record); - CWrite(&isfd->f,record,isfd->RecNo,NoLock); - if ((isfd->r->NKeys) && IndActive) addkeys(isfd, record, knum, err) ; - restkeystat(isfd,knum); - } -#ifndef DOS - else - { - if (isstate == NOTRANS) - { - writelog(FNDELETE, isfd, NULL); - CRead(&isfd->f,record,isfd->RecNo,UnLock); - } - else writeundo(FNDELETE, isfd, NULL); - } - if (/* test_share() && */(isfd->r->NKeys) && IndActive && - (isfd->f.LockMode != ExclLock)) - CBUnLockFile(&isfd->i, &werr) ; -#else - /* if (test_share()) */ -{ - CRead(&isfd->f,record,isfd->RecNo,UnLock); - if (isfd->r->NKeys && IndActive && - (isfd->f.LockMode != ExclLock)) - CBUnLockFile(&isfd->i, &werr) ; -} -#endif -return(*err); -} - -/* - @($) replkeys ISAM - - @(ID) - Rimpiazza le chiavi all'interno dell'indice. - Ritorna il codice di errore. - @(FD) - - @(ISV) - i,j = contatori. - - werr = codice errore ritornato da CBDelete e CBWrite. - - key,key1 = valori delle chiavi. - @(FSV) - */ - -int replkeys (isfd,oldrec,record,knum,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecType oldrec; /* buffer contenente il vecchio record */ - RecType record; /* buffer contenente il nuovo record */ - int knum; /* numero della chiave attuale */ - int *err; /* codice di errore */ - -{ - int i,j,werr; - TKey key,key1; - - for (i = 1;(i <= isfd->r->NKeys)&&(!*err);i++) - { - CBuildKey(isfd->r,i,record,key); - CBuildKey(isfd->r,i,oldrec,key1); - if (strcmp(key,key1) != 0) - { - CBDelete(&isfd->i,i,key1,isfd->RecNo,err); - if (*err) break; - CBWrite(&isfd->i,i,key,isfd->RecNo,err); - if (*err) CBWrite(&isfd->i,i,key1,isfd->RecNo,err); - if (i == knum) savekeystat(isfd); - } - } - if (*err) - { - for (j = 1;(j < i);j++) - { - CBuildKey(isfd->r,j,record,key); - CBuildKey(isfd->r,j,oldrec,key1); - if (strcmp(key,key1) != 0) - { - CBDelete (&isfd->i,j,key,isfd->RecNo,&werr); - CBWrite(&isfd->i,j,key1,isfd->RecNo,&werr); - } - } - } - else restkeystat(isfd,knum); - return(*err); -} - -/* - @(#) cisrewrite ISAM - - @(ID) - Aggiorna un record nel file ISAM. - Ritorna il codice di errore. - @(FD) - - @(ISV) - knum = numero chiave successiva all'attuale. - - werr = codice errore restituito da CBUnLock. - - key, key1 = valori delle chiavi. - - oldrec = buffer di lavoro. - - - Versione DOS e XENIX - @(FSV) - - @(IN) - La variabile record in input contiene il record da aggiornare. - Utilizza la chiave 1 per ritrovare il record da aggiornare. - @(FN) - */ - -int cisrewrite(isfd,record,err) - isfdptr isfd; /* descrittore del file isam */ - RecType record; /* buffer contenente i record */ - int *err; /* codice di errore */ - -{ - int knum = (isfd->i.PN+1), werr; - TKey key,key1; - RecType oldrec; - - *err = NoErr ; - if(isfd == ((isfdptr) NULL)) return((*err = IsNotOpen)); - oldrec = (RecType) malloc(isfd->d->LenR); - savekeystat(isfd); - IRecallRec(record); - CBuildKey(isfd->r,1,record,key); - CBRead(&isfd->i,1,key,key1,&isfd->RecNo,err); - if(*err) - { - restkeystat(isfd,knum); - return(*err); - } - CRead(&isfd->f,oldrec,isfd->RecNo,NoLock); - if ((*err = isfd->f.IOR)) - { - restkeystat(isfd,knum); - free(oldrec); - return(*err); - } - if (memcmp(oldrec,record,isfd->d->LenR) == 0) - { - *err = NoErr; - restkeystat(isfd,knum); - CLockRec(&isfd->f,isfd->RecNo,UnLock); - free(oldrec); - return(*err); - } - if ((isfd->r->NKeys) && IndActive) - { - if(/* test_share() && */ isfd->f.LockMode != ExclLock) - CBLockFile(&isfd->i, err) ; - replkeys(isfd, oldrec, record, knum, err) ; - if(/* test_share() && */ isfd->f.LockMode != ExclLock) - CBUnLockFile(&isfd->i, &werr) ; - } - CWrite(&isfd->f,record,isfd->RecNo,NoLock); - if ((*err = isfd->f.IOR)) - { - CWrite(&isfd->f,oldrec,isfd->RecNo,NoLock); - replkeys(isfd, record, oldrec, knum, err) ; - restkeystat(isfd,knum); - } - else -#ifndef DOS - { - if (isstate == NOTRANS) - { - writelog(FNREWRITE, isfd, record); - CLockRec(&isfd->f,isfd->RecNo,UnLock); - } - else writeundo(FNREWRITE, isfd, oldrec); - } - -#else - /* if (test_share()) */ - CLockRec(&isfd->f,isfd->RecNo,UnLock); -#endif - free(oldrec); - return(*err); -} - -/* - @(#) cisdelcurr ISAM - - @(ID) - Cancella il record corrente. - Ritorna il codice di errore. - @(FD) - */ - -int cisdelcurr(isfd,err) - isfdptr isfd; /* descrittore del file ISAM */ - int *err; /* codice di errore */ - -{ - if(isfd->RecNo) cisdelrec(isfd,isfd->RecNo,err); - else *err = IsNotCurr; - return(*err); -} - -/* - @(#) cisrewcurr ISAM - - @(ID) - Riscrive il record corrente. - Ritorna il codice di errore. - @(FD) - - @(IN) - La variabile record in input contiene il record da aggiornare. - @(FN) - */ - -int cisrewcurr(isfd,record,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecType record; /* buffer contenente il record */ - int *err; /* codice di errore */ - -{ - if(isfd->RecNo) cisrewrec(isfd,isfd->RecNo,record,err); - else *err = IsNotCurr; - return (*err); -} - -/* - @(#) cisreadrec ISAM - - @(ID) - Legge un record di numero "recnum". - Ritorna il codice di errore. - @(FD) - */ - -int cisreadrec(isfd,recnum,record,mode,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecNoType recnum; /* numero del record */ - RecType record; /* buffer per il record */ - unsigned int mode; /* modo di lock */ - int *err; /* codice di errore */ - -{ - isfd->RecNo = recnum; - return(cisread(isfd,record,IsCurr+(mode & RecLockTypes),err)); -} - -/* - @(#) ciswriterec ISAM - - @(ID) - Riscrive un record di numero "recnum". - @(FD) - - @(IN) - La variabile record in input contiene il record da aggiornare. - @(FN) - - @(ISV) - knum = numero chiave attiva. - - werr = codice errore restituito da CBUnLockFile. - - oldrec = buffer di lavoro. - - - Versione DOS e XENIX - @(FSV) - */ - -int cisrewrec(isfd,recnum,record,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecNoType recnum; /* numero del record da riscrivere */ - RecType record; /* buffer per il record */ - int *err; /* codice di errore */ - -{ - int knum = (isfd->i.PN+1), werr; - RecType oldrec; - - *err = NoErr; - if (isfd == ((isfdptr) NULL)) return ((*err = IsNotOpen)); - oldrec = (RecType) malloc(isfd->d->LenR); - isfd->RecNo = recnum; - IRecallRec(record); - CRead(&isfd->f,oldrec,isfd->RecNo,NoLock); - if ((*err = isfd->f.IOR)) - { - free(oldrec); - return(*err); - } - if (memcmp(oldrec,record,isfd->d->LenR) == 0) - { - *err = NoErr; - /* if (test_share()) */ - CLockRec(&isfd->f,isfd->RecNo,UnLock); - free(oldrec); - return(*err); - } - if ((isfd->r->NKeys) && IndActive) - { - if (/* test_share() && */ isfd->f.LockMode != ExclLock) - CBLockFile(&isfd->i, err) ; - replkeys(isfd, oldrec, record, knum, err) ; - if (/* test_share() && */ isfd->f.LockMode != ExclLock) - CBUnLockFile(&isfd->i, &werr) ; - } - if (isstate == NOTRANS) CWrite(&isfd->f,record,isfd->RecNo,UnLock); - else CWrite(&isfd->f,record,isfd->RecNo,NoLock); - if ((*err = isfd->f.IOR)) - { - CWrite(&isfd->f,oldrec,isfd->RecNo,NoLock); - replkeys(isfd, record, oldrec, knum, err) ; - } -#ifndef DOS - else - { - if (isstate == NOTRANS) - { - writelog(FNREWRITE, isfd, record); - CLockRec(&isfd->f,isfd->RecNo,UnLock); - } - else writeundo(FNREWRITE, isfd, oldrec); - } -#else - /* if (test_share()) */ - CLockRec(&isfd->f,isfd->RecNo,UnLock); -#endif - free(oldrec); - return(*err); -} -/* - @(#) cisdelrec ISAM - @(ID) - Cancella un record utilizzando un numero di record. - Ritorna il codice di errore. - @(FD) - @(IN) - La variabile record in input contiene il record da cancellare. - @(FN) - @(ISV) - knum = numero della chiave attiva. - werr = codice di errore restituito da CBUnLockFiles. - oldrec = buffer di lavoro. - key1 = valore della chiave. - - Versione DOS e XENIX - @(FSV) - */ -int cisdelrec(isfd,recnum,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecNoType recnum; /* numero di record */ - int *err; /* codice di errore */ -{ - int knum = (isfd->i.PN+1), werr; - int junk; - RecType oldrec ; - TKey key1 ; - *err = NoErr; - if(isfd == (isfdptr) NULL) return ((*err = IsNotOpen)); - oldrec = (RecType) malloc(isfd->d->LenR); - isfd->RecNo = recnum; - savekeystat(isfd); - CRead(&isfd->f, oldrec, isfd->RecNo, NoLock); - if ((*err = isfd->f.IOR)) - { - free(oldrec); - return(*err); - } - if ((isfd->r->NKeys) && IndActive) - { - if(/* test_share() && */ isfd->f.LockMode != ExclLock) - CBLockFile(&isfd->i, err) ; - delkeys(isfd, oldrec, knum, err); - } - IDeleteRec(oldrec); - CWrite(&isfd->f,oldrec,isfd->RecNo,UnLock); - if ((*err = isfd->f.IOR)) - { - IRecallRec(oldrec); - CWrite(&isfd->f,oldrec,isfd->RecNo,NoLock); - if ((isfd->r->NKeys) && IndActive) addkeys(isfd, oldrec, knum, err); - } -#ifndef DOS - else - { - if (isstate == NOTRANS) - { - writelog(FNDELETE, isfd, NULL); - CLockRec(&isfd->f,isfd->RecNo,UnLock); - } - else writeundo(FNDELETE, isfd, NULL); - } - if (/* test_share() && */(isfd->r->NKeys) && IndActive && (isfd->f.LockMode != ExclLock)) - CBUnLockFile(&isfd->i, &werr) ; -#else - /* if (test_share()) */ -{ - CLockRec(&isfd->f,isfd->RecNo,UnLock); - if (isfd->r->NKeys && IndActive && - (isfd->f.LockMode != ExclLock)) - CBUnLockFile(&isfd->i, &werr) ; -} -#endif -free(oldrec); -isfd->RecNo = 0; -return(*err); -} -/* - @(#) cisgetrecno ISAM - @(ID) - Restituisce il numero del record corrente. - @(FD) - */ -RecNoType cisgetrecno(isfd, err) - isfdptr isfd; /* descrittore del file ISAM */ - int *err; /* codice di errore */ - -{ - if (!isfd->RecNo) *err = IsNotCurr; - else *err = NoErr; - return(isfd->RecNo); -} -/* - @(#) cislock ISAM - @(ID) - Blocca il file ISAM. - @(FD) - @(ISV) - junk = variabile spazzatura per la chiamata di sleep. - @(FSV) - */ -int cislock(isfd,err) - isfdptr isfd; /* descrittore del file ISAM */ - int *err; /* codice di errore */ -{ - int junk; - *err = NoErr ; - if (lseek(isfd->f.F, 0L, 0) == -1) return ((*err = CIOResult())); -#ifndef DOS - do - { - if (lockf(isfd->f.F,F_TLOCK,0L) == -1) - { - *err = CIOResult() ; - junk = sleep(1) ; - } - } while (TESTLOCK(*err)) ; -#endif - if(/* test_share() && */ isfd->f.LockMode != ExclLock) - CBLockFile(&isfd->i,err); - return(*err); -} -/* - @(#) cisunlock ISAM - @(ID) - Sblocca un file ISAM. - @(FD) - */ -int cisunlock(isfd,err) - isfdptr isfd; /* descrittore del file */ - int *err; /* codice di errore */ -{ - return(cisrelease(isfd,err)); -} -/* - @(#) cisrelease ISAM - @(ID) - Sblocca un file ISAM. - @(FD) - */ -int cisrelease(isfd,err) - isfdptr isfd; /* descrittore del file ISAM */ - int *err; /* codice di errore */ -{ - *err = NoErr ; -#ifndef DOS - if (lseek(isfd->f.F, 0L, 0) == -1) return ((*err = CIOResult())); - do - { - if (lockf(isfd->f.F,F_ULOCK,0L) == -1) *err = CIOResult() ; - } while (TESTLOCK(*err)) ; -#endif - if(/* test_share() && */ isfd->f.LockMode != ExclLock) - CBUnLockFile(&isfd->i,err); - return(*err); -} -/* - @(#) IndexOn ISAM - @(ID) - Attiva Aggiornamento Indici. - @(FD) - @(IN) - Di default gli indici sono attivi. - @(FN) - */ -void IndexOn() -{ - IndActive = TRUE ; -} -/* - @(#) IndexOff ISAM - @(ID) - Disattiva l'aggiornamento Indici. - @(FD) - */ -void IndexOff() -{ - IndActive = FALSE ; -} -#ifndef DOS -/* - @($) undoname ISAM - @(ID) - Restituisce il nome del file di Undo. - @(FD) - @(ISV) - path = stringa contenente il nome file. - @(FSV) - */ -char *undoname() -{ - static PathSt path; - TMPFNAME(path, "undo"); - return(path); -} -/* - @($) writeundo ISAM - @(ID) - Scrive una operazione effettuata nel file di Undo. - @(FD) - @(ISV) - fd = puntatore al file. - uname = nome del file di undo. - lgh = variabile di lavoro che contiene l' header del record di undo. - @(FSV) - */ -void writeundo(fntype,isfd,record) - int fntype; /* operazione da effettuare */ - isfdptr isfd; /* descrittore del file */ - RecType record; /* buffer contenente il record */ -{ - int fd; - PathSt uname; - loghead lgh; - - if (isfd->ln <= 0) return ; - strcpy(uname ,undoname()); - if ((fd = open(uname, O_WRONLY | O_CREAT | O_APPEND, 0666)) == -1) - fatal_box("Writeundo : Error n. %d ", errno); - lgh.type = fntype; - lgh.time = time(NULL); - lgh.procid = getpid(); - lgh.userid = getuid(); - lgh.filenum = isfd->ln; - lgh.recnum = isfd->RecNo; - lgh.lenrec = isfd->d->LenR; - if (write(fd, &lgh, sizeof(lgh)) == -1) - fatal_box("Writeundo : Error n. %d ", errno); - if (fntype & (FNREWRITE)) - if (write(fd, record, lgh.lenrec) == -1) - fatal_box("Writeundo : Error n. %d ", errno); - if (close(fd) == -1) - fatal_box("Writeundo : Error n. %d ", errno); -} -/* - @($) writelog ISAM - @(ID) - Scrive sul file Giornale l'operazione effettuata. - @(FD) - @(ISV) - junk = variabile spazzatura per la chiamata di execunlock. - lname = nome del file Giornale (LOG). - fd = puntatore al file giornale. - lgh = testata del file giornale. - @(FSV) - */ -void writelog(fntype,isfd,record) - int fntype; /* operazione effetuata */ - isfdptr isfd; /* descrittore del file ISAM */ - RecType record; /* buffer per il record */ -{ - int fd,junk; - PathSt lname; - loghead lgh; - if (!isjournal) return; - if (isfd->ln <= 0) return ; - strcpy(lname, CInsPref(logname, NORDIR)); - while (excllock(lname,TRUE) == -1) sleep(1); - if ((fd = open(lname, O_WRONLY | O_CREAT | O_APPEND, 0666)) == -1) - { - junk = exclunlock(lname,TRUE); - fatal_box("Writelog : Error n. %d ", errno); - } - lgh.type = fntype + FNSTTRANS; - lgh.time = time(NULL); - lgh.procid = getpid(); - lgh.userid = getuid(); - if (fntype & (FNREWRITE + FNWRITE + FNDELETE)) - { - lgh.filenum = isfd->ln; - lgh.recnum = isfd->RecNo; - lgh.lenrec = isfd->d->LenR; - } - else - { - lgh.filenum = 0; - if (fntype == FNREORG) lgh.recnum = *((RecNoType *) record); - else lgh.recnum = 0L; - if (fntype == FNCHGREC) lgh.lenrec = sizeof(RecDes); - else lgh.lenrec = 0; - } - if (write(fd, &lgh, sizeof(lgh)) == -1) - { - junk = exclunlock(lname,TRUE); - fatal_box("Writelog : Error n. %d ", errno); - } - if (fntype & (FNREWRITE + FNWRITE + FNCHGREC)) - if (write(fd, record, lgh.lenrec) == -1) - { - junk = exclunlock(lname,TRUE); - fatal_box("Writelog : Error n. %d ", errno); - } - if (close(fd) == -1) - fatal_box("Writelog : Error n. %d ", errno); - junk = exclunlock(lname,TRUE); -} -#endif -/* - @(#) StTrans ISAM - @(ID) - Inizia una transazione. - @(FD) - */ -void StTrans() -{ -#ifndef DOS - if (isstate == TRANS) EndTrans(); -#endif - isstate = TRANS; -} -#ifndef DOS -/* - @($) getopenf ISAM - @(ID) - Riconfigura il file di lavoro attivo sul file di numero logico "ln". - @(FD) - @(ISV) - junk = variabile spazzatura per la chiamata alla cisclose. - err = codice di errore ritornato dalla cisopen. - @(FSV) - */ -void getopenf(ln,record) - int ln; /* numero logico del file */ - RecType *record; /* puntatore al buffer per il record */ -{ - int err,junk; - if (openf[ln - 1] == NULL) - { - if (wln != ln) - { - if (wln != -1) junk = cisclose(&wisfd ,record ,&err); - cisopen(&wisfd, ln, record, ManuLock, &err); - wln = ln; - } - } - else *record = realloc(*record, openf[ln - 1]->d->LenR); -} -#endif -/* - @(#) EndTrans ISAM - @(ID) - Chiude una transazione. - @(FD) - @(ISV) - fdl, fdu = puntatori ai file di LOG e di Undo. - lname, uname = nomi dei file di LOG e di Undo. - lgh, lgh1 = variabili di lavoro contenenti le testate dei file di log. - nread = variabile di lavoro per la chiamata alla read. - werr = codice di errore ritornato dalla cisclose. - junk = variabile spazzatura per la chiamata di exclunlock. - start = variabile di lavoro. - record = buffer di lavoro. - @(FSV) - */ -void EndTrans() -{ -#ifndef DOS - int fdl, fdu; - PathSt lname, uname; - loghead lgh, lgh1; - int nread, werr, junk, start = FNSTTRANS; - RecType record; - strcpy(lname ,CInsPref(logname, NORDIR)); - while (excllock(lname,TRUE) == -1) sleep(1); - if (((fdl = open(lname, O_WRONLY | O_CREAT | O_APPEND, 0666)) == -1) || - ((fdu = open(uname, O_RDONLY, 0666)) == -1)) - { - junk = exclunlock(lname,TRUE); - fatal_box("Endtrans : Error n. %d ", errno); - } - while ((nread = read(fdu, &lgh, sizeof(lgh))) > 0) - { - lgh.type += start; - start = 0; - if (write(fdl, &lgh, sizeof(lgh)) == -1) - { - junk = exclunlock(lname,TRUE); - fatal_box("Endtrans : Error n. %d ", errno); - } - if (lgh.type == FNREWRITE) - if (lseek(fdu, (long) lgh.lenrec, 1) == -1) - { - junk = exclunlock(lname,TRUE); - fatal_box("Endtrans : Error n. %d ", errno); - } - getopenf(lgh.filenum, &record); - CRead(&(openf[lgh.filenum - 1]->f), record, lgh.recnum, UnLock); - if (write(fdl, record, lgh.lenrec) == -1) - { - junk = exclunlock(lname,TRUE); - fatal_box("Endtrans : Error n. %d ", errno); - } - } - if ((nread <= 0) || (close(fdu) == -1) || (close(fdl) == -1) || - (unlink(uname) == -1)) - { - junk = exclunlock(lname,TRUE); - fatal_box("Endtrans : Error n. %d ", errno); - } - if (wln != -1) - { - junk = cisclose(&wisfd, &record, &werr); - wln = -1; - } - junk = exclunlock(lname,TRUE); -#endif -} -/* - @(#) AbTrans ISAM - @(ID) - Abortisce una transazione. - @(FD) - */ -void AbTrans() -{ -#ifndef DOS - int fd; - PathSt uname; - loghead lgh; - int nread, werr, junk; - RecType record; - RecType oldrec; - strcpy(uname ,undoname()); - if ((fd = open(uname, O_RDONLY, 0666)) == -1) - fatal_box("Abtrans : Error n. %d ", errno); - while ((nread = read(fd, &lgh, sizeof(lgh))) > 0) - { - getopenf(lgh.filenum, &record); - if (oldrec == NULL) oldrec = malloc(lgh.lenrec); - else oldrec = realloc(oldrec, lgh.lenrec); - if (lgh.type & (FNREWRITE)) - { - if ((nread = read(fd, record, lgh.lenrec)) <= 0) - fatal_box("Abtrans : Error n. %d ", errno); - } - if (lgh.lenrec != openf[lgh.filenum - 1]->d->LenR) - fatal_box("Abtrans : Error n. %d ", IsNoMatch); - CRead(&(openf[lgh.filenum - 1]->f), oldrec, lgh.recnum, NoLock); - switch (lgh.type) - { - case FNREWRITE : - junk = replkeys(openf[lgh.filenum - 1], oldrec, record, - openf[lgh.filenum - 1]->i.PN + 1, &werr); - CWrite(&(openf[lgh.filenum - 1]->f), record, lgh.recnum, UnLock); - break; - case FNDELETE : - IRecallRec(oldrec); - junk = addkeys(openf[lgh.filenum - 1], oldrec, - openf[lgh.filenum - 1]->i.PN + 1, &werr); - CWrite(&(openf[lgh.filenum - 1]->f), oldrec, lgh.recnum, UnLock); - break; - case FNWRITE : - IDeleteRec(oldrec); - junk = delkeys(openf[lgh.filenum - 1], oldrec, - openf[lgh.filenum - 1]->i.PN + 1, &werr); - CWrite(&(openf[lgh.filenum - 1]->f), record, lgh.recnum, UnLock); - break; - } - } - if ((nread == -1) || (close(fd) == -1) || (unlink(uname) == -1)) - fatal_box("Abtrans : Error n. %d ", errno); - if (wln != -1) - { - junk = cisclose(&wisfd, &record, &werr); - wln = -1; - } -#endif -} - +/* + * + @(SH) Funzioni per la gestione dei file ISAM + @(C$) PRIVATE + logname : nome del file di LOG (GIORNALE) + INTTLOCK : costante che indica alla funzione di lettura che e' stata chaimata dalla funzione di scrittura e quindi deve solo controllare lo stato di lock del record + ISLOCKED : costante che indica che il record e' bloccato + @(VG$) PRIVATE + KSv, PosSv : variabili di lavoro + PagSv, IndSv : variabili di lavoro + IndActive : stato indici - TRUE = Aggiornati ad ogni modifica, FALSE = aggiorna solo i dati + isstate : Stato transazione corrente + win,wisfd : variabili di lavoro + isjournal : TRUE scrive il giornale + openf : array di TUTTI i puntatori ai descrittori dei file ISAM aperti + ------------------------------------------------------------------------------- + */ +#include "cisam.h" +#include "libdefs.h" +#include "checks.h" +#ifdef __WATCOMC__ +#include +#else +#include +#endif +#define logname "log.gen" +#define INTTLOCK 0xF000 +#define ISLOCKED 225 +#define NOALLOC (char **) -1 +TKey KSv; +int PosSv; +RecNoType PagSv,IndSv; +BOOLEAN IndActive = TRUE; +int isstate = NOTRANS ; +int wln = -1; +isfdptr wisfd; +extern BOOLEAN isjournal; +/* Guy moved them here from extcdecl.h */ +Str80 cprefix; +isfdptr* openf; +void savekeystat(isdef *); +void restkeystat(isdef *,int ); +int addkeys(isdef *,RecType ,int ,int *); +int delkeys(isdef *,RecType ,int ,int *); +int replkeys(isdef *,RecType ,RecType ,int ,int *); +#ifndef DOS +void writeundo(int ,isdef *,RecType); +void writelog(int ,isdef *,RecType); +char *undoname(void); +void getopenf(int ,RecType *); +#endif +/* + @($) savekeystat ISAM + @(ID) + Salva la chiave corrente. + @(FD) + */ +void savekeystat(isfd) + isfdptr isfd; /* descrittore del file ISAM */ +{ + strcpy(KSv,isfd->i.Key); + IndSv = isfd->i.Ind; + PosSv = isfd->i.Pos; + PagSv = isfd->i.CurPag; +} +/* + @($) restkeystat ISAM + @(ID) + Ripristina la chiave corrente. + @(FD) + */ +void restkeystat(isfd,knum) + isfdptr isfd; /* descrittore del file ISAM */ + int knum; /* numero della chiave */ +{ + isfd->i.PN = knum - 1; + strcpy(isfd->i.Key,KSv); + isfd->i.Ind = IndSv; + isfd->i.Pos = PosSv; + isfd->i.CurPag = PagSv; +} +/* + @($) relisfd ISAM + @(ID) + Vuota il descrittore del file . + @(FD) + */ +void relisfd(isfd) + isfdptr *isfd; /* descrittore del file ISAM */ +{ + free((char *) (*isfd)->d); + free((char *) (*isfd)->r); + free((char *) (*isfd)); +} +/* + @($) getisfd ISAM + @(ID) + Alloca e carica il descrittore del file con numero logico "logicname". + @(FD) + */ +void getisfd(isfd, logicname) + isdef **isfd; /* descrittore del file ISAM */ + int logicname; /* numero logico del file */ +{ + (*isfd) = (isfdptr) malloc(sizeof(**isfd)); + (*isfd)->d = (FileDes *) malloc(sizeof(*((*isfd)->d))); + (*isfd)->r = (RecDes *) malloc(sizeof(*((*isfd)->r))); + COpenDir(ManuLock, NORDIR); + CGetFile(logicname, (*isfd)->d, NoLock, NORDIR); + if ((!(STREMPTY((*isfd)->d->SysName))) && ((*isfd)->d->SysName[0] != '$')) + (*isfd)->ft = COMDIR; + else + (*isfd)->ft = NORDIR; + CCloseDir(NORDIR); + COpenDir(ManuLock, (*isfd)->ft); + COpenFile(logicname, (*isfd)->d, NoLock, (*isfd)->ft); + CCloseDir((*isfd)->ft); + COpenRecDir(ManuLock, (*isfd)->ft); + CGetRec(logicname,(*isfd)->r, (*isfd)->ft); + CCloseRecDir((*isfd)->ft); +} +/*void dump(s,l) + RecType s; + int l; + { + message_box("dump : record: %s ", &s[1]); + }*/ +/* + @(#) cisupdflags ISAM + @(ID) + Aggiorna all'interno del direttorio i campi EOD e Flags. + Ritorna il codice di errore. + @(FD) + @(ISV) + wd = riga relativa al file ISAM in oggetto nel Direttorio. + fdir = identificatore del file direttorio. + - Versione DOS e XENIX + @(FSV) + @(IN) + Il campo Flags viene aggiornato comunque, mentre EOD viene aggiornato solo + se il parametro di input "updateeod" e' TRUE. + @(FN) + */ +int cisupdflags(isfd,err,updateeod) + isdef *isfd; /* puntatore al descrittore del file ISAM */ + int *err; /* codice di errore */ + BOOLEAN updateeod; /* se TRUE si aggiorna anche EOD */ + +{ + FileDes wd; + + *err = NoErr ; + if (isfd->ln <= 0) return(*err) ; + COpenDir( ManuLock, isfd->ft); + COpenFile(isfd->ln, &wd, Lock, isfd->ft); + if ((*err = fdir[isfd->ft].IOR) == NoErr) + { + wd.Flags = isfd->d->Flags; + /* #ifdef DOS + if (updateeod) wd.EOD = isfd->d->EOD; + #else */ + if ((updateeod) && (isfd->f.LockMode == ExclLock)) wd.EOD = isfd->d->EOD; + /* #endif */ + CCloseFile(isfd->ln, &wd, isfd->ft); + } + CCloseDir(isfd->ft); + return(*err); +} + +/* + @(#) cisgeteod ISAM + + @(ID) + Ritorna l' EOD del file. + @(FD) + + @(ISV) + + - Versione DOS e XENIX + @(FSV) + + */ + +RecNoType cisgeteod(isfd,err) + isfdptr isfd; /* puntatore al descrittore del file ISAM */ + int *err; /* codice di errore */ + +{ + + *err = NoErr ; + if (isfd->ln > 0) + { + COpenDir( ManuLock , isfd->ft); + COpenFile(isfd->ln, isfd->d, NoLock, isfd->ft); + CCloseDir(isfd->ft); + } + return(isfd->d->EOD) ; +} + +/* + @(#) cisopen ISAM + + @(ID) + Apre un file ISAM e alloca il buffer per un record a attiva la chiave 1 (uno). + Ritorna il codice di errore. + @(FD) + + @(ISV) + werr = variabile di lavoro che raccoglie il codice errore proveniente dalla CBCloseFile. + + s = stringa di lavoro per messaggi di errore. + + - Versione DOS e XENIX + @(FSV) + + @(IN) + @(FN) + */ + +int cisopen (isfd,logicname,record,mode,err) + isfdptr *isfd; /* puntatore al descrittore del file */ + int logicname; /* numero logico */ + RecType *record; /* buffer per contenere un record */ + unsigned int mode; /* modo di apertura (lock) */ + int *err; /* codice di errore */ + +{ + *err = NoErr; + if (openf[logicname - 1] != NULL) + fatal_box("File n. %d already open", logicname); +#ifndef DOS + if ((excllock(CInsPref(glockname, NORDIR), FALSE) == -1) && (errno == EACCES)) + fatal_box("Can't open directory : Error n. %d ", errno); +#endif + getisfd (isfd,logicname); + COpen(&((*isfd)->f), (*isfd)->d->SysName, (*isfd)->d->LenR, 0, mode); + if (*err = (*isfd)->f.IOR) + { + Str80 name; strcpy(name, (*isfd)->d->SysName); + relisfd(isfd); + isfd = NULL; + if (*err == 13) + { + if (mode == ExclLock) + fatal_box("L'archivio n. %d (%s) non puo' essere aperto in modo esclusivo", logicname, name); + else + fatal_box("L'archivio n. %d (%s) e' stato aperto in modo esclusivo da un altro programma", logicname, name); + } + fatal_box("Can't open file n. %d (%s): error %d ", logicname, name, *err); + } + if ((*isfd)->r->NKeys) + { + Str80 name; strcpy(name, CGetIdxName((*isfd)->d->SysName)); + CBOpenFile (&((*isfd)->i), name, mode, err); + if (*err) + { + CClose(&((*isfd)->f)); + relisfd(isfd); + isfd = NULL; + if (*err == 13) + { + if (mode == ExclLock) + fatal_box("L'indice n. %d (%s) non puo' essere aperto in modo esclusivo", logicname, name); + else + fatal_box("L'indice n. %d (%s) e' stato aperto in modo esclusivo da un altro programma", logicname, name); + } + fatal_box("Can't open index n. %d (%s): error %d ", + logicname, name, *err); + } +#ifndef DOS + else + if (mode == ExclLock) + { + CBLockFile(&((*isfd)->i), err); + if (*err) + { + int werr; + CClose(&((*isfd)->f)); + CBCloseFile(&((*isfd)->i), &werr); + relisfd(isfd); + fatal_box("Can't open exclusively file n. %d: error %d ", logicname, *err); + } + } +#endif + } + if (record != NOALLOC) + *record = (RecType) malloc((*isfd)->d->LenR); + (*isfd)->ln = logicname; + openf[logicname - 1] = *isfd; + if ((*isfd)->r->NKeys) (*isfd)->i.PN = 0; + return (*err); +} + +/* + @(#) ciscopyrec ISAM + + @(ID) + Copia un record dati da un record ad un altro. + Ritorna il codice di errore. + @(FD) + + @(ISV) + d = riga del direttorio corrispondente al file in esame. + @(FSV) + + @(IN) + @(FN) + */ + +int ciscopyrec(logicname,recdest, recsrc ,err) + int logicname; /* numero logico del file ISAM */ + RecType recdest; /* buffer destinazione */ + RecType recsrc; /* buffer sorgente */ + int *err; /* codice di errore */ + +{ + FileDes d; + int ft; + + *err = NoErr; + if (logicname < 0) logicname = -logicname; + if (openf[logicname - 1] != NULL) d = *(openf[logicname - 1]->d); +{ + COpenDir(ManuLock, NORDIR); + CGetFile(logicname, &d, NoLock, NORDIR); + if ((!(STREMPTY(d.SysName))) && (d.SysName[0] != '$')) ft = COMDIR; + else ft = NORDIR; + CCloseDir(NORDIR); + COpenDir(ManuLock, ft); + COpenFile(logicname, &d, NoLock, ft); + CCloseDir(ft); +} +memcpy(recdest, recsrc, d.LenR); +return(*err); +} + +/* + @(#) cisallocrec ISAM + + @(ID) + Alloca il buffer per un record. + Ritorna il codice di errore. + @(FD) + + @(ISV) + d = riga del direttorio corrispondente al file in esame. + @(FSV) + + @(IN) + @(FN) + */ + +int cisallocrec(logicname,record,err) + int logicname; /* numero logico del file ISAM */ + RecType *record; /* buffer per il record */ + int *err; /* codice di errore */ + +{ + FileDes d; + int ft; + + *err = NoErr; + if (logicname < 0) logicname = -logicname; + if (openf[logicname - 1] != NULL) d = *(openf[logicname - 1]->d); + else + { + COpenDir(ManuLock, NORDIR); + CGetFile(logicname, &d, NoLock, NORDIR); + if ((!(STREMPTY(d.SysName))) && (d.SysName[0] != '$')) ft = COMDIR; + else ft = NORDIR; + CCloseDir(NORDIR); + COpenDir(ManuLock, ft); + COpenFile(logicname, &d, NoLock, ft); + CCloseDir(ft); + } + *record = (RecType) malloc(d.LenR); + if (*record == ((RecType) NULL)) return(ENOMEM); + else return(*err); +} + +/* + @(#) cisclose ISAM + + @(ID) + Chiude un file ISAM e libera il buffer del record. + Ritorna il codice di errore. + @(FD) + + @(ISV) + werr = variabile di lavoro che raccoglie il codice errore proveniente dalla CBCloseFile. + + s[20] = stringa di lavoro per messaggi di errore. + + - Versione DOS e XENIX + @(FSV) + + @(IN) + Restituisce il codice di errore + @(FN) + */ + +int cisclose(isfd,rec,err) + isdef **isfd; /* puntatore al descrittore del file */ + RecType *rec; /* buffer per il record */ + int *err; /* codice di errore */ + +{ + int werr = NoErr; + + *err = NoErr; + if (((*isfd)->ln > 0) && ((*isfd == NULL) || (openf[(*isfd)->ln - 1] == NULL))) + { + if (*isfd != NULL) + error_box("File n. % isclose : Error n. %d ", (*isfd)->ln, IsNotOpen); + else + error_box("isclose : errore n. %d ", IsNotOpen); + } + CClose(&((*isfd)->f)); + *err = ((*isfd)->f.IOR); + if ((*isfd)->r->NKeys) + { + CBCloseFile(&((*isfd)->i), &werr); + if (werr != NoErr ) *err = werr; + } + if ((*isfd)->ln > 0) + openf[(*isfd)->ln - 1] = NULL ; + if ((rec != NULL) && (*rec != NULL)) + free(*rec); + relisfd(isfd); +#ifndef DOS + exclunlock(CInsPref(glockname, NORDIR), FALSE); +#endif + if (*err) + fatal_box("isclose : Error n. %d ", *err); + return (*err); +} + +/* + @(#) cisstart ISAM + + @(ID) + Esegue una lettura cambiando il numero di chiave attiva. + Ritorna il codice di errore. + @(FD) + + @(IN) + La variabile record in input contiene i campi necessari per la ricerca, + in output contiene il record letto. + + La variabile mode e' formata da un comando di lock + comando di posizionamento + . Se non si utilizza ISEQUAL o ISGREAT o ISGTEQ, il valore della variabile + record non ha nessuna importanza. + @(FN) + */ + +int cisstart(isfd,keynum,record,mode,err) + isfdptr isfd; /* descrittore del file ISAM */ + int keynum; /* numero della chiave */ + RecType record; /* buffer per il record */ + unsigned int mode; /* comando di lettura */ + int *err; /* codice di errore */ + +{ + if(isfd == ((isfdptr) NULL)) return ((*err = IsNotOpen)); + *err = NoErr; + if(!(keynum >= 1) && (keynum <= isfd->r->NKeys)) + return((*err = BTrPathErr)); + isfd->i.PN = keynum - 1; + *err = cisread(isfd,record,mode,err); + return(*err); +} + +/* + @(#) cisread ISAM + + @(ID) + Esegue una lettura utilizzando la chiave attiva. + Ritorna il codice di errore. + @(FD) + + @(ISV) + rmode = variabile che contiene il tipo lettura utilizzato. + + lmode = varibaile dhe contiene il tipo lock utilizzato. + + knum = numero chiave attiva. + + junk = variabile spazzatura per la chiamata alla funzione "sleep". + + times = variabile di lavoro. + + s = stringa contenente messaggio. + + w = descrittore finestra . + + internaltlock = flag che verifica se la isread e' stata chiamata da iswrite per testare l' esistenza di un record. + + @(FSV) + + @(IN) + La variabile record in input contiene i campi necessari per la ricerca, + in output contiene il record letto. + + La variabile mode e' formata da un comando di lock + comando di posizionamento + . Se non si utilizza ISEQUAL o ISGREAT o ISGTEQ, il valore della variabile + record non ha nessuna importanza. + @(FN) + */ + +int cisread(isfd,record,mode,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecType record;/* buffer per il record */ + unsigned int mode; /* modo di lettura */ + int *err; /* codice di errore */ + +{ + unsigned int rmode = (mode & READTYPES), + lmode = (mode & RecLockTypes), + knum = (isfd->i.PN+1); + int junk,times = 1; + TKey key,key1,key2; + /* char s[120]; */ + BOOLEAN internaltlock = (lmode == INTTLOCK); + + if (internaltlock) lmode = ShareLock; + *err = NoErr ; + if (isfd == ((isfdptr) NULL)) return ((*err = IsNotOpen)); + if (rmode & (IsPrevN + IsNextN)) + { + times = rmode & BYTEMASK; + if (rmode & IsPrevN) rmode = IsPrev; + else rmode = IsNext; + } + if (rmode == IsCurr) + { + if (!isfd->RecNo) return((*err = IsNotCurr)); + } + else + { + if (rmode == IsNext) + { + while ((times--) && (!*err)) + { + CBNext(&isfd->i,knum,key1,&isfd->RecNo,err); + } + } + else + { + if (rmode == IsPrev) + { + while ((times--) && (!*err)) + { + CBPrev(&isfd->i,knum,key1,&isfd->RecNo,err); + } + } + else + { + if (rmode == IsFirst) MinKey(CCalcLenKey(isfd->r,knum),key); + else + if (rmode == IsLast) MaxKey(CCalcLenKey(isfd->r,knum),key); + else + CBuildKey(isfd->r,knum,record,key); + CBRead(&isfd->i,knum,key,key1,&isfd->RecNo,err); + if ((rmode == IsGreat) && (!*err)) + while ((strcmp(key,key1) == 0) && (!*err)) + CBNext (&isfd->i,knum,key1,&isfd->RecNo,err); + } + } + } + do + { + if (((*err) && (rmode == IsEqual)) || + ((*err == BTrEOF) && (rmode == IsGreat))) + CRead(&isfd->f,record,isfd->RecNo,NoLock); + else + CRead(&isfd->f,record,isfd->RecNo,lmode); + if (TESTLOCK(isfd->f.IOR)) + { + if (lmode == ShareLock) + { + if (!*err) *err = ISLOCKED; + break; + } + message_box("Codice %s in uso da parte\ndi un altro utente.", key1); + if (rmode != IsCurr) + { + CBReRead(&isfd->i,knum,key1,key2,isfd->RecNo,&isfd->RecNo,&junk); + if (junk) strcpy(key1, key2) ; + } + } + else + if (!*err) *err = isfd->f.IOR; + } while (TESTLOCK(isfd->f.IOR)) ; + if (((rmode == IsFirst) || (rmode == IsLast)) && (*err != BTrEmptyTree)) + *err = NoErr; + if ((rmode == IsGtEq) && (*err != BTrEOF) && (*err != BTrEmptyTree)) + *err = NoErr ; + if (DEADLOCK(*err)) return(*err = IsDeadLock); + if (rmode == IsCurr) + { + CBuildKey(isfd->r,knum,record,key); + CBReRead(&isfd->i,knum,key,key1,isfd->RecNo,&isfd->RecNo,&junk); + } + if (*err == BTrEmptyTree) CZeroRec(isfd->r, record); + return(*err); +} + +/* + @($) addkeys ISAM + + @(ID) + Aggiunge all'indice le chiavi contenute nel record. + Ritorna il codice di errore. + @(FD) + + @(ISV) + i,j = contatori. + + werr = codice errore restituito dalla CBDelete. + + key = valore delle chiavi. + @(FSV) + + @(IN) + @(FN) + */ + +int addkeys (isfd,record,knum,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecType record; /* buffer per il record */ + int knum; /* numero chiave corrente */ + int *err; /* codice errore */ + +{ + int i,j,werr; + TKey key; + + for (i = 1;(i <= isfd->r->NKeys) && (!*err);i++) + { + CBuildKey(isfd->r,i,record,key); + CBWrite(&isfd->i,i,key,isfd->RecNo,err); + if (i == knum) savekeystat(isfd); + } + if (*err) + { + if (i == 2 && *err == BTrDupKeysNotAll) *err = IsReInsert; + for (j = 1; (j < i); j++) + { + CBuildKey(isfd->r,j,record,key); + CBDelete(&isfd->i,j,key,isfd->RecNo,&werr); + } + } + else restkeystat(isfd,knum); + return(*err); +} + +/* + @(#) ciswrite ISAM + + @(ID) + Aggiunge un nuovo record al file ISAM. + Ritorna il codice di errore. + @(FD) + + @(ISV) + werr = codice errore restituito. + + knum = numero chiave attiva. + + junk = variabile di lavoro per la chiamata di varie funzioni. + + wrec = buffer di lavoro. + @(FSV) + + @(IN) + La variabile record in input contiene il record da aggiungere. + @(FN) + */ + +int ciswrite (isfd,record,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecType record; /* buffer per il record */ + int *err; /* codice di errore */ + +{ + int knum = (isfd->i.PN+1), werr, junk; + RecNoType neweox; + + *err = NoErr; + if(isfd == ((isfdptr) NULL)) return((*err = IsNotOpen)); + if (isfd->ln > 0) + { + COpenDir (ManuLock, isfd->ft); + COpenFile(isfd->ln,isfd->d, NoLock, isfd->ft); + } + if (isfd->d->EOD == isfd->d->EOX) + { + neweox = isfd->d->EOX / 20 + 1; + if (neweox < 10) neweox = 10; + if (demoflag) + *err = IsFileFull; + else + { + neweox += isfd->d->EOX; + cisextend(isfd, isfd->ln, neweox, err); + } + if (*err == NoErr) + { + if (isfd->ln > 0) + { + COpenFile(isfd->ln,isfd->d, NoLock, isfd->ft); + for (junk = 0; junk < isfd->r->NKeys; junk++) + isfd->i.Base[junk].PEOX = neweox; + } + else + { + isfd->d->EOX = neweox; + if (isfd->f.LockMode == ExclLock) + for (junk = 0; junk < isfd->r->NKeys; junk++) + isfd->i.Base[junk].PEOX = neweox; + } + } + else + { + if (isfd->ln > 0) + CCloseDir(isfd->ft); + isfd->RecNo = 0; + if (DEADLOCK(*err)) *err = IsDeadLock; + return((*err ? *err : (*err = IsFileFull))); + } + } + IRecallRec(record); + if (/* test_share() && */ isfd->f.LockMode != ExclLock) + { + RecType wrec = malloc(isfd->d->LenR); + memcpy(wrec, record, isfd->d->LenR); + savekeystat(isfd); + junk = cisstart(isfd, 1, wrec, NoLock+IsEqual, &junk); + restkeystat(isfd, knum); + free(wrec); + + if ((junk == NoErr) || (junk == ISLOCKED)) + { + *err = IsReInsert; + if (isfd->ln > 0) + CCloseDir(isfd->ft); + isfd->RecNo = 0; + return(*err); + } + } + if (isfd->ln > 0) + { + COpenFile(isfd->ln,isfd->d, Lock, isfd->ft); + } + isfd->RecNo = (++isfd->d->EOD); + if ((isfd->r->NKeys) && IndActive) + { + if(/* test_share() && */ isfd->f.LockMode != ExclLock) + CBLockFile(&isfd->i,err) ; + if (!addkeys(isfd, record, knum, err)) + { + CWrite(&isfd->f,record,isfd->RecNo,NoLock); + if ((*err = isfd->f.IOR)) + { + isfd->RecNo = 0; + junk = delkeys(isfd, record, knum, &werr); + } + /* else + if (isfd->ln > 0) + CCloseFile(isfd->ln,isfd->d, isfd->ft) ; */ + } + else isfd->d->EOD-- ; + if (isfd->ln > 0) + { + CCloseFile(isfd->ln,isfd->d, isfd->ft) ; + } + if(/* test_share() && */ isfd->f.LockMode != ExclLock) + CBUnLockFile(&isfd->i, &werr) ; + } + else + { + CWrite(&isfd->f,record,isfd->RecNo,NoLock); + if ((*err = isfd->f.IOR)) isfd->RecNo = 0; + else CCloseFile(isfd->ln,isfd->d, isfd->ft) ; + } + if (!(*err)) + { +#ifndef DOS + if (isstate == NOTRANS) writelog(FNWRITE, isfd, record); + else writeundo(FNWRITE, isfd, record); +#endif + } + if (isfd->ln > 0) + CCloseDir(isfd->ft); + /* if (test_share()) */ +{ + junk = cisunlock(isfd, &junk); + if (isstate == NOTRANS) + CLockRec(&isfd->f,isfd->RecNo,UnLock); + if (DEADLOCK(*err)) *err = IsDeadLock; +} +return(*err); +} + +/* + @($) delkeys ISAM + + @(ID) + Cancella le chiavi contenute nel record dall'indice. + Ritorna il codice di errore. + @(FD) + + @(ISV) + i,j = contatori. + + werr = codice errore da CBWrite. + + key = valori chiave. + @(FSV) + + @(IN) + @(FN) + */ + +int delkeys (isfd,record,knum,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecType record; /* buffer per il record */ + int knum; /* numero della chiave attuale */ + int *err; /* codice di errore */ + +{ + int i,j,werr; + TKey key; + + for (i = 1;(i <= isfd->r->NKeys)&&(!*err);i++) + { + CBuildKey(isfd->r,i,record,key); + CBDelete(&isfd->i,i,key,isfd->RecNo,err); + } + if (*err) + { + for (j = 1;(j < i);j++) + { + CBuildKey(isfd->r,j,record,key); + CBWrite(&isfd->i,j,key,isfd->RecNo,&werr); + } + } + else restkeystat(isfd,knum); + return(*err); +} + +/* + @(#) cisdelete ISAM + + @(ID) + Cancella un record da un file ISAM. + Ritorna il codice di errore. + @(FD) + + @(ISV) + knum = numero chiave successiva a quella attiva. + + werr = codice errore da CBUnLockFile. + + key1,key = valori chiave. + + - Versione DOS e XENIX + @(FSV) + + @(IN) + La variabile record in input contiene il record da cancellare. + @(FN) + */ + +int cisdelete(isfd,record,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecType record; /* buffer per il record */ + int *err; /* codice di errore */ + +{ + int knum = (isfd->i.PN+1), werr; + TKey key,key1; + + if(isfd == ((isfdptr) NULL)) return((*err = IsNotOpen)); + *err = NoErr; + savekeystat(isfd); + CBuildKey(isfd->r,1,record,key); + *err = NoErr ; + CBRead(&isfd->i,1,key,key1,&isfd->RecNo,err); + if (*err) + { + restkeystat(isfd,knum); + return(*err); + } + CRead(&isfd->f, record, isfd->RecNo, NoLock); + if ((*err = isfd->f.IOR)) + { + restkeystat(isfd,knum); + return(*err); + } + if ((isfd->r->NKeys) && IndActive) + { + if( /* test_share() && */ isfd->f.LockMode != ExclLock) + CBLockFile(&isfd->i,err) ; + delkeys(isfd, record, knum, err) ; + } + IDeleteRec(record); + CWrite(&isfd->f,record,isfd->RecNo,UnLock); + if((*err = isfd->f.IOR)) + { + IRecallRec(record); + CWrite(&isfd->f,record,isfd->RecNo,NoLock); + if ((isfd->r->NKeys) && IndActive) addkeys(isfd, record, knum, err) ; + restkeystat(isfd,knum); + } +#ifndef DOS + else + { + if (isstate == NOTRANS) + { + writelog(FNDELETE, isfd, NULL); + CRead(&isfd->f,record,isfd->RecNo,UnLock); + } + else writeundo(FNDELETE, isfd, NULL); + } + if (/* test_share() && */(isfd->r->NKeys) && IndActive && + (isfd->f.LockMode != ExclLock)) + CBUnLockFile(&isfd->i, &werr) ; +#else + /* if (test_share()) */ +{ + CRead(&isfd->f,record,isfd->RecNo,UnLock); + if (isfd->r->NKeys && IndActive && + (isfd->f.LockMode != ExclLock)) + CBUnLockFile(&isfd->i, &werr) ; +} +#endif +return(*err); +} + +/* + @($) replkeys ISAM + + @(ID) + Rimpiazza le chiavi all'interno dell'indice. + Ritorna il codice di errore. + @(FD) + + @(ISV) + i,j = contatori. + + werr = codice errore ritornato da CBDelete e CBWrite. + + key,key1 = valori delle chiavi. + @(FSV) + */ + +int replkeys (isfd,oldrec,record,knum,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecType oldrec; /* buffer contenente il vecchio record */ + RecType record; /* buffer contenente il nuovo record */ + int knum; /* numero della chiave attuale */ + int *err; /* codice di errore */ + +{ + int i,j,werr; + TKey key,key1; + + for (i = 1;(i <= isfd->r->NKeys)&&(!*err);i++) + { + CBuildKey(isfd->r,i,record,key); + CBuildKey(isfd->r,i,oldrec,key1); + if (strcmp(key,key1) != 0) + { + CBDelete(&isfd->i,i,key1,isfd->RecNo,err); + if (*err) break; + CBWrite(&isfd->i,i,key,isfd->RecNo,err); + if (*err) CBWrite(&isfd->i,i,key1,isfd->RecNo,err); + if (i == knum) savekeystat(isfd); + } + } + if (*err) + { + for (j = 1;(j < i);j++) + { + CBuildKey(isfd->r,j,record,key); + CBuildKey(isfd->r,j,oldrec,key1); + if (strcmp(key,key1) != 0) + { + CBDelete (&isfd->i,j,key,isfd->RecNo,&werr); + CBWrite(&isfd->i,j,key1,isfd->RecNo,&werr); + } + } + } + else restkeystat(isfd,knum); + return(*err); +} + +/* + @(#) cisrewrite ISAM + + @(ID) + Aggiorna un record nel file ISAM. + Ritorna il codice di errore. + @(FD) + + @(ISV) + knum = numero chiave successiva all'attuale. + + werr = codice errore restituito da CBUnLock. + + key, key1 = valori delle chiavi. + + oldrec = buffer di lavoro. + + - Versione DOS e XENIX + @(FSV) + + @(IN) + La variabile record in input contiene il record da aggiornare. + Utilizza la chiave 1 per ritrovare il record da aggiornare. + @(FN) + */ + +int cisrewrite(isfd,record,err) + isfdptr isfd; /* descrittore del file isam */ + RecType record; /* buffer contenente i record */ + int *err; /* codice di errore */ + +{ + int knum = (isfd->i.PN+1), werr; + TKey key,key1; + RecType oldrec; + + *err = NoErr ; + if(isfd == ((isfdptr) NULL)) return((*err = IsNotOpen)); + oldrec = (RecType) malloc(isfd->d->LenR); + savekeystat(isfd); + IRecallRec(record); + CBuildKey(isfd->r,1,record,key); + CBRead(&isfd->i,1,key,key1,&isfd->RecNo,err); + if(*err) + { + restkeystat(isfd,knum); + return(*err); + } + CRead(&isfd->f,oldrec,isfd->RecNo,NoLock); + if ((*err = isfd->f.IOR)) + { + restkeystat(isfd,knum); + free(oldrec); + return(*err); + } + if (memcmp(oldrec,record,isfd->d->LenR) == 0) + { + *err = NoErr; + restkeystat(isfd,knum); + CLockRec(&isfd->f,isfd->RecNo,UnLock); + free(oldrec); + return(*err); + } + if ((isfd->r->NKeys) && IndActive) + { + if(/* test_share() && */ isfd->f.LockMode != ExclLock) + CBLockFile(&isfd->i, err) ; + replkeys(isfd, oldrec, record, knum, err) ; + if(/* test_share() && */ isfd->f.LockMode != ExclLock) + CBUnLockFile(&isfd->i, &werr) ; + } + CWrite(&isfd->f,record,isfd->RecNo,NoLock); + if ((*err = isfd->f.IOR)) + { + CWrite(&isfd->f,oldrec,isfd->RecNo,NoLock); + replkeys(isfd, record, oldrec, knum, err) ; + restkeystat(isfd,knum); + } + else +#ifndef DOS + { + if (isstate == NOTRANS) + { + writelog(FNREWRITE, isfd, record); + CLockRec(&isfd->f,isfd->RecNo,UnLock); + } + else writeundo(FNREWRITE, isfd, oldrec); + } + +#else + /* if (test_share()) */ + CLockRec(&isfd->f,isfd->RecNo,UnLock); +#endif + free(oldrec); + return(*err); +} + +/* + @(#) cisdelcurr ISAM + + @(ID) + Cancella il record corrente. + Ritorna il codice di errore. + @(FD) + */ + +int cisdelcurr(isfd,err) + isfdptr isfd; /* descrittore del file ISAM */ + int *err; /* codice di errore */ + +{ + if(isfd->RecNo) cisdelrec(isfd,isfd->RecNo,err); + else *err = IsNotCurr; + return(*err); +} + +/* + @(#) cisrewcurr ISAM + + @(ID) + Riscrive il record corrente. + Ritorna il codice di errore. + @(FD) + + @(IN) + La variabile record in input contiene il record da aggiornare. + @(FN) + */ + +int cisrewcurr(isfd,record,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecType record; /* buffer contenente il record */ + int *err; /* codice di errore */ + +{ + if(isfd->RecNo) cisrewrec(isfd,isfd->RecNo,record,err); + else *err = IsNotCurr; + return (*err); +} + +/* + @(#) cisreadrec ISAM + + @(ID) + Legge un record di numero "recnum". + Ritorna il codice di errore. + @(FD) + */ + +int cisreadrec(isfd,recnum,record,mode,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecNoType recnum; /* numero del record */ + RecType record; /* buffer per il record */ + unsigned int mode; /* modo di lock */ + int *err; /* codice di errore */ + +{ + isfd->RecNo = recnum; + return(cisread(isfd,record,IsCurr+(mode & RecLockTypes),err)); +} + +/* + @(#) ciswriterec ISAM + + @(ID) + Riscrive un record di numero "recnum". + @(FD) + + @(IN) + La variabile record in input contiene il record da aggiornare. + @(FN) + + @(ISV) + knum = numero chiave attiva. + + werr = codice errore restituito da CBUnLockFile. + + oldrec = buffer di lavoro. + + - Versione DOS e XENIX + @(FSV) + */ + +int cisrewrec(isfd,recnum,record,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecNoType recnum; /* numero del record da riscrivere */ + RecType record; /* buffer per il record */ + int *err; /* codice di errore */ + +{ + int knum = (isfd->i.PN+1), werr; + RecType oldrec; + + *err = NoErr; + if (isfd == ((isfdptr) NULL)) return ((*err = IsNotOpen)); + oldrec = (RecType) malloc(isfd->d->LenR); + isfd->RecNo = recnum; + IRecallRec(record); + CRead(&isfd->f,oldrec,isfd->RecNo,NoLock); + if ((*err = isfd->f.IOR)) + { + free(oldrec); + return(*err); + } + if (memcmp(oldrec,record,isfd->d->LenR) == 0) + { + *err = NoErr; + /* if (test_share()) */ + CLockRec(&isfd->f,isfd->RecNo,UnLock); + free(oldrec); + return(*err); + } + if ((isfd->r->NKeys) && IndActive) + { + if (/* test_share() && */ isfd->f.LockMode != ExclLock) + CBLockFile(&isfd->i, err) ; + replkeys(isfd, oldrec, record, knum, err) ; + if (/* test_share() && */ isfd->f.LockMode != ExclLock) + CBUnLockFile(&isfd->i, &werr) ; + } + if (isstate == NOTRANS) CWrite(&isfd->f,record,isfd->RecNo,UnLock); + else CWrite(&isfd->f,record,isfd->RecNo,NoLock); + if ((*err = isfd->f.IOR)) + { + CWrite(&isfd->f,oldrec,isfd->RecNo,NoLock); + replkeys(isfd, record, oldrec, knum, err) ; + } +#ifndef DOS + else + { + if (isstate == NOTRANS) + { + writelog(FNREWRITE, isfd, record); + CLockRec(&isfd->f,isfd->RecNo,UnLock); + } + else writeundo(FNREWRITE, isfd, oldrec); + } +#else + /* if (test_share()) */ + CLockRec(&isfd->f,isfd->RecNo,UnLock); +#endif + free(oldrec); + return(*err); +} +/* + @(#) cisdelrec ISAM + @(ID) + Cancella un record utilizzando un numero di record. + Ritorna il codice di errore. + @(FD) + @(IN) + La variabile record in input contiene il record da cancellare. + @(FN) + @(ISV) + knum = numero della chiave attiva. + werr = codice di errore restituito da CBUnLockFiles. + oldrec = buffer di lavoro. + key1 = valore della chiave. + - Versione DOS e XENIX + @(FSV) + */ +int cisdelrec(isfd,recnum,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecNoType recnum; /* numero di record */ + int *err; /* codice di errore */ +{ + int knum = (isfd->i.PN+1), werr; + int junk; + RecType oldrec ; + TKey key1 ; + *err = NoErr; + if(isfd == (isfdptr) NULL) return ((*err = IsNotOpen)); + oldrec = (RecType) malloc(isfd->d->LenR); + isfd->RecNo = recnum; + savekeystat(isfd); + CRead(&isfd->f, oldrec, isfd->RecNo, NoLock); + if ((*err = isfd->f.IOR)) + { + free(oldrec); + return(*err); + } + if ((isfd->r->NKeys) && IndActive) + { + if(/* test_share() && */ isfd->f.LockMode != ExclLock) + CBLockFile(&isfd->i, err) ; + delkeys(isfd, oldrec, knum, err); + } + IDeleteRec(oldrec); + CWrite(&isfd->f,oldrec,isfd->RecNo,UnLock); + if ((*err = isfd->f.IOR)) + { + IRecallRec(oldrec); + CWrite(&isfd->f,oldrec,isfd->RecNo,NoLock); + if ((isfd->r->NKeys) && IndActive) addkeys(isfd, oldrec, knum, err); + } +#ifndef DOS + else + { + if (isstate == NOTRANS) + { + writelog(FNDELETE, isfd, NULL); + CLockRec(&isfd->f,isfd->RecNo,UnLock); + } + else writeundo(FNDELETE, isfd, NULL); + } + if (/* test_share() && */(isfd->r->NKeys) && IndActive && (isfd->f.LockMode != ExclLock)) + CBUnLockFile(&isfd->i, &werr) ; +#else + /* if (test_share()) */ +{ + CLockRec(&isfd->f,isfd->RecNo,UnLock); + if (isfd->r->NKeys && IndActive && + (isfd->f.LockMode != ExclLock)) + CBUnLockFile(&isfd->i, &werr) ; +} +#endif +free(oldrec); +isfd->RecNo = 0; +return(*err); +} +/* + @(#) cisgetrecno ISAM + @(ID) + Restituisce il numero del record corrente. + @(FD) + */ +RecNoType cisgetrecno(isfd, err) + isfdptr isfd; /* descrittore del file ISAM */ + int *err; /* codice di errore */ + +{ + if (!isfd->RecNo) *err = IsNotCurr; + else *err = NoErr; + return(isfd->RecNo); +} +/* + @(#) cislock ISAM + @(ID) + Blocca il file ISAM. + @(FD) + @(ISV) + junk = variabile spazzatura per la chiamata di sleep. + @(FSV) + */ +int cislock(isfd,err) + isfdptr isfd; /* descrittore del file ISAM */ + int *err; /* codice di errore */ +{ + int junk; + *err = NoErr ; + if (lseek(isfd->f.F, 0L, 0) == -1) return ((*err = CIOResult())); +#ifndef DOS + do + { + if (lockf(isfd->f.F,F_TLOCK,0L) == -1) + { + *err = CIOResult() ; + junk = sleep(1) ; + } + } while (TESTLOCK(*err)) ; +#endif + if(/* test_share() && */ isfd->f.LockMode != ExclLock) + CBLockFile(&isfd->i,err); + return(*err); +} +/* + @(#) cisunlock ISAM + @(ID) + Sblocca un file ISAM. + @(FD) + */ +int cisunlock(isfd,err) + isfdptr isfd; /* descrittore del file */ + int *err; /* codice di errore */ +{ + return(cisrelease(isfd,err)); +} +/* + @(#) cisrelease ISAM + @(ID) + Sblocca un file ISAM. + @(FD) + */ +int cisrelease(isfd,err) + isfdptr isfd; /* descrittore del file ISAM */ + int *err; /* codice di errore */ +{ + *err = NoErr ; +#ifndef DOS + if (lseek(isfd->f.F, 0L, 0) == -1) return ((*err = CIOResult())); + do + { + if (lockf(isfd->f.F,F_ULOCK,0L) == -1) *err = CIOResult() ; + } while (TESTLOCK(*err)) ; +#endif + if(/* test_share() && */ isfd->f.LockMode != ExclLock) + CBUnLockFile(&isfd->i,err); + return(*err); +} +/* + @(#) IndexOn ISAM + @(ID) + Attiva Aggiornamento Indici. + @(FD) + @(IN) + Di default gli indici sono attivi. + @(FN) + */ +void IndexOn() +{ + IndActive = TRUE ; +} +/* + @(#) IndexOff ISAM + @(ID) + Disattiva l'aggiornamento Indici. + @(FD) + */ +void IndexOff() +{ + IndActive = FALSE ; +} +#ifndef DOS +/* + @($) undoname ISAM + @(ID) + Restituisce il nome del file di Undo. + @(FD) + @(ISV) + path = stringa contenente il nome file. + @(FSV) + */ +char *undoname() +{ + static PathSt path; + TMPFNAME(path, "undo"); + return(path); +} +/* + @($) writeundo ISAM + @(ID) + Scrive una operazione effettuata nel file di Undo. + @(FD) + @(ISV) + fd = puntatore al file. + uname = nome del file di undo. + lgh = variabile di lavoro che contiene l' header del record di undo. + @(FSV) + */ +void writeundo(fntype,isfd,record) + int fntype; /* operazione da effettuare */ + isfdptr isfd; /* descrittore del file */ + RecType record; /* buffer contenente il record */ +{ + int fd; + PathSt uname; + loghead lgh; + + if (isfd->ln <= 0) return ; + strcpy(uname ,undoname()); + if ((fd = open(uname, O_WRONLY | O_CREAT | O_APPEND, 0666)) == -1) + fatal_box("Writeundo : Error n. %d ", errno); + lgh.type = fntype; + lgh.time = time(NULL); + lgh.procid = getpid(); + lgh.userid = getuid(); + lgh.filenum = isfd->ln; + lgh.recnum = isfd->RecNo; + lgh.lenrec = isfd->d->LenR; + if (write(fd, &lgh, sizeof(lgh)) == -1) + fatal_box("Writeundo : Error n. %d ", errno); + if (fntype & (FNREWRITE)) + if (write(fd, record, lgh.lenrec) == -1) + fatal_box("Writeundo : Error n. %d ", errno); + if (close(fd) == -1) + fatal_box("Writeundo : Error n. %d ", errno); +} +/* + @($) writelog ISAM + @(ID) + Scrive sul file Giornale l'operazione effettuata. + @(FD) + @(ISV) + junk = variabile spazzatura per la chiamata di execunlock. + lname = nome del file Giornale (LOG). + fd = puntatore al file giornale. + lgh = testata del file giornale. + @(FSV) + */ +void writelog(fntype,isfd,record) + int fntype; /* operazione effetuata */ + isfdptr isfd; /* descrittore del file ISAM */ + RecType record; /* buffer per il record */ +{ + int fd,junk; + PathSt lname; + loghead lgh; + if (!isjournal) return; + if (isfd->ln <= 0) return ; + strcpy(lname, CInsPref(logname, NORDIR)); + while (excllock(lname,TRUE) == -1) sleep(1); + if ((fd = open(lname, O_WRONLY | O_CREAT | O_APPEND, 0666)) == -1) + { + junk = exclunlock(lname,TRUE); + fatal_box("Writelog : Error n. %d ", errno); + } + lgh.type = fntype + FNSTTRANS; + lgh.time = time(NULL); + lgh.procid = getpid(); + lgh.userid = getuid(); + if (fntype & (FNREWRITE + FNWRITE + FNDELETE)) + { + lgh.filenum = isfd->ln; + lgh.recnum = isfd->RecNo; + lgh.lenrec = isfd->d->LenR; + } + else + { + lgh.filenum = 0; + if (fntype == FNREORG) lgh.recnum = *((RecNoType *) record); + else lgh.recnum = 0L; + if (fntype == FNCHGREC) lgh.lenrec = sizeof(RecDes); + else lgh.lenrec = 0; + } + if (write(fd, &lgh, sizeof(lgh)) == -1) + { + junk = exclunlock(lname,TRUE); + fatal_box("Writelog : Error n. %d ", errno); + } + if (fntype & (FNREWRITE + FNWRITE + FNCHGREC)) + if (write(fd, record, lgh.lenrec) == -1) + { + junk = exclunlock(lname,TRUE); + fatal_box("Writelog : Error n. %d ", errno); + } + if (close(fd) == -1) + fatal_box("Writelog : Error n. %d ", errno); + junk = exclunlock(lname,TRUE); +} +#endif +/* + @(#) StTrans ISAM + @(ID) + Inizia una transazione. + @(FD) + */ +void StTrans() +{ +#ifndef DOS + if (isstate == TRANS) EndTrans(); +#endif + isstate = TRANS; +} +#ifndef DOS +/* + @($) getopenf ISAM + @(ID) + Riconfigura il file di lavoro attivo sul file di numero logico "ln". + @(FD) + @(ISV) + junk = variabile spazzatura per la chiamata alla cisclose. + err = codice di errore ritornato dalla cisopen. + @(FSV) + */ +void getopenf(ln,record) + int ln; /* numero logico del file */ + RecType *record; /* puntatore al buffer per il record */ +{ + int err,junk; + if (openf[ln - 1] == NULL) + { + if (wln != ln) + { + if (wln != -1) junk = cisclose(&wisfd ,record ,&err); + cisopen(&wisfd, ln, record, ManuLock, &err); + wln = ln; + } + } + else *record = realloc(*record, openf[ln - 1]->d->LenR); +} +#endif +/* + @(#) EndTrans ISAM + @(ID) + Chiude una transazione. + @(FD) + @(ISV) + fdl, fdu = puntatori ai file di LOG e di Undo. + lname, uname = nomi dei file di LOG e di Undo. + lgh, lgh1 = variabili di lavoro contenenti le testate dei file di log. + nread = variabile di lavoro per la chiamata alla read. + werr = codice di errore ritornato dalla cisclose. + junk = variabile spazzatura per la chiamata di exclunlock. + start = variabile di lavoro. + record = buffer di lavoro. + @(FSV) + */ +void EndTrans() +{ +#ifndef DOS + int fdl, fdu; + PathSt lname, uname; + loghead lgh, lgh1; + int nread, werr, junk, start = FNSTTRANS; + RecType record; + strcpy(lname ,CInsPref(logname, NORDIR)); + while (excllock(lname,TRUE) == -1) sleep(1); + if (((fdl = open(lname, O_WRONLY | O_CREAT | O_APPEND, 0666)) == -1) || + ((fdu = open(uname, O_RDONLY, 0666)) == -1)) + { + junk = exclunlock(lname,TRUE); + fatal_box("Endtrans : Error n. %d ", errno); + } + while ((nread = read(fdu, &lgh, sizeof(lgh))) > 0) + { + lgh.type += start; + start = 0; + if (write(fdl, &lgh, sizeof(lgh)) == -1) + { + junk = exclunlock(lname,TRUE); + fatal_box("Endtrans : Error n. %d ", errno); + } + if (lgh.type == FNREWRITE) + if (lseek(fdu, (long) lgh.lenrec, 1) == -1) + { + junk = exclunlock(lname,TRUE); + fatal_box("Endtrans : Error n. %d ", errno); + } + getopenf(lgh.filenum, &record); + CRead(&(openf[lgh.filenum - 1]->f), record, lgh.recnum, UnLock); + if (write(fdl, record, lgh.lenrec) == -1) + { + junk = exclunlock(lname,TRUE); + fatal_box("Endtrans : Error n. %d ", errno); + } + } + if ((nread <= 0) || (close(fdu) == -1) || (close(fdl) == -1) || + (unlink(uname) == -1)) + { + junk = exclunlock(lname,TRUE); + fatal_box("Endtrans : Error n. %d ", errno); + } + if (wln != -1) + { + junk = cisclose(&wisfd, &record, &werr); + wln = -1; + } + junk = exclunlock(lname,TRUE); +#endif +} +/* + @(#) AbTrans ISAM + @(ID) + Abortisce una transazione. + @(FD) + */ +void AbTrans() +{ +#ifndef DOS + int fd; + PathSt uname; + loghead lgh; + int nread, werr, junk; + RecType record; + RecType oldrec; + strcpy(uname ,undoname()); + if ((fd = open(uname, O_RDONLY, 0666)) == -1) + fatal_box("Abtrans : Error n. %d ", errno); + while ((nread = read(fd, &lgh, sizeof(lgh))) > 0) + { + getopenf(lgh.filenum, &record); + if (oldrec == NULL) oldrec = malloc(lgh.lenrec); + else oldrec = realloc(oldrec, lgh.lenrec); + if (lgh.type & (FNREWRITE)) + { + if ((nread = read(fd, record, lgh.lenrec)) <= 0) + fatal_box("Abtrans : Error n. %d ", errno); + } + if (lgh.lenrec != openf[lgh.filenum - 1]->d->LenR) + fatal_box("Abtrans : Error n. %d ", IsNoMatch); + CRead(&(openf[lgh.filenum - 1]->f), oldrec, lgh.recnum, NoLock); + switch (lgh.type) + { + case FNREWRITE : + junk = replkeys(openf[lgh.filenum - 1], oldrec, record, + openf[lgh.filenum - 1]->i.PN + 1, &werr); + CWrite(&(openf[lgh.filenum - 1]->f), record, lgh.recnum, UnLock); + break; + case FNDELETE : + IRecallRec(oldrec); + junk = addkeys(openf[lgh.filenum - 1], oldrec, + openf[lgh.filenum - 1]->i.PN + 1, &werr); + CWrite(&(openf[lgh.filenum - 1]->f), oldrec, lgh.recnum, UnLock); + break; + case FNWRITE : + IDeleteRec(oldrec); + junk = delkeys(openf[lgh.filenum - 1], oldrec, + openf[lgh.filenum - 1]->i.PN + 1, &werr); + CWrite(&(openf[lgh.filenum - 1]->f), record, lgh.recnum, UnLock); + break; + } + } + if ((nread == -1) || (close(fd) == -1) || (unlink(uname) == -1)) + fatal_box("Abtrans : Error n. %d ", errno); + if (wln != -1) + { + junk = cisclose(&wisfd, &record, &werr); + wln = -1; + } +#endif +} + diff --git a/include/default.url b/include/default.url index c11efcdd9..78ca71530 100755 --- a/include/default.url +++ b/include/default.url @@ -1,7 +1,7 @@ #ifndef APPNAME #define APPNAME PRASSI #define QAPPNAME "PRASSI" -#define LIBDIR f:\xvt.400\win_x86\ptk\lib +#define LIBDIR f:\xvt.45b\w16_x86\ptk\lib #endif #define NO_STD_EDIT_MENU diff --git a/include/isam.cpp b/include/isam.cpp index f6b2fb4d1..b3558977d 100755 --- a/include/isam.cpp +++ b/include/isam.cpp @@ -1781,13 +1781,6 @@ bool TRectype::get_bool(const char* fieldname) const return *_isam_string == 'X'; } -#else - -const char* TRectype::get(const char* fieldname) const -{ - return get_str(fieldname); -} - #endif // FOXPRO @@ -2124,8 +2117,8 @@ long TRecfield::operator =(long l) #ifndef FOXPRO + const real& TRecfield::operator =(const real& r) - { strcpy(_isam_string, r.string()); __putfieldbuff( _len, _dec, _type, _isam_string, _p); @@ -2133,29 +2126,10 @@ const real& TRecfield::operator =(const real& r) return r; } -#else - -const char* TRectype::get(const char* fieldname) const -{ - RecDes* rd = rec_des(); - - if (CFieldType((char*) fieldname, rd) == _datefld) - { - const TRecfield f((TRectype&)*this, fieldname); - strcpy(_isam_string, (const char*) f); - } - else - if (CGetFieldBuff((char*) fieldname, rd, _rec, _isam_string) == -1) - UNKNOWN_FIELD(num(), fieldname); - - return _isam_string; -} - #endif // FOXPRO const TDate& TRecfield::operator =(const TDate& d) - { strcpy(_isam_string, (const char*)d); __putfieldbuff( _len, _dec, _type, _isam_string, _p); @@ -2166,7 +2140,6 @@ const TDate& TRecfield::operator =(const TDate& d) const char* TRecfield::operator =(const char* s) - { __putfieldbuff( _len, _dec, _type, s, _p); _rec->setempty(FALSE); @@ -2175,7 +2148,6 @@ const char* TRecfield::operator =(const char* s) void TRecfield::setptr(TRecnotype r) - { if (_p == NULL) return; @@ -2194,7 +2166,6 @@ void TRecfield::setptr(TRecnotype r) TRecfield::operator int() const - { __getfieldbuff( _len, _type, _p, _isam_string); return atoi(_isam_string); @@ -2202,7 +2173,6 @@ TRecfield::operator int() const TRecfield::operator long() const - { __getfieldbuff( _len, _type, _p, _isam_string); return atol(_isam_string); @@ -2211,18 +2181,18 @@ TRecfield::operator long() const #ifndef FOXPRO -TRecfield::operator const real() const +TRecfield::operator const real() const { __getfieldbuff( _len, _type, _p, _isam_string); real r(_isam_string); return r; } + #endif // FOXPRO TRecfield::operator TDate() const - { static TDate d; __getfieldbuff( _len, _type, _p, _isam_string); diff --git a/include/isam.h b/include/isam.h index 1339e6102..019046c8c 100755 --- a/include/isam.h +++ b/include/isam.h @@ -96,8 +96,6 @@ public: char get_char(const char* fieldname) const ; bool get_bool(const char* fieldname) const ; real get_real(const char* fieldname) const ; -#else - const char* get(const char* fieldname) const ; #endif TDate get_date(const char* fieldname) const ; @@ -278,8 +276,8 @@ public: void put(const char* fieldname, const real& val) { curr().put(fieldname, val);} #else - const char* get(const char* fieldname) const - { return curr().get(fieldname);} + const char* get_str(const char* fieldname) const + { return curr().get_str(fieldname);} #endif // @DES Put NON tipizzata diff --git a/include/mask.cpp b/include/mask.cpp index 1cc8bddb9..8411fa148 100755 --- a/include/mask.cpp +++ b/include/mask.cpp @@ -145,12 +145,12 @@ void TMask::handler(WINDOW win, EVENT* ep) stop_run(K_AUTO_ENTER); break; case DLG_CANCEL : - if (test_focus_change(ep->v.ctl.ci.win)) - stop_run(K_ESC); + // if (test_focus_change(ep->v.ctl.ci.win)) + stop_run(K_ESC); break; case DLG_QUIT : - if (test_focus_change(ep->v.ctl.ci.win)) - stop_run(K_FORCE_CLOSE); + // if (test_focus_change(ep->v.ctl.ci.win)) + stop_run(K_FORCE_CLOSE); break; case DLG_F9: { @@ -214,6 +214,9 @@ void TMask::read_mask(const char* name, int num, int max) _sheetmask = num > 0; long start_t = clock(); + while (clock() == start_t) continue; // Attende scatto timer + start_t = clock(); + if (!_sheetmask) _total_time = _build_time = _init_time = 0; @@ -786,8 +789,8 @@ bool TMask::on_key(KEY key) next_page(+1); break; case K_F12: - message_box("Lettura = %ld:\n" - "Creazione = %ld:\n" + message_box("Lettura = %ld\n" + "Creazione = %ld\n" "Inizializzazione = %ld", _total_time-_build_time, _build_time, _init_time); break; @@ -799,15 +802,14 @@ bool TMask::on_key(KEY key) next_page(1000 + key - K_F1); else { - const int last = fields(); - for (int i = 0; i < last; i++) + for (int i = 0; i < fields(); i++) { TMask_field& f = fld(i); if (f.class_id() != CLASS_BUTTON_FIELD || !f.active()) continue; TButton_field& b = (TButton_field&)f; if (b.virtual_key() == key) { - bool ok = b.dlg() != DLG_CANCEL && b.dlg() != DLG_QUIT && b.dlg() != DLG_F9; + bool ok = b.dlg() == DLG_CANCEL || b.dlg() == DLG_QUIT || b.dlg() == DLG_F9; if (!ok) ok = test_focus_change(b.win()); if (ok) f.on_key(K_SPACE); diff --git a/include/maskfld.cpp b/include/maskfld.cpp index 03f1dcc5c..8702a51b2 100755 --- a/include/maskfld.cpp +++ b/include/maskfld.cpp @@ -730,8 +730,8 @@ bool TMask_field::do_message(int num) bool TMask_field::test_focus_change() { bool ok = TRUE; - if (focusdirty()) on_key(K_TAB); // Comportamento normale - else if (is_edit() && in_key(1)) on_hit(); // Serve per eseguire gli handler autoprementi + if (focusdirty()) ok = on_key(K_TAB); // Comportamento normale + else if (is_edit() && in_key(1)) ok = on_hit(); // Serve per eseguire gli handler autoprementi return ok; } @@ -2123,9 +2123,12 @@ bool TEdit_field::on_key(KEY key) const bool query = mask().query_mode(); // check consistency - if (_sheet) ok = query || _sheet->check(FINAL_CHECK); + if (_sheet) + ok = query || _sheet->check(FINAL_CHECK); else - if (_browse && + { + ok = query || !(check_type() == CHECK_REQUIRED && get().empty()); + if (_browse && ok && check_enabled() && _validate_func != 21 && // 21 = NOT_EMPTY_CHECK_FIELD (!query || forced())) @@ -2133,9 +2136,7 @@ bool TEdit_field::on_key(KEY key) if (dirty()) ok = _browse->check(FINAL_CHECK); // Check consistency else ok = _browse->empty_check(); } - else - ok = query || !(check_type() == CHECK_REQUIRED && get().empty()); - + } if (!ok) return default_error_box(); } diff --git a/include/msksheet.cpp b/include/msksheet.cpp index 497bbb31b..486e68466 100755 --- a/include/msksheet.cpp +++ b/include/msksheet.cpp @@ -361,16 +361,17 @@ void TSpreadsheet::update_rec(int rec) XI_OBJ row; XI_MAKE_ROW(&row, _list, riga); xi_cell_request(&row); // Update internal values - if (_update) - { - // xi_set_row_height(&row, CHARY+1); // Force row updating - XI_OBJ cell; - for (int c = 1; c < _columns; c++) - { - XI_MAKE_CELL(&cell, _list, riga, c); - xi_set_text(&cell, xi_get_text(&cell, NULL, -1)); - } - } + /* + if (_update) + { + XI_OBJ cell; + for (int c = 1; c < _columns; c++) + { + XI_MAKE_CELL(&cell, _list, riga, c); + xi_set_text(&cell, xi_get_text(&cell, NULL, -1)); + } + } + */ } } @@ -566,7 +567,7 @@ void TSpreadsheet::list_handler(XI_EVENT *xiev) char* dst = xiev->v.cell_request.s; if (src && *src) { - const int len = xiev->v.cell_request.len; + const int& len = xiev->v.cell_request.len; strncpy(dst, src, len); } else @@ -574,10 +575,11 @@ void TSpreadsheet::list_handler(XI_EVENT *xiev) } break; case XIE_CHG_CELL: - if (_edit_field) + if (_edit_field && !_cell_dirty) { notify_change(); - _edit_field->set_focusdirty(_cell_dirty = TRUE); + _cell_dirty = TRUE; + _edit_field->set_focusdirty(); } break; case XIE_BUTTON: @@ -643,7 +645,7 @@ void TSpreadsheet::list_handler(XI_EVENT *xiev) } break; case XIE_ON_LIST: - if (_firstfocus) // Trick to avoid the sheet to keep the focus forever ... + if (_firstfocus) // Trick to avoid the sheet to keep the focus forever ... { // .. it costed me two day worth of hard work! xiev->refused = TRUE; _firstfocus = FALSE; @@ -683,10 +685,13 @@ void TSpreadsheet::list_handler(XI_EVENT *xiev) ok = notify(_cur_rec, K_ENTER); // Notify edit _update = TRUE; // Reenable update } - if (!ok) - xiev->refused = TRUE; - else + if (ok) + { xvt_statbar_refresh(); + _edit_field = NULL; // Reset current field + } + else + xiev->refused = TRUE; _check_enabled = TRUE; } @@ -723,8 +728,6 @@ void TSpreadsheet::list_handler(XI_EVENT *xiev) else mask2str(_cur_rec); // Update sheet row } - if (!xiev->refused) - _edit_field = NULL; // Reset current field _check_enabled = TRUE; } break; @@ -764,10 +767,8 @@ void TSpreadsheet::list_handler(XI_EVENT *xiev) _lastab = k; break; case K_UP: - _lastab = K_BTAB; - break; case K_DOWN: - _lastab = K_TAB; + _lastab = _cur_col < 2 ? K_TAB : K_BTAB; break; case K_F1: _check_enabled = FALSE; // Disable checks diff --git a/include/printapp.cpp b/include/printapp.cpp index a86fd380d..1aa443d83 100755 --- a/include/printapp.cpp +++ b/include/printapp.cpp @@ -1,4 +1,4 @@ -// $Id: printapp.cpp,v 1.25 1995-05-09 09:12:14 villa Exp $ +// $Id: printapp.cpp,v 1.26 1995-05-09 13:33:21 guy Exp $ #include #include @@ -846,9 +846,7 @@ void TPrint_application::print() if (_cur->items () >= _wthr && (_force_progind || printer ().printtype () != screenvis)) - _prind = new TProgind (_cur->items (), - (char *) (const char *) _wmess, - _wcancel, _wbar, 35); + _prind = new TProgind (_cur->items (), _wmess, _wcancel, _wbar, 35); print_tree (_pr_tree); _cur->freeze (FALSE); diff --git a/include/real.cpp b/include/real.cpp index a61273f49..cd66788a6 100755 --- a/include/real.cpp +++ b/include/real.cpp @@ -873,3 +873,13 @@ const TImporto& TImporto::normalize() return *this; } + +int TImporto::compare(const TSortable& s) const +{ + const TImporto& i = (const TImporto&)s; + const real d = valore() - i.valore(); + int res = d.sign(); + if (res == 0) + res = sezione() != i.sezione(); + return res; +} \ No newline at end of file diff --git a/include/real.h b/include/real.h index d31c17a7d..4743f38fc 100755 --- a/include/real.h +++ b/include/real.h @@ -25,6 +25,7 @@ class real : public TObject // @END protected: + virtual TObject* dup() const; char* literals() const; char* points(int decimals = 0) const; @@ -156,10 +157,13 @@ public: }; -class TImporto : public TObject +class TImporto : public TSortable { char _sezione; real _valore; + +protected: + virtual int compare(const TSortable& s) const; public: char sezione() const { return _sezione; } diff --git a/include/relapp.cpp b/include/relapp.cpp index 63762e86a..5d82a9eb4 100755 --- a/include/relapp.cpp +++ b/include/relapp.cpp @@ -1,4 +1,4 @@ -// $Id: relapp.cpp,v 1.53 1995-04-06 15:42:50 alex Exp $ +// $Id: relapp.cpp,v 1.54 1995-05-09 13:33:26 guy Exp $ #include #include #include @@ -22,7 +22,7 @@ HIDDEN bool can_change_firm() HTASK ct = GetCurrentTask(); TaskFindHandle(&te, ct); TaskFindHandle(&te, te.hTaskParent); - can = strcmp(te.szModule, "BA0") == 0; + can = stricmp(te.szModule, "BA0") == 0; #else can = TRUE; #endif @@ -34,7 +34,6 @@ HIDDEN bool can_change_firm() } - /////////////////////////////////////////////////////////// // Array delle chiavi della maschera di ricerca /////////////////////////////////////////////////////////// @@ -229,11 +228,10 @@ void TRelation_application::set_fixed() void TRelation_application::enable_query() { - const bool query = _mask->query_mode(); - const bool noedit = !_mask->edit_mode(); - const byte numkeys = _maskeys->items(); + const bool query = _mask->query_mode(); + const bool keyon = query || get_relation()->status() == _isreinsert; - for (byte k = 1; k <= numkeys; k++) + for (byte k = 1; k <= _maskeys->items(); k++) { const TChiave& chiave = _maskeys->key(k); for (int i = 0; i < chiave.items(); i++) @@ -243,7 +241,7 @@ void TRelation_application::enable_query() if (c.enabled_default()) { if (k == 1) - c.enable(noedit); + c.enable(keyon); if (c.has_query()) ((TEdit_field&)c).enable_check(query); } @@ -449,7 +447,7 @@ bool TRelation_application::modify_mode() if (changing) { _mask->open_modal(); - delete _maskeys; // May conflict! Keep this one + delete _maskeys; _maskeys = new TKey_array(_mask); } @@ -458,7 +456,6 @@ bool TRelation_application::modify_mode() err = read(*_mask); if (err != NOERR) { - error_box("Errore di caricamento dati: %d", err); query_mode(); return FALSE; } @@ -488,12 +485,18 @@ bool TRelation_application::search_mode() if (_mask->mode() != MODE_QUERY) query_mode(); - TMask_field* f = get_search_field(); - if (f) - if (f->on_key(K_F9)) + TMask_field* prima = get_search_field(); + while (prima) + { + if (prima->on_key(K_F9)) + { if (find(1)) return modify_mode(); - + } + + TMask_field* dopo = &_mask->fld(_mask->focus_field()); + prima = (dopo == prima) ? NULL : dopo; + } return FALSE; } @@ -645,7 +648,10 @@ bool TRelation_application::save(bool check_dirty) { changed = autonum(_mask, TRUE); if (!changed) + { _mask->disable_starting_check(); + enable_query(); // Abilita chiave 1 per rinumerazione manuale + } } else changed = FALSE; diff --git a/include/scanner.cpp b/include/scanner.cpp index e8ee25f98..3dc2f02d3 100755 --- a/include/scanner.cpp +++ b/include/scanner.cpp @@ -12,15 +12,19 @@ HIDDEN const char* strlwr (const char* str) } inline bool string_start(char c) -{ return c == '"' || c == '\'' || c == '{' || c == '\''; } +{ return c == '"' || c == '\'' || c == '{'; } inline char match(char c) { return (c == '{') ? '}' : c; } TScanner::TScanner(const char* filename) -: ifstream(strlwr(filename)), _token(128), _key(2), _pushed(FALSE), _line(0) -{ - if (bad()) fatal_box("Impossibile aprire %s", filename); +: _pushed(FALSE), _line(0), + _token(128), _key(2), _buffer(1024*16) +{ + setbuf((char*)(const char*)_buffer, _buffer.size()); + open(filename); + if (bad()) + fatal_box("Impossibile aprire %s", filename); } const TString& TScanner::pop() diff --git a/include/scanner.h b/include/scanner.h index 695ac4117..937584f1c 100755 --- a/include/scanner.h +++ b/include/scanner.h @@ -17,7 +17,7 @@ class TScanner : private ifstream { // @DPRIV - TString _token, _key; + TString _token, _key, _buffer; bool _pushed; word _line; diff --git a/include/sheet.cpp b/include/sheet.cpp index dadce4f61..64a1ed8a7 100755 --- a/include/sheet.cpp +++ b/include/sheet.cpp @@ -64,7 +64,7 @@ TSheet::TSheet(short x, short y, short dx, short dy, flags = WSF_VSCROLL; } - if (dx == 0) // Calculates window width + if (dx == 0) // Compute window width { RCT r; xvt_vobj_get_client_rect(parent, &r); dx = r.right/CHARX -6; @@ -72,7 +72,7 @@ TSheet::TSheet(short x, short y, short dx, short dy, const int larg = width(); if (dx > larg) dx = larg; } - if (dy == 0) dy = 20; // Calculates window height + if (dy == 0) dy = 20; // Compute window height create(x, y, dx, dy, title, flags, wt, parent); if (wt != W_PLAIN) // If normal sheet add buttons @@ -139,6 +139,10 @@ void TSheet::open() { // Abilita selezione se c'e' almeno un elemento xvt_enable_control(_button[0], items() > 0 && _disabled.ones() < items()); + + if (_checkable) + xvt_enable_control(_button[1], items() > 0 && _check_enabled); + repos_buttons(); } TScroll_window::open(); @@ -200,8 +204,8 @@ void TSheet::handler(WINDOW win, EVENT* ep) const short f = head_on() ? 1 : 0; if (y >= f) { - long vec = selected(); - long nuo = first()+y-f; + const long vec = selected(); + const long nuo = first()+y-f; select(nuo); if (ep->type == E_MOUSE_DBL) dispatch_e_char(win, K_ENTER); @@ -746,7 +750,7 @@ TBrowse_sheet::TBrowse_sheet(TCursor* cursor, const char* fields, CTL_FLAG_DISABLED, 0L, DLG_EDIT); } - if (s && s->items() > 2) + if (s && s->items() > 0) { int maxlen = 0; SLIST lst = xvt_slist_create(); @@ -764,8 +768,8 @@ TBrowse_sheet::TBrowse_sheet(TCursor* cursor, const char* fields, xvt_slist_destroy(lst); TString16 id; id << f->dlg(); - const int sel = s->get_pos(id) >> 1; - xvt_list_set_sel(listbox, sel, TRUE); + _sel = s->get_pos(id) >> 1; + xvt_list_set_sel(listbox, _sel, TRUE); } } @@ -864,7 +868,7 @@ void TBrowse_sheet::handler(WINDOW win, EVENT* ep) if (ep->type == E_CONTROL && ep->v.ctl.id == DLG_FINDREC) { const int what = xvt_list_get_sel_index(ep->v.ctl.ci.win); - if (what >= 0) + if (what >= 0 && what != _sel) stop_run(K_CTRL + what); else set_focus(); diff --git a/include/sheet.h b/include/sheet.h index c9e062bf7..1a94e16ec 100755 --- a/include/sheet.h +++ b/include/sheet.h @@ -148,7 +148,8 @@ public: class TBrowse_sheet : public TCursor_sheet { - TEdit_field* const _field; + TEdit_field* const _field; // Linked edit field + int _sel; // Current listbox selection protected: virtual void handler(WINDOW win, EVENT* ep); diff --git a/include/xvtility.cpp b/include/xvtility.cpp index 12340caf2..683b8b520 100755 --- a/include/xvtility.cpp +++ b/include/xvtility.cpp @@ -10,7 +10,6 @@ extern "C" { long nap(long period); } #endif - // ERROR HOOK che intercetta errori XVT // put breakpoint here @@ -117,7 +116,7 @@ bool allow_another_instance() GlobalLock(GetModuleHandle((const char*)MAKELP(0,hInstance)))); if ( hModuleSel == 0 ) // Make sure we succeeded. - return 0; + return FALSE; // Make pointers to the resident names table and the OFSTRUCT LPSTR moduleName = (LPSTR)MAKELP( hModuleSel, *(WORD FAR *)MAKELP(hModuleSel, 0x26)); @@ -147,7 +146,7 @@ bool allow_another_instance() { // Stop when we come to a directory separator or colon if ( (*fileName=='\\') || (*fileName=='/') || (*fileName==':') ) - return 0; + return FALSE; if ( isupper(*fileName) ) { @@ -175,10 +174,6 @@ static BOOLEAN event_hook(HWND hwnd, break; case WM_CTLCOLOR: { -#ifdef __CTL3D__ - *ret = Ctl3dCtlColorEx(msg, wparam, lparam); - return FALSE; // Non fare altro -#else const word type = HIWORD(lparam); if (type == CTLCOLOR_LISTBOX || type == CTLCOLOR_EDIT || type == CTLCOLOR_MSGBOX) @@ -206,6 +201,14 @@ static BOOLEAN event_hook(HWND hwnd, *ret = focus ? FocusBrush : NormalBrush; return FALSE; // Non fare altro } +#ifdef __CTL3D__ + else + { + *ret = Ctl3dCtlColorEx(msg, wparam, lparam); + return TRUE; + } +#else + #endif } break; @@ -577,6 +580,7 @@ void customize_controls(bool on) xvt_vobj_set_attr(NULL_WIN,ATTR_WIN_PM_DRAWABLE_TWIN, TRUE); xvt_vobj_set_attr(NULL_WIN,ATTR_EVENT_HOOK, (long)event_hook); xvt_vobj_set_attr(NULL_WIN,ATTR_WIN_CREATEWINDOW_HOOK, (long)createwindow_hook); + allow_another_instance(); HINSTANCE _hInstance = (HINSTANCE)xvt_vobj_get_attr(NULL_WIN, ATTR_WIN_INSTANCE); @@ -797,7 +801,7 @@ WINDOW xvt_create_control(WIN_TYPE wt, if (wt == WC_GROUPBOX) { win = xvt_create_text(r.left, r.top, r.right, r.top+CHARY, - caption, parent, flags, app_data, id); + caption, parent, 0, app_data, id); } #endif @@ -860,7 +864,7 @@ void xvt_set_title(WINDOW win, const char* cap) TControl* c = TControl::WINDOW2TControl(win); c->set_caption(cap); #else - xvt_vobj_set_title(win, cap); + xvt_vobj_set_title(win, (char*)cap); #endif }