d77c676749
Files correlati : ve1 ba8 Ricompilazione Demo : [ ] Commento : Corretto ordinamento date nelle espressioni BY delle query. Portato limite di lunghezza dei nomi dei file temporanei da 42 a 260 caratteri. git-svn-id: svn://10.65.10.50/trunk@19764 c028cbd2-c16b-5b4b-a496-9718f37d4682
670 lines
17 KiB
C
Executable File
670 lines
17 KiB
C
Executable File
#include "xvt.h"
|
|
|
|
#include <cfiles.h>
|
|
#include <csort.h>
|
|
#include <stdio.h>
|
|
|
|
#define MOSTMEM 51200
|
|
#define LEASTMEM 10240
|
|
|
|
/*----------------------- 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 [_MAX_PATH];
|
|
static char f2name [_MAX_PATH];
|
|
|
|
//static int sortcomp(char **, char **);
|
|
static int sortcomp(const void*, const void*);
|
|
static char *appr_mem(unsigned *);
|
|
/* @(!) 2.3.00.112 */
|
|
static FILE *wopen(char *, int);
|
|
/* @(:) 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)
|
|
*/
|
|
|
|
/* struttura di descrizione del sort */
|
|
int init_sort(struct s_prm *prms)
|
|
{
|
|
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(const 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()
|
|
{
|
|
unsigned 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[_MAX_PATH]; /* sort work name */
|
|
|
|
fp2 = wopen(f2name, sizeof(wname)); /* 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);
|
|
xvt_fsys_remove_file(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) {
|
|
unsigned nrcd_last = (unsigned) totrcd % nrcds;
|
|
if (nrcd_last == 0)
|
|
nrcd_last = nrcds;
|
|
if (nrcd_last > rcds_seq) {
|
|
rr->rbuf = rcds_seq;
|
|
/* @(!) 2.3.00.112 */
|
|
rr->rdsk = nrcd_last - rcds_seq;
|
|
/* @(:) 2.3.00.112 */
|
|
}
|
|
else {
|
|
/* @(!) 2.3.00.112 */
|
|
rr->rbuf = nrcd_last;
|
|
/* @(:) 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()
|
|
{
|
|
unsigned 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 */
|
|
unsigned x, y; /* sequence counters */
|
|
long adx, ady; /* sequence record disk addresses */
|
|
/* @(!) 2.3.00.112 */
|
|
char *ysptr = init_sptr + sp->rc_len;
|
|
|
|
/* Calcolo dei records residui nell'ultima sequenza */
|
|
/* nel caso in cui sia piena */
|
|
unsigned nrcd_last = (unsigned) totrcd % nrcds;
|
|
|
|
if (nrcd_last == 0)
|
|
nrcd_last = nrcds;
|
|
/* @(:) 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 */
|
|
nrcd_last : nrcds);
|
|
xcnt = y == no_seq ? nrcd_last : 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, sizeof(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)
|
|
*/
|
|
|
|
static FILE *wopen(char* name, int size) /* nome del file temporaneo */
|
|
{
|
|
FILE* fp = NULL;
|
|
char* tmp = _tempnam(".", "srt");
|
|
if (tmp != NULL)
|
|
{
|
|
strncpy(name, tmp, size);
|
|
free(tmp);
|
|
}
|
|
else
|
|
tmpnam_s(name, size);
|
|
fp = fopen(name, "wb+");
|
|
if (fp == NULL)
|
|
xvt_dm_post_fatal_exit("Can't open SORT file");
|
|
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 */
|
|
xvt_fsys_remove_file(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++) */
|
|
for (i = 1; 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;
|
|
if (nrd == 0)
|
|
nrd = 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()
|
|
{
|
|
char msg[256];
|
|
sprintf(msg,
|
|
"Record length = %d\n"
|
|
"%lu records sorted\n"
|
|
"%u sequences\n"
|
|
"%u bytes of sort buffer\n"
|
|
"%u records per buffer",
|
|
sp->rc_len, totrcd, no_seq, bspace, nrcds
|
|
);
|
|
xvt_dm_post_note(msg);
|
|
}
|
|
|
|
/*
|
|
@($) 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(unsigned* h)
|
|
{
|
|
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 */
|
|
|
|
static int sortcomp(const void* pa, const void* pb)
|
|
{
|
|
int i, k;
|
|
|
|
const char** a = (const char**)pa;
|
|
const char** b = (const char**)pb;
|
|
|
|
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 */
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|