Add check for integer overflow in odr_write YAZ-816
[yaz-moved-to-github.git] / src / cql.y
index 67e2f76..ed5735d 100644 (file)
--- a/src/cql.y
+++ b/src/cql.y
@@ -1,5 +1,5 @@
 /* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2013 Index Data
+ * Copyright (C) Index Data
  * See the file LICENSE for details.
  */
 /* bison parser for CQL grammar. */
 #endif
 #include <stdio.h>
 #include <stdlib.h>
+/* avoid that bison stuff defines malloc/free - already in stdlib.h */
+#ifdef _MSC_VER
+#define _STDLIB_H 1
+#endif
 #include <string.h>
 #include <yaz/yaz-iconv.h>
 #include <yaz/xmalloc.h>
         int last_pos;
         struct cql_node *top;
         NMEM nmem;
+        int strict;
     };
 
 #define YYSTYPE token
 
-#define YYPARSE_PARAM parm
-#define YYLEX_PARAM parm
+int yylex(YYSTYPE *lval, void *vp);
+int yyerror(void *lval, char *msg);
 
-    int yylex(YYSTYPE *lval, void *vp);
-    int yyerror(char *s);
 %}
 
-%pure_parser
-%token SIMPLE_STRING AND OR NOT PROX GE LE NE EXACT SORTBY
+
+%lex-param {void *parm}
+%parse-param {void *parm}
+%pure-parser
+%token PREFIX_NAME SIMPLE_STRING AND OR NOT PROX GE LE NE EXACT SORTBY
 
 %%
 
@@ -145,12 +151,12 @@ searchClause:
       $$.cql = $3.cql;
   }
 |
-searchTerm {
+searchTerm extraTerms {
       struct cql_node *st = cql_node_dup(((CQL_parser) parm)->nmem, $0.rel);
+      st->u.st.extra_terms = $2.cql;
       st->u.st.term = nmem_strdup(((CQL_parser)parm)->nmem, $1.buf);
       $$.cql = st;
   }
-
 |
   index relation modifiers {
       $$.rel = cql_node_mk_sc(((CQL_parser) parm)->nmem, $1.buf, $2.buf, 0);
@@ -161,6 +167,18 @@ searchTerm {
   }
 ;
 
+extraTerms:
+SIMPLE_STRING extraTerms {
+    struct cql_node *st = cql_node_mk_sc(((CQL_parser) parm)->nmem,
+                                        /* index */ 0, /* rel */ 0, $1.buf);
+    st->u.st.extra_terms = $2.cql;
+    $$.cql = st;
+}
+|
+{ $$.cql = 0; }
+;
+
+
 /* unary NOT search SIMPLE_STRING here .. */
 
 boolean:
@@ -189,7 +207,7 @@ modifiers '/' searchTerm relation_symbol searchTerm
 }
 ;
 
-relation: SIMPLE_STRING | relation_symbol;
+relation: PREFIX_NAME | relation_symbol;
 
 relation_symbol:
   '='
@@ -206,6 +224,7 @@ index:
 
 searchTerm:
   SIMPLE_STRING
+| PREFIX_NAME
 | AND
 | OR
 | NOT
@@ -215,7 +234,7 @@ searchTerm:
 
 %%
 
-int yyerror(char *s)
+int yyerror(void *locp, char *s)
 {
     return 0;
 }
@@ -325,8 +344,11 @@ int yylex(YYSTYPE *lval, void *vp)
     }
     else
     {
+       int relation_like = 0;
        while (c != 0 && !strchr(" \n()=<>/", c))
        {
+           if (c == '.')
+               relation_like = 1;
            if (c == '\\')
            {
                putb(lval, cp, c);
@@ -368,6 +390,16 @@ int yylex(YYSTYPE *lval, void *vp)
            lval->buf = "sortby";
            return SORTBY;
        }
+        if (cp->strict)
+            return PREFIX_NAME;
+       if (!cql_strcmp(lval->buf, "all"))
+           relation_like = 1;
+       if (!cql_strcmp(lval->buf, "any"))
+           relation_like = 1;
+       if (!cql_strcmp(lval->buf, "adj"))
+           relation_like = 1;
+       if (relation_like)
+           return PREFIX_NAME;
     }
     return SIMPLE_STRING;
 }
@@ -400,6 +432,7 @@ CQL_parser cql_parser_create(void)
     cp->last_error = 0;
     cp->last_pos = 0;
     cp->nmem = nmem_create();
+    cp->strict = 0;
     return cp;
 }
 
@@ -415,6 +448,11 @@ struct cql_node *cql_parser_result(CQL_parser cp)
     return cp->top;
 }
 
+void cql_parser_strict(CQL_parser cp, int mode)
+{
+    cp->strict = mode;
+}
+
 /*
  * Local variables:
  * c-basic-offset: 4