#include "main.h"
#include <stdlib.h>

#include <ext/hash_map>
#include <vector>
#include <string>

/* 
	EXTREMELY IMPORTANT WEIRDNESS NOTE -- MUST REMEMBER FOR UPDATES

	When adding similar items (ex: 'restart' and 'restart-limit') at the same tree level, you must
	place the longer keyword (the one containing the other keyword... 'restart-limit' in our example)
	AFTER the shorter keyword ('restart' in our example).

	If you don't the generated VIM file will be confused and not break it in weird ways.
*/


int main(int argc, char **argv) {
	clear(root);

	add("system:::trace-options");

	add("system:::storage:::debug");
	add("system:::storage:::primary:::driver");
	add("system:::storage:::primary:::server");
	add("system:::storage:::primary:::port");
	add("system:::storage:::primary:::database");
	add("system:::storage:::primary:::username");
	add("system:::storage:::primary:::password");

	add("system:::snmp-mib");

	add("system:::default:::description");
	add("system:::default:::nice");
	add("system:::default:::order");
	add("system:::default:::restart");
	add("system:::default:::restart-limit");
	add("system:::default:::no-restart");
	add("system:::default:::user");
	add("system:::default:::group");
	add("system:::default:::umask");
	add("system:::default:::chroot");
	add("system:::default:::config-file");
	add("system:::default:::directory");
	add("system:::default:::environment");
	add("system:::default:::facility");

	add("system:::default:::schedule:::launch-delay");
	add("system:::default:::schedule:::delay");
	add("system:::default:::schedule:::startup");
	add("system:::default:::schedule:::cron");

	add("discovery:::nice");
	add("discovery:::no-restart");

	add("discovery:::schedule:::startup");
	add("discovery:::schedule:::hour");
	add("discovery:::schedule:::minute");
	add("discovery:::schedule:::second");

	add("discovery:::icmp:::description");
	add("discovery:::icmp:::executable");
	add("discovery:::icmp:::order");
	add("discovery:::icmp:::trace-options");
	add("discovery:::icmp:::source");
	add("discovery:::icmp:::interface");
	add("discovery:::icmp:::transmit");
	add("discovery:::icmp:::require");
	add("discovery:::icmp:::timeout");
	add("discovery:::icmp:::prefix");

	add("discovery:::snmp:::description");
	add("discovery:::snmp:::executable");
	add("discovery:::snmp:::order");
	add("discovery:::snmp:::trace-options");
	add("discovery:::snmp:::source");
	add("discovery:::snmp:::interface");
	add("discovery:::snmp:::threads");
	add("discovery:::snmp:::commit-count");
	add("discovery:::snmp:::community");
	add("discovery:::snmp:::timeout");
	add("discovery:::snmp:::retry");
	add("discovery:::snmp:::prefix");
	add("discovery:::snmp:::oid");

	add("discovery:::topology:::description");
	add("discovery:::topology:::executable");
	add("discovery:::topology:::order");
	add("discovery:::topology:::trace-options");
	add("discovery:::topology:::policy:::input");
	add("discovery:::topology:::merge-percent");
	add("discovery:::topology:::duplicate-percent");
	add("discovery:::topology:::maximum-entry-delete");

	add("monitor:::icmp:::description");
	add("monitor:::icmp:::executable");
	add("monitor:::icmp:::trace-options");
	add("monitor:::icmp:::source");
	add("monitor:::icmp:::interface");
	add("monitor:::icmp:::interval");
	add("monitor:::icmp:::interval-adjustment");
	add("monitor:::icmp:::payload");
	add("monitor:::icmp:::timeout");
	add("monitor:::icmp:::transmit");
	add("monitor:::icmp:::ttl");
	add("monitor:::icmp:::tos");
	add("monitor:::icmp:::dscp");
	add("monitor:::icmp:::precedence");
	add("monitor:::icmp:::queue-depth");

	add("monitor:::icmp:::policy:::input");
	add("monitor:::icmp:::policy:::output");

	add("monitor:::icmp:::policy-queue-depth");
	add("monitor:::icmp:::policy-queue-limit");
	add("monitor:::icmp:::policy-queue-lower-threshold");
	add("monitor:::icmp:::policy-queue-upper-threshold");

	add("monitor:::icmp:::calc-interval");
	add("monitor:::icmp:::calc-interval-adjustment");
	add("monitor:::icmp:::calc-queue-depth");
	add("monitor:::icmp:::calc-queue-lower-threshold");
	add("monitor:::icmp:::calc-queue-upper-threshold");
	add("monitor:::icmp:::supression:::packet-loss");
	add("monitor:::icmp:::supression:::rtt");
	add("monitor:::icmp:::supression:::jitter");
	add("monitor:::icmp:::supression:::normalized-rtt");

	add("monitor:::snmptrap:::description");
	add("monitor:::snmptrap:::executable");
	add("monitor:::snmptrap:::trace-options");
	add("monitor:::snmptrap:::source");
	add("monitor:::snmptrap:::interface");
	add("monitor:::snmptrap:::port");
	add("monitor:::snmptrap:::proxy:::convert");
	add("monitor:::snmptrap:::queue-depth");
	add("monitor:::snmptrap:::rate-interval");
	add("monitor:::snmptrap:::rate-clean");
	add("monitor:::snmptrap:::exit-after");
	add("monitor:::snmptrap:::policy:::input");
	add("monitor:::snmptrap:::policy:::output");

	add("monitor:::syslog:::description");
	add("monitor:::syslog:::executable");
	add("monitor:::syslog:::trace-options");
	add("monitor:::syslog:::source");
	add("monitor:::syslog:::interface");
	add("monitor:::syslog:::port");
	add("monitor:::syslog:::duplicate-history-max");
	add("monitor:::syslog:::duplicate-history-age");
	add("monitor:::syslog:::duplicate-fuzz-factor");
	add("monitor:::syslog:::queue-depth");
	add("monitor:::syslog:::rate-interval");
	add("monitor:::syslog:::rate-clean");
	add("monitor:::syslog:::exit-after");
	add("monitor:::syslog:::policy:::input");
	add("monitor:::syslog:::policy:::output");

	add("monitor:::bgp:::description");
	add("monitor:::bgp:::executable");
	add("monitor:::bgp:::trace-options");
	add("monitor:::bgp:::interface");
	add("monitor:::bgp:::source");
	add("monitor:::bgp:::local-as");
	add("monitor:::bgp:::peer-as");
	add("monitor:::bgp:::hold-time");
	add("monitor:::bgp:::multihop:::ttl");
	add("monitor:::bgp:::graceful-restart:::restart-time");
	add("monitor:::bgp:::family");
	add("monitor:::bgp:::authentication-key");
	add("monitor:::bgp:::damping");
	add("monitor:::bgp:::policy:::input");
	add("monitor:::bgp:::policy:::output");
	add("monitor:::bgp:::allow");
	add("monitor:::bgp:::neighbor[ 	][ 	]*[A-Za-z0-9\-\.][A-Za-z0-9\-\.]*:::description");
	add("monitor:::bgp:::neighbor[ 	][ 	]*[A-Za-z0-9\-\.][A-Za-z0-9\-\.]*:::peer-as");
	add("monitor:::bgp:::neighbor[ 	][ 	]*[A-Za-z0-9\-\.][A-Za-z0-9\-\.]*:::local-as");
	add("monitor:::bgp:::neighbor[ 	][ 	]*[A-Za-z0-9\-\.][A-Za-z0-9\-\.]*:::hold-time");
	add("monitor:::bgp:::neighbor[ 	][ 	]*[A-Za-z0-9\-\.][A-Za-z0-9\-\.]*:::multihop:::ttl");
	add("monitor:::bgp:::neighbor[ 	][ 	]*[A-Za-z0-9\-\.][A-Za-z0-9\-\.]*:::graceful-restart:::restart-time");
	add("monitor:::bgp:::neighbor[ 	][ 	]*[A-Za-z0-9\-\.][A-Za-z0-9\-\.]*:::family");
	add("monitor:::bgp:::neighbor[ 	][ 	]*[A-Za-z0-9\-\.][A-Za-z0-9\-\.]*:::authentication-key");
	add("monitor:::bgp:::neighbor[ 	][ 	]*[A-Za-z0-9\-\.][A-Za-z0-9\-\.]*:::damping");
	add("monitor:::bgp:::neighbor[ 	][ 	]*[A-Za-z0-9\-\.][A-Za-z0-9\-\.]*:::policy:::input");
	add("monitor:::bgp:::neighbor[ 	][ 	]*[A-Za-z0-9\-\.][A-Za-z0-9\-\.]*:::policy:::output");

	add("monitor:::state:::description");
	add("monitor:::state:::executable");
	add("monitor:::state:::trace-options");
	add("monitor:::state:::interval");
	add("monitor:::state:::process-element");
	add("monitor:::state:::policy:::output");

	add("output:::gui:::description");
	add("output:::gui:::executable");
	add("output:::gui:::trace-options");
	add("output:::gui:::interval");
	add("output:::gui:::expire-interval");
	add("output:::gui:::queue-depth");
	add("output:::gui:::max-delete");
	add("output:::gui:::policy:::output");

	add("output:::email:::description");
	add("output:::email:::executable");
	add("output:::email:::trace-options");
	add("output:::email:::interval");
	add("output:::email:::queue-depth");

	add("output:::email:::default:::server");
	add("output:::email:::default:::from");
	add("output:::email:::default:::to");
	add("output:::email:::default:::cc");
	add("output:::email:::default:::bcc");
	add("output:::email:::default:::port");
	add("output:::email:::default:::timeout");
	add("output:::email:::default:::reply-to");
	add("output:::email:::default:::subject");
	add("output:::email:::default:::body");
	add("output:::email:::default:::priority");
	add("output:::email:::default:::length");

	add("output:::email:::alias:::[A-Za-z0-9_][A-Za-z0-9_]*:::server");
	add("output:::email:::alias:::[A-Za-z0-9_][A-Za-z0-9_]*:::from");
	add("output:::email:::alias:::[A-Za-z0-9_][A-Za-z0-9_]*:::to");
	add("output:::email:::alias:::[A-Za-z0-9_][A-Za-z0-9_]*:::cc");
	add("output:::email:::alias:::[A-Za-z0-9_][A-Za-z0-9_]*:::bcc");
	add("output:::email:::alias:::[A-Za-z0-9_][A-Za-z0-9_]*:::port");
	add("output:::email:::alias:::[A-Za-z0-9_][A-Za-z0-9_]*:::timeout");
	add("output:::email:::alias:::[A-Za-z0-9_][A-Za-z0-9_]*:::reply-to");
	add("output:::email:::alias:::[A-Za-z0-9_][A-Za-z0-9_]*:::subject");
	add("output:::email:::alias:::[A-Za-z0-9_][A-Za-z0-9_]*:::body");
	add("output:::email:::alias:::[A-Za-z0-9_][A-Za-z0-9_]*:::priority");
	add("output:::email:::alias:::[A-Za-z0-9_][A-Za-z0-9_]*:::length");

	add("output:::email:::policy:::input");
	add("output:::email:::policy:::output");

	add("output:::syslog:::description");
	add("output:::syslog:::executable");
	add("output:::syslog:::interval");
	add("output:::syslog:::trace-options");
	add("output:::syslog:::queue-depth");
	add("output:::syslog:::policy:::input");
	add("output:::syslog:::policy:::output");

	add("internal:::tidy:::description");
	add("internal:::tidy:::executable");
	add("internal:::tidy:::trace-options");
	add("internal:::tidy:::interval");
	add("internal:::tidy:::output-age");
	add("internal:::tidy:::policy:::input");
	add("internal:::tidy:::policy:::output");

	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::apply-format");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::set");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::apply-map");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::output:::gui:::brief");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::output:::gui:::detail");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::output:::gui:::channel");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::output:::log:::brief");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::output:::log:::detail");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::output:::log:::channel");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::output:::email:::brief");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::output:::email:::detail");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::output:::email:::channel");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::output:::state:::protocol");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::output:::state:::channel");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::output:::state:::state");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::evaluate:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::accept");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::reject");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::next-term");
	add("policy-options:::policy-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::next-policy");

	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::required");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::type");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::function");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::apply-map");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::value");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::suffix-modifier[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::function");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::suffix-modifier[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::argument");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::dependency[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*");

	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::group[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::required");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::group[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::type");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::group[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::function");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::group[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::apply-map");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::group[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::value");

	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::group[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::required");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::group[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::type");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::group[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::function");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::group[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::apply-map");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::group[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::value");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::group[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::suffix-modifier[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::function");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::group[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::suffix-modifier[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::argument");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::group[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::suffix-modifier[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::function");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::group[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::suffix-modifier[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::argument");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::group[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::dependency[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::group[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::dependency[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*");

	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::action:::default");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::action:::value");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::set:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::value");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::set:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::type");
	add("policy-options:::format-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::set:::variable[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::required");

	add("policy-options:::map-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::defined");
	add("policy-options:::map-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::from:::defined-except");
	add("policy-options:::map-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::set");
	add("policy-options:::map-statement[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::term[ 	][ 	]*[A-Za-z0-9_\\-:][A-Za-z0-9_\\-:]*[ 	]*:::then:::query:::database:::sql");

	printHead();
	print(&root, "", false);
	printFoot();

	return 0;
}

