%{
#include <stdio.h>
#include <stdlib.h>

%}

%option noyywrap

%x DQNAME
%x NAME_OR_PREFIX
%x APPNAME
%x GRPCLOSED

space			[ \t\n\r\f]
whitespace		{space}+

dquote            \"
app_name_chars    [\x21-\x27\x2a\x2b\x2d-\x5a\x5c\x5e-\x7a\x7c\x7e]
app_name_indq_chars [\x20\x21\x23-\x7e]
app_name    {app_name_chars}+
app_name_dq ({app_name_indq_chars}|{dquote}{dquote})+
delimiter         {whitespace}*,{whitespace}*
app_name_start {app_name_chars}
any_app \*|({dquote}\*{dquote})
xdstart {dquote}
xdstop  {dquote}
openlist [\[\(]
prefix [0-9]+{whitespace}*{openlist}
closelist [\]\)]
%%
{xdstart} { BEGIN(DQNAME); }
<DQNAME>{xdstop} { BEGIN(INITIAL); }
<DQNAME>{app_name_dq} {
  appname *name = (appname *)malloc(sizeof(appname));
  int i, j;

  for (i = j = 0 ; j < 63 && yytext[i] ; i++, j++)
  {
    if (yytext[i] == '"')
    {
		if (yytext[i+1] == '"')
			name->str[j] = '"';
		else
			fprintf(stderr, "illegal quote escape\n");
		i++;
	}
    else
		name->str[j] = yytext[i];

  }
  name->str[j] = 0;
  name->quoted = 1;

  yylval.name = name;
  return NAME;
}
{app_name_start} { BEGIN(NAME_OR_PREFIX); yyless(0);}
<NAME_OR_PREFIX>{app_name} {
    appname *name = (appname *)malloc(sizeof(appname));
	char *p;

    name->quoted = 0;
	strncpy(name->str, yytext, 63);
	name->str[63] = 0;
	for (p = name->str ; *p ; p++)
	{
		if (*p >= 'A' && *p <= 'Z')
			*p = *p + ('a' - 'A');
	}
	yylval.name = name;
	BEGIN(INITIAL);
	return NAME;
}
<NAME_OR_PREFIX>{prefix} {
	static char prefix[16];
	int i, l;

	/* find the last digit */
	for (l = 0 ; l < 16 && isdigit(yytext[l]) ; l++);
	if (l > 15)
		fprintf(stderr, "too long prefix number for lists\n");
	for (i = 0 ; i < l ; i++)
		prefix[i] = yytext[i];
	prefix[i] = 0;
	yylval.str = strdup(prefix);

    /* prefix ends with a left brace or paren, so go backward by 1
       char for further readin */

	yyless(yyleng - 1);
    BEGIN(INITIAL);
	return PREFIX;
}
<GRPCLOSED>{whitespace}*. {
	BEGIN(INITIAL);
	if (yytext[yyleng - 1] == ':')
		return yytext[yyleng - 1];
	yyless(0);
}
{delimiter} { return DELIMITER;}
{openlist} {
	yylval.character = yytext[0];
	return OPENLIST;	
}
{closelist} { 
	BEGIN(GRPCLOSED);
	yylval.character = yytext[0];
	return CLOSELIST;	
}

%%

//int main(void)
//{
//	int r;
//
//	while(r = yylex()) {
//	fprintf(stderr, "#%d:(%s)#", r, yylval.str);
//	yylval.str = "";
//    }
//}