home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR2 / CBUFF09.ZIP / SRC.ZIP / SORT.C < prev    next >
C/C++ Source or Header  |  1993-11-16  |  8KB  |  357 lines

  1. /*  $Id$
  2.  *  
  3.  *  File    sort.c
  4.  *  Part of    ChessBase utilities file format (CBUFF)
  5.  *  Author    Anjo Anjewierden, anjo@swi.psy.uva.nl
  6.  *        Urban Koistinen, md85-epi@nada.kth.se
  7.  *  Purpose    Sorting utility
  8.  *  Works with    GNU CC 2.4.5
  9.  *  
  10.  *  Notice    Copyright (c) 1993  Anjo Anjewierden
  11.  *  
  12.  *  History    10/07/93  (Created)
  13.  *          03/11/93  (Last modified)
  14.  */ 
  15.  
  16.  
  17. /*------------------------------------------------------------
  18.  *  Directives
  19.  *------------------------------------------------------------*/
  20.  
  21. #include "cbuff.h"
  22.  
  23. char *        UTILITY_NAME = "Sort utility";
  24. char *        UTILITY_VERSION = "1.1.0";
  25.  
  26. void        helpUtility(FILE *fd);
  27. void        sortUtility(Option);
  28.  
  29.  
  30. /*------------------------------------------------------------
  31.  *  Definitions
  32.  *------------------------------------------------------------*/
  33.  
  34. static CBase    SortBase;
  35.  
  36. static int    compareSortData(const void *, const void *);
  37. static char *    prepare_key(char *, char *, char *, short, char *, long);
  38. static int    addchar(unsigned char *, unsigned char);
  39. static int    addstring(unsigned char *, unsigned char *, int);
  40. static int    addshort(unsigned char *, short);
  41. static void    storelong(unsigned char *, unsigned long);
  42.  
  43. #define SORT_WHITE    1
  44. #define SORT_BLACK    2
  45. #define SORT_SOURCE    3
  46. #define SORT_ECO    4
  47. #define SORT_YEAR    5
  48.  
  49.  
  50. struct sort_option
  51. { int         option;
  52.   int        count;
  53. } SortOptions[10];
  54.  
  55.  
  56.  
  57. typedef unsigned char *     SortData;
  58.  
  59.  
  60. int        NoSortOptions = 0;
  61.  
  62.  
  63. /*------------------------------------------------------------
  64.  *  Sort utility
  65.  *------------------------------------------------------------*/
  66.  
  67. void
  68. sortUtility(Option opt)
  69. { CBase cb = opt->database;
  70.   long n = getNoGamesCBase(cb);
  71.   SortData *sd;
  72.   long i;
  73.   Game g = newGame();
  74.   long inc, count;
  75.   long k;                /* Games to be sorted */
  76.  
  77.   printMemoryAvailable(stderr);
  78.   reportCBase(cb, stderr);
  79.  
  80.   if (opt->dump == NULL)
  81.   { fprintf(stderr, "No output database specified (-dump/-append option)\n");
  82.     exit(1);
  83.   }
  84.  
  85.   if (NoSortOptions == 0)
  86.   { fprintf(stderr, "No sort options specified; cannot sort\n");
  87.     exit(1);
  88.   }
  89.  
  90.   sd = alloc(sizeof(SortData) * n);
  91.   if (sd == NULL)
  92.   { fprintf(stderr, "Not enough memory for sort\n");
  93.     exit(1);
  94.   }
  95.  
  96.   inc = (n < 50L ? 1 : n / 50);
  97.  
  98.   printMemoryAvailable(stderr);
  99.   fprintf(stderr, "Reading games from database %s\n", cb->name);
  100.  
  101.   for (i=1, count=0, k=0; i<=n; i++, count++)
  102.   { if (inc == count)
  103.     { fprintf(stderr, ".");
  104.       count = 0;
  105.     }
  106.     environmentError(cb, g, i);
  107.     initialiseGame(g, i, cb);
  108.     if (foundError())
  109.     { reportError(stderr);
  110.       continue;
  111.     }
  112.     { char *black = getBlackGame(g);
  113.       char *white = getWhiteGame(g);
  114.       char *source = getSourceGame(g);
  115.       char *eco = getEcoGame(g);
  116.       short year = getYearGame(g);
  117.       unsigned long index = getIndexGameCBase(cb, i);
  118.  
  119.       if (foundError())
  120.       { reportError(stderr);
  121.         continue;
  122.       }
  123.       if (white == NULL)  /* So games are at least partially sort correctly. */
  124.     white = getPlayersGame(g);
  125.       sd[k++] = prepare_key(black, white, source, year, eco, index);
  126.     }
  127.   }
  128.  
  129.   fprintf(stderr, " Done!\n");
  130.   printMemoryAvailable(stderr);
  131.  
  132.   SortBase = cb;
  133.  
  134.   fprintf(stderr, "Sorting games ");
  135.   qsort(sd, (size_t) k, sizeof(SortData), compareSortData);
  136.   fprintf(stderr, " Done!\n");
  137.  
  138.   for (i=0; i<k; i++)
  139.   { unsigned long val;
  140.  
  141.                val  = (unsigned char) sd[i][-4]; 
  142.     val <<= 8; val |= (unsigned char) sd[i][-3];
  143.     val <<= 8; val |= (unsigned char) sd[i][-2];
  144.     val <<= 8; val |= (unsigned char) sd[i][-1];
  145.     cb->index[i] = val;
  146.   }
  147.  
  148.   exportManyCBase(opt->dump, cb, 1, k);
  149. }
  150.  
  151.  
  152. /*------------------------------------------------------------
  153.  *  Main
  154.  *------------------------------------------------------------*/
  155.  
  156. int
  157. main(int argc, char *argv[])
  158. { int i;
  159.   Option options = newOption();
  160.  
  161.   for (i=1; i<argc; i++)
  162.   {
  163.     if (strhead(argv[i], "-white"))    /* -white */
  164.     { i++;
  165.       SortOptions[NoSortOptions].option = SORT_WHITE;
  166.       SortOptions[NoSortOptions++].count = intArgument(argv[i],"-white",argc,i);
  167.       continue;
  168.     }
  169.  
  170.     if (strhead(argv[i], "-black"))    /* -black */
  171.     { i++;
  172.       SortOptions[NoSortOptions].option = SORT_BLACK;
  173.       SortOptions[NoSortOptions++].count = intArgument(argv[i],"-black",argc,i);
  174.       continue;
  175.     }
  176.  
  177.     if (strhead(argv[i], "-eco"))    /* -eco */
  178.     { SortOptions[NoSortOptions++].option = SORT_ECO;
  179.       continue;
  180.     }
  181.  
  182.     if (strhead(argv[i], "-source"))    /* -source */
  183.     { i++;
  184.       SortOptions[NoSortOptions].option = SORT_SOURCE;
  185.       SortOptions[NoSortOptions++].count = intArgument(argv[i],"-source",argc,i);
  186.       continue;
  187.     }
  188.  
  189.     if (strhead(argv[i], "-year"))    /* -year */
  190.     { SortOptions[NoSortOptions++].option = SORT_YEAR;
  191.       continue;
  192.     }
  193.  
  194.     if (strhead(argv[i], "-"))
  195.     { int n;
  196.  
  197.       n = genericOption(options, argv, argc, i);
  198.       if (n == 0)
  199.       { fprintf(stderr, "Fatal: Unknown command %s\n", argv[i]);
  200.     fprintf(stderr, "Do ``%s -help'' or see the documentation\n", argv[0]);
  201.     exit(1);
  202.       }
  203.       i = n;
  204.       continue;
  205.     }
  206.  
  207.     setCurrentCBase(argv[i], "-database", argc, i);
  208.     options->database = CurrentBase;
  209.     sortUtility(options);
  210.     freeCBase(options->database);
  211.     options->database = (CBase) NULL;
  212.   }
  213.  
  214.   if (options->database)
  215.   { sortUtility(options);
  216.     freeCBase(options->database);
  217.   }
  218.  
  219.   exit(0);
  220. }
  221.  
  222.  
  223. /*------------------------------------------------------------
  224.  *  Help
  225.  *------------------------------------------------------------*/
  226.  
  227. void
  228. helpUtility(FILE *fd)
  229. { helpCBUFF(fd);
  230.   fprintf(fd, "%s options:\n", UTILITY_NAME);
  231.   fprintf(fd, "-black n      Use n characters of Black (0: entire name)\n");
  232.   fprintf(fd, "-eco          Compare by ascending ECO\n");
  233.   fprintf(fd, "-source n     Use n characters of source (0: entire source)\n");
  234.   fprintf(fd, "-white n      Use n characters of White (0: entire name)\n");
  235.   fprintf(fd, "-year         Compare by ascending year\n");
  236. }
  237.  
  238.  
  239. /*------------------------------------------------------------
  240.  *  Implementation
  241.  *------------------------------------------------------------*/
  242.  
  243. static int
  244. addchar(unsigned char *buf, unsigned char c)
  245. { if (c < 3)
  246.   { if (c==0)
  247.     { buf[0] = 1;
  248.       return 1;
  249.     } else
  250.     { buf[0] = 2;
  251.       buf[1] = c;
  252.       return 2;
  253.     }
  254.   }
  255.   buf[0] = c;
  256.   return 1;
  257. }
  258.  
  259.  
  260. static int
  261. addstring(unsigned char *buf, unsigned char *s, int count)
  262. { int i = 0;
  263.  
  264.   if (s)
  265.   { for (;*s && count--; s++)
  266.       i += addchar(&buf[i], *s);
  267.     i += addchar(&buf[i], *s);
  268.   } else
  269.     i += addchar(&buf[i], '\0');
  270.   return i;
  271. }
  272.  
  273.  
  274. static int
  275. addshort(unsigned char *buf, short n)
  276. { int i;
  277.  
  278.   i = addchar(buf, ((n>>8)+0x80)&0xff);
  279.   i += addchar(&buf[i], n&0xff);
  280.   return i;
  281. }
  282.  
  283.  
  284. static void
  285. storelong(unsigned char *buf, unsigned long n)
  286. { buf[0] = (unsigned char) (n>>24);
  287.   buf[1] = (unsigned char) (n>>16);
  288.   buf[2] = (unsigned char) (n>>8);
  289.   buf[3] = (unsigned char) n;
  290. }
  291.  
  292.  
  293. static int
  294. compareSortData(const void *a, const void *b)
  295. { char *s1 = *((char **) a);
  296.   char *s2 = *((char **) b);
  297.  
  298.   return strcmp(s1, s2);
  299. }
  300.  
  301.  
  302. static char *
  303. prepare_key(char *black, char *white, char *source, short year, char *eco, long index)
  304. { unsigned char buf[500];
  305.   int i, j;
  306.   unsigned char *s;
  307.  
  308.   i = 0;
  309.   for (j=0;j<NoSortOptions;j++)
  310.   { int option = SortOptions[j].option;
  311.     int count = SortOptions[j].count;
  312.  
  313.     switch (option)
  314.     { case SORT_WHITE:
  315.     i += addstring(&buf[i], white, count);
  316.     break;
  317.  
  318.       case SORT_BLACK:
  319.     i += addstring(&buf[i], black, count);
  320.     break;
  321.  
  322.       case SORT_SOURCE:
  323.     i += addstring(&buf[i], source, count);
  324.     break;
  325.  
  326.       case SORT_ECO:
  327.     i += addstring(&buf[i], eco, 7);
  328.     break;
  329.  
  330.       case SORT_YEAR:
  331.     i += addshort(&buf[i], year);
  332.     break;
  333.  
  334.       default:
  335.     fprintf(stderr, "Internal error: Unknown sort option (%d)\n", option);
  336.     exit(1);
  337.     }
  338.   }
  339.  
  340.   buf[i] = '\0';
  341.   if (i && (buf[i-1]==1))
  342.     buf[--i] = '\0';
  343.  
  344.   if ((s = alloc(i+5)) == NULL)
  345.   { fprintf(stderr, "Not enough memory for sort key\n");
  346.     exit(1);
  347.   }
  348.   storelong(s, index);
  349.   s += 4;
  350.   strcpy(s, buf);
  351.   return s;
  352. }
  353.  
  354.  
  355.  
  356.  
  357.