%{
    #include "parser.p"
%}    

%token USERS LINE IDENTIFIER DESTINATIONS NUMBER DIRECT EXTRA USING
        PATH MGETTYCONFIG MODEMBASE LOGIN EMAIL PANICLOG LOGFILE
        EMAIL RETRY SHOWNUMS CALL LOG ON DEFAULT OFF MAX MAXTIME
        MODE CALLBACK DIALIN NODESTINATIONS DIALLOG TTYNR

%%

input:
    MODE
    colon
    modetype

modetype:
    callback
    defaultlist
    destinationsection
    usersection
|
    dialin
    defaultlist
;

callback:
    CALLBACK
    {
        setmode(mode_callback);
    }
;

dialin:
    DIALIN
    {
        setmode(mode_dialin);
    }
;

defaultlist:
    defaults
    {
        checkconfig();  /* check the configuration of the setup file */
    }
;

defaults:
    defaults 
    default
|
    default                     /* at least one default (line) needed */
;

default:
    linesection
|
    pathsection
|
    gettydefault
|
    modembase
|
    retry
|
    maxage
|
    shownums
|
    paniclog
|
    logfile
|
    diallogfile
|
    email
|
    login
|
    call
|
    logtype
|
    showextra
|
    showdirect
|
    nodestinations
|
    error
;

call:
    CALL
    {
        if (getmode() != mode_callback)
            yysemantic("'call' only valid for mode callback");
        setcall();
    }
;
    
logtype:
    LOG
    colon
    logvalue
;

logvalue:
    on_off
    {
        setlog((LOG_TYPE_)$1);
    }
|
    DEFAULT
    {
        setlog(log_default);
    }
|
    MAX
    {
        setlog(log_max);
    }
|
    {
        expect = "log type (on, off, or default)";
    }
    error
;

on_off:
    ON
    {
        $$ = (int)log_on;
    }
|
    OFF
    {
        $$ = (int)log_off;
    }
;

login:
    login_keyword
    colon
    loginprog
;

login_keyword:
    LOGIN
    {
        if (getmode() != mode_callback)
            yysemantic("'login: ...' only valid for mode callback");
    }
;

loginprog:
    IDENTIFIER
    {
        setloginprogram(yytext);
        expect = "default setting or 'destinations'";
    }
|
    {
        expect = "login programname";
    }
    error
;

email:
    EMAIL
    colon
    address
;

address:
    IDENTIFIER
    {
        setemailaddress(yytext);
        expect = "default setting or 'destinations'";
    }
|
    {
        expect = "e-mail address";
    }
    error
;

diallogfile:
    DIALLOG
    colon
    diallog
;

diallog:
    IDENTIFIER
    {
        setdiallogfilename(yytext);
        expect = "default setting or 'destinations'";
    }
|
    {
        expect = "dial-logfilename";
    }
    error
;

logfile:
    LOGFILE
    colon
    log
;

log:
    IDENTIFIER
    {
        setlogfilename(yytext);
        expect = "default setting or 'destinations'";
    }
|
    {
        expect = "logfilename";
    }
    error
;

paniclog:
    PANICLOG
    colon
    panic
;

panic:
    IDENTIFIER
    {
        setpanicfilename(yytext);
        expect = "default setting or 'destinations'";
    }
|
    {
        expect = "panic-logfilename";
    }
    error
;

showextra:
    EXTRA
    {
        showextra();
    };

showdirect:
    DIRECT
    {
        showdirect();
    };

nodestinations:
    NODESTINATIONS
    {
        hidedestinations();
    };

shownums:
    SHOWNUMS
    {
        if (getmode() != mode_callback)
            yysemantic("'phonenumbers' only valid for mode callback");
        showphonenumbers();
    };

retry:
    RETRY
    {
        if (getmode() != mode_callback)
            yysemantic("'retry' only valid for mode callback");
    }
    colon
    nretries;

nretries:
    NUMBER
    {
        setntries(yytext);
        expect = "default setting or 'destinations'";
    }
|
    {
        expect = "Maximum callback retries expected";
    }
    error
;
    
maxage:
    MAXTIME
    {
        if (getmode() != mode_callback)
            yysemantic("'maxtime' only valid for mode callback");
    }
    colon
    maxtime;

maxtime:
    NUMBER
    {
        set_maxage(yytext);
        expect = "default setting or 'destinations'";
    }
|
    {
        expect = "Maximum callback time expected";
    }
    error
;
    
modembase:
    MODEMBASE
    colon
    modem
;

modem:
    IDENTIFIER
    {
        setmodembase(yytext);
        expect = "default setting or 'destinations'";
    }
|
    {
        expect = "modem_getty specification";
    }
    error
;

gettydefault:
    MGETTYCONFIG
    colon
    mgetty
;

mgetty:
    IDENTIFIER
    {
        setmgettypath(yytext);
        expect = "default setting or 'destinations'";
    }
|
    {
        expect = "getty-configuration filename";
    }
    error
;


linesection:
    LINE
    colon
    {
        expect = "ttyS<nr> line";
    }
    ttylines
;


ttylines:
    ttylines
    ttyline
|
    ttyline
;

ttyline:
    TTYNR
    {
        settyline(yytext);
        expect = "ttyS<nr> line or 'destinations'";
    }
/*
|
    error
*/
;

pathsection:
    PATH
    colon
    pathname
;

pathname:
    IDENTIFIER
    {
        setbase(yytext);
        expect = "default setting or 'destinations'";
    }
|
    {
        expect = "Callback path";
    }
    error
;

usersection:
    USERS
    colon
    users
;

users:
    users
    user
|
    user
;    

user:
    username
    colon
    grouplist
|
    {
        expect = "username";
    }
    error
;

username:
    IDENTIFIER
    {
        define_user(yytext);
    }
;

grouplist:
    grouplist
    {
        expect = "','";
    }
    ','
    group
|
    group
;    

group:
    IDENTIFIER
    {
        addgroup(yytext);
    }
|
    {
        expect = "groupname";
    }
    error
;

destinationsection:
    DESTINATIONS
    colon
    destinations
;

destinations:
    destinations
    destination
|
    destination
;    

destination:
    dgroup
    {
        expect = "earlier 'using' or ':'";
    }
    ':'
    dname
    dphone
;

dgroup:
    IDENTIFIER
    {
        define_dest(yytext);
    }
|
    {
        expect = "dest. name";
    }
    error
;

dname:    
    IDENTIFIER
    {
        set_dname(yytext);
    }
|
    {
        expect = "destination name";
    }
    error
;

dphone:
    DIRECT
    {
        set_cbmode(direct_mode);
    }
|
    EXTRA
    {
        set_cbmode(extra_mode);
    }
|
    phone_number
|
    {
        expect = "'direct', 'extra', or phonenumber";
    }
    error
;

phone_number:
    NUMBER
    {
        set_phone(yytext);
        expect = "'using' or groupname";
    }
    opt_file
;


opt_file:
    USING
    filename
|
   /*  empty */
;    

filename:
    IDENTIFIER
    {
        set_file(yytext);
    }
|
    {
        expect = "filename";
    }
    error
;

colon:
    {
        expect = "':'";
    }
    ':'
;
