From ec9e033319c41c2ce9b3b5f07c4af08c794e5f92 Mon Sep 17 00:00:00 2001 From: guy Date: Fri, 19 Dec 2003 10:34:43 +0000 Subject: [PATCH] Patch level : 2.0 664 Files correlati : Ricompilazione Demo : [ ] Commento : EP20153 problema sui list-box: non e' piu' possibile selezionare una voce facendo doppio click su di essa.Es: entro nel programma documenti interattivi vado su file impostazioni stampante e provo a selezionare un font dal list box git-svn-id: svn://10.65.10.50/trunk@11683 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- include/codebase.c | 1188 +++++++++++++++++++++++++++++++++++++++++++ include/strings.cpp | 10 +- 2 files changed, 1195 insertions(+), 3 deletions(-) create mode 100755 include/codebase.c diff --git a/include/codebase.c b/include/codebase.c new file mode 100755 index 000000000..792dcd853 --- /dev/null +++ b/include/codebase.c @@ -0,0 +1,1188 @@ +#define XVT_INCL_NATIVE +#include +#include + +#define S4OFF_REPORT + +#if XVT_OS == XVT_OS_WIN32 + #define S4DLL + #define S4WIN32 +#endif + +#include + +#include +#include + +/*-------------------------------------------------------------------------- + Utility + --------------------------------------------------------------------------*/ + +HIDDEN void progind_create(long m, const char* t, bool b, bool c, int n) +{ + statbar_set_title(TASK_WIN, t); +} + +HIDDEN void progind_destroy() +{ + statbar_set_title(TASK_WIN, NULL); // Restore default title +} + +HIDDEN void progind_set_status(long l) +{ +} + +/*-------------------------------------------------------------------------- + numero massimo di database aperti contemporaneamente + --------------------------------------------------------------------------*/ +#define CB4FILES 64 + +#define MAXLEN 137 /* Lunghezza massima chiave */ + +static CODE4 code_base; +static DATA4 *dbdata[CB4FILES]; + +bool handle_ok(int handle) +{ + return handle >= 0 && handle < CB4FILES && dbdata[handle] != NULL; +} + +static char* find_slash_backslash(const char* s) +{ + const char* slash = NULL; + for ( ; *s; s++) + { + if (*s == '\\' || *s == '/') + slash = s; + } + return (char*)slash; +} + + +/*-------------------------------------------------------------------------- + inizializzazione di CodeBase e delle variabili necessarie + questa funzione deve essere chiamata SOLO una volta all'interno + di ciascun eseguibile + --------------------------------------------------------------------------*/ +void DB_init(void) +{ + int i; + for(i=0;i 0) + d4top(dbdata[found]); + return(found); +} + + +/*------------------------------------------------------------------------- + chiusura del database inviduato da handle + torna -1 se il database non puo essere chiuso + --------------------------------------------------------------------------*/ +int DB_close(int handle) +{ + if(!handle_ok(handle)) return(-1); + d4close(dbdata[handle]); + dbdata[handle]=(DATA4 *) 0; + code_base.errorCode=0; + return(0); +} + +/*------------------------------------------------------------------------- + torna il puntatore al buffer del record del database individuato da + handle. In caso di errore torna (char *) 0 + --------------------------------------------------------------------------*/ +char *DB_getrecord(int handle) +{ + if(!handle_ok(handle)) return((char *) 0); + return(d4record(dbdata[handle])); +} + +/*------------------------------------------------------------------------- + torna la lunghezza del record + --------------------------------------------------------------------------*/ +int DB_reclen(int handle) +{ + if(!handle_ok(handle)) return(-1); + return((int) d4recWidth(dbdata[handle])); +} + +/*------------------------------------------------------------------------- + torna la lunghezza della chiave corrente + --------------------------------------------------------------------------*/ + +int DB_keylen(int handle) +{ + return a4tagKeyLen(dbdata[handle]); +} + +/*------------------------------------------------------------------------- + torna il numero del record attuale + --------------------------------------------------------------------------*/ +long int DB_recno(int handle) +{ + if(!handle_ok(handle)) return(-1L); + return(d4recNo(dbdata[handle])); +} + +/*------------------------------------------------------------------------- + torna il numero complessivo dei records presenti nell'archivio + --------------------------------------------------------------------------*/ +long int DB_reccount(int handle) +{ + if(!handle_ok(handle)) return(-1L); + return(d4recCount(dbdata[handle])); +} + +/*------------------------------------------------------------------------- + seleziona un indice sul database specificato + torna -1 se errore, altrimenti 0 + --------------------------------------------------------------------------*/ +int DB_tagselect(int handle,int index_no) +{ + TAG4 *tt; + int i; + + if(!handle_ok(handle)) return(-1); + /* si posiziona sul primo indice */ + tt=d4tagNext(dbdata[handle],NULL); + if(tt==NULL) return(-1); + for(i=1;i 0 && k[len-1] == ' ') len--; + rc = strncmp(key, k, len); + if (rc == 0) + return 0; + else + if (rc < 0) + return r4after; + else + return r4eof; +} + +/*------------------------------------------------------------------------- + torna 1 se eof, 0 altrimenti + --------------------------------------------------------------------------*/ +int DB_eof(int handle) +{ + if(!handle_ok(handle)) return(-1); + return(d4eof(dbdata[handle])); +} + +/*------------------------------------------------------------------------- + torna 1 se bof, 0 altrimenti + --------------------------------------------------------------------------*/ +int DB_bof(int handle) +{ + if(!handle_ok(handle)) return(-1); + return(d4bof(dbdata[handle])); +} + +/*------------------------------------------------------------------------- + legge un record per numero record + --------------------------------------------------------------------------*/ +int DB_go(int handle,long recno) +{ + if(!handle_ok(handle)) return(-1); + return(d4go(dbdata[handle],recno)); +} + +/*------------------------------------------------------------------------- + cancella il record attuale. Non cancella le chiavi. + --------------------------------------------------------------------------*/ +int DB_delete(int handle) +{ + + if(!handle_ok(handle)) return(-1); + d4delete(dbdata[handle]); + return(0); +} + +/*------------------------------------------------------------------------- + ripristina il record attuale + --------------------------------------------------------------------------*/ +int DB_recall(int handle) +{ + + if(!handle_ok(handle)) return(-1); + d4recall(dbdata[handle]); + return(0); +} + +/*------------------------------------------------------------------------- + + --------------------------------------------------------------------------*/ +int DB_flush(int handle) +{ + int rt; + while ((rt = d4flush(dbdata[handle])) == r4locked) + u4delaySec(); + return rt; +} + +/*------------------------------------------------------------------------- + riscrive il record attuale + --------------------------------------------------------------------------*/ +int DB_rewrite(int handle) +{ + int rt; + if(!handle_ok(handle)) return(-1); + while ((rt=d4write(dbdata[handle],d4recNo(dbdata[handle]))) == r4locked) + u4delaySec(); + if (rt == 0) + { + while ((rt = d4flush(dbdata[handle])) == r4locked) + u4delaySec(); + } + if (rt == e4unique) + { + char msg[256]; + DB_get_error(); + sprintf(msg, "Errore in DB_rewrite(): chiave duplicata nel record %ld, file %s", + d4recNo(dbdata[handle]) + 1, d4fileName(dbdata[handle])); + xvt_dm_post_fatal_exit(msg); + } + rt=DB_unlock(handle); + return (rt); +} + + +/*------------------------------------------------------------------------- + appende il record attuale + --------------------------------------------------------------------------*/ +int DB_add(int handle) +{ + int rt; + int is_locked = 0; + DATA4 * data = dbdata[handle]; + + if (data==0) return(-1); + is_locked = DB_file_locked(handle); + if (is_locked == 0) /* Se non e' stato gia' bloccato in modo esclusivo */ + { + while (d4lockAll(data) == r4locked) + u4delaySec(); + } + while ((rt = d4appendStart(data,0)) == r4locked) + u4delaySec(); + if (rt == 0) + { + d4recall(data); + while ((rt = d4append(data)) == r4locked) + u4delaySec(); + if (rt == e4unique) + { + long rec_num = d4recNo(data); + + DB_get_error(); + if (rec_num > 0) + { + char msg[256]; + sprintf(msg, "Errore in DB_add(): chiave duplicata nell' indice %ld, file %s", + rec_num + 1, d4fileName(data)); + xvt_dm_post_fatal_exit(msg); + } + else + rt = _isreinsert; + } + else + if (rt == 0) + { + while ((rt = d4flush(data)) == r4locked) + u4delaySec(); + } + } + DB_unlock(handle); + if (is_locked == 0) + d4unlock(data); + return(rt); +} + +/*------------------------------------------------------------------------- + Blocca in modo esclusivo il file dati ed indice + --------------------------------------------------------------------------*/ +int DB_lockfile(int handle) +{ + int rt; + + if(!handle_ok(handle)) return(-1); + rt = d4lockFile(dbdata[handle]); + if (rt==0) rt=d4lockIndex(dbdata[handle]); + return(rt); +} + +HIDDEN int is_inkey(RecDes *r, int numfield) +{ + int found=0,i,j; + + for (i=0; ((i < MaxKeys) && (i < r->NKeys) && !found); i++) + for (j=0; ((j < r->Ky[i].NkFields) && !found); j++) + if (numfield == r->Ky[i].FieldSeq[j]) + found=1; + return(found); +} + +HIDDEN void do_key(char *fname, RecDes *r, TAG4INFO *tag_info, int n_keys) +{ + int i,j; + char tiname[9]; /* Tag name, max 8 characters long! */ + char* dot; + + strcpy(tiname,fname); + dot = strchr(tiname, '.'); + if (dot) *dot = '\0'; + _strupr(tiname); + for (i=0; ((i < MaxKeys) && (i < n_keys)); i++) + { + tag_info[i].name=(char *)u4alloc(9); + tag_info[i].expression=(char *)u4alloc(256); + tag_info[i].filter=(char*)u4alloc(20); + tag_info[i].descending=0; + if (r->Ky[i].DupKeys) + tag_info[i].unique=0; + else + tag_info[i].unique= i == 0 ? e4unique : r4unique_continue; +/* tag_info[i].unique=e4unique; */ + strcpy((char *)tag_info[i].filter,".NOT. DELETED()"); /* Not available for DBIII and CLIPPER */ + strcpy((char *)tag_info[i].name,tiname) ; + if (strlen(tiname) < 8) + strcat((char *)tag_info[i].name," "); + tag_info[i].name[strlen(tag_info[i].name)-1] = '0' + i + 1; + for (j=0; j < r->Ky[i].NkFields; j++) + { + int nf= r->Ky[i].FieldSeq[j]; + if (nf > MaxFields) /* When Upper field is specified */ + { + nf -= MaxFields; + strcat((char *) tag_info[i].expression,"UPPER("); + } + if (r->Ky[i].FromCh[j] != 255) /* When partial field is specified */ + strcat((char *)tag_info[i].expression,"SUBSTR("); + + switch (r->Fd[nf].TypeF) /* When numeric field in key is specified */ + { + case _intfld: + case _longfld: + case _realfld: + case _wordfld: + case _intzerofld: + case _longzerofld: + strcat((char *)tag_info[i].expression,"STR("); + break; + case _datefld: + strcat((char *)tag_info[i].expression,"DTOS("); + break; + case _boolfld: + strcat((char *)tag_info[i].expression,"IIF("); /* Logical fields are in key too.. */ + break; + default: /* It's a non sense to keep _realfld in key... */ + break; /* however it's possible to have it... */ + } /* Le chiavi composte da campi data non necessitano di funzioni di traduzione. */ + + strcat((char *)tag_info[i].expression,r->Fd[nf].Name); /* Append field name */ + + switch (r->Fd[nf].TypeF) /* If numeric field was specified */ + { /* add parameters to STR */ + case _intfld: + case _longfld: + case _realfld: /* Questo tipo di campo(real) non ha senso in un a chiave... */ + case _wordfld: + case _intzerofld: + case _longzerofld: + { + char ts[8]; + strcat((char *)tag_info[i].expression,","); + sprintf(ts,"%d",r->Fd[nf].Len); + strcat((char *)tag_info[i].expression,ts); + strcat((char *)tag_info[i].expression,",0)"); + } + break; + case _boolfld: + strcat((char *)tag_info[i].expression,",\"T\",\"F\")"); + break; + default: + break; + } + + /* Close parentheses if UPPER or DTOS operators were used: */ + if (r->Ky[i].FieldSeq[j] > MaxFields || (r->Fd[nf].TypeF == _datefld)) + strcat((char *)tag_info[i].expression,")"); + if (r->Ky[i].FromCh[j] != 255) /* If partial field was specified */ + { /* add parameters to SUBSTR */ + char ts[8]; + + strcat((char *)tag_info[i].expression,","); + sprintf(ts,"%d",r->Ky[i].FromCh[j] + 1); + strcat((char *)tag_info[i].expression,ts); + strcat((char *)tag_info[i].expression,","); + sprintf(ts,"%d",r->Ky[i].ToCh[j] - r->Ky[i].FromCh[j] + 1); + strcat((char *)tag_info[i].expression,ts); + strcat((char *)tag_info[i].expression,")"); + } + /* If there's another field in key adds "+" operator: */ + if ((j < (r->Ky[i].NkFields-1)) && (strlen(r->Fd[nf].Name) > 0)) + strcat((char *)tag_info[i].expression,"+"); + } + } + tag_info[i].name=NULL; + tag_info[i].expression=NULL; + tag_info[i].filter=NULL; + tag_info[i].unique=0; + tag_info[i].descending=0; +} + +/*------------------------------------------------------------------------- + Compatta il file dati + --------------------------------------------------------------------------*/ +int DB_packfile(short vis, const char * filename, long eod) +{ + int rt=0,handle; + + code_base.autoOpen = 0; + handle=DB_open(filename,1,0); /* Exclusive mode open! */ + if (handle > -1) + { + if (vis) + { + char s[_MAX_PATH]; + strcpy(s,"Compattamento "); + strcat(s, filename); + progind_create(100L,s,0,0,60); + } + if (eod < d4recCount(dbdata[handle])) + { + rt=d4zap(dbdata[handle],++eod,d4recCount(dbdata[handle])); + } else + rt=d4pack(dbdata[handle]); + if (vis) + progind_destroy(); + DB_close(handle); + } + else + rt=code_base.errorCode; + code_base.autoOpen = 1; + return rt; +} + +/*------------------------------------------------------------------------- + Compatta il file dati + --------------------------------------------------------------------------*/ +int DB_packmemo(short vis, const char * filename) +{ + int rt=0,handle; + + code_base.autoOpen = 0; + handle=DB_open(filename,1,0); /* Exclusive mode open! */ + if (handle > -1) + { + char s[81]; + + if (vis) + { + strcpy(s,"Compattamento memo file : "); + strcat(s,(char*)filename); + progind_create(100L,s,0,0,60); + } + rt=d4memoCompress(dbdata[handle]); + if (vis) + progind_destroy(); + DB_close(handle); + } + else + rt=code_base.errorCode; + code_base.autoOpen = 1; + return rt; +} + +/*------------------------------------------------------------------------- + Elimina i record duplicati + --------------------------------------------------------------------------*/ +int DB_clean_file(int handle, char * filename, char * ff, RecDes * r, short vis) +{ + TAG4INFO tags[2]; + TAG4 * t; + char s[256], s0[256]; + int l = 0, lt = 0, rt = 0; + long cnt = 0; + INDEX4 *w = NULL; + long items = DB_reccount(handle); + + if (items == 0) + return 0; + + s[0] = '\0'; + do_key(ff, r, tags, 1); + strcat((char *) tags[0].expression, "+STR(RECNO(),9)"); + w = i4create(dbdata[handle],(char*)filename,tags); + u4free((char *) tags[0].name); + u4free((char *) tags[0].expression); + u4free((char *) tags[0].filter); + if (w == NULL) return code_base.errorCode; + t = d4tagDefault(dbdata[handle]); + lt = expr4len(t->tagFile->expr); + l = lt - 9; + if (vis) + progind_create(items,"Ricerca record duplicati",0,1,60); + + rt = tfile4bottom(t->tagFile); + + while (code_base.errorCode == 0) + { + strncpy(s0, a4tagKey(dbdata[handle]), lt); + + if (vis) + progind_set_status(++cnt); + + if (!strncmp(s, s0, l)) + { + d4go(dbdata[handle],tfile4recNo(t->tagFile)); + d4delete(dbdata[handle]); + tfile4seek(t->tagFile, s0, lt); + } + strncpy(s, s0, lt); + if (tfile4skip(t->tagFile, -1L) >= 0) + break; + + } // while + rt = code_base.errorCode; + if (vis) + progind_destroy(); + + i4close(w); + return rt; +} + +/*------------------------------------------------------------------------- + Compatta gli indici + --------------------------------------------------------------------------*/ + +int DB_yesnobox(const char* msg) +{ + return xvt_dm_post_ask("Si", "No", NULL, msg) == RESP_DEFAULT; +} + +int DB_packindex(short vis, const char * filename, RecDes *r, long *peod, bool ask) +{ + int rt=0,handle; + TAG4INFO tags[MaxKeys+1]; + char s[256]; + INDEX4 * w = NULL; + + strcpy(s,"Ricostruzione indici file : "); + strcat(s,filename); + + code_base.autoOpen=0 ; + handle=DB_open(filename,1,0); /* Exclusive mode open */ + if (handle >= 0) + { + int i; + char *ff = find_slash_backslash(filename); + if (vis) + progind_create((long)r->NKeys,s,0,1,60); + if ((ff == NULL) || *ff == '\0') + ff = (char *)filename; + else + ff++; + do_key(ff,r,tags, r->NKeys); + w = i4create(dbdata[handle],NULL,tags); + if (vis) + { + progind_set_status((long)r->NKeys); + progind_destroy(); + } + if (w == NULL) rt = code_base.errorCode; + if (rt == e4unique || rt == r4unique) + { + rt = 0; + if (!ask || DB_yesnobox("Sono stati rilevati alcuni records duplicati:\nsi desidera eliminarli?")) + rt = DB_clean_file(handle, (char*) filename, ff, r, vis); + else + tags[0].unique = r4unique_continue; + if (rt == 0) + { + if (vis) + progind_create((long)r->NKeys,s,0,1,60); + w = i4create(dbdata[handle],(char*)filename,tags); + if (w == NULL) rt = code_base.errorCode; + if (vis) + { + progind_set_status((long)r->NKeys); + progind_destroy(); + } + } + } + if (rt == 0) + { + if (u4switch() & 2 || u4switch() & 8) /* Clipper and DBIII */ + { + FILE *fp; + char cgp[81]; + + strcpy(cgp,filename); + strcat(cgp,".cgp"); + if ((fp=fopen(cgp,"w"))!=NULL) + { + int j; + + for (j=0; jNKeys;j++) + fprintf(fp,"%s\n",tags[j].name); + fclose(fp); + } + } + } + for (i=0; ((i < MaxKeys) && (i < r->NKeys)); i++) + { + u4free((char *) tags[i].name); + u4free((char *) tags[i].expression); + u4free((char *) tags[i].filter); + } + *peod=DB_reccount(handle); + DB_close(handle); + } + code_base.autoOpen = 1; + return(rt); +} + + +/*------------------------------------------------------------------------- + costruisce il file filename + --------------------------------------------------------------------------*/ + +int DB_build(const char * filename, RecDes *r) +{ + + FIELD4INFO field_info[MaxFields+1]; /* Numero di campi in un record */ + TAG4INFO tag_info[MaxKeys+1]; /* Numero di chiavi in un file */ + DATA4 *dbuilded; + int rt=0,i; + char *ff = find_slash_backslash(filename); + + + for (i=0; ((iNFields) && (iFd[i].Name); + field_info[i].len = r->Fd[i].Len; + field_info[i].dec = r->Fd[i].Dec; + switch (r->Fd[i].TypeF) + { + case _intfld: + case _longfld: + case _realfld: /* It's a non sense to keep this in key! */ + case _wordfld: + case _intzerofld: + case _longzerofld: + field_info[i].type=r4num; + break; + case _boolfld: + field_info[i].type=r4log; + break; + case _datefld: + field_info[i].type=r4date; + break; + case _memofld: + field_info[i].type=r4memo; + field_info[i].len = 10; + field_info[i].dec = 0; + break; + case _charfld: + default: + field_info[i].type=r4str; + break; + } + } + field_info[i].name=NULL; + field_info[i].type=0; + field_info[i].len=0; + field_info[i].dec=0; + + if (ff == NULL || *ff == '\0') + ff = (char *) filename; + else + ff++; + do_key(ff,r,tag_info, r->NKeys); + + if ((dbuilded=d4create(&code_base, (char *)filename, field_info, tag_info))==0) /* deve solo creare il file dati vuoto */ + rt=code_base.errorCode; + else + rt=d4close(dbuilded); + if (u4switch() & 2 || u4switch() & 8) /* Rebuild filename.cgp for CLIPPER AND DBIII only */ + { + FILE* fp; + char xx[81]; + + strcpy(xx,(char*)filename); + + strcat(xx,".cgp"); + if ((fp=fopen(xx,"w"))!=NULL) + { + int j; + for (j=0; tag_info[j].name ; j++) + fprintf(fp,"%s\n",tag_info[j].name); + fclose(fp); + } + } + if (rt!=0) + rt=code_base.errorCode; + for (i=0; ((i < MaxFields) && (i < r->NFields)); i++) + u4free(field_info[i].name); + for (i=0; ((i < MaxKeys) && (i < r->NKeys)); i++) + { + u4free((char *) tag_info[i].name); + u4free((char *) tag_info[i].expression); + u4free((char *) tag_info[i].filter); + } + return(rt) ; +} + +/*------------------------------------------------------------------------- + reperisce il tracciato record e la stringa di definizione delle chiavi + Stringa di definizione chiavi: + expression1|unique1$expression2|unique2$expression3|unique3 + --------------------------------------------------------------------------*/ + +int DB_recinfo(const char * filename, FileDes *d, RecDes *r, char* keys) +{ + /* filename must not have extension since it's used to search index name too*/ + FIELD4INFO *field_info; /* Definizione del tracciato record */ + TAG4INFO *tag_info; /* Definizione delle chiavi */ + INDEX4 *index_file; + DATA4 *data_file; + int rt=0,num_fields,i; + + data_file = d4open(&code_base, (char*)filename); + if (data_file != NULL) + { + field_info = d4fieldInfo(data_file); + index_file = d4index(data_file,"" /*(char*)filename */); + if (index_file == NULL) + { + char msg[256]; + sprintf(msg, "Il file %s e' senza indici.",filename); + xvt_dm_post_fatal_exit(msg); + } + tag_info = i4tagInfo(index_file); + d->EOD = d->EOX = d4recCount(data_file); + d->LenR = (word)d4recWidth(data_file); + d->Flags = 0L; + strcpy(d->Des,"File esterno"); + strcpy(d->FCalc,""); + strcpy(d->GenPrompt,""); + if (field_info != NULL && tag_info != NULL) + { + /* Compile field information */ + num_fields = d4numFields(data_file); + r->NFields = num_fields; + for (i=0; ((iFd[i].Name,field_info[i].name); + _strupr(r->Fd[i].Name); + r->Fd[i].Len = (unsigned char)field_info[i].len; + r->Fd[i].Dec = (unsigned char)field_info[i].dec; + switch(field_info[i].type) + { + case r4str: + if (r->Fd[i].Len > 1) + r->Fd[i].TypeF = _alfafld; + else + r->Fd[i].TypeF = _charfld; + break; + case r4log: + r->Fd[i].TypeF = _boolfld; + break; + case r4date: + r->Fd[i].TypeF = _datefld; + break; + case r4memo: + r->Fd[i].TypeF = _memofld; + break; + case r4num: + if (r->Fd[i].Dec > 0) + r->Fd[i].TypeF = _realfld; + else + r->Fd[i].TypeF = r->Fd[i].Len < 6 ? _intfld : _longfld; + break; + default: + break; + } + } + + strcpy(keys,""); + /* Compile key definition */ + for (i=0; i < MaxKeys; i++) /* Browse all tags */ + { + if (tag_info[i].name == NULL) + break; + strcat(keys,tag_info[i].expression); + /* Tell me if you're unique my Boy... */ + strcat(keys,"|"); + strcat(keys,tag_info[i].unique == 0 ? "X" : " "); + strcat(keys,"$"); + } + r->NKeys = i; + u4free(field_info); + u4free(tag_info); + } + else + rt = code_base.errorCode; + d4close(data_file); + } + else + rt = code_base.errorCode; + return (rt); +} + +/*------------------------------------------------------------------------- + ritorna l'ultimo errore + --------------------------------------------------------------------------*/ + +int DB_get_error(void) +{ + int rt = code_base.errorCode; + code_base.errorCode=0; + return (rt); +} + +/*------------------------------------------------------------------------- + Azzera la viarabile globale d'errore + --------------------------------------------------------------------------*/ + +void DB_zero_error(void) +{ + code_base.errorCode=0; +} + +/*------------------------------------------------------------------------- + Si posiziona sull'indice attivo alla chiave indicata, restituisce + la prima chiave che trova >= a from. (TCusrsor) + --------------------------------------------------------------------------*/ + +int DB_index_seek(int handle, char* from) +{ + TAG4 *t; + + if(!handle_ok(handle)) return(-1); + if ((t=d4tagDefault(dbdata[handle]))==NULL) return(-1); + + if (tfile4seek(t->tagFile,from,strlen(from)) < 0) return(DB_get_error()); + return(0); + +} + +/*------------------------------------------------------------------------- + Ritorna il numero di record corrispondente alla chiave corrente + --------------------------------------------------------------------------*/ + +long DB_index_recno(int handle) +{ + TAG4 *t; + + if(!handle_ok(handle)) return(-1); + if ((t=d4tagDefault(dbdata[handle]))==NULL) return(-1); + + return(tfile4recNo(t->tagFile)); +} + +/*------------------------------------------------------------------------- + Si posiziona sulla chiave successiva dell'indice corrente + --------------------------------------------------------------------------*/ +long DB_index_next(int handle) +{ + TAG4 *t; + + if(!handle_ok(handle)) return(-1); + if ((t=d4tagDefault(dbdata[handle]))==NULL) return(-1); + + return(tfile4skip(t->tagFile,1L)); +} + +/*------------------------------------------------------------------------- + Restituisce la chiave corrente + --------------------------------------------------------------------------*/ + +char* DB_index_getkey(int handle) +{ + static char* key = NULL; + TAG4 *t; + int klen; + + if (key == NULL) + key = malloc(MAXLEN); + if(!handle_ok(handle)) + return(NULL); + if ((t=d4tagDefault(dbdata[handle]))==NULL) return(NULL); + klen=a4tagKeyLen(dbdata[handle]); + if (klen > (MAXLEN-1)) klen=MAXLEN-1; + memcpy(key,a4tagKey(dbdata[handle]),klen); /* tfile4key non restituisce una null terminated string */ + key[klen]='\0'; + return key; +} + +/*------------------------------------------------------------------------- + Si posiziona sulla chiave ed il record indicati + --------------------------------------------------------------------------*/ +int DB_index_go(int handle, const char* key, long recno) +{ + TAG4 *t; + + if(!handle_ok(handle)) return(-1); + if ((t=d4tagDefault(dbdata[handle]))==NULL) return(-1); + + return(tfile4go(t->tagFile, key, recno, FALSE)); +} + +/*------------------------------------------------------------------------- + Restituisce vero se l'indice e' alla fine + --------------------------------------------------------------------------*/ + +int DB_index_eof(int handle) +{ + TAG4 *t; + + if(!handle_ok(handle)) return(-1); + if ((t=d4tagDefault(dbdata[handle]))==NULL) return(-1); + return(tfile4eof(t->tagFile)); +} + +/*------------------------------------------------------------------------- + Blocca il record indicato + --------------------------------------------------------------------------*/ + +int DB_lock_rec(int handle,long nrec) +{ + if(!handle_ok(handle)) return(-1); + if(d4lock(dbdata[handle],nrec)==r4locked) return(-1); + else return(0); +} + +/*------------------------------------------------------------------------- + Ritorna vero(non zero) se il file dati od indice sono stati bloccati + in modo esclusivo dalla presente applicazione, non da altri programmi!!! + --------------------------------------------------------------------------*/ + + +int DB_file_locked(int handle) +{ + if(!handle_ok(handle)) return(-1); + return a4lockTest(dbdata[handle]); +} + +/*------------------------------------------------------------------------- + Ritorna vero se il record nrec e' bloccato dalla presente applicazione, + non da altri programmi!!! + --------------------------------------------------------------------------*/ + +int DB_rec_locked(int handle,long nrec) +{ + if(!handle_ok(handle)) return(-1); + return(d4lockTest(dbdata[handle],nrec)); +} + +/*------------------------------------------------------------------------- + restituisce la configurazione della libreria + --------------------------------------------------------------------------*/ + +long DB_getconf() +{ + return(u4switch()); +} + +/*------------------------------------------------------------------------- + Restituisce il numero di versione scritto sull'header dell'indice + --------------------------------------------------------------------------*/ + +long DB_changed(int handle) +{ + return(a4indexVersion(dbdata[handle])); +} + +char* DB_memoptr( const int handle, const char * fieldname ) +{ + FIELD4 * f; + f = d4field( dbdata[ handle ], ( char *)fieldname ); + return f4memoPtr( f ); +} + +int DB_memowrite( const int handle, const char * fieldname, const char * data ) +{ + int ret; + FIELD4 * f; + f = d4field(dbdata[handle], fieldname ); + ret = f4memoAssign( f, ( char * )data ); + d4flush(dbdata[handle]); + + d4unlock(dbdata[handle]); + return ret; +} diff --git a/include/strings.cpp b/include/strings.cpp index 4edd016af..dd32cbc05 100755 --- a/include/strings.cpp +++ b/include/strings.cpp @@ -1295,12 +1295,16 @@ bool TFilename::custom_path(const char* path_list) TToken_string pl = path_list; if (pl.empty()) { + pl.add("custom"); // c:/campo32/custom if (prefix_valid()) { - pl = firm2dir(prefix().get_codditta()); // f:/campo/dati/00001A - pl.add(firm2dir(-1)); pl << "custom"; // f:/campo/dati/custom + TFilename n; + n = firm2dir(prefix().get_codditta()); n.add("custom"); + pl.add(n); // f:/campo32/dati/00001A/custom + + n = firm2dir(-1); n.add("custom"); + pl.add(n); // f:/campo32/dati/custom } - pl.add("custom"); // c:/campo/custom } const TString fname = name(); FOR_EACH_TOKEN(pl, path)