sync/gen_statemachine.ysl2
author Volker Birk <vb@pep.foundation>
Sun, 31 Jul 2016 19:38:23 +0200
branchkeysync
changeset 951 dec407deb10e
parent 939 ed7dfdae3031
child 952 986fd7b2eb8f
permissions -rw-r--r--
...
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 {
vb@623
    10
    include ./functions.ysl2
Edouard@605
    11
vb@811
    12
    template "/protocol" {
vb@811
    13
        document "../src/Makefile.protocols", "text"
vb@811
    14
            apply "fsm", 0, mode="make";
vb@811
    15
        apply "fsm", 0, mode=gen;
vb@811
    16
    }
vb@811
    17
vb@811
    18
    template "fsm", mode=make
vb@811
    19
    ||
vb@811
    20
    «@filename»_fsm.c: ../sync/devicegroup.fsm
vb@811
    21
    \tmake -C ../«@filename»
vb@811
    22
    ||
vb@811
    23
vb@811
    24
    template "fsm", mode=gen {
vb@807
    25
        document "../src/{@filename}_fsm.h", "text" {
vb@609
    26
        ||
vb@609
    27
        #pragma once
vb@577
    28
vb@609
    29
        // state machine for «@name»
vb@577
    30
vb@609
    31
        #include "pEpEngine.h"
vb@951
    32
        #include "../asn.1/«../@name»-Protocol.h"
vb@654
    33
        
vb@654
    34
        #ifdef __cplusplus
vb@654
    35
        extern "C" {
vb@654
    36
        #endif
vb@608
    37
vb@609
    38
        // types
Edouard@605
    39
vb@609
    40
        typedef pEp_identity * Identity;
vb@939
    41
        typedef stringlist_t * Stringlist;
vb@939
    42
        typedef union _param { Identity partner; stringlist_t *keylist; } param_t;
vb@583
    43
vb@609
    44
        // error values
vb@577
    45
vb@609
    46
        typedef enum _fsm_error {
vb@743
    47
            invalid_state = -2,
vb@743
    48
            invalid_event = -3
vb@609
    49
        } fsm_error;
vb@583
    50
vb@951
    51
        // conditions
vb@951
    52
vb@951
    53
        `` for "func:distinctName(condition)" | bool «@name»(PEP_SESSION session`apply "parm", 0`);
vb@951
    54
vb@609
    55
        // states
vb@578
    56
vb@609
    57
        typedef enum _«@name»_state {
vb@951
    58
            «@name»_state_NONE = 0,
vb@623
    59
        `` for "func:distinctName(state)" |> «@name»`if "position()!=last()" > , `
vb@609
    60
        } «@name»_state;
vb@583
    61
vb@609
    62
        // events
vb@578
    63
vb@609
    64
        typedef enum _«@name»_event {
vb@951
    65
            «@name»_event_NONE = 0,
vb@711
    66
        ||
vb@711
    67
        for "func:distinctName(state/event[not(not(/protocol/fsm/tag/@name=@name))])" {
vb@711
    68
            const "name", "@name";
vb@711
    69
            |> «$name» = «/protocol/fsm/tag[@name=$name]/@id»,
vb@711
    70
        }
vb@711
    71
        for "func:distinctName(state/event[not(/protocol/fsm/tag/@name=@name)])"
vb@711
    72
            |> «@name»`if "position()!=last()" > , `
vb@711
    73
        ||
vb@609
    74
        } «@name»_event;
vb@583
    75
vb@609
    76
        // actions
vb@582
    77
vb@690
    78
        `` const "name", "@name"
vb@939
    79
        `` for "func:distinctName(//action)" | PEP_STATUS «@name»(PEP_SESSION session, «$name»_state state, Identity partner, void *extra);
Edouard@605
    80
vb@951
    81
        // message receiver
vb@951
    82
        
vb@951
    83
        PEP_STATUS receive_«@name»_msg(PEP_SESSION session, «../@name»_Protocol_t *msg);
vb@951
    84
vb@626
    85
        // state machine
vb@626
    86
vb@626
    87
        «@name»_state fsm_«@name»(
vb@627
    88
                PEP_SESSION session,
vb@626
    89
                «@name»_state state,
vb@626
    90
                «@name»_event event,
vb@939
    91
                Identity partner,
vb@951
    92
                void *extra
vb@626
    93
            );
vb@626
    94
vb@609
    95
        // driver
Edouard@605
    96
vb@782
    97
        DYNAMIC_API PEP_STATUS fsm_«@name»_inject(
vb@690
    98
                PEP_SESSION session,
vb@690
    99
                «@name»_event event,
vb@690
   100
                Identity partner,
vb@951
   101
                void *extra
vb@690
   102
            );
Edouard@605
   103
vb@654
   104
        #ifdef __cplusplus
vb@654
   105
        }
vb@654
   106
        #endif
vb@654
   107
vb@609
   108
        ||
vb@711
   109
        }
vb@807
   110
        document "../src/{@filename}_driver.c", "text"
vb@690
   111
        ||
vb@690
   112
        // Driver for «@name» state machine
vb@690
   113
vb@690
   114
        #include <assert.h>
vb@690
   115
        #include "pEp_internal.h"
vb@690
   116
vb@690
   117
vb@743
   118
        DYNAMIC_API PEP_STATUS fsm_«@name»_inject(
vb@690
   119
                PEP_SESSION session,
vb@690
   120
                «@name»_event event,
vb@690
   121
                Identity partner,
vb@951
   122
                void *extra
vb@690
   123
            )
vb@690
   124
        {
vb@951
   125
            assert(session);
vb@951
   126
            if (!session)
vb@951
   127
                return PEP_ILLEGAL_VALUE;
vb@690
   128
vb@807
   129
            session->«@filename»_state = fsm_«@name»(session, session->«@filename»_state,
vb@951
   130
                    event, partner, extra);
vb@690
   131
vb@951
   132
            return PEP_STATUS_OK;
vb@690
   133
        }
vb@690
   134
vb@690
   135
        ||
vb@807
   136
        document "../src/{@filename}_fsm.c", "text"
vb@609
   137
        ||
vb@807
   138
        #include "«@filename»_fsm.h"
vb@609
   139
vb@609
   140
        // state machine for «@name»
vb@609
   141
vb@609
   142
        «@name»_state fsm_«@name»(
vb@627
   143
                PEP_SESSION session,
vb@609
   144
                «@name»_state state,
vb@609
   145
                «@name»_event event,
vb@939
   146
                Identity partner,
vb@951
   147
                void *extra
vb@609
   148
            )
vb@609
   149
        {
vb@609
   150
            switch (state) {
vb@951
   151
            `` apply "state", 2
vb@609
   152
                default:
vb@743
   153
                    return («@name»_state) invalid_state;
vb@609
   154
            }
vb@609
   155
vb@609
   156
            return state;
vb@577
   157
        }
vb@582
   158
vb@609
   159
        ||
vb@577
   160
    }
vb@577
   161
vb@580
   162
    template "state"
vb@577
   163
    ||
vb@577
   164
    case «@name»:
vb@578
   165
        switch (event) {
vb@578
   166
        `` apply "event", 2
vb@951
   167
            default:
vb@951
   168
                return («../@name»_state) invalid_event;
vb@578
   169
        }
vb@577
   170
        break;
vb@577
   171
vb@577
   172
    ||
vb@578
   173
vb@578
   174
    template "event"
vb@578
   175
    ||
vb@578
   176
    case «@name»:
vb@951
   177
    `` apply "action|transition|condition";
vb@582
   178
    `` if "name(*[position()=last()]) != 'transition'" |> break;
vb@578
   179
    ||
vb@578
   180
vb@582
   181
    template "action" {
vb@582
   182
        indent(0);
vb@690
   183
        > «@name»(session, state, 
vb@582
   184
        choose {
vb@582
   185
            when "parm" > «name(parm/*)»
vb@582
   186
            otherwise > NULL
vb@582
   187
        }
vb@939
   188
        > , NULL);\n
vb@582
   189
    }
vb@582
   190
vb@951
   191
    template "condition" {
vb@951
   192
        | if («@name»(session`apply "parm", 0`)) {
vb@951
   193
        apply "action|transition|condition";
vb@951
   194
        | }
vb@951
   195
    }
vb@951
   196
vb@951
   197
    template "parm" choose {
vb@951
   198
        when "count(*) = 1"
vb@951
   199
            > , «name(*)»
vb@951
   200
        otherwise
vb@951
   201
            > , «name(*[1])» «name(*[2])»
vb@951
   202
    }
vb@951
   203
vb@578
   204
    template "transition" | return «@target»;
vb@577
   205
}
vb@577
   206