summaryrefslogtreecommitdiff
path: root/indexing/makeindex/src/scanid.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /indexing/makeindex/src/scanid.c
Initial commit
Diffstat (limited to 'indexing/makeindex/src/scanid.c')
-rw-r--r--indexing/makeindex/src/scanid.c830
1 files changed, 830 insertions, 0 deletions
diff --git a/indexing/makeindex/src/scanid.c b/indexing/makeindex/src/scanid.c
new file mode 100644
index 0000000000..4426110517
--- /dev/null
+++ b/indexing/makeindex/src/scanid.c
@@ -0,0 +1,830 @@
+/*
+ *
+ * This file is part of
+ * MakeIndex - A formatter and format independent index processor
+ *
+ * Copyright (C) 1989 by Chen & Harrison International Systems, Inc.
+ * Copyright (C) 1988 by Olivetti Research Center
+ * Copyright (C) 1987 by Regents of the University of California
+ *
+ * Author:
+ * Pehong Chen
+ * Chen & Harrison International Systems, Inc.
+ * Palo Alto, California
+ * USA
+ * (phc@renoir.berkeley.edu or chen@orc.olivetti.com)
+ *
+ * Contributors:
+ * Please refer to the CONTRIB file that comes with this release
+ * for a list of people who have contributed to this and/or previous
+ * release(s) of MakeIndex.
+ *
+ * All rights reserved by the copyright holders. See the copyright
+ * notice distributed with this software for a complete description of
+ * the conditions under which it is made available.
+ *
+ */
+
+#include "mkind.h"
+#include "scanid.h"
+
+#define CHECK_LENGTH() if (i > len_field) goto OVERFLOW
+
+int idx_lc; /* line count */
+int idx_tc; /* total entry count */
+int idx_ec; /* erroneous entry count */
+int idx_dc; /* number of dots printed so far */
+
+static int first_entry = TRUE;
+static int comp_len;
+static char key[ARGUMENT_MAX];
+static char no[NUMBER_MAX];
+extern char *strchr ARGS((const char* s,int c));
+
+NODE_PTR head;
+NODE_PTR tail;
+
+static void flush_to_eol ARGS((void));
+static int make_key ARGS((void));
+static void make_string ARGS((char **ppstr,int n));
+static int scan_alpha_lower ARGS((char *no,short *npg,short *count));
+static int scan_alpha_upper ARGS((char *no,short *npg,short *count));
+static int scan_arabic ARGS((char *no,short *npg,short *count));
+static int scan_arg1 ARGS((void));
+static int scan_arg2 ARGS((void));
+static int scan_field ARGS((int *n,char field[],int len_field,
+ int ck_level, int ck_encap,int ck_actual));
+static int scan_key ARGS((struct KFIELD *data));
+static int scan_no ARGS((char *no,short *npg,short *count,short *type));
+static int scan_roman_lower ARGS((char *no,short *npg,short *count));
+static int scan_roman_upper ARGS((char *no,short *npg,short *count));
+static void search_quote ARGS((char sort_key[],char actual_key[]));
+
+#if (OS_BS2000 | OS_MVSXA)
+char UPCC[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+#endif
+
+void
+scan_idx(VOID_ARG)
+{
+ char keyword[ARRAY_MAX];
+ int c;
+ int i = 0;
+ int not_eof = TRUE;
+ int arg_count = -1;
+
+ MESSAGE("Scanning input file %s...", idx_fn);
+ idx_lc = idx_tc = idx_ec = idx_dc = 0;
+ comp_len = strlen(page_comp);
+ while (not_eof) {
+ switch (c = GET_CHAR(idx_fp)) {
+ case EOF:
+ if (arg_count == 2) {
+ idx_lc++;
+ if (make_key())
+ IDX_DOT(DOT_MAX);
+ arg_count = -1;
+ } else
+ not_eof = FALSE;
+ break;
+
+ case LFD:
+ idx_lc++;
+ if (arg_count == 2) {
+ if (make_key())
+ IDX_DOT(DOT_MAX);
+ arg_count = -1;
+ } else if (arg_count > -1) {
+ IDX_ERROR("Missing arguments -- need two (premature LFD).\n",
+ NULL);
+ arg_count = -1;
+ }
+ case TAB:
+ case SPC:
+ break;
+
+ default:
+ switch (arg_count) {
+ case -1:
+ i = 0;
+ keyword[i++] = (char) c;
+ arg_count++;
+ idx_tc++;
+ break;
+ case 0:
+ if (c == idx_aopen) {
+ arg_count++;
+ keyword[i] = NUL;
+ if (STREQ(keyword, idx_keyword)) {
+ if (!scan_arg1()) {
+ arg_count = -1;
+ }
+ } else {
+ IDX_SKIPLINE;
+ IDX_ERROR("Unknown index keyword %s.\n", keyword);
+ }
+ } else {
+ if (i < ARRAY_MAX)
+ keyword[i++] = (char) c;
+ else {
+ IDX_SKIPLINE;
+ IDX_ERROR2("Index keyword %s too long (max %d).\n",
+ keyword, ARRAY_MAX);
+ }
+ }
+ break;
+ case 1:
+ if (c == idx_aopen) {
+ arg_count++;
+ if (!scan_arg2()) {
+ arg_count = -1;
+ }
+ } else {
+ IDX_SKIPLINE;
+IDX_ERROR(
+"No opening delimiter for second argument (illegal character `%c').\n", c);
+ }
+ break;
+ case 2:
+ IDX_SKIPLINE;
+IDX_ERROR(
+"No closing delimiter for second argument (illegal character `%c').\n", c);
+ break;
+ }
+ break;
+ }
+ }
+
+ /* fixup the total counts */
+ idx_tt += idx_tc;
+ idx_et += idx_ec;
+
+ DONE(idx_tc - idx_ec, "entries accepted", idx_ec, "rejected");
+ CLOSE(idx_fp);
+}
+
+static void
+flush_to_eol(VOID_ARG)
+{ /* flush to end-of-line, or end-of-file, whichever is first */
+ int a;
+
+ while ( ((a = GET_CHAR(idx_fp)) != LFD) && (a != EOF) )
+ /* NO-OP */;
+}
+
+static int
+make_key(VOID_ARG)
+{
+ NODE_PTR ptr;
+ int i;
+
+ /* allocate and initialize a node */
+
+#ifdef DEBUG
+ totmem += sizeof(NODE);
+ (void)fprintf(stderr,"make_key(): malloc(%d)\ttotmem = %ld\n",
+ sizeof(NODE),totmem);
+#endif /* DEBUG */
+
+ if ((ptr = (NODE_PTR) malloc(sizeof(NODE))) == NULL)
+ FATAL("Not enough core...abort.\n", "");
+
+ for (i = 0; i < FIELD_MAX; i++)
+ {
+ ptr->data.sf[i] = ""; /* initialize fields to pointers */;
+ ptr->data.af[i] = ""; /* to constant empty strings */
+ }
+ ptr->data.encap = "";
+ ptr->data.lpg[0] = NUL;
+ ptr->data.count = 0;
+ ptr->data.type = EMPTY;
+
+ /* process index key */
+ if (!scan_key(&(ptr->data)))
+ return (FALSE);
+
+ /* determine group type */
+ ptr->data.group = group_type(ptr->data.sf[0]);
+
+ /* process page number */
+ strcpy(ptr->data.lpg, no);
+ if (!scan_no(no, ptr->data.npg, &(ptr->data.count), &(ptr->data.type)))
+ return (FALSE);
+
+ if (first_entry) {
+ head = tail = ptr;
+ first_entry = FALSE;
+ } else {
+ tail->next = ptr;
+ tail = ptr;
+ }
+ ptr->data.lc = idx_lc;
+ ptr->data.fn = idx_fn;
+ tail->next = NULL;
+
+ return (TRUE);
+}
+
+static void
+#if STDC
+make_string(char **ppstr, int n)
+#else
+make_string(ppstr,n) /* allocate n-byte string if *ppstr */
+char **ppstr; /* points to an empty string */
+int n;
+#endif
+{
+ if ((*ppstr)[0] == NUL) /* then we have an empty string */
+ {
+ (*ppstr) = (char*)malloc(n);
+ if ((*ppstr) == (char*)NULL)
+ FATAL("Not enough core...abort.\n", "");
+ (*ppstr)[0] = NUL;
+ }
+}
+
+static int
+#if STDC
+scan_key(FIELD_PTR data)
+#else
+scan_key(data)
+FIELD_PTR data;
+#endif
+{
+ int i = 0; /* current level */
+ int n = 0; /* index to the key[] array */
+ int second_round = FALSE;
+ int last = FIELD_MAX - 1;
+
+ while (TRUE) {
+ if (key[n] == NUL)
+ break;
+ if (key[n] == idx_encap)
+ {
+ n++;
+ make_string(&(data->encap),strlen(key) + 1);
+ if (scan_field(&n, data->encap, strlen(key), FALSE, FALSE, FALSE))
+ break;
+ else
+ return (FALSE);
+ }
+ if (key[n] == idx_actual) {
+ n++;
+ if (i == last)
+ {
+ make_string(&(data->af[i]),strlen(key) + 1);
+ if (!scan_field(&n, data->af[i], strlen(key),
+ FALSE, TRUE, FALSE))
+ return (FALSE);
+ }
+ else
+ {
+ make_string(&(data->af[i]),strlen(key) + 1);
+ if (!scan_field(&n, data->af[i], strlen(key),
+ TRUE, TRUE, FALSE))
+ return (FALSE);
+ }
+ } else {
+ /* Next nesting level */
+ if (second_round) {
+ i++;
+ n++;
+ }
+ if (i == last)
+ {
+ make_string(&(data->sf[i]),strlen(key) + 1);
+ if (!scan_field(&n, data->sf[i], strlen(key),
+ FALSE, TRUE, TRUE))
+ return (FALSE);
+ }
+ else
+ {
+ make_string(&(data->sf[i]),strlen(key) + 1);
+ if (!scan_field(&n, data->sf[i], strlen(key),
+ TRUE, TRUE, TRUE))
+ return (FALSE);
+ }
+ second_round = TRUE;
+ if (german_sort && strchr(data->sf[i], '"'))
+ {
+ make_string(&(data->af[i]),strlen(data->sf[i]) + 1);
+ search_quote(data->sf[i], data->af[i]);
+ }
+ }
+ }
+
+ /* check for empty fields which shouldn't be empty */
+ if (*data->sf[0] == NUL) {
+ NULL_RTN;
+ }
+ for (i = 1; i < FIELD_MAX - 1; i++)
+ if ((*data->sf[i] == NUL) &&
+ ((*data->af[i] != NUL) || (*data->sf[i + 1] != NUL))) {
+ NULL_RTN;
+ }
+ /* i == FIELD_MAX-1 */
+ if ((*data->sf[i] == NUL) && (*data->af[i] != NUL)) {
+ NULL_RTN;
+ }
+ return (TRUE);
+}
+
+static int
+#if STDC
+scan_field(int *n, char field[], int len_field, int ck_level, int ck_encap,
+ int ck_actual)
+#else
+scan_field(n, field, len_field, ck_level, ck_encap, ck_actual)
+int *n;
+char field[];
+int len_field; /* length of field[], EXCLUDING space for final NUL */
+int ck_level;
+int ck_encap;
+int ck_actual;
+#endif
+{
+ int i = 0;
+ int nbsh; /* backslash count */
+
+ if (compress_blanks && ((key[*n] == SPC) || (key[*n] == TAB)))
+ ++* n;
+
+ while (TRUE) {
+ nbsh = 0;
+ while (key[*n] == idx_escape)
+ {
+ nbsh++;
+ field[i++] = key[*n];
+ CHECK_LENGTH();
+ ++*n;
+ }
+
+ if (key[*n] == idx_quote)
+ {
+ if (nbsh % 2 == 0)
+ field[i++] = key[++*n];
+ else
+ field[i++] = key[*n];
+ CHECK_LENGTH();
+ }
+ else if ((ck_level && (key[*n] == idx_level)) ||
+ (ck_encap && (key[*n] == idx_encap)) ||
+ (ck_actual && (key[*n] == idx_actual)) ||
+ (key[*n] == NUL))
+ {
+ if ((i > 0) && compress_blanks && (field[i - 1] == SPC))
+ field[i - 1] = NUL;
+ else
+ field[i] = NUL;
+ return (TRUE);
+ } else {
+ field[i++] = key[*n];
+ CHECK_LENGTH();
+ if ((!ck_level) && (key[*n] == idx_level)) {
+ IDX_ERROR2("Extra `%c' at position %d of first argument.\n",
+ idx_level, *n + 1);
+ return (FALSE);
+ } else if ((!ck_encap) && (key[*n] == idx_encap)) {
+ IDX_ERROR2("Extra `%c' at position %d of first argument.\n",
+ idx_encap, *n + 1);
+ return (FALSE);
+ } else if ((!ck_actual) && (key[*n] == idx_actual)) {
+ IDX_ERROR2("Extra `%c' at position %d of first argument.\n",
+ idx_actual, *n + 1);
+ return (FALSE);
+ }
+ }
+ /* check if max field length is reached */
+ if (i > len_field)
+ {
+ OVERFLOW:
+ if (!ck_encap) {
+ IDX_ERROR("Encapsulator of page number too long (max. %d).\n",
+ len_field);
+ } else if (ck_actual) {
+ IDX_ERROR("Index sort key too long (max. %d).\n", len_field);
+ } else {
+ IDX_ERROR("Text of key entry too long (max. %d).\n", len_field);
+ }
+ return (FALSE);
+ }
+ ++*n;
+ }
+#if IBM_PC_TURBO
+ return (FALSE); /* not reached, but keeps compiler happy */
+#endif
+}
+
+int
+#if STDC
+group_type(char *str)
+#else
+group_type(str)
+char *str;
+#endif
+{
+ int i = 0;
+
+ while ((str[i] != NUL) && ISDIGIT(str[i]))
+ i++;
+
+ if (str[i] == NUL) {
+ sscanf(str, "%d", &i);
+ return (i);
+ } else if (ISSYMBOL(str[0]))
+ return (SYMBOL);
+ else
+ return (ALPHA);
+}
+
+static int
+#if STDC
+scan_no(char no[], short npg[], short *count, short *type)
+#else
+scan_no(no, npg, count, type)
+char no[];
+short npg[];
+short *count;
+short *type;
+#endif
+{
+ int i = 1;
+
+ if (isdigit(no[0])) {
+ *type = ARAB;
+ if (!scan_arabic(no, npg, count))
+ return (FALSE);
+ /* simple heuristic to determine if a letter is Roman or Alpha */
+ } else if (IS_ROMAN_LOWER(no[0]) && (!IS_COMPOSITOR)) {
+ *type = ROML;
+ if (!scan_roman_lower(no, npg, count))
+ return (FALSE);
+ /* simple heuristic to determine if a letter is Roman or Alpha */
+ } else if (IS_ROMAN_UPPER(no[0]) &&
+ ((no[0] == ROMAN_I) || (!IS_COMPOSITOR))) {
+ *type = ROMU;
+ if (!scan_roman_upper(no, npg, count))
+ return (FALSE);
+ } else if (IS_ALPHA_LOWER(no[0])) {
+ *type = ALPL;
+ if (!scan_alpha_lower(no, npg, count))
+ return (FALSE);
+ } else if (IS_ALPHA_UPPER(no[0])) {
+ *type = ALPU;
+ if (!scan_alpha_upper(no, npg, count))
+ return (FALSE);
+ } else {
+ IDX_ERROR("Illegal page number %s.\n", no);
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+static int
+#if STDC
+scan_arabic(char no[], short npg[], short *count)
+#else
+scan_arabic(no, npg, count)
+char no[];
+short npg[];
+short *count;
+#endif
+{
+ short i = 0;
+ char str[ARABIC_MAX+1]; /* space for trailing NUL */
+
+ while ((no[i] != NUL) && (i <= ARABIC_MAX) && (!IS_COMPOSITOR)) {
+ if (isdigit(no[i])) {
+ str[i] = no[i];
+ i++;
+ } else {
+IDX_ERROR2("Illegal Arabic digit: position %d in %s.\n", i + 1, no);
+ return (FALSE);
+ }
+ }
+ if (i > ARABIC_MAX) {
+ IDX_ERROR2("Arabic page number %s too big (max %d digits).\n",
+ no, ARABIC_MAX);
+ return (FALSE);
+ }
+ str[i] = NUL;
+
+ ENTER(strtoint(str) + page_offset[ARAB]);
+
+ if (IS_COMPOSITOR)
+ return (scan_no(&no[i + comp_len], npg, count, &i));
+ else
+ return (TRUE);
+}
+
+
+static int
+#if STDC
+scan_roman_lower(char no[], short npg[], short *count)
+#else
+scan_roman_lower(no, npg, count)
+char no[];
+short npg[];
+short *count;
+#endif
+{
+ short i = 0;
+ int inp = 0;
+ int prev = 0;
+ int the_new;
+
+ while ((no[i] != NUL) && (i < ROMAN_MAX) && (!IS_COMPOSITOR)) {
+ if ((IS_ROMAN_LOWER(no[i])) &&
+ ((the_new = ROMAN_LOWER_VAL(no[i])) != 0)) {
+ if (prev == 0)
+ prev = the_new;
+ else {
+ if (prev < the_new) {
+ prev = the_new - prev;
+ the_new = 0;
+ }
+ inp += prev;
+ prev = the_new;
+ }
+ } else {
+IDX_ERROR2("Illegal Roman number: position %d in %s.\n", i + 1, no);
+ return (FALSE);
+ }
+ i++;
+ }
+ if (i == ROMAN_MAX) {
+ IDX_ERROR2("Roman page number %s too big (max %d digits).\n",
+ no, ROMAN_MAX);
+ return (FALSE);
+ }
+ inp += prev;
+
+ ENTER(inp + page_offset[ROML]);
+
+ if (IS_COMPOSITOR)
+ return (scan_no(&no[i + comp_len], npg, count, &i));
+ else
+ return (TRUE);
+}
+
+
+static int
+#if STDC
+scan_roman_upper(char no[], short npg[], short *count)
+#else
+scan_roman_upper(no, npg, count)
+char no[];
+short npg[];
+short *count;
+#endif
+{
+ short i = 0;
+ int inp = 0;
+ int prev = 0;
+ int the_new;
+
+ while ((no[i] != NUL) && (i < ROMAN_MAX) && (!IS_COMPOSITOR)) {
+ if ((IS_ROMAN_UPPER(no[i])) &&
+ ((the_new = ROMAN_UPPER_VAL(no[i])) != 0)) {
+ if (prev == 0)
+ prev = the_new;
+ else {
+ if (prev < the_new) {
+ prev = the_new - prev;
+ the_new = 0;
+ }
+ inp += prev;
+ prev = the_new;
+ }
+ } else {
+IDX_ERROR2("Illegal Roman number: position %d in %s.\n", i + 1, no);
+ return (FALSE);
+ }
+ i++;
+ }
+ if (i == ROMAN_MAX) {
+ IDX_ERROR2("Roman page number %s too big (max %d digits).\n",
+ no, ROMAN_MAX);
+ return (FALSE);
+ }
+ inp += prev;
+
+ ENTER(inp + page_offset[ROMU]);
+
+ if (IS_COMPOSITOR)
+ return (scan_no(&no[i + comp_len], npg, count, &i));
+ else
+ return (TRUE);
+}
+
+
+static int
+#if STDC
+scan_alpha_lower(char no[], short npg[], short *count)
+#else
+scan_alpha_lower(no, npg, count)
+char no[];
+short npg[];
+short *count;
+#endif
+{
+ short i;
+
+ ENTER(ALPHA_VAL(no[0]) + page_offset[ALPL]);
+
+ i = 1;
+ if (IS_COMPOSITOR)
+ return (scan_no(&no[comp_len + 1], npg, count, &i));
+ else
+ return (TRUE);
+}
+
+
+static int
+#if STDC
+scan_alpha_upper(char no[], short npg[], short *count)
+#else
+scan_alpha_upper(no, npg, count)
+char no[];
+short npg[];
+short *count;
+#endif
+{
+ short i;
+
+ ENTER(ALPHA_VAL(no[0]) + page_offset[ALPU]);
+
+ i = 1;
+ if (IS_COMPOSITOR)
+ return (scan_no(&no[comp_len + 1], npg, count, &i));
+ else
+ return (TRUE);
+}
+
+
+static int
+scan_arg1(VOID_ARG)
+{
+ int i = 0;
+ int n = 0; /* delimiter count */
+ int a;
+
+ if (compress_blanks)
+ while (((a = GET_CHAR(idx_fp)) == SPC) || (a == TAB));
+ else
+ a = GET_CHAR(idx_fp);
+
+ while ((i < ARGUMENT_MAX) && (a != EOF))
+ {
+ if ((a == idx_quote) || (a == idx_escape))
+ { /* take next character literally */
+ key[i++] = (char) a; /* but preserve quote or escape */
+ a = GET_CHAR(idx_fp);
+ key[i++] = (char) a; /* save literal character */
+ }
+ else if (a == idx_aopen)
+ { /* opening delimiters within the argument list */
+ key[i++] = (char) a;
+ n++;
+ }
+ else if (a == idx_aclose)
+ {
+ if (n == 0) /* end of argument */
+ {
+ if (compress_blanks && key[i - 1] == SPC)
+ key[i - 1] = NUL;
+ else
+ key[i] = NUL;
+ return (TRUE);
+ }
+ else /* nested delimiters */
+ {
+ key[i++] = (char) a;
+ n--;
+ }
+ }
+ else
+ {
+ switch (a)
+ {
+ case LFD:
+ idx_lc++;
+ IDX_ERROR("Incomplete first argument (premature LFD).\n", "");
+ return (FALSE);
+ case TAB:
+ case SPC:
+ /* compress successive SPC's to one SPC */
+ if (compress_blanks)
+ {
+ if ((i > 0) && (key[i - 1] != SPC) && (key[i - 1] != TAB))
+ key[i++] = SPC;
+ break;
+ }
+ default:
+ key[i++] = (char) a;
+ break;
+ }
+ }
+ a = GET_CHAR(idx_fp);
+ }
+
+ flush_to_eol(); /* Skip to end of line */
+ idx_lc++;
+ IDX_ERROR("First argument too long (max %d).\n", ARGUMENT_MAX);
+ return (FALSE);
+}
+
+
+static int
+scan_arg2(VOID_ARG)
+{
+ int i = 0;
+ int a;
+ int hit_blank = FALSE;
+
+ while (((a = GET_CHAR(idx_fp)) == SPC) || (a == TAB));
+
+ while (i < NUMBER_MAX) {
+ if (a == idx_aclose) {
+ no[i] = NUL;
+ return (TRUE);
+ } else
+ switch (a) {
+ case LFD:
+ idx_lc++;
+IDX_ERROR("Incomplete second argument (premature LFD).\n", "");
+ return (FALSE);
+ case TAB:
+ case SPC:
+ hit_blank = TRUE;
+ break;
+ default:
+ if (hit_blank) {
+ flush_to_eol(); /* Skip to end of line */
+ idx_lc++;
+IDX_ERROR("Illegal space within numerals in second argument.\n", "");
+ return (FALSE);
+ }
+ no[i++] = (char) a;
+ break;
+ }
+ a = GET_CHAR(idx_fp);
+ }
+ flush_to_eol(); /* Skip to end of line */
+ idx_lc++;
+ IDX_ERROR("Second argument too long (max %d).\n", NUMBER_MAX);
+ return (FALSE);
+}
+
+
+static void
+#if STDC
+search_quote(char sort_key[], char actual_key[])
+#else
+search_quote(sort_key, actual_key)
+char sort_key[];
+char actual_key[];
+#endif
+{
+ char *ptr; /* pointer to sort_key */
+ char *sort; /* contains sorting text */
+ int char_found = FALSE;
+
+ strcpy(actual_key, sort_key);
+ ptr = strchr(sort_key, '"'); /* look for first double quote */
+ while (ptr != (char*)NULL)
+ {
+ sort = "";
+ switch (*(ptr + 1))
+ { /* skip to umlaut or sharp S */
+ case 'a':
+ case 'A':
+ sort = isupper(*(ptr + 1)) ? "Ae" : "ae";
+ break;
+ case 'o':
+ case 'O':
+ sort = isupper(*(ptr + 1)) ? "Oe" : "oe";
+ break;
+ case 'u':
+ case 'U':
+ sort = isupper(*(ptr + 1)) ? "Ue" : "ue";
+ break;
+ case 's':
+ sort = "ss";
+ break;
+ default:
+ break;
+ }
+ if (sort[0] != NUL)
+ {
+ char_found = TRUE;
+ *ptr = sort[0]; /* write to sort_key */
+ *(ptr + 1) = sort[1];
+ }
+ ptr = strchr(ptr + 1, '"'); /* next double quote */
+ }
+ if (!char_found) /* reset actual_key ? */
+ actual_key[0] = NUL;
+ return;
+}