home *** CD-ROM | disk | FTP | other *** search
- /*
- * SORT.C
- *
- * This module contains the sorting routines that read sorting order from
- * the command line, and sort the file database according to that order.
- *
- */
-
- #ifndef LATTICE_50
- #include "system.h"
- #endif
-
- #include "bbsindex.h"
-
-
- /*
- * Arrays used to determine sorting order for SORT.
- */
-
- int i_order[MAXINDEX+1];
- int i_ascend[MAXINDEX+1];
-
-
- /*
- * sortcmp()
- * ---------
- * This function is called by qsort. It compares the two specified
- * elements, and returns -ve, 0 or +ve to indicate whether the second
- * record is greater than, equal or less than the first, using the
- * sorting criteria defined in SORT.
- */
-
- /*
- * DOCMP is a macro which sets cmp equal to the value of the enclosed
- * expression if i_ascend[i] is true, or the negative of the expression
- * if i_ascend is false.
- */
- #define DOCMP(x) (cmp = (i_ascend[i] ? (x) : -(x)))
- int sortcmp(ptr1,ptr2)
- UDHEAD **ptr1, **ptr2;
- {
- UDHEAD *p1 = *ptr1, *p2 = *ptr2;
- int i, cmp = 0;
-
- /*
- * Note safety exit - last element of i_order is guaranteed == I_ANY
- */
- for (i = 0; !cmp; i++) {
- switch (i_order[i]) {
-
- case I_ANY: return(0);
-
- case I_ACCESS: DOCMP(p1->accesses - p2->accesses);
- break;
- case I_BINARY: DOCMP(p2->bin - p1->bin);
- break;
- case I_COMMENT: DOCMP(stricmp(p1->desc, p2->desc));
- break;
- case I_DISKNAME: DOCMP(stricmp(p1->disk_name, p2->disk_name));
- break;
- case I_SECTION: DOCMP(p1->section - p2->section);
- break;
- case I_ONLINE: DOCMP(p2->online - p1->online);
- break;
- case I_LOCAL: DOCMP(p2->local - p1->local);
- break;
- case I_NAME: DOCMP(strcmp(p1->cat_name, p2->cat_name));
- break;
- case I_OWNER: DOCMP(strcmp(p1->owner, p2->owner));
- break;
- case I_PATHNAME: DOCMP(strcmp(dirnames[p1->dirnum],
- dirnames[p2->dirnum]));
- break;
- case I_DIRECTORY: DOCMP(p1->dir - p2->dir);
- break;
- case I_DISKDIRNUM: DOCMP(p1->dirnum - p2->dirnum);
- break;
- case I_VALID: DOCMP(p2->valid - p1->valid);
- break;
- case I_DATE: DOCMP(p1->date - p2->date);
- break;
- case I_SIZE: DOCMP(p1->length - p2->length);
- break;
- case I_KSIZE: DOCMP(BTOK(p1->length) - BTOK(p2->length));
- break;
- }
- }
- return (cmp);
- }
-
-
- /*
- * com_sort()
- * ----------
- * This command sorts the file database into order, according to
- * the indexes specified. Each index may be optionally followed by
- * a + or - to indirect sorting direction (ascending or descending).
- * There must be no space between the direction and the +/-.
- */
- void com_sort()
- {
- char *index, *p;
- int i, j;
- int ascend;
-
- CHECKDATABASE();
-
- sorted = TRUE;
- for (i = 0; i < MAXINDEX && compos < comlen; i++) {
- index = getstring();
- p = index + strlen(index) - 1;
-
- /*
- * Now check to see if sorting direction specified, and adjust
- * string if it was. Set 'ascend' to TRUE if ascending,
- * else FALSE.
- */
- ascend = TRUE;
- if (*p == CHAR_ASCEND || *p == CHAR_DESCEND) {
- if (*p == CHAR_DESCEND)
- ascend = FALSE;
- *p = CHAR_NULL;
- }
-
- /*
- * Now match index, and setup appropriate entry in array
- */
-
- for (j = 0; j < MAXINDEX && strcmp(index,indexes[j].name); j++)
- ;
- if (j == MAXINDEX) {
- scripterror("unknown index ");
- print2(index, "\n");
- Cleanup(10);
- }
- i_order[i] = indexes[j].tag;
- i_ascend[i] = ascend;
- }
- if (i == 0) {
- i_order[i] = I_NAME;
- i_ascend[i++] = TRUE;
- }
- i_order[i] = I_ANY;
-
- /* Finally, do the sort! */
- qsort(ptrblock, numrecs, sizeof(UDHEAD *), sortcmp);
- }
-