/* -------------------------------------------------------------------------- */
/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org)             */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

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

#include "template_syntax.h"
#include "mem_collector.h"

#define YY_NO_INPUT 

#define YY_DECL int template_lex (YYSTYPE *lvalp, YYLTYPE *llocp, \
                                  mem_collector *mc)

#define YY_USER_ACTION  llocp->first_line = yylineno;   \
                        llocp->first_column = llocp->last_column;   \
                        llocp->last_column += yyleng;
%}

%option nounput
%option prefix="template_"
%option outfile="template_parser.c"
%option yylineno

%x VALUE

STRING [^=#[:blank:]\n,\[\]]+
%%

 /* ------------------------------------------------------------------------- */
 /* Comments (lines with an starting #), and empty lines                      */
 /* ------------------------------------------------------------------------- */
[[:blank:]]*#.*\n  ;
[[:blank:]\n]+    ;

 /* ------------------------------------------------------------------------- */
 /* Variable: Alpha numeric charatcers and '_'                                */
 /* ------------------------------------------------------------------------- */
[[:alnum:]_]+  { lvalp->val_str = mem_collector_strdup(mc,yytext);
                 return VARIABLE; }

 /* ------------------------------------------------------------------------ */
 /* TOKENS                                                                   */
 /* Single attribute (VARIABLE = VALUE, also empty VAIABLE=)                */
 /* Vector attributes (VARIABLE = [ ATTR1 = VAL1, ATTR2 = VAL2 ])            */
 /* ------------------------------------------------------------------------ */
[[:blank:]]*=[[:blank:]]*           { BEGIN VALUE; return EQUAL;}

[[:blank:]]*=[[:blank:]]*\n         { return EQUAL_EMPTY;}

[[:blank:]\n]*,[[:blank:]\n]*       { return COMMA;}

[[:blank:]\n]*\][[:blank:]\n]*      { return CBRACKET;}

<VALUE>[[:blank:]]*\[[[:blank:]\n]* { BEGIN(INITIAL); return OBRACKET;}

 /* ------------------------------------------------------------------------ */
 /* Attribute values                                                         */
 /*   - String in double quoted form                                         */
 /*   - Anything but  =,][# and blanks                                       */
 /* ------------------------------------------------------------------------ */
<VALUE>\"([^\"]|"\\\"")+\" { lvalp->val_str = mem_collector_strdup(mc,yytext+1);
                             lvalp->val_str[yyleng-2] = '\0';
                             BEGIN(INITIAL); return STRING; }

 /*
<VALUE>'[^']+'    { lvalp->val_str = strdup(yytext+1);
                    lvalp->val_str[yyleng-2] = '\0';
                    BEGIN(INITIAL); return STRING; }
 */
<VALUE>{STRING}   { lvalp->val_str = mem_collector_strdup(mc,yytext);
                    BEGIN(INITIAL); return STRING;}
%%

int template_wrap()
{
    return 1;
}
