sync/gen_statemachine.ysl2
author Volker Birk <vb@pep.foundation>
Mon, 08 Aug 2016 17:32:51 +0200
branchkeysync
changeset 985 087d5d60c082
parent 964 ef02296c41ca
child 1043 f786ee22e281
permissions -rw-r--r--
moving #include and installing headers
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@952
    32
        #include "message.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@964
    47
            // these error values are corresponding to
vb@964
    48
            // PEP_SYNC_STATEMACHINE_ERROR - value
vb@743
    49
            invalid_state = -2,
vb@959
    50
            invalid_event = -3,
vb@959
    51
            invalid_condition = -4,
vb@964
    52
            invalid_action = -5,
vb@964
    53
vb@964
    54
            // out of memory condition
vb@964
    55
            invalid_out_of_memory = -128
vb@609
    56
        } fsm_error;
vb@583
    57
vb@951
    58
        // conditions
vb@951
    59
vb@959
    60
        `` for "func:distinctName(condition)" | int «@name»(PEP_SESSION session`apply "parm", 0`);
vb@951
    61
vb@609
    62
        // states
vb@578
    63
vb@609
    64
        typedef enum _«@name»_state {
vb@951
    65
            «@name»_state_NONE = 0,
vb@623
    66
        `` for "func:distinctName(state)" |> «@name»`if "position()!=last()" > , `
vb@609
    67
        } «@name»_state;
vb@583
    68
vb@609
    69
        // events
vb@578
    70
vb@609
    71
        typedef enum _«@name»_event {
vb@951
    72
            «@name»_event_NONE = 0,
vb@711
    73
        ||
vb@711
    74
        for "func:distinctName(state/event[not(not(/protocol/fsm/tag/@name=@name))])" {
vb@711
    75
            const "name", "@name";
vb@711
    76
            |> «$name» = «/protocol/fsm/tag[@name=$name]/@id»,
vb@711
    77
        }
vb@711
    78
        for "func:distinctName(state/event[not(/protocol/fsm/tag/@name=@name)])"
vb@711
    79
            |> «@name»`if "position()!=last()" > , `
vb@711
    80
        ||
vb@609
    81
        } «@name»_event;
vb@583
    82
vb@609
    83
        // actions
vb@582
    84
vb@690
    85
        `` const "name", "@name"
vb@939
    86
        `` for "func:distinctName(//action)" | PEP_STATUS «@name»(PEP_SESSION session, «$name»_state state, Identity partner, void *extra);
Edouard@605
    87
vb@951
    88
        // message receiver
vb@951
    89
        
vb@952
    90
        PEP_STATUS receive_«@name»_msg(PEP_SESSION session, message *msg);
vb@951
    91
vb@626
    92
        // state machine
vb@626
    93
vb@626
    94
        «@name»_state fsm_«@name»(
vb@627
    95
                PEP_SESSION session,
vb@626
    96
                «@name»_state state,
vb@626
    97
                «@name»_event event,
vb@939
    98
                Identity partner,
vb@951
    99
                void *extra
vb@626
   100
            );
vb@626
   101
vb@609
   102
        // driver
Edouard@605
   103
vb@782
   104
        DYNAMIC_API PEP_STATUS fsm_«@name»_inject(
vb@690
   105
                PEP_SESSION session,
vb@690
   106
                «@name»_event event,
vb@690
   107
                Identity partner,
vb@951
   108
                void *extra
vb@690
   109
            );
Edouard@605
   110
vb@654
   111
        #ifdef __cplusplus
vb@654
   112
        }
vb@654
   113
        #endif
vb@654
   114
vb@609
   115
        ||
vb@711
   116
        }
vb@807
   117
        document "../src/{@filename}_driver.c", "text"
vb@690
   118
        ||
vb@690
   119
        // Driver for «@name» state machine
vb@690
   120
vb@690
   121
        #include <assert.h>
vb@690
   122
        #include "pEp_internal.h"
vb@690
   123
vb@690
   124
vb@743
   125
        DYNAMIC_API PEP_STATUS fsm_«@name»_inject(
vb@690
   126
                PEP_SESSION session,
vb@690
   127
                «@name»_event event,
vb@690
   128
                Identity partner,
vb@951
   129
                void *extra
vb@690
   130
            )