int clear(node &n) {
	n.value.clear();
	memset(n.children, 0, sizeof(node *) * 255);
}

vector<string>	*split(string input, string separator) {
	vector<string>		*result = new vector<string>;

	string::size_type	begin = 0;
	string::size_type	end = 0;

	string				value;

	while ((end = input.find(separator, begin)) < input.size()) {
		value = input.substr(begin, end - begin);
		result->push_back(value);

		begin = end + separator.size();
	}
	if (begin < end) {
		value = input.substr(begin, end - begin);
		result->push_back(value);

		begin = end + separator.size();
	}

	return result;
}

int add(string	value) {
	vector<string>		*parts = split(value, SEPARATOR);
	string::size_type	illegal = 0;
	string::size_type	end = 0;

	node	*n = &root;
	int	c = 0;
	for (vector<string>::iterator	i = parts->begin(); i != parts->end(); ++i) {
		c = 0;
		while (n->children[c] != NULL) {
			if (i->compare(n->children[c]->value) != 0) {
				c++;
			} else {
				break;
			}
		}
		if (n->children[c] == NULL) {
			n->children[c] = new node;
			clear(*(n->children[c]));
		}
		n = n->children[c];
		n->value = *i;	


		while ((illegal = i->find(".")) < i->size()) {
			i->erase(illegal, 1);
		}
		while ((illegal = i->find("*")) < i->size()) {
			i->erase(illegal, 1);
		}
		while ((illegal = i->find("\\")) < i->size()) {
			i->erase(illegal, 1);
		}
		while ((illegal = i->find("$")) < i->size()) {
			i->erase(illegal, 1);
		}
		while ((illegal = i->find(":")) < i->size()) {
			i->erase(illegal, 1);
		}
		while ((illegal = i->find("^")) < i->size()) {
			i->erase(illegal, 1);
		}
		while ((illegal = i->find(" ")) < i->size()) {
			i->erase(illegal, 1);
		}
		while ((illegal = i->find("	")) < i->size()) {
			i->erase(illegal, 1);
		}
		while ((illegal = i->find("[")) < i->size()) {
			if ((end = i->find("]")) < i->size()) {
				i->erase(illegal, end - illegal + 1);
			}
		}
		n->c_value = *i;

		while ((illegal = i->find("-")) < i->size()) {
			i->erase(illegal, 1);
		}

		n->v_value = *i;
	}
	delete parts;
}

