Files correlati : Ricompilazione Demo : [ ] Commento :correzioni dovute al passaggio al nuovo compilatore git-svn-id: svn://10.65.10.50/trunk@14698 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			672 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			672 lines
		
	
	
		
			16 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 [42];
 | |
| static char f2name [42];
 | |
| 
 | |
| //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 *);
 | |
| /* @(:) 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(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()
 | |
| {
 | |
|   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[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);
 | |
|       xvt_fsys_removefile(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);
 | |
|   /* @(:) 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) /* nome del file temporaneo */
 | |
| {
 | |
|   FILE* fp = NULL;
 | |
| 	char* tmp = _tempnam(".", "srt");
 | |
|   if (tmp != NULL)
 | |
| 	{
 | |
| 		strcpy(name, tmp);
 | |
| 		free(tmp);
 | |
| 	}
 | |
| 	else
 | |
| 		tmpnam(name);
 | |
|   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_removefile(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 */
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------------------------------*/
 |