+/*
+ * Copyright (c) 1995, the EUROPAGATE consortium (see below).
+ *
+ * The EUROPAGATE consortium members are:
+ *
+ * University College Dublin
+ * Danmarks Teknologiske Videnscenter
+ * An Chomhairle Leabharlanna
+ * Consejo Superior de Investigaciones Cientificas
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation, in whole or in part, for any purpose, is hereby granted,
+ * provided that:
+ *
+ * 1. This copyright and permission notice appear in all copies of the
+ * software and its documentation. Notices of copyright or attribution
+ * which appear at the beginning of any file must remain unchanged.
+ *
+ * 2. The names of EUROPAGATE or the project partners may not be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * 3. Users of this software (implementors and gateway operators) agree to
+ * inform the EUROPAGATE consortium of their use of the software. This
+ * information will be used to evaluate the EUROPAGATE project and the
+ * software, and to plan further developments. The consortium may use
+ * the information in later publications.
+ *
+ * 4. Users of this software agree to make their best efforts, when
+ * documenting their use of the software, to acknowledge the EUROPAGATE
+ * consortium, and the role played by the software in their work.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ * IN NO EVENT SHALL THE EUROPAGATE CONSORTIUM OR ITS MEMBERS BE LIABLE
+ * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF
+ * ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
+ * OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND
+ * ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
/* CCL - lexical analysis
* Europagate, 1995
*
* $Log: ccltoken.c,v $
- * Revision 1.2 1995-09-27 15:02:44 quinn
- * Modified function heads & prototypes.
+ * Revision 1.10 1998-07-07 15:49:41 adam
+ * Added braces to avoid warning.
+ *
+ * Revision 1.9 1998/02/11 11:53:33 adam
+ * Changed code so that it compiles as C++.
+ *
+ * Revision 1.8 1997/09/29 08:56:38 adam
+ * Changed CCL parser to be thread safe. New type, CCL_parser, declared
+ * and a create/destructers ccl_parser_create/ccl_parser/destory has
+ * been added.
+ *
+ * Revision 1.7 1997/09/01 08:48:12 adam
+ * New windows NT/95 port using MSV5.0. Only a few changes made
+ * to avoid warnings.
*
- * Revision 1.1 1995/04/10 10:28:22 quinn
- * Added copy of CCL.
+ * Revision 1.6 1997/04/30 08:52:07 quinn
+ * Null
+ *
+ * Revision 1.5 1996/10/11 15:00:26 adam
+ * CCL parser from Europagate Email gateway 1.0.
+ *
+ * Revision 1.10 1995/07/11 12:28:31 adam
+ * New function: ccl_token_simple (split into simple tokens) and
+ * ccl_token_del (delete tokens).
+ *
+ * Revision 1.9 1995/05/16 09:39:28 adam
+ * LICENSE.
+ *
+ * Revision 1.8 1995/05/11 14:03:57 adam
+ * Changes in the reading of qualifier(s). New function: ccl_qual_fitem.
+ * New variable ccl_case_sensitive, which controls whether reserved
+ * words and field names are case sensitive or not.
+ *
+ * Revision 1.7 1995/04/19 12:11:24 adam
+ * Minor change.
+ *
+ * Revision 1.6 1995/04/17 09:31:48 adam
+ * Improved handling of qualifiers. Aliases or reserved words.
*
* Revision 1.5 1995/02/23 08:32:00 adam
* Changed header.
#include <ccl.h>
-static int strin (const char *s, const char *cset)
+/*
+ * token_cmp: Compare token with keyword(s)
+ * kw: Keyword list. Each keyword is separated by space.
+ * token: CCL token.
+ * return: 1 if token string matches one of the keywords in list;
+ * 0 otherwise.
+ */
+static int token_cmp (CCL_parser cclp, const char *kw, struct ccl_token *token)
{
- while (*cset)
+ const char *cp1 = kw;
+ const char *cp2;
+ if (!kw)
+ return 0;
+ while ((cp2 = strchr (cp1, ' ')))
{
- if (*cset++ == *s)
- return 1;
+ if (token->len == (size_t) (cp2-cp1))
+ {
+ if (cclp->ccl_case_sensitive)
+ {
+ if (!memcmp (cp1, token->name, token->len))
+ return 1;
+ }
+ else
+ {
+ if (!ccl_memicmp (cp1, token->name, token->len))
+ return 1;
+ }
+ }
+ cp1 = cp2+1;
+ }
+ if (cclp->ccl_case_sensitive)
+ return token->len == strlen(cp1)
+ && !memcmp (cp1, token->name, token->len);
+ return token->len == strlen(cp1) &&
+ !ccl_memicmp (cp1, token->name, token->len);
+}
+
+/*
+ * ccl_token_simple: tokenize CCL raw tokens
+ */
+struct ccl_token *ccl_token_simple (const char *command)
+{
+ const char *cp = command;
+ struct ccl_token *first = NULL;
+ struct ccl_token *last = NULL;
+
+ while (1)
+ {
+ while (*cp && strchr (" \t\r\n", *cp))
+ {
+ cp++;
+ continue;
+ }
+ if (!first)
+ {
+ first = last = (struct ccl_token *)malloc (sizeof (*first));
+ assert (first);
+ last->prev = NULL;
+ }
+ else
+ {
+ last->next = (struct ccl_token *)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_TERM;
+ last->name = cp;
+ last->len = 0;
+ while (*cp && *cp != '\"')
+ {
+ cp++;
+ ++ last->len;
+ }
+ if (*cp == '\"')
+ cp++;
+ break;
+ default:
+ while (*cp && !strchr (" \t\n\r", *cp))
+ {
+ cp++;
+ ++ last->len;
+ }
+ last->kind = CCL_TOK_TERM;
+ }
}
- return 0;
+ return first;
}
-const char *ccl_token_and = "and";
-const char *ccl_token_or = "or";
-const char *ccl_token_not = "not";
-const char *ccl_token_set = "set";
-struct ccl_token MDF *ccl_tokenize (const char *command)
+/*
+ * ccl_tokenize: tokenize CCL command string.
+ * return: CCL token list.
+ */
+struct ccl_token *ccl_parser_tokenize (CCL_parser cclp, const char *command)
{
const char *cp = command;
struct ccl_token *first = NULL;
while (1)
{
- while (*cp && strin (cp, " \t\r\n"))
+ while (*cp && strchr (" \t\r\n", *cp))
{
cp++;
continue;
}
if (!first)
{
- first = last = malloc (sizeof (*first));
+ first = last = (struct ccl_token *)malloc (sizeof (*first));
assert (first);
last->prev = NULL;
}
else
{
- last->next = malloc (sizeof(*first));
+ last->next = (struct ccl_token *)malloc (sizeof(*first));
assert (last->next);
last->next->prev = last;
last = last->next;
cp++;
break;
default:
- while (*cp && !strin (cp, "(),%!><=- \t\n\r"))
+ while (*cp && !strchr ("(),%!><=- \t\n\r", *cp))
{
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;
+ if (token_cmp (cclp, cclp->ccl_token_and, last))
+ last->kind = CCL_TOK_AND;
+ else if (token_cmp (cclp, cclp->ccl_token_or, last))
+ last->kind = CCL_TOK_OR;
+ else if (token_cmp (cclp, cclp->ccl_token_not, last))
+ last->kind = CCL_TOK_NOT;
+ else if (token_cmp (cclp, cclp->ccl_token_set, last))
+ last->kind = CCL_TOK_SET;
else
last->kind = CCL_TOK_TERM;
}
}
return first;
}
+
+struct ccl_token *ccl_tokenize (const char *command)
+{
+ CCL_parser cclp = ccl_parser_create ();
+ struct ccl_token *list;
+
+ list = ccl_parser_tokenize (cclp, command);
+
+ ccl_parser_destroy (cclp);
+ return list;
+}
+
+/*
+ * ccl_token_del: delete CCL tokens
+ */
+void ccl_token_del (struct ccl_token *list)
+{
+ struct ccl_token *list1;
+
+ while (list)
+ {
+ list1 = list->next;
+ free (list);
+ list = list1;
+ }
+}
+
+CCL_parser ccl_parser_create (void)
+{
+ CCL_parser p = (CCL_parser)malloc (sizeof(*p));
+ if (!p)
+ return p;
+ p->look_token = NULL;
+ p->error_code = 0;
+ p->error_pos = NULL;
+ p->bibset = NULL;
+
+ p->ccl_token_and = "and";
+ p->ccl_token_or = "or";
+ p->ccl_token_not = "not andnot";
+ p->ccl_token_set = "set";
+ p->ccl_case_sensitive = 1;
+
+ return p;
+}
+
+void ccl_parser_destroy (CCL_parser p)
+{
+ if (!p)
+ return;
+ free (p);
+}
+