vb@690
   131
        {
vb@951
   132
            assert(session);
vb@951
   133
            if (!session)
vb@951
   134
                return PEP_ILLEGAL_VALUE;
vb@690
   135
vb@964
   136
            «@name»_state state = fsm_«@name»(session,
vb@964
   137
                    session->«@filename»_state, event, partner, extra);
vb@964
   138
            if (state == invalid_out_of_memory)
vb@964
   139
                return PEP_OUT_OF_MEMORY;
vb@964
   140
            if (state < 0)
vb@964
   141
                return PEP_SYNC_STATEMACHINE_ERROR - state;
vb@690
   142
vb@964
   143
            session->«@filename»_state = state;
vb@951
   144
            return PEP_STATUS_OK;
vb@690
   145
        }
vb@690
   146
vb@690
   147
        ||
vb@807
   148
        document "../src/{@filename}_fsm.c", "text"
vb@609
   149
        ||
vb@807
   150
        #include "«@filename»_fsm.h"
vb@609
   151
vb@609
   152
        // state machine for «@name»
vb@609
   153
vb@609
   154
        «@name»_state fsm_«@name»(
vb@627
   155
                PEP_SESSION session,
vb@609
   156
                «@name»_state state,
vb@609
   157
                «@name»_event event,
vb@939
   158
                Identity partner,
vb@951
   159
                void *extra
vb@609
   160
            )
vb@609
   161
        {
vb@964
   162
            int cond_result;
vb@959
   163
            PEP_STATUS status = PEP_STATUS_OK;
vb@959
   164
vb@609
   165
            switch (state) {
vb@951
   166
            `` apply "state", 2
vb@609
   167
                default:
vb@743
   168
                    return («@name»_state) invalid_state;
vb@609
   169
            }
vb@609
   170
vb@609
   171
            return state;
vb@577
   172
        }
vb@582
   173
vb@609
   174
        ||
vb@577
   175
    }
vb@577
   176
vb@580
   177
    template "state"
vb@577
   178
    ||
vb@577
   179
    case «@name»:
vb@578
   180
        switch (event) {
vb@578
   181
        `` apply "event", 2
vb@951
   182
            default:
vb@951
   183
                return («../@name»_state) invalid_event;
vb@578
   184
        }
vb@577
   185
        break;
vb@577
   186
vb@577
   187
    ||
vb@578
   188
vb@578
   189
    template "event"
vb@578
   190
    ||
vb@578
   191
    case «@name»:
vb@951
   192
    `` apply "action|transition|condition";
vb@582
   193
    `` if "name(*[position()=last()]) != 'transition'" |> break;
vb@578
   194
    ||
vb@578
   195
vb@582
   196
    template "action" {
vb@582
   197
        indent(0);
vb@959
   198
        > status = «@name»(session, state, 
vb@582
   199
        choose {
vb@582
   200
            when "parm" > «name(parm/*)»
vb@582
   201
            otherwise > NULL
vb@582
   202
        }
vb@939
   203
        > , NULL);\n
vb@964
   204
        | if (status == PEP_OUT_OF_MEMORY)
vb@964
   205
        |> return invalid_out_of_memory;
vb@959
   206
        | if (status != PEP_STATUS_OK)
vb@959
   207
        |> return invalid_action;
vb@582
   208
    }
vb@582
   209
vb@951
   210
    template "condition" {
vb@959
   211
        | cond_result = «@name»(session`apply "parm", 0`);
vb@964
   212
        | if (cond_result < 0)
vb@964
   213
        |> return cond_result;
vb@959
   214
        | if (cond_result) {
vb@951
   215
        apply "action|transition|condition";
vb@951
   216
        | }
vb@951
   217
    }
vb@951
   218
vb@951
   219
    template "parm" choose {
vb@951
   220
        when "count(*) = 1"
vb@951
   221
            > , «name(*)»
vb@951
   222
        otherwise
vb@951
   223
            > , «name(*[1])» «name(*[2])»
vb@951
   224
    }
vb@951
   225
vb@578
   226
    template "transition" | return «@target»;
vb@577
   227
}
vb@577
   228