Change to emit_term(): when a term has the /regexp relation modifier,
[yaz-moved-to-github.git] / src / cqltransform.c
index 9cbe7e0..2f2f353 100644 (file)
@@ -1,5 +1,5 @@
-/* $Id: cqltransform.c,v 1.24 2006-10-05 16:12:23 adam Exp $
-   Copyright (C) 1995-2005, Index Data ApS
+/* $Id: cqltransform.c,v 1.28 2007-03-29 11:14:11 mike Exp $
+   Copyright (C) 1995-2007, Index Data ApS
    Index Data Aps
 
 This file is part of the YAZ toolkit.
@@ -53,36 +53,48 @@ cql_transform_t cql_transform_open_FILE(FILE *f)
     {
         const char *cp_value_start;
         const char *cp_value_end;
+        const char *cp_pattern_start;
         const char *cp_pattern_end;
         const char *cp = line;
-        while (*cp && !strchr(" \t=\r\n#", *cp))
+
+        while (*cp && strchr(" \t", *cp))
+            cp++;
+        cp_pattern_start = cp;
+        
+        while (*cp && !strchr(" \t\r\n=#", *cp))
             cp++;
         cp_pattern_end = cp;
-        if (cp == line)
+        if (cp == cp_pattern_start)
             continue;
-        while (*cp && strchr(" \t\r\n", *cp))
+        while (*cp && strchr(" \t", *cp))
             cp++;
         if (*cp != '=')
-            continue;
+        {
+            *pp = 0;
+            cql_transform_close(ct);
+            return 0;
+        }
         cp++;
         while (*cp && strchr(" \t\r\n", *cp))
             cp++;
         cp_value_start = cp;
-        if (!(cp_value_end = strchr(cp, '#')))
+        cp_value_end = strchr(cp, '#');
+        if (!cp_value_end)
             cp_value_end = strlen(line) + line;
 
         if (cp_value_end != cp_value_start &&
             strchr(" \t\r\n", cp_value_end[-1]))
             cp_value_end--;
         *pp = (struct cql_prop_entry *) xmalloc (sizeof(**pp));
-        (*pp)->pattern = (char *) xmalloc (cp_pattern_end - line + 1);
-        memcpy ((*pp)->pattern, line, cp_pattern_end - line);
-        (*pp)->pattern[cp_pattern_end-line] = 0;
+        (*pp)->pattern = (char *) xmalloc(cp_pattern_end-cp_pattern_start + 1);
+        memcpy ((*pp)->pattern, cp_pattern_start,
+                cp_pattern_end-cp_pattern_start);
+        (*pp)->pattern[cp_pattern_end-cp_pattern_start] = '\0';
 
-        (*pp)->value = (char *) xmalloc (cp_value_end - cp_value_start + 1);
+        (*pp)->value = (char *) xmalloc (cp_value_end-cp_value_start + 1);
         if (cp_value_start != cp_value_end)
             memcpy ((*pp)->value, cp_value_start, cp_value_end-cp_value_start);
-        (*pp)->value[cp_value_end - cp_value_start] = 0;
+        (*pp)->value[cp_value_end - cp_value_start] = '\0';
         pp = &(*pp)->next;
     }
     *pp = 0;
@@ -183,6 +195,7 @@ int cql_pr_attr_uri(cql_transform_t ct, const char *category,
         const char *cp0 = res, *cp1;
         while ((cp1 = strchr(cp0, '=')))
         {
+            int i;
             while (*cp1 && *cp1 != ' ')
                 cp1++;
             if (cp1 - cp0 >= sizeof(buf))
@@ -190,7 +203,19 @@ int cql_pr_attr_uri(cql_transform_t ct, const char *category,
             memcpy (buf, cp0, cp1 - cp0);
             buf[cp1-cp0] = 0;
             (*pr)("@attr ", client_data);
-            (*pr)(buf, client_data);
+
+            for (i = 0; buf[i]; i++)
+            {
+                if (buf[i] == '*')
+                    (*pr)(eval, client_data);
+                else
+                {
+                    char tmp[2];
+                    tmp[0] = buf[i];
+                    tmp[1] = '\0';
+                    (*pr)(tmp, client_data);
+                }
+            }
             (*pr)(" ", client_data);
             cp0 = cp1;
             while (*cp0 == ' ')
@@ -328,6 +353,18 @@ static const char *wcchar(const char *term, int length)
 }
 
 
+/* ### checks for CQL relation-name rather than Type-1 attribute */
+static int has_modifier(struct cql_node *cn, const char *name) {
+    struct cql_node *mod;
+    for (mod = cn->u.st.modifiers; mod != 0; mod = mod->u.st.modifiers) {
+        if (!strcmp(mod->u.st.index, name))
+            return 1;
+    }
+
+    return 0;
+}
+
+
 void emit_term(cql_transform_t ct,
                struct cql_node *cn,
                const char *term, int length,
@@ -336,10 +373,11 @@ void emit_term(cql_transform_t ct,
 {
     int i;
     const char *ns = cn->u.st.index_uri;
+    int process_term = !has_modifier(cn, "regexp");
 
     assert(cn->which == CQL_NODE_ST);
 
-    if (length > 0)
+    if (process_term && length > 0)
     {
         if (length > 1 && term[0] == '^' && term[length-1] == '^')
         {
@@ -368,7 +406,7 @@ void emit_term(cql_transform_t ct,
         }
     }
 
-    if (length > 0)
+    if (process_term && length > 0)
     {
         /* Check for well-known globbing patterns that represent
          * simple truncation attributes as expected by, for example,