int print(node *n = &root, string prefix = "", bool contained = false) {
	string	subprefix;
	int		c = 0;

	if (n == &root) {
		for (int i = 0; (n->children[i]) != NULL; i++) {
			print(n->children[i], n->v_value, false);
		}
		return 0;
	}
	fprintf(stdout, "syntax match s_%s%s \"%s[ 	]*{.*$\" transparent %scontains=s_%s%s_keyword,s_%s%s_clause\n", prefix.c_str(), n->v_value.c_str(), n->value.c_str(), (contained == false) ? "" : "contained ", prefix.c_str(), n->v_value.c_str(), prefix.c_str(), n->v_value.c_str());
//	if (n->children[0] == NULL) {
		fprintf(stdout, "syntax match ss_%s%s \"%s[ 	]*[^{]*$\" transparent %scontains=s_%s%s_keyword\n", prefix.c_str(), n->v_value.c_str(), n->value.c_str(), (contained == false) ? "" : "contained ", prefix.c_str(), n->v_value.c_str());
//	}

	/* Print Clause Section */
	if (n->children[0] != NULL) {
		fprintf(stdout, "syntax region s_%s%s_clause start=\"{\" end=\"}\" transparent contained extend contains=", prefix.c_str(), n->v_value.c_str());
	} else {
		fprintf(stdout, "syntax region s_%s%s_clause start=\"{\" end=\"}\" transparent contained extend", prefix.c_str(), n->v_value.c_str());
	}
	c = 0;
	for (int i = 0; (n->children[i]) != NULL; i++) {
		if (c > 0) {
			fprintf(stdout, ",");
		}
		fprintf(stdout, "s_%s%s_%s", prefix.c_str(), n->v_value.c_str(), n->children[i]->v_value.c_str());
//		if (n->children[i]->children[0] == NULL) {
			fprintf(stdout, ",ss_%s%s_%s", prefix.c_str(), n->v_value.c_str(), n->children[i]->v_value.c_str());
//		}

		c++;
	}
	fprintf(stdout, "\n");

	/* Print Keyword Section */
	if (n->c_value.size() > 0) {
		fprintf(stdout, "syntax keyword s_%s%s_keyword contained %s\n\n", prefix.c_str(), n->v_value.c_str(), n->c_value.c_str());
	} else {
		fprintf(stdout, "syntax keyword s_%s%s_keyword contained %s\n\n", prefix.c_str(), n->v_value.c_str(), n->value.c_str());
	}

	subprefix = prefix + n->v_value + "_";
	for (int i = 0; (n->children[i]) != NULL; i++) {
		print(n->children[i], subprefix, true);
	}
	return 0;
}

