/*
 * This file is part of the Poliqarp suite.
 * 
 * Copyright (C) 2004-2009 by Instytut Podstaw Informatyki Polskiej
 * Akademii Nauk (IPI PAN; Institute of Computer Science, Polish
 * Academy of Sciences; cf. www.ipipan.waw.pl).  All rights reserved.
 * 
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file gpl.txt included in the packaging
 * of this file.  (See http://www.gnu.org/licenses/translations.html for
 * unofficial translations.)
 * 
 * A commercial license is available from IPI PAN (contact
 * Michal.Ciesiolka@ipipan.waw.pl or ipi@ipipan.waw.pl for more
 * information).  Licensees holding a valid commercial license from IPI
 * PAN may use this file in accordance with that license.
 * 
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

#include <poliqarp-config.h>

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "tag-lookup.h"

struct tag {
   const char *name;
   enum xml_tag value;
};

/* A very dummy hash-table. It doesn't even do collisions; I'll add 'em
 * if they ever get bumped to. */
static struct tag *tag_table[1 << CHAR_BIT];

static inline unsigned char hash(const char *tag)
{
   unsigned char res = 0;
   const unsigned char *ptr = (const unsigned char *)tag;
   while (*ptr)
      res += *ptr++;
   return res;
}

static void add_tag(const char *name, enum xml_tag value)
{
   unsigned char index = hash(name);
   if (tag_table[index] == NULL) {
      struct tag *tag = malloc(sizeof(*tag));
      tag->name = name;
      tag->value = value;
      tag_table[index] = tag;
   } else {
      fprintf(stderr, "Tag hashtable collision");
      abort();
   }
}

enum xml_tag lookup_tag(const char *text)
{
   unsigned char index = hash(text);
   if (tag_table[index] == NULL)
      return TOK_UNKNOWN;
   else
      return tag_table[index]->value;
}

void tag_lookup_init()
{
   size_t i;

   for (i = 0; i <= UCHAR_MAX; i++)
      tag_table[i] = NULL;

   add_tag("chunk", TOK_CHUNK);
   add_tag("ns", TOK_NS);
   add_tag("cesAna", TOK_OTHER);
   add_tag("chunkList", TOK_CHUNK_LIST);
   add_tag("tok", TOK_TOK);
   add_tag("orth", TOK_ORTH);
   add_tag("lex", TOK_LEX);
   add_tag("base", TOK_BASE);
   add_tag("ctag", TOK_CTAG);
   add_tag("group", TOK_GROUP);
}
