sync/gen_statemachine.ysl2
author Volker Birk <vb@pep-project.org>
Thu, 12 May 2016 10:45:54 +0200
changeset 608 3bf69b382303
parent 605 70e80b27b624
child 609 a22a400611ca
permissions -rw-r--r--
types fix
vb@577
     1
// generate state machine code
vb@577
     2
vb@577
     3
// Copyleft (c) 2016, p≡p foundation
vb@577
     4
vb@577
     5
// Written by Volker Birk
vb@577
     6
vb@577
     7
include yslt.yml2
vb@577
     8
vb@577
     9
tstylesheet {
Edouard@605
    10
Edouard@605
    11
    key "ActionByNames", "/protocol/fsm/state/event//action", "@name";
Edouard@605
    12
    variable "UniqueActions", "/protocol/fsm/state/event//action[generate-id()=generate-id(key('ActionByNames',@name)[1])]";
Edouard@605
    13
vb@577
    14
    template "/protocol/fsm"
vb@577
    15
    ||
vb@577
    16
    // state machine for «@name»
vb@577
    17
vb@577
    18
    #include "pEpEngine.h"
vb@577
    19
vb@608
    20
    // types
vb@608
    21
vb@608
    22
    typedef pEp_identity * Identity;
vb@608
    23
    typedef union _param { const Identity partner; const stringlist_t *keylist; } param_t;
Edouard@605
    24
vb@583
    25
    // error values
vb@583
    26
vb@578
    27
    typedef enum _fsm_error {
vb@578
    28
        invalid_state = -1,
vb@578
    29
        invalid_event = -2
vb@578
    30
    } fsm_error;
vb@577
    31
vb@583
    32
    // states
vb@583
    33
vb@578
    34
    typedef enum _«@name»_state {
vb@580
    35
    `` for "set:distinct(state/@name)" |> «.»`if "position()!=last()" > , `
vb@578
    36
    } «@name»_state;
vb@578
    37
vb@583
    38
    // events
vb@583
    39
vb@578
    40
    typedef enum _«@name»_event {
vb@580
    41
    `` for "set:distinct(state/event/@name)" |> «.»`if "position()!=last()" > , `
vb@578
    42
    } «@name»_event;
vb@578
    43
vb@583
    44
    // actions
vb@583
    45
vb@608
    46
    `` for "set:distinct(state/event//action/@name)" | void «.»(const Identity partner);
vb@582
    47
Edouard@605
    48
    // decoders
Edouard@605
    49
Edouard@605
    50
    `` apply "$UniqueActions[starts-with(@name,'send')]",0 mode="proto" with "pfx", "'decode'"
Edouard@605
    51
Edouard@605
    52
    // encoders 
Edouard@605
    53
Edouard@605
    54
    `` apply "$UniqueActions[starts-with(@name,'send')]",0 mode="proto" with "pfx", "'encode'"
Edouard@605
    55
vb@583
    56
    // state machine
vb@583
    57
vb@582
    58
    «@name»_state fsm_«@name»(
vb@582
    59
            «@name»_state state,
vb@582
    60
            «@name»_event event,
vb@608
    61
            const Identity partner
vb@582
    62
        )
vb@577
    63
    {
vb@577
    64
        switch (state) {
vb@580
    65
            `` apply "state"
vb@578
    66
            default:
vb@578
    67
                return invalid_state;
vb@577
    68
        }
vb@582
    69
vb@582
    70
        return state;
vb@577
    71
    }
vb@577
    72
vb@577
    73
    ||
vb@577
    74
vb@580
    75
    template "state"
vb@577
    76
    ||
vb@577
    77
    case «@name»:
vb@578
    78
        switch (event) {
vb@578
    79
        `` apply "event", 2
vb@578
    80
        default:
vb@578
    81
            return invalid_event;
vb@578
    82
        }
vb@577
    83
        break;
vb@577
    84
vb@577
    85
    ||
vb@578
    86
vb@578
    87
    template "event"
vb@578
    88
    ||
vb@578
    89
    case «@name»:
vb@578
    90
    `` apply "action|transition";
vb@582
    91
    `` if "name(*[position()=last()]) != 'transition'" |> break;
vb@578
    92
    ||
vb@578
    93
vb@582
    94
    template "action" {
vb@582
    95
        indent(0);
vb@582
    96
        > «@name»(
vb@582
    97
        choose {
vb@582
    98
            when "parm" > «name(parm/*)»
vb@582
    99
            otherwise > NULL
vb@582
   100
        }
vb@582
   101
        > );\n
vb@582
   102
    }
vb@582
   103
Edouard@605
   104
    def "xsl:typeOfActionParam" {
Edouard@605
   105
        param "n", "name(.)";
Edouard@605
   106
        result "name(ancestor::event/child::parm[child::*[position()=2 and name(.)=$n]]/child::*[position()=1])";
Edouard@605
   107
    }
Edouard@605
   108
Edouard@605
   109
    template "action", mode="proto" {
Edouard@605
   110
        param "pfx";
Edouard@605
   111
        > void «$pfx»«substring-after(@name, 'send')»(
Edouard@605
   112
        if "count(parm/*) = 0"
Edouard@605
   113
            > void
Edouard@605
   114
        for "set:distinct(parm/*)" {
Edouard@605
   115
            > «xsl:typeOfActionParam()» «name(.)»
Edouard@605
   116
            if "position() != last()" > ,
Edouard@605
   117
        }
Edouard@605
   118
        | );
Edouard@605
   119
    }
Edouard@605
   120
vb@578
   121
    template "transition" | return «@target»;
vb@577
   122
}
vb@577
   123