int printLink(node *n = &root, string prefix = "") {
	string	subprefix;

	if (n == &root) {
		for (int i = 0; (n->children[i]) != NULL; i++) {
			printLink(n->children[i], n->value);
		}
		return 0;
	}
	if ((n->children[0]) != NULL) {
		fprintf(stdout, "   HiLink s_%s%s_keyword Keyword\n", prefix.c_str(), n->v_value.c_str());
	} else {
		fprintf(stdout, "   HiLink s_%s%s_keyword Type\n", prefix.c_str(), n->v_value.c_str());
	}

	subprefix = prefix + n->v_value + "_";
	for (int i = 0; (n->children[i]) != NULL; i++) {
		printLink(n->children[i], subprefix);
	}
	return 0;
}

int printHead() {
	fprintf(stdout, "\" Vim syntax file\n");
	fprintf(stdout, "\" $Id: main.cxx,v 1.9 2006/01/21 23:21:47 bill Exp $\n");
	fprintf(stdout, "\" Language: SellaNMS Configuration\n");
	fprintf(stdout, "\" Maintainer:  mkvim (auto-generated)\n");
	fprintf(stdout, "\" Last Change: 2005 April 30\n");
	fprintf(stdout, "\n");
	fprintf(stdout, "\" For version 5.x: Clear all syntax items\n");
	fprintf(stdout, "\" For version 6.x: Quit when a syntax file was already loaded\n");
	fprintf(stdout, "\n");
	fprintf(stdout, "if version < 600\n");
	fprintf(stdout, "   syntax clear\n");
	fprintf(stdout, "elseif exists(\"b:current_syntax\")\n");
	fprintf(stdout, "   finish\n");
	fprintf(stdout, "endif\n");
	fprintf(stdout, "\n");
	fprintf(stdout, "syntax case match\n");
	fprintf(stdout, "syntax sync fromstart\n");
	fprintf(stdout, "\n");
	fprintf(stdout, "setlocal iskeyword+=-\n");
	fprintf(stdout, "\n");
	fprintf(stdout, "syntax region s_comment_cpp start=\"//\" end=\"$\" containedin=ALL keepend extend\n");
	fprintf(stdout, "syntax region s_comment_sql start=\"--\" end=\"$\" containedin=ALL keepend extend\n");
	fprintf(stdout, "syntax region s_comment_shell start=\"#\"  end=\"$\" containedin=ALL keepend extend contains=s_include\n");
	fprintf(stdout, "syntax region s_comment_c start=\"/\\*\" end=\"\\*/\" containedin=ALL keepend extend\n");
	fprintf(stdout, "\n");
	fprintf(stdout, "syntax region s_included start=\"\\\"\" end=\"\\\"\" display contained\n");
	fprintf(stdout, "syntax match s_include \"^\\s*#\\s*include\\>\\s*[\"<]\" display contained contains=s_included\n");
	fprintf(stdout, "\n");
	fprintf(stdout, "syntax region s_string start=+\"+ end=+\"+ containedin=ALL keepend\n");
	fprintf(stdout, "syntax region s_variable start=+@+ end=+@+ containedin=ALL oneline keepend\n");
	fprintf(stdout, "syntax match s_snmpcolon \"snmp:\" containedin=ALL\n");
	fprintf(stdout, "syntax match s_disable \"disable\" containedin=ALL\n");
	fprintf(stdout, "\n");
}

