Files correlati : Ricompilazione Demo : [ ] Commento : Allineato main trunk alla versione a 32 bit. git-svn-id: svn://10.65.10.50/trunk@10282 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			665 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			665 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
#include <checks.h>
 | 
						|
#include <csort.h>
 | 
						|
 | 
						|
/*----------------------- 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)
 | 
						|
   */
 | 
						|
 | 
						|
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()
 | 
						|
{
 | 
						|
  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);
 | 
						|
      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)  {
 | 
						|
      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;
 | 
						|
 | 
						|
/*
 | 
						|
  char  s[42];
 | 
						|
  static int  n = 0;
 | 
						|
  sprintf(s, "srt%02d", ++n);
 | 
						|
  TMPFNAME(name,s);
 | 
						|
*/
 | 
						|
	tmpnam(name);
 | 
						|
  
 | 
						|
  fp = fopen(name, "wb+");
 | 
						|
  if (fp == NULL)  
 | 
						|
    fatal_box("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 */
 | 
						|
      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++) */
 | 
						|
     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()
 | 
						|
  {
 | 
						|
    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
 | 
						|
      );
 | 
						|
  }
 | 
						|
 | 
						|
  /*
 | 
						|
     @($) 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 */
 | 
						|
 | 
						|
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 */
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*---------------------------------------------------------------------------*/
 |