1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
/* This file is part of the YAZ toolkit.
* Copyright (C) Index Data
* See the file LICENSE for details.
*/
/**
* \file cql_sortkeys.c
* \brief CQL sortkeys utilities
*
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <yaz/wrbuf.h>
#include <yaz/cql.h>
static void pr_n(void (*pr)(const char *buf, void *client_data),
const char *buf, int len, void *client_data)
{
char tmp[4];
int left = len;
while (left > 0)
{
if (left >= sizeof(tmp))
{
memcpy(tmp, buf, sizeof(tmp)-1);
tmp[sizeof(tmp)-1] = '\0';
left = left - (sizeof(tmp)-1);
}
else
{
memcpy(tmp, buf, left);
tmp[left] = '\0';
left = 0;
}
pr(tmp, client_data);
}
}
static int cql_sort_modifiers(struct cql_node *cn,
void (*pr)(const char *buf, void *client_data),
void *client_data)
{
int ascending = 1;
int caseSensitive = 0;
const char *missingValue = "highValue";
for (; cn; cn = cn->u.st.modifiers)
{
const char *indx = cn->u.st.index;
if (!strncmp(indx, "sort.", 5))
indx = indx + 5;
if (!strcmp(indx, "ignoreCase"))
caseSensitive = 0;
else if (!strcmp(indx, "respectCase"))
caseSensitive = 1;
else if (!strcmp(indx, "ascending"))
ascending = 1;
else if (!strcmp(indx, "descending"))
ascending = 0;
else if (!strcmp(indx, "missingOmit"))
missingValue = "omit";
else if (!strcmp(indx, "missingFail"))
missingValue = "abort";
else if (!strcmp(indx, "missingLow"))
missingValue = "lowValue";
else if (!strcmp(indx, "missingHigh"))
missingValue = "highValue";
else
return -1;
}
pr(ascending ? "1" : "0", client_data);
pr(",", client_data);
pr(caseSensitive ? "1" : "0", client_data);
pr(",", client_data);
pr(missingValue, client_data);
return 0;
}
int cql_sortby_to_sortkeys(struct cql_node *cn,
void (*pr)(const char *buf, void *client_data),
void *client_data)
{
int r = 0;
if (cn && cn->which == CQL_NODE_SORT)
{
for (; cn; cn = cn->u.sort.next)
{
const char *indx = cn->u.sort.index;
if (indx)
{
const char *s = strchr(indx, '.');
if (s)
{
pr(s+1, client_data);
pr(",", client_data);
pr_n(pr, indx, s - indx, client_data);
}
else
{
pr(indx, client_data);
pr(",", client_data);
}
pr(",", client_data);
r = cql_sort_modifiers(cn->u.sort.modifiers, pr, client_data);
if (r)
break;
if (cn->u.sort.next)
pr(" ", client_data);
}
}
}
return r;
}
int cql_sortby_to_sortkeys_buf(struct cql_node *cn, char *out, int max)
{
struct cql_buf_write_info info;
int r;
info.off = 0;
info.max = max;
info.buf = out;
r = cql_sortby_to_sortkeys(cn, cql_buf_write_handler, &info);
if (info.off >= 0)
info.buf[info.off] = '\0';
return r;
}
/*
* Local variables:
* c-basic-offset: 4
* c-file-style: "Stroustrup"
* indent-tabs-mode: nil
* End:
* vim: shiftwidth=4 tabstop=8 expandtab
*/
|