First version of CCL. Qualifiers aren't handled yet.
[egate.git] / ccl / ccltoken.c
diff --git a/ccl/ccltoken.c b/ccl/ccltoken.c
new file mode 100644 (file)
index 0000000..adbf1f6
--- /dev/null
@@ -0,0 +1,136 @@
+/* CCL - lexical analysis
+ * Europagate, 1995
+ *
+ * $Log: ccltoken.c,v $
+ * Revision 1.1  1995/02/13 12:35:21  adam
+ * First version of CCL. Qualifiers aren't handled yet.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "cclp.h"
+
+static int strin (const char *s, const char *cset)
+{
+    while (*cset)
+    {
+       if (*cset++ == *s)
+           return 1;
+    }
+    return 0;
+}
+
+char *ccl_token_and = "and";
+char *ccl_token_or = "or";
+char *ccl_token_not = "not";
+char *ccl_token_set = "set";
+
+struct ccl_token *ccl_tokenize (const char *command)
+{
+    const char *cp = command;
+    struct ccl_token *first = NULL;
+    struct ccl_token *last = NULL;
+
+    while (1)
+    {
+       while (*cp && strin (cp, " \t\r\n"))
+       {
+           cp++;
+           continue;
+       }
+       if (!first)
+       {
+           first = last = malloc (sizeof (*first));
+           assert (first);
+           last->prev = NULL;
+       }
+       else
+       {
+           last->next = malloc (sizeof(*first));
+           assert (last->next);
+           last->next->prev = last;
+           last = last->next;
+       }
+       last->next = NULL;
+       last->name = cp;
+       last->len = 1;
+       switch (*cp++)
+       {
+        case '\0':
+            last->kind = CCL_TOK_EOL;
+            return first;
+       case '(':
+           last->kind = CCL_TOK_LP;
+           break;
+       case ')':
+           last->kind = CCL_TOK_RP;
+           break;
+       case ',':
+           last->kind = CCL_TOK_COMMA;
+           break;
+       case '%':
+       case '!':
+           last->kind = CCL_TOK_PROX;
+           while (*cp == '%' || *cp == '!')
+           {
+               ++ last->len;
+               cp++;
+           }
+           break;
+       case '>':
+       case '<':
+       case '=':
+           if (*cp == '=' || *cp == '<' || *cp == '>')
+           {
+               cp++;
+               last->kind = CCL_TOK_REL;
+               ++ last->len;
+           }
+           else if (cp[-1] == '=')
+               last->kind = CCL_TOK_EQ;
+           else
+               last->kind = CCL_TOK_REL;
+           break;
+       case '-':
+           last->kind = CCL_TOK_MINUS;
+           break;
+       case '\"':
+           last->kind = CCL_TOK_TERM;
+           last->name = cp;
+           last->len = 0;
+           while (*cp && *cp != '\"')
+           {
+               cp++;
+               ++ last->len;
+           }
+           if (*cp == '\"')
+               cp++;
+           break;
+       default:
+           while (*cp && !strin (cp, "(),%!><=- \t\n\r"))
+           {
+               cp++;
+               ++ last->len;
+           }
+           if (strlen (ccl_token_and)==last->len &&
+               !memcmp (ccl_token_and, last->name, last->len))
+               last->kind = CCL_TOK_AND;
+           else if (strlen (ccl_token_or)==last->len &&
+               !memcmp (ccl_token_or, last->name, last->len))
+               last->kind = CCL_TOK_OR;
+           else if (strlen (ccl_token_not)==last->len &&
+               !memcmp (ccl_token_not, last->name, last->len))
+               last->kind = CCL_TOK_NOT;
+           else if (strlen (ccl_token_set)==last->len &&
+               !memcmp (ccl_token_set, last->name, last->len))
+               last->kind = CCL_TOK_SET;
+           else
+               last->kind = CCL_TOK_TERM;
+       }
+    }
+    return first;
+}