Back to index

tetex-bin  3.0
Defines | Functions | Variables
sortid.c File Reference
#include "mkind.h"

Go to the source code of this file.

Defines

#define isrange(c)   ( ((c) == idx_ropen) || ((c) == idx_rclose) )

Functions

static int check_mixsym ARGS ((char *x, char *y))
static int compare ARGS ((struct KFIELD **a, struct KFIELD **b))
static int compare_string ARGS ((unsigned char *a, unsigned char *b))
static int new_strcmp ARGS ((unsigned char *a, unsigned char *b, int option))
void sort_idx (VOID_ARG)
static int compare (FIELD_PTR *a, FIELD_PTR *b)
static int compare_one (char *x, char *y)
static int check_mixsym (char *x, char *y)
static int compare_string (unsigned char *a, unsigned char *b)
static int compare_page (FIELD_PTR *a, FIELD_PTR *b)
static int new_strcmp (unsigned char *s1, unsigned char *s2, int option)

Variables

static long idx_gc

Define Documentation

#define isrange (   c)    ( ((c) == idx_ropen) || ((c) == idx_rclose) )

Function Documentation

static int compare_one ARGS ( (char *x, char *y ) [static]
static int compare_page ARGS ( (struct KFIELD **a, struct KFIELD **b ) [static]
static int compare_string ARGS ( (unsigned char *a, unsigned char *b ) [static]
static int new_strcmp ARGS ( (unsigned char *a, unsigned char *b, int option ) [static]
static int check_mixsym ( char *  x,
char *  y 
) [static]

Definition at line 159 of file sortid.c.

{
    int     m;
    int     n;

    m = ISDIGIT(x[0]);
    n = ISDIGIT(y[0]);

    if (m && !n)
       return (1);

    if (!m && n)
       return (-1);

    return (locale_sort ? strcoll(x, y) : strcmp(x, y));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compare ( FIELD_PTR a,
FIELD_PTR b 
) [static]

Definition at line 70 of file sortid.c.

{
    int     i;
    int     dif;

    idx_gc++;
    IDX_DOT(CMP_MAX);

    for (i = 0; i < FIELD_MAX; i++) {
       /* compare the sort fields */
       if ((dif = compare_one((*a)->sf[i], (*b)->sf[i])) != 0)
           break;

       /* compare the actual fields */
       if ((dif = compare_one((*a)->af[i], (*b)->af[i])) != 0)
           break;
    }

    /* both key aggregates are identical, compare page numbers */
    if (i == FIELD_MAX)
       dif = compare_page(a, b);
    return (dif);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compare_one ( char *  x,
char *  y 
) [static]

Definition at line 101 of file sortid.c.

{
    int     m;
    int     n;

    if ((x[0] == NUL) && (y[0] == NUL))
       return (0);

    if (x[0] == NUL)
       return (-1);

    if (y[0] == NUL)
       return (1);

    m = group_type(x);
    n = group_type(y);

    /* both pure digits */
    if ((m >= 0) && (n >= 0))
       return (m - n);

    /* x digit, y non-digit */
    if (m >= 0) {
       if (german_sort)
           return (1);
       else
           return ((n == -1) ? 1 : -1);
    }
    /* x non-digit, y digit */
    if (n >= 0) {
       if (german_sort)
           return (-1);
       else
           return ((m == -1) ? -1 : 1);
    }
    /* strings started with a symbol (including digit) */
    if ((m == SYMBOL) && (n == SYMBOL))
       return (check_mixsym(x, y));

    /* x symbol, y non-symbol */
    if (m == SYMBOL)
       return (-1);

    /* x non-symbol, y symbol */
    if (n == SYMBOL)
       return (1);

    /* strings with a leading letter, the ALPHA type */
    return (compare_string((unsigned char*)x, (unsigned char*)y));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compare_page ( FIELD_PTR a,
FIELD_PTR b 
) [static]

Definition at line 225 of file sortid.c.

{
    int     m = 0;
    short   i = 0;

    while ((i < (*a)->count) && (i < (*b)->count) &&
          ((m = (*a)->npg[i] - (*b)->npg[i]) == 0))
    {
       i++;
    }
    if (m == 0)
    {                       /* common leading page numbers match */
       if ((i == (*a)->count) && (i == (*b)->count))
       {                    /* all page numbers match */
           /***********************************************************
           We have identical entries, except possibly in encap fields.
           The ordering is tricky here.  Consider the following input
           sequence of index names, encaps, and page numbers:

              foo|(  2
              foo|)  6
              foo|(  6
              foo|)  10

           This might legimately occur when a page range ends, and
           subsequently, a new range starts, on the same page.  If we
           just order by range_open and range_close (here, parens),
           then we will produce

              foo|(  2
              foo|(  6
              foo|)  6
              foo|)  10

           This will later generate the index entry

              foo, 2--6, \({6}, 10

           which is not only wrong, but has also introduced an illegal
           LaTeX macro, \({6}, because the merging step treated this
           like a \see{6} entry.

           The solution is to preserve the original input order, which
           we can do by treating range_open and range_close as equal,
           and then ordering by input line number.  This will then
           generate the correct index entry

              foo, 2--10

           Ordering inconsistencies from missing range open or close
           entries, or mixing roman and arabic page numbers, will be
           detected later.
           ***********************************************************/

#define isrange(c) ( ((c) == idx_ropen) || ((c) == idx_rclose) )

           /* Order two range values by input line number */

           if (isrange(*(*a)->encap) && isrange(*(*b)->encap))
              m = (*a)->lc - (*b)->lc;

           /* Handle identical encap fields; neither is a range delimiter */

           else if (STREQ((*a)->encap, (*b)->encap))
           {
              /* If neither are yet marked duplicate, mark the second
              of them to be ignored. */
              if (((*a)->type != DUPLICATE) &&
                  ((*b)->type != DUPLICATE))
                  (*b)->type = DUPLICATE;
              /* leave m == 0 to show equality */
           }

           /* Encap fields differ: only one may be a range delimiter, */
           /* or else neither of them is.   If either of them is a range */
           /* delimiter, order by input line number; otherwise, order */
           /* by name. */

           else
           {
              if ( isrange(*(*a)->encap) || isrange(*(*b)->encap) )
                  m = (*a)->lc - (*b)->lc; /* order by input line number */
              else                 /* order non-range items by */
                                   /* their encap strings */
                  m = compare_string((unsigned char*)((*a)->encap),
                                   (unsigned char*)((*b)->encap));
           }
       }
       else if ((i == (*a)->count) && (i < (*b)->count))
           m = -1;
       else if ((i < (*a)->count) && (i == (*b)->count))
           m = 1;
    }
    return (m);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compare_string ( unsigned char *  a,
unsigned char *  b 
) [static]

Definition at line 184 of file sortid.c.

{
    int     i = 0;
    int     j = 0;
    int     al;
    int     bl;

    if (locale_sort) return strcoll(a, b);

    while ((a[i] != NUL) || (b[j] != NUL)) {
       if (a[i] == NUL)
           return (-1);
       if (b[j] == NUL)
           return (1);
       if (letter_ordering) {
           if (a[i] == SPC)
              i++;
           if (b[j] == SPC)
              j++;
       }
       al = TOLOWER(a[i]);
       bl = TOLOWER(b[j]);

       if (al != bl)
           return (al - bl);
       i++;
       j++;
    }
    if (german_sort)
       return (new_strcmp(a, b, GERMAN));
    else
       return (strcmp((char*)a, (char*)b));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int new_strcmp ( unsigned char *  s1,
unsigned char *  s2,
int  option 
) [static]

Definition at line 329 of file sortid.c.

{
    int     i;

    i = 0;
    while (s1[i] == s2[i])
       if (s1[i++] == NUL)
           return (0);
    if (option)                           /* ASCII */
       return (isupper(s1[i]) ? -1 : 1);
    else                           /* GERMAN */
       return (isupper(s1[i]) ? 1 : -1);
}

Here is the caller graph for this function:

Definition at line 45 of file sortid.c.

{
#ifdef HAVE_SETLOCALE
    char *prev_locale;
#endif

    MESSAGE("Sorting entries...", "");
#ifdef HAVE_SETLOCALE
    prev_locale = setlocale(LC_CTYPE, NULL);
    setlocale(LC_CTYPE, "");
#endif
    idx_dc = 0;
    idx_gc = 0L;
    qqsort((char *) idx_key, (int) idx_gt, (int) sizeof(FIELD_PTR), 
       (int (*) ARGS((char*,char*)))compare);
#ifdef HAVE_SETLOCALE
    setlocale(LC_COLLATE, prev_locale);
#endif
    MESSAGE("done (%ld comparisons).\n", idx_gc);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

long idx_gc [static]

Definition at line 34 of file sortid.c.