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