#!/usr/bin/perl

# ====================================================================
# The Vovida Software License, Version 1.0 
# 
# Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. The names "VOCAL", "Vovida Open Communication Application Library",
#    and "Vovida Open Communication Application Library (VOCAL)" must
#    not be used to endorse or promote products derived from this
#    software without prior written permission. For written
#    permission, please contact vocal\@vovida.org.
# 
# 4. Products derived from this software may not be called "VOCAL", nor
#    may "VOCAL" appear in their name, without prior written
#    permission of Vovida Networks, Inc.
# 
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
# NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
# 
# ====================================================================
# 
# This software consists of voluntary contributions made by Vovida
# Networks, Inc. and many individuals on behalf of Vovida Networks,
# Inc.  For more information on Vovida Networks, Inc., please see
# <http://www.vovida.org/>.

require "getopts.pl";
&Getopts("o:");

if($opt_o) {
    $output_file = $opt_o;
} else {
    $output_file = "tokenGen";
}

open(OUTPUT_H, ">$output_file.hxx") or die "cannot open $ARGV[1] $!";
open(OUTPUT_CXX, ">$output_file.cxx") or die "cannot open $ARGV[1] $!";

$type{"Unknown"} = 1;
$type{"String"} = 1;
$type{"TableEnd"} = 1;

print OUTPUT_H "#ifndef HEADER_$output_file", "_H_\n";
print OUTPUT_H "#define HEADER_$output_file", "_H_\n";

print OUTPUT_H "// this file is automatically generated!  do not edit\n\n";
print OUTPUT_CXX "// this file is automatically generated!  do not edit\n\n";
print OUTPUT_H <<END_INCLUDES
#include "global.h"
#include <map>
#include <string>
#include "substring.h"
END_INCLUDES
  ;
print OUTPUT_CXX '#include "', "$output_file.hxx", '"', "\n";
print OUTPUT_CXX "\n";

$max_size = 256;

while(<>) {
    chomp;

    s/^\#.*$//;

    if(/^begin (\w+)/) {
	$struct_name = $1;
#	$output_last_header .= "extern struct TokenRecognizerTable recTable$struct_name;\n";
	$output_last_header .= "extern TokenRecognizer recognizer$struct_name;\n";

	print OUTPUT_CXX "struct TokenRecognizerTable recTable$struct_name", "[$max_size] =\n";
	print OUTPUT_CXX "{\n";
    } elsif(/^end/) {
	print OUTPUT_CXX "    { \"\", MgcpTokenTypeTableEnd }\n";
	print OUTPUT_CXX "};\n";

	print OUTPUT_CXX "TokenRecognizer recognizer$struct_name (recTable$struct_name);\n";

    } elsif(s/^token\s+//) {
    
	($name, $string) = split(/\s+/);

	if(!$type{$name}) {
	    $type{$name} = $string;
	} elsif($type{$name} ne $string) {
	    print STDERR "duplicate $name in token table with different string.\n";
	    exit -1;
	}

	print OUTPUT_CXX "    { \"$string\", MgcpTokenType$name },\n";
    }
}

print OUTPUT_H "enum MgcpTokenType\n";
print OUTPUT_H "{\n";

$first_key=1;

foreach(sort keys %type) {
    if ( $first_key ) {
        print OUTPUT_H "     MgcpTokenType$_";
        $first_key=0;
    }
    else {
        print OUTPUT_H ",\n     MgcpTokenType$_";
    }
}
print OUTPUT_H "\n};\n";

print OUTPUT_H "\n";

print OUTPUT_H <<ENDL
struct TokenRecognizerTable
{
    char* string;
    MgcpTokenType type;
};

class TokenRecognizer
{
public:
    TokenRecognizer(struct TokenRecognizerTable* rootTable) {
	int i = 0;
	while(rootTable[i].type != MgcpTokenTypeTableEnd)
	{
	    myMap[rootTable[i].string] = rootTable[i].type;
	    i++;
	}
    };

    MgcpTokenType matchToken(const string& s) {
        map<string, MgcpTokenType>::iterator i = myMap.find(s);

	if (i == myMap.end())
	  return MgcpTokenTypeUnknown;

	else return i->second;
    };

    MgcpTokenType matchToken(const substring& s) {
        map<string, MgcpTokenType>::iterator i = myMap.find(s.str());

	if (i == myMap.end())
	  return MgcpTokenTypeUnknown;

	else return i->second;
    };

private:
    map<string, MgcpTokenType> myMap;
};

ENDL
  ;


print OUTPUT_H $output_last_header;
print OUTPUT_H "#endif\n";


syntax highlighted by Code2HTML, v. 0.9.1