diff --git a/include/csort.c b/include/csort.c new file mode 100755 index 000000000..a4b8938e4 --- /dev/null +++ b/include/csort.c @@ -0,0 +1,753 @@ +/* +@(SH) Funzioni per l'esecuzione di sort +@(VG$) PRIVATE +datisort : copia struttura del sort attivo +nsortfield : Numero campi definiti dal sort +sp : struttura dei parametri sort +totrcd : numero totale di record ordinati +no_seq : contatore sequenze +no_seq1 : contatore sequenze +bspace : spazio disponibile nel buffer +nrcds : numero di records nel buffer di sort +nrcds1 : numero di records nel buffer di sort +bf, bf1 : puntatori al buffer di sort +inbf : records variabili nel buffer di sort +sptr : puntatore al vettore dei puntatori ai buffer +init_sptr : puntatore al buffer appropriato +rcds_seq : sequenza record nel buffer di merge +fp1, fp2 : puntatori a file di lavoro per il sort +fdname : nome di lavoro del sort +f2name : nome di lavoro del sort +------------------------------------------------------------------------------- + @(H) 2.3.00.112 23/11/91 Bonazzi Corretta fine sort + @(H) 2.3.01.245 08/03/94 Soragna Corretto sort_op per 386 +*/ + +#include "csort.h" +#include + +/*----------------------- STATIC PER PRIMA PARTE ----------------------------*/ + +static struct s_prm datisort; +static int nsortfield; + +/*----------------------- STATIC PER SECONDA PARTE --------------------------*/ + +static struct s_prm *sp; +/* @(!) 2.3.00.112 */ +static unsigned long totrcd; +static unsigned no_seq; +static unsigned no_seq1; +/* @(:) 2.3.00.112 */ +static unsigned bspace; +/* @(!) 2.3.00.112 */ +static unsigned nrcds; +static unsigned nrcds1; +/* @(:) 2.3.00.112 */ +static char *bf, *bf1; +/* @(!) 2.3.00.112 */ +static unsigned inbf; +/* @(:) 2.3.00.112 */ +static char **sptr; +static char *init_sptr; +/* @(!) 2.3.00.112 */ +static unsigned rcds_seq; +/* @(:) 2.3.00.112 */ +static FILE *fp1, *fp2; +static char fdname [42]; +static char f2name [42]; + +static int sortcomp(char **, char **); +static char *appr_mem(unsigned *); +/* @(!) 2.3.00.112 */ +static FILE *wopen(char *); +/* @(:) 2.3.00.112 */ +static void dumpbuff(void); +static void merge(void); +static void prep_merge(void); +/* @(!) 2.3.01.245 */ +void dummy(void); +/* @(:) 2.3.01.245 */ + +/*----------------------- PRIMA PARTE ---------------------------------------*/ + +/* +@(#) init_sort SORT + +@(ID) +Inizializza le variabili globali per il sort. +@(FD) +*/ + +int init_sort(prms) +struct s_prm *prms; /* struttura di descrizione del sort */ +{ + sp = prms; + if ((bf = appr_mem(&bspace)) != NULL) { + nrcds1 = nrcds = bspace / (sp->rc_len + sizeof(char *)); + init_sptr = bf; + sptr = (char **) bf; + bf += nrcds * sizeof(char *); + fp1 = fp2 = NULL; + totrcd = no_seq = inbf = 0; + return 0; + } + else + return -1; +} + +/* +@(#) sort SORT + +@(ID) +Funzione per l'input dei record da ordinare. +@(FD) + +@(IN) +La chiamata sort(char *) NULL) chiude la fase di input dei record. +@(FN) +*/ + +void sort(s_rcd) +char *s_rcd; /* buffer contenente il record da ordinare */ + +{ +/* @(!) 2.3.00.112 */ + if (inbf == nrcds) { /* if the sort buffer is full */ +/* @(:) 2.3.00.112 */ + qsort(init_sptr, inbf, sizeof (char *), sortcomp); + if (s_rcd) { /* if there are more records to sort */ + dumpbuff(); /* dump the buffer to a sort work file*/ + no_seq++; /* count the sorted sequences */ + } + } + if (s_rcd !=NULL) { + /* --- this is a record to sort --- */ + totrcd++; + /* --- put the rcd addr in the pointer array --- */ + *sptr = bf + inbf * sp->rc_len; + inbf++; + /* --- move the rcd to the buffer --- */ + memcpy(*sptr, s_rcd, sp->rc_len); + sptr++; /* point to next array entry*/ + } + else { /* null pointer means no more rcds */ + if (inbf) { /* any records in the buffer? */ + qsort(init_sptr, inbf, sizeof (char *), sortcomp); + if (no_seq) /* if this isn't the only sequence*/ + dumpbuff(); /* dump the buffer to a work file */ + no_seq++; /* count the sequence */ + } + no_seq1 = no_seq; + if (no_seq > 1) /* if there is more than 1 sequence */ + prep_merge(); /* prepare for the merge */ + } +} +/* +@($) prep_merge SORT + +@(ID) +Funzione per la preparazione del Merge. +@(FD) + +@(ISV) +i = contatore. + +rr = puntatore ad una struttura di sequenza (di lavoro). + +n_bfsz = ampiezza in byte del merge buffer. + +@(FSV) +*/ + +static void prep_merge() +{ +int i; +struct bp *rr; +unsigned n_bfsz; + +memset(init_sptr, '\0', bspace); + /* -------- merge buffer size ------ */ +n_bfsz = bspace - no_seq * sizeof(struct bp); +/* ------ # rcds/seq in merge buffer ------- */ +rcds_seq = n_bfsz / no_seq / sp->rc_len; +if (rcds_seq < 2) { + /* ---- more sequence blocks than will fit in buffer, + merge down ---- */ + while (rcds_seq < 2) { + FILE *hd; +/* @(!) 2.3.00.112 */ + char wname[42]; /* sort work name */ + + fp2 = wopen(f2name); /* open a sort work file */ +/* @(:) 2.3.00.112 */ + merge(); /* binary merge */ + hd = fp1; /* swap fds */ + fp1 = fp2; + fp2 = hd; +/* @(!) 2.3.00.112 */ + strcpy(wname, fdname); + strcpy(fdname, f2name); + strcpy(f2name, wname); + fclose(fp2); + unlink(f2name); + fp2 = NULL; +/* @(:) 2.3.00.112 */ + nrcds *= 2; + /* ------ adjust number of sequence ------ */ + no_seq = (no_seq + 1) / 2; + n_bfsz = bspace - no_seq * sizeof(struct bp); + rcds_seq = n_bfsz / no_seq / sp->rc_len; + } +} +bf1 = init_sptr; +rr = (struct bp *) init_sptr; +bf1 += no_seq * sizeof(struct bp); +bf = bf1; + +/* fill the merge buffer with records from all sequences */ + +for (i = 0; i < no_seq; i++) { + fseek(fp1, (long) i * ((long) nrcds * sp->rc_len), 0); + /* ------ read them all at once ------ */ +/* @(!) 2.3.00.112 modificata fread(bf1, rcds_seq * sp->rc_len, 1, fp1); */ + fread(bf1, sp->rc_len, rcds_seq, fp1); +/* @(:) 2.3.00.112 */ + rr->rc = bf1; + /* --- the last seq has fewer rcds than the rest --- */ + if (i == no_seq-1) { + if (totrcd % nrcds > rcds_seq) { + rr->rbuf = rcds_seq; +/* @(!) 2.3.00.112 */ + rr->rdsk = (unsigned) (totrcd % nrcds) - rcds_seq; +/* @(:) 2.3.00.112 */ + } + else { +/* @(!) 2.3.00.112 */ + rr->rbuf = (unsigned) (totrcd % nrcds); +/* @(:) 2.3.00.112 */ + rr->rdsk = 0; + } + } + else { + rr->rbuf = rcds_seq; + rr->rdsk = nrcds - rcds_seq; + } + rr++; + bf1 += rcds_seq * sp->rc_len; +} +} + +/* @(!) 2.3.01.245 */ +/* Funzione che non fa assolutamente nulla, ma e' estremamente + utile all'interno di sort_op, quando si supera una certa mole di + dati immessi nel buffer di sort; e' necessaria solo per la + compilazione di eseguibili per 386. Questa funzione inserita tra + le righe rtn= k+..... e memcpy(..) evita il fastidioso memory + fault che si ottiene utilizzando strutture molto ampie o molto + numerose. Probabilmente evita, in fase di compilazione, che vengano + creati indirizzi strani, oppure in fase di esecuzione, che vengano + reperite zone di memoria che non c'entrano per nulla. +*/ +void dummy() +{ +} +/* @(:) 2.3.01.245 */ + + +/* +@($) merge SORT + +@(ID) +Effettua un merge. +E' un merge binario di records dalla sequenza fp1 in fp2. +@(FD + +@(ISV) +i = contatore. + +needy,needx = se true necessita un record da (x/y). + +xcnt,ycnt = numero di records lasciati in ogni sequenza. + +x,y = contatori per le sequenze. + +adx,ady = indirizzi sul disco delle sequenze di record. + +ysptr = stringa di lavoro. +@(FSV) +*/ + +static void merge() +{ + int i; + int needy, needx; /* true = need a rcd from (x/y) */ +/* @(!) 2.3.00.112 */ + unsigned xcnt, ycnt; /* # rcds left each sequence */ +/* @(:) 2.3.00.112 */ + int x, y; /* sequence counters */ + long adx, ady; /* sequence record disk addresses */ +/* @(!) 2.3.00.112 */ + char *ysptr = init_sptr + sp->rc_len; +/* @(:) 2.3.00.112 */ + + /* --- the two sets of sequences are x and y ----- */ + fseek (fp2, 0L, 0); + for (i = 0; i < no_seq; i += 2) { + x = y = i; + y++; + ycnt = + y == no_seq ? 0 : y == no_seq - 1 ? +/* @(!) 2.3.00.112 */ + (unsigned) (totrcd % nrcds) : nrcds; + xcnt = y == no_seq ? (unsigned) (totrcd % nrcds) : nrcds; +/* @(:) 2.3.00.112 */ + adx = (long) x * (long) nrcds * sp->rc_len; + ady = adx + (long) nrcds * sp ->rc_len; + needy = needx = 1; + while (xcnt || ycnt) { + if (needx && xcnt) { /* need a rcd from x? */ + fseek(fp1, adx, 0); + adx += (long) sp->rc_len; + fread(init_sptr, sp->rc_len, 1, fp1); + needx = 0; + } + if (needy && ycnt) { /* need a rcd from y? */ + fseek(fp1, ady, 0); + ady += sp->rc_len; +/* @(!) 2.3.00.112 modificata fread(init_sptr+sp->rc_len, sp->rc_len, 1, fp1); */ + fread(ysptr, sp->rc_len, 1, fp1); +/* @(:) 2.3.00.112 */ + needy = 0; + } + if (xcnt || ycnt) { /* if anything is left */ + /* ---- compare the two sequences --- */ +/* @(!) 2.3.00.112 modificata if (!ycnt || (xcnt && (sortcomp(&init_sptr, &init_sptr + sp->rc_len)) < 0)) { */ + if (!ycnt || (xcnt && (sortcomp(&init_sptr, &ysptr)) < 0)) { +/* @(:) 2.3.00.112 */ + /* ----- record from x is lower ---- */ + fwrite(init_sptr, sp->rc_len, 1, fp2); + --xcnt; + needx = 1; + } + else if (ycnt) { /* record from y is lower */ +/* @(!) 2.3.00.112 */ + fwrite(ysptr, sp->rc_len, 1, fp2); +/* @(:) 2.3.00.112 */ + --ycnt; + needy = 1; + } + } + } + } +} +/* +@($) dumpbuff SORT + +@(ID) +Copia il buffer di sort nel file di lavoro. +@(FD) + +@(ISV) +i = contatore. +@(FSV) +*/ + +static void dumpbuff() +{ +/* @(!) 2.3.00.112 */ + unsigned i; +/* @(:) 2.3.00.112 */ + + if (fp1 == NULL) +/* @(!) 2.3.00.112 */ + fp1 = wopen(fdname); +/* @(:) 2.3.00.112 */ + sptr = (char **) init_sptr; + for (i = 0; i < inbf; i++) { + fwrite(*(sptr + i), sp->rc_len, 1, fp1); +/* @(!) 2.3.00.112 */ + *(sptr + i) = 0; +/* @(:) 2.3.00.112 */ +} +inbf = 0; +} + +/* +@($) wopen SORT + +@(ID) +Apre un file di lavoro temporaneo (per il sort). +@(FD) + +@(ISV) +fp = puntatore al file temporaneo. + +s = stringa di formato. + +n = numero del file. + +@(FSV) +*/ + +/* @(!) 2.3.00.112 */ +static FILE *wopen(name) +char *name; /* nome del file temporaneo */ +/* @(:) 2.3.00.112 */ +{ + FILE *fp; + char s[42]; +/* @(!) 2.3.00.112 */ + static int n = 0; +/* @(:) 2.3.00.112 */ + + sprintf(s, "srt%03d", ++n); + TMPFNAME(name,s); +#ifdef DOS + if ((fp = fopen(name, "wb+")) == NULL) { +#else + if ((fp = fopen(name, "w+")) == NULL) { +#endif + +#ifndef XVT_OS + printf("\nFile error"); + exit(1); +#else + fatal_box("Can't open SORT file"); +#endif + } + return fp; +} + +/* +@(#) sort_op SORT + +@(ID) +Ritorna il puntatore al primo record non ancora elaborato nella sequenza ordinata. +@(FD) + +@(ISV) +j = e' true se una qualche sequenza contiene ancora dei records. + +i = contatore. + +k,nrd,l = variabili di lavoro. + +rr = variabile di lavoro. + +r1 = variabile di lavoro. + +rtn = indirizzo del buffer da ritornare. + +ad,tr = variabili di lavoro. +@(FSV) + +@(FN) + Se la funzione sort_op ritorna NULL non ci sono piu' records nella sequenza ordinata. +@(FN) +*/ + + +char *sort_op() +{ + int j = 0; +/* @(!) 2.3.00.112 */ + unsigned i, k, nrd, l; +/* @(:) 2.3.00.112 */ + struct bp *rr; +/* @(!) 2.3.00.112 */ + static unsigned r1 = 0; +/* @(:) 2.3.00.112 */ + char *rtn; + long ad, tr; + + if (init_sptr == NULL) return NULL; + + sptr = (char **) init_sptr; + if (no_seq < 2) { + /* -- with only 1 sequence, mo merge has been done -- */ +/* @(!) 2.3.00.112 */ + if (r1 == (unsigned) totrcd) { +/* @(:) 2.3.00.112 */ + if (init_sptr != NULL) free(init_sptr); +/* @(!) 2.3.00.112 */ + init_sptr = NULL; +/* @(:) 2.3.00.112 */ + fp1 = fp2 = NULL; + r1 = 0; + return NULL; + } + return *(sptr + r1++); + } + + + rr = (struct bp *) init_sptr; + for (i = 0; i < no_seq; i++) +/* @(!) 2.3.00.112 */ + j |= (int) (rr + i)->rbuf | (rr + i)->rdsk; +/* @(:) 2.3.00.112 */ + + /* -- j will be true if any sequence still has records - */ + if (!j) + { + fclose(fp1); /* none left */ + unlink(fdname); +/* @(!) 2.3.00.112 eliminata if (fp2) */ +/* @(!) 2.3.00.112 eliminata { */ +/* @(!) 2.3.00.112 eliminata fclose(fp2); */ +/* @(!) 2.3.00.112 eliminata unlink(f2name); */ +/* @(!) 2.3.00.112 eliminata } */ +/* @(:) 2.3.00.112 */ + if (init_sptr != NULL) free(init_sptr); +/* @(!) 2.3.00.112 */ + init_sptr = NULL; +/* @(:) 2.3.00.112 */ + fp1 = fp2 = NULL; + r1 = 0; + return NULL; + } + k = 0; + + /* --- find the sequence in the merge buffer + with the lowest record --- */ + for (i = 0; i < no_seq; i++) + k = ((sortcomp( &(rr + k)->rc, &(rr + i)->rc) < 0) ? k : i); + + + /* --- k is an integer sequence number that offsets to the + sequence with the lowest record ---- */ + + (rr + k)->rbuf--; /* decrement the rcd counter */ + rtn = (rr + k)->rc; /* set the return pointer */ + (rr + k)->rc += sp->rc_len; + if ((rr + k)->rbuf == 0) { + /* ---- the sequence got empty ---- */ + /* --- so get some more if there are any --- */ + rtn = bf + k * rcds_seq * sp->rc_len; +/* @(!) 2.3.01.245 */ + dummy(); +/* @(:) 2.3.01.245 */ + memcpy(rtn, (rr + k)->rc - sp->rc_len, sp->rc_len); + (rr + k)->rc = rtn + sp->rc_len; + if ((rr + k)->rdsk != 0) { + l = ((rcds_seq-1) < (rr+k)->rdsk) ? rcds_seq-1 : (rr+k)->rdsk; +/* @(!) 2.3.00.112 */ + nrd = k == no_seq - 1 ? (unsigned) (totrcd % nrcds) : nrcds; +/* @(:) 2.3.00.112 */ + tr = (long) ((k * nrcds + (nrd - (rr + k)->rdsk))); + ad = tr * sp->rc_len; + fseek(fp1, ad, 0); +/* @(!) 2.3.00.112 modificata fread(rtn + sp->rc_len, l * sp->rc_len, 1, fp1); */ + fread(rtn + sp->rc_len, sp->rc_len, l, fp1); +/* @(:) 2.3.00.112 */ + (rr + k)->rbuf = l; + (rr + k)->rdsk -= l; + } + else + memset((rr + k)->rc, 127, sp->rc_len); + } + return rtn; +} + +/* +@(#) sort_stats SORT + +@(ID) +Visualizza la statistica sul sort. +@(FD) +*/ + +void sort_stats() +{ +#ifndef XVT_OS + printf("\n\r\n\r\n\rRecord Length = %d",sp->rc_len); +/* @(!) 2.3.00.112 */ + printf("\n\r%u records sorted",totrcd); + printf("\n\r%u sequence",no_seq); +/* @(:) 2.3.00.112 */ + if (no_seq1 != 1) putchar('s'); + printf("\n\r%u characters of sort buffer", bspace); +/* @(!) 2.3.00.112 */ + printf("\n\r%u records per buffer\n\n",nrcds); +/* @(:) 2.3.00.112 */ +#else + message_box( + "Record length = %d\n" + "%u records sorted\n" + "%u sequences\n" + "%u bytes of sort buffer\n" + "%u records per buffer", + sp->rc_len, totrcd, no_seq, bspace, nrcds + ); +#endif +} + +/* +@($) appr_mem SORT + +@(ID) +Alloca memoria per un buffer. +@(FD) + +@(ISV) +buff = buffer di memoria allocato. +@(FSV) + +@(IN) +Se puo' alloca MOSTMEM altrimenti ne alloca quanto puo', +non scendendo mai sotto il minimo LEASTMEM +@(FN) +*/ + +static char *appr_mem(h) +unsigned *h; /* puntatore alla quantita' di byte allocati */ +{ + char *buff = NULL; + + *h = (unsigned) MOSTMEM + 1024; + while (buff == NULL && *h > LEASTMEM) { + *h -= 1024; + buff = malloc(*h); + } + return buff; +} + +/* +@($) sortcomp SORT + +@(ID) +Esegue i confronti per il sort ed il merge. +@(FD) + +@(ISV) +i = contatore. + +k = risultato della comparazione. +@(FSV) + +@(IN) +Ritorna un intero < 0 se a < b + 0 se a = b + > 0 se a > b +@(FN) +*/ + +static int sortcomp(a,b) +char **a; char **b; /* puntatori ai puntatori ai record da confrontare */ +{ + int i, k; + + if (**a == 127 || **b == 127) + return (int) **a - (int) **b; + for (i = 0; i < NOFLDS; i++) + { + if (sp->s_fld[i].f_pos == 0) break; + if (sp->s_fld[i].f_len >= 0) /* string compare */ + { + if ( ( k=strncmp ( (*a)+sp->s_fld[i].f_pos-1, + (*b)+sp->s_fld[i].f_pos-1, + sp->s_fld[i].f_len + ) ) != 0) + return (sp->s_fld[i].ad == 'd')?-k:k; + } + + if (sp->s_fld[i].f_len == -1) /* integer compare */ + { + if ( (*( (int*) (*a)+sp->s_fld[i].f_pos-1 )) != + (*( (int*) (*b)+sp->s_fld[i].f_pos-1 )) ) + { + k=(*( (int*) (*a)+sp->s_fld[i].f_pos-1 )) - (*( (int*) (*b)+sp->s_fld[i].f_pos-1 )); + return (sp->s_fld[i].ad == 'd')?-k:k; + } + } + + if (sp->s_fld[i].f_len == -2) /* BOOLEAN compare */ + { + if ( (*( (BOOLEAN*) (*a)+sp->s_fld[i].f_pos-1 )) != + (*( (BOOLEAN*) (*b)+sp->s_fld[i].f_pos-1 )) ) + { + k=(int) ( (*( (BOOLEAN*) (*a)+sp->s_fld[i].f_pos-1 )) - (*( (BOOLEAN*) (*b)+sp->s_fld[i].f_pos-1 )) ); + return (sp->s_fld[i].ad == 'd')?-k:k; + } + } + } + return 0; +} + +/*---------------------------- SECONDA PARTE --------------------------------*/ + +/* +@(#) initsortfield SORT + +@(ID) +Definizione di sort per un record ISAM. +@(FD) +*/ + +void initsortfield () +{ + nsortfield = datisort.s_fld[0].f_pos = 0; /* sort su nessun campo */ +} + +/* +@(#) addsortfield SORT + +@(ID) +Aggiunge campi alla descrizione. +@(FD) + +@(ISV) +i = variablie di lavoro. + +n = variablie di lavoro. +@(FSV) +*/ + +int addsortfield (isfd,ncampo,da,a,ad) +isfdptr isfd; /* puntatore al descrittore del file ISAM */ +FieldName ncampo; /* nome campo */ +int da; /* carattere da cui considerare il campo per il sort */ +int a; /* carattere fino al quale considerare il campo per il sort */ +char ad; /* ordine crescente o decrescente */ + +{ + int i,n; + + if (((n = findfld(isfd->r, ncampo)) != -1) && (nsortfield < NOFLDS)) + { + /* sostituito i con n in Fd[_].RecOff e Fd[_].len */ +/* @(!) 2.3.01.temp */ + datisort.s_fld[nsortfield].f_pos = (da==0) ? (isfd->r->Fd[n].RecOff + 1) : (isfd->r->Fd[n].RecOff+da); + datisort.s_fld[nsortfield].f_len = (a==0) ? (isfd->r->Fd[n].Len) : (a-da+1); /* carica FLDLEN */ + datisort.s_fld[nsortfield].ad = ad; /* carica AD */ + nsortfield++; +/* @(:) 2.3.01.temp */ + return 0; + } + else return -1; +} + +/* +@(#) finesortfield SORT + +@(ID) +Chiude la descrizione del sort per i record ISAM. +@(FD) + +@(IN) +Attenzione : questa funzione inizializza anche il sort. +@(FN) +*/ + +int finesortfield (isfd) +isfdptr isfd; /* puntatore al descrittore del file ISAM */ +{ + datisort.rc_len=isfd->d->LenR; +/* @(!) 2.3.01.temp */ + if (nsortfield < NOFLDS) + datisort.s_fld[nsortfield].f_pos = 0; /* chiude l'elenco campi */ +/* @(:) 2.3.01.temp */ + return (init_sort (&datisort)); +} + +/*---------------------------------------------------------------------------*/ diff --git a/include/csort.h b/include/csort.h new file mode 100755 index 000000000..1e4018259 --- /dev/null +++ b/include/csort.h @@ -0,0 +1,148 @@ +/* +@(SH) Header + +@(C#) PUBBLICHE +NOFLDS : massimo numero di chiavi da ordinare + +@(C$) PRIVATE +MOSTMEM : numero massimo di bytes di memoria per il buffer di sort +LEASTMEM : numero minimo di bytes di memoria per il buffer di sort +@(VG#) PUBBLICHE +s_prm : struttura di un sort +s_prm.rc_len : lunghezza del record +s_prm.s_fld : vettore della struttura dei campi di sort +s_prm.s_fld[].f_pos : prima posizione del campo (contando da 1) +s_prm.s_fld[].f_len : lunghezza del campo e tipo del campo; se f_len > 0 e' una stringa; se f_len = -1 e' un intero; se f_len = -2 e' un boolean +s_prm.s_fld[].ad : a = crescente; d = decrescente + +@(VG$) PRIVATE +bp : struttura di una sequenza in un buffer di merge +bp.rc : puntatore al record nel merge buffer +bp.rbuf : record rimasti nel buffer in questa sequenza di sort +bp.rdsk : record rimasti nel disco in questa sequenza di sort +------------------------------------------------------------------------------- +*/ + +#ifndef __CSORT_H +#define __CSORT_H + +#ifndef __CCOMMON_H +#include "ccommon.h" +#endif +#ifndef __CCUSTIO_H +#include "ccustio.h" +#endif +#include "/usr/include/isam.h" + +#define NOFLDS 10 +#define MOSTMEM 51200 +#define LEASTMEM 10240 +#define MaxFields 100 +#define MKFields 10 +#define MaxKeys 8 +#define MAXKEYS 8 + +typedef char FieldName[12] ; + +typedef struct +{ + char SysName[42] __PACKED__ ; + RecNoType EOD __PACKED__ ; + RecNoType EOX __PACKED__ ; + unsigned short LenR __PACKED__ ; + RecNoType Flags __PACKED__ ; + char Des[42] __PACKED__ ; + char FCalc[32] __PACKED__ ; + char GenPrompt[32] __PACKED__ ; +} FileDes; + +typedef struct +{ + FieldName Name __PACKED__ ; + byte TypeF __PACKED__; + byte Len __PACKED__ ; + byte Dec __PACKED__ ; +#ifdef __PACK_1__ + byte junk __PACKED__ ; +#endif + unsigned short RecOff __PACKED__ ; +} RecFieldDes ; + + +typedef struct +{ + word DupKeys __ALIGNED__ ; + byte NkFields __ALIGNED__ ; + byte FieldSeq[MKFields] __PACKED__ ; + byte FromCh[MKFields] __PACKED__ ; + byte ToCh[MKFields] __PACKED__ ; +} KeyDes ; + + +typedef struct +{ + short NFields __PACKED__ ; + RecFieldDes Fd[MaxFields] __PACKED__ ; + byte SortFd[MaxFields] __PACKED__ ; + short NKeys __PACKED__ ; + KeyDes Ky[MaxKeys] __PACKED__ ; +} RecDes ; + +typedef struct +{ + int i; + FileDes *d; + RecDes *r; + RecNoType RecNo; + short ln; + short ft; + short knum; + short newkey; + int mode; + struct keydesc k[MAXKEYS + 1]; +} isdef ; + + +typedef isdef* isfdptr; +struct s_prm { + int rc_len; + struct { + int f_pos; + int f_len; + char ad; + + } s_fld [NOFLDS]; + }; +struct bp { + char *rc; +/* @(!) 2.3.00.112 */ + unsigned rbuf; + unsigned rdsk; +/* @(:) 2.3.00.112 */ + }; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/*----------------------- FUNZIONI VISIBILI PRIMA PARTE ---------------------*/ + +int init_sort(struct s_prm *); /* Initialize the sort */ +void sort(char *); /* Pass records to Sort */ +char *sort_op(void); /* Retrieve sorted records */ +void sort_stats(void); /* Display sort statistics */ + +/*----------------------- FUNZIONI VISIBILI SECONDA PARTE -------------------*/ + +void initsortfield (void); +int addsortfield (isfdptr, FieldName, int, int, char); +int finesortfield (isfdptr); + + /* azzera l'elenco dei campi in base a cui eseguire il sort */ + /* ritorna 0 se tutto ok, -1 se chiamata piu' di NOFLDS volte dopo l'ultimo initsortfield */ + /* ritorna 0 se tutto ok, -1 se non c'e' sufficiente memoria per procedere */ + +/*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +}; +#endif /* __cplusplus */ +#endif /* __CSORT_H */ diff --git a/include/include.mak b/include/include.mak index 332b85604..a3aa55b86 100755 --- a/include/include.mak +++ b/include/include.mak @@ -59,7 +59,7 @@ I56=$(IP)config.h $(I55) $(I13) I57=$(IP)confapp.h $(I56) $(I24) I58=$(IP)text.h $(I10) $(I13) $(I32) I59=$(IP)viswin.h $(I13) $(I32) $(I10) $(I58) -I60=$(IP)printwin.h $(I32) +I60=$(IP)printwin.h $(I32) $(I58) U1=$(IP)default.url $(I43) #U2=$(IP)pr_menu.h $(I43) # Guai a chi la usa! diff --git a/include/makeuno.mak b/include/makeuno.mak index 5cec2cf7c..2d8d0325e 100755 --- a/include/makeuno.mak +++ b/include/makeuno.mak @@ -114,7 +114,9 @@ $(LIB)(isreorg.o): $(C1) $(C2) $(C3) $(C9) $(C11) $(C12) $(H1) $(IP)isreorg.c $(LIB)(isbuild.o): $(C1) $(C2) $(C3) $(C9) $(C11) $(C12) $(H1) $(CLIB)isbuild.c -$(LIB)(csort.o): $(C1) $(C2) $(C3) $(C11) $(C12) $(C19) $(CLIB)csort.c +$(LIB)(csort.o): $(C1) $(C2) $(C3) $(C11) $(C12) $(C19) $(IP)csort.c + $(CCOMP) $(CFLAGS) $(IP)csort $* + $(LIBINSERT) $*.o $(LIB)(mshell.o): $(CLIB)mshell.h $(CLIB)mshell.c