bridge/class-master/depend/pari/src/modules/mpqs.c
/* Given a file "filename" containing full or `large prime' relations,
 * rearrange the file so that relations are sorted by their first elements.
 * Works also for sorting full relations. Works in memory, discards duplicate
 * lines, and overwrites the original file. */
Given a file "filename" containing full or `large prime' relations,
rearrange the file so that relations are sorted by their first elements.
Works also for sorting full relations. Works in memory, discards duplicate
lines, and overwrites the original file.
Given a file " filename " containing full or ` large prime ' relations rearrange the file so that relations are sorted by their first elements . Works also for sorting full relations . Works in memory discards duplicate lines and overwrites the original file .
static long
mpqs_sort_lp_file(char *filename)
{
  pariFILE *pTMP;
  FILE *TMP;
  char *old_s, *buf, *cur_line;
  char **sort_table, **buflist, **next_buflist, **buflist_head;
  long i, j, count;
  size_t length, bufspace;
  pari_sp av=avma;
  buflist_head = (char**) stack_malloc(buflist_size * sizeof(char*));
  buflist = buflist_head;
  *buflist++ = NULL; 
  pTMP = pari_fopen_or_fail(filename, READ);
  TMP = pTMP->file;
  buf = (char*) pari_malloc(MPQS_STRING_LENGTH * sizeof(char));
  cur_line = buf;
  bufspace = MPQS_STRING_LENGTH;
  if (fgets(cur_line, bufspace, TMP) == NULL)
  { 
    pari_free(buf); pari_fclose(pTMP);
    avma = av; return 0;
  }
  *buflist++ = buf; 
  length = strlen(cur_line) + 1; 
  bufspace -= length;
  sort_table = (char**)avma;
  for (i=0, sort_table--; ; i++, sort_table--)
  { 
    if ((i & 0xff) == 0) (void)new_chunk(0x100);
    *sort_table = cur_line;
    cur_line += length;
    if (bufspace < min_bufspace)
    {
      if (MPQS_DEBUGLEVEL >= 7)
        err_printf("MQPS: short of space -- another buffer for sorting\n");
      buf = (char*) pari_malloc(MPQS_STRING_LENGTH * sizeof(char));
      cur_line = buf;
      bufspace = MPQS_STRING_LENGTH;
      if (fgets(cur_line, bufspace, TMP) == NULL) { pari_free(buf); break; }
      if (buflist - buflist_head >= buflist_size)
      { 
        next_buflist = (char**) pari_malloc(buflist_size * sizeof(char*));
        *next_buflist = (char*)buflist_head; 
        buflist_head = next_buflist;
        buflist = buflist_head + 1;
      }
      *buflist++ = buf;
      length = strlen(cur_line) + 1;
      bufspace -= length; continue;
    }
    if (fgets(cur_line, bufspace, TMP) == NULL) break; 
    length = strlen(cur_line) + 1;
    bufspace -= length;
    if (bufspace == 0 && cur_line[length-2] != '\n')
    {
      size_t lg1;
      if (MPQS_DEBUGLEVEL >= 7)
        err_printf("MQPS: line wrap -- another buffer for sorting\n");
      buf = (char*) pari_malloc(MPQS_STRING_LENGTH * sizeof(char));
      if (buflist - buflist_head >= buflist_size)
      { 
        next_buflist = (char**)pari_malloc(buflist_size * sizeof(char*));
        *next_buflist = (char*)buflist_head; 
        buflist_head = next_buflist;
        buflist = buflist_head + 1;
      }
      *buflist++ = buf;
      (void)strcpy(buf, cur_line); 
      cur_line = buf + length - 1; 
      bufspace = MPQS_STRING_LENGTH - length + 1;
      if (fgets(cur_line, bufspace, TMP) == NULL)
        pari_err_FILE("TMP file [fgets]", pTMP->name);
      lg1 = strlen(cur_line);
      length += lg1; 
      bufspace -= (lg1 + 1); 
      cur_line = buf; 
    }
  } 
  pari_fclose(pTMP);
  qsort(sort_table, i, sizeof(char*), mpqs_relations_cmp);
  pTMP = pari_fopen_or_fail(filename, WRITE);
  old_s = sort_table[0];
  pari_fputs(sort_table[0], pTMP);
  count = 1;
  for(j = 1; j < i; j++)
  {
    if (strcmp(old_s, sort_table[j]))
    {
      pari_fputs(sort_table[j], pTMP);
      count++;
    }
    old_s = sort_table[j];
  }
  pari_fclose(pTMP);
  if (MPQS_DEBUGLEVEL >= 6) err_printf("MPQS: done sorting one file.\n");
  while (*--buflist)
  {
    if (buflist != buflist_head) 
      pari_free((void*) *buflist);   
    else
    { 
      next_buflist = (char**)(*buflist);
      pari_free((void*)buflist_head); 
      buflist_head = next_buflist;
      buflist = buflist_head + buflist_size;
    }
  }
  avma = av; return count;
}
static long mpqs_sort_lp_file ( char * filename ) { pariFILE * pTMP ; FILE * TMP ; char * old_s , * buf , * cur_line ; char * * sort_table , * * buflist , * * next_buflist , * * buflist_head ; long i , j , count ; size_t length , bufspace ; pari_sp av = avma ; buflist_head = ( char * * ) stack_malloc ( buflist_size * sizeof ( char * ) ) ; buflist = buflist_head ; * buflist ++ = NULL ; pTMP = pari_fopen_or_fail ( filename , READ ) ; TMP = pTMP -> file ; buf = ( char * ) pari_malloc ( MPQS_STRING_LENGTH * sizeof ( char ) ) ; cur_line = buf ; bufspace = MPQS_STRING_LENGTH ; if ( fgets ( cur_line , bufspace , TMP ) == NULL ) { pari_free ( buf ) ; pari_fclose ( pTMP ) ; avma = av ; return 0 ; } * buflist ++ = buf ; length = strlen ( cur_line ) + 1 ; bufspace -= length ; sort_table = ( char * * ) avma ; for ( i = 0 , sort_table -- ; ; i ++ , sort_table -- ) { if ( ( i & 0xff ) == 0 ) ( void ) new_chunk ( 0x100 ) ; * sort_table = cur_line ; cur_line += length ; if ( bufspace < min_bufspace ) { if ( MPQS_DEBUGLEVEL >= 7 ) err_printf ( " \n " ) ; buf = ( char * ) pari_malloc ( MPQS_STRING_LENGTH * sizeof ( char ) ) ; cur_line = buf ; bufspace = MPQS_STRING_LENGTH ; if ( fgets ( cur_line , bufspace , TMP ) == NULL ) { pari_free ( buf ) ; break ; } if ( buflist - buflist_head >= buflist_size ) { next_buflist = ( char * * ) pari_malloc ( buflist_size * sizeof ( char * ) ) ; * next_buflist = ( char * ) buflist_head ; buflist_head = next_buflist ; buflist = buflist_head + 1 ; } * buflist ++ = buf ; length = strlen ( cur_line ) + 1 ; bufspace -= length ; continue ; } if ( fgets ( cur_line , bufspace , TMP ) == NULL ) break ; length = strlen ( cur_line ) + 1 ; bufspace -= length ; if ( bufspace == 0 && cur_line [ length - 2 ] != ' \n ' ) { size_t lg1 ; if ( MPQS_DEBUGLEVEL >= 7 ) err_printf ( " \n " ) ; buf = ( char * ) pari_malloc ( MPQS_STRING_LENGTH * sizeof ( char ) ) ; if ( buflist - buflist_head >= buflist_size ) { next_buflist = ( char * * ) pari_malloc ( buflist_size * sizeof ( char * ) ) ; * next_buflist = ( char * ) buflist_head ; buflist_head = next_buflist ; buflist = buflist_head + 1 ; } * buflist ++ = buf ; ( void ) strcpy ( buf , cur_line ) ; cur_line = buf + length - 1 ; bufspace = MPQS_STRING_LENGTH - length + 1 ; if ( fgets ( cur_line , bufspace , TMP ) == NULL ) pari_err_FILE ( " " , pTMP -> name ) ; lg1 = strlen ( cur_line ) ; length += lg1 ; bufspace -= ( lg1 + 1 ) ; cur_line = buf ; } } pari_fclose ( pTMP ) ; qsort ( sort_table , i , sizeof ( char * ) , mpqs_relations_cmp ) ; pTMP = pari_fopen_or_fail ( filename , WRITE ) ; old_s = sort_table [ 0 ] ; pari_fputs ( sort_table [ 0 ] , pTMP ) ; count = 1 ; for ( j = 1 ; j < i ; j ++ ) { if ( strcmp ( old_s , sort_table [ j ] ) ) { pari_fputs ( sort_table [ j ] , pTMP ) ; count ++ ; } old_s = sort_table [ j ] ; } pari_fclose ( pTMP ) ; if ( MPQS_DEBUGLEVEL >= 6 ) err_printf ( " \n " ) ; while ( * -- buflist ) { if ( buflist != buflist_head ) pari_free ( ( void * ) * buflist ) ; else { next_buflist = ( char * * ) ( * buflist ) ; pari_free ( ( void * ) buflist_head ) ; buflist_head = next_buflist ; buflist = buflist_head + buflist_size ; } } avma = av ; return count ; }
Given a file "filename" containing full or `large prime' relations,
 rearrange the file so that relations are sorted by their first elements.
Given a file " filename " containing full or ` large prime ' relations rearrange the file so that relations are sorted by their first elements .
/* flag this as last and only buflist block */ /* extra blocks may be allocated as needed and linked ahead of
   * buflist_head.  NB: whilst extra buflist blocks might have been
   * needed when we were still sorting entire FREL files (more than 1023
   * buffers, corresponding to about 20000 lines of ~200 characters), they
   * should never be touched now that we only sort LPNEW and FNEW files, which
   * are rather shorter. But the code might as well stay around for future
   * upgrades to handling even larger numbers (and factor bases and thus
   * relations files).  It costs one comparison per buffer allocation. --GN */ /* get first buffer and read first line, if any, into it */ /* file empty */ /* enter first buffer into buflist */ /* can't overflow the buflist block */ /* count the \0 byte as well */ /* at start of loop, one line from the file is sitting in cur_line inside buf,
   * the next will go into cur_line + length, and there's room for bufspace
   * further characters in buf. The loop reads another line if one exists, and
   * if this overruns the current buffer, it allocates a fresh one --GN */ /* until end of file */ /* sort_table is allocated on the stack, 0x100 cells at a time. Hence the
     * stack must be left alone in the rest of the loop to keep the array
     * connected. In particular, buffers can't be new_chunk'ed */ /* if little room is left, allocate a fresh buffer before attempting to
     * read a line, and remember to free it if no further line is forthcoming.
     * This avoids some copying of partial lines --GN */ /* remember buffer for later deallocation */ /* need another buflist block */ /* link */ /* normal case:  try fitting another line into the current buffer */ /* none exists */ /* check whether we got the entire line or only part of it */ /* remember buffer for later deallocation */ /* need another buflist block */ /* link */ /* copy what we've got to the new buffer */ /* cannot overflow */ /* point at the \0 byte */ /* read remainder of line */ /* we already counted the \0 once */ /* but here we must take it into account */ /* back up to the beginning of the line */ /* for */ /* sort the whole lot in place by swapping pointers */ /* copy results back to the original file, skipping exact duplicates */ /* deallocate buffers and any extraneous buflist blocks except the first */ /* not a linkage pointer */ /* free a buffer */ /* linkage pointer */ /* free a buflist block */