int printFoot() {
	fprintf(stdout, "if version >= 508 || !exists(\"did_c_syn_inits\")\n");
	fprintf(stdout, "   if version < 508\n");
	fprintf(stdout, "      let did_c_syn_inits = 1\n");
	fprintf(stdout, "      command -nargs=+ HiLink hi link <args>\n");
	fprintf(stdout, "   else\n");
	fprintf(stdout, "      command -nargs=+ HiLink hi def link <args>\n");
	fprintf(stdout, "   endif\n");
	fprintf(stdout, "   \n");
	fprintf(stdout, "   HiLink s_comment_cpp Comment\n");
	fprintf(stdout, "   HiLink s_comment_sql Comment\n");
	fprintf(stdout, "   HiLink s_comment_shell Comment\n");
	fprintf(stdout, "   HiLink s_comment_c Comment\n");
	fprintf(stdout, "   HiLink s_include Include\n");
	fprintf(stdout, "   HiLink s_string String\n");
	fprintf(stdout, "   HiLink s_variable Operator\n");
	fprintf(stdout, "   HiLink s_snmpcolon Identifier\n");
	fprintf(stdout, "   HiLink s_disable Error\n");
	fprintf(stdout, "   \n");

	printLink();	

	fprintf(stdout, "   \n");
	fprintf(stdout, "   delcommand HiLink\n");
	fprintf(stdout, "endif\n");
	fprintf(stdout, "   \n");
	fprintf(stdout, "let b:current_syntax = \"sella_nms\"\n");
}

