sync/gen_statemachine.ysl2
author Roker <roker@pep-project.org>
Tue, 20 Sep 2016 15:54:57 +0200
branchroker-linux
changeset 1168 4d4e3ecbaf8b
parent 811 71418dbb493c
child 939 ed7dfdae3031
permissions -rw-r--r--
merge "default" into my branch
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@654
    32
        
vb@654
    33
        #ifdef __cplusplus
vb@654
    34
        extern "C" {
vb@654
    35
        #endif
vb@608
    36
vb@609
    37
        // types
Edouard@605
    38
vb@609
    39
        typedef pEp_identity * Identity;
vb@609
    40
        typedef union _param { const Identity partner; const stringlist_t *keylist; } param_t;
vb@583
    41
vb@609
    42
        // error values
vb@577
    43
vb@609
    44
        typedef enum _fsm_error {
vb@743
    45
            invalid_state = -2,
vb@743
    46
            invalid_event = -3
vb@609
    47
        } fsm_error;
vb@583
    48
vb@609
    49
        // states
vb@578
    50
vb@609
    51
        typedef enum _«@name»_state {
vb@743
    52
            «@name»_state_NONE = -1,
vb@623
    53
        `` for "func:distinctName(state)" |> «@name»`if "position()!=last()" > , `
vb@609
    54
        } «@name»_state;
vb@583
    55
vb@609
    56
        // events
vb@578
    57
vb@609
    58
        typedef enum _«@name»_event {
vb@743
    59
            «@name»_event_NONE = -1,
vb@711
    60
        ||
vb@711
    61
        for "func:distinctName(state/event[not(not(/protocol/fsm/tag/@name=@name))])" {
vb@711
    62
            const "name", "@name";
vb@711
    63
            |> «$name» = «/protocol/fsm/tag[@name=$name]/@id»,
vb@711
    64
        }
vb@711
    65
        for "func:distinctName(state/event[not(/protocol/fsm/tag/@name=@name)])"
vb@711
    66
            |> «@name»`if "position()!=last()" > , `
vb@711
    67
        ||
vb@609
    68
        } «@name»_event;
vb@583
    69
vb@609
    70
        // actions
vb@582
    71
vb@690
    72
        `` const "name", "@name"
vb@690
    73
        `` for "func:distinctName(//action)" | PEP_STATUS «@name»(PEP_SESSION session, «$name»_state state, const Identity partner);
Edouard@605
    74
vb@626
    75
        // state machine
vb@626
    76
vb@626
    77
        «@name»_state fsm_«@name»(
vb@627
    78
                PEP_SESSION session,
vb@626
    79
                «@name»_state state,
vb@626
    80
                «@name»_event event,
vb@690
    81
                const Identity partner,
vb@690
    82
                «@name»_state state_partner
vb@626
    83
            );
vb@626
    84
vb@609
    85
        // driver
Edouard@605
    86
vb@782
    87
        DYNAMIC_API PEP_STATUS fsm_«@name»_inject(
vb@690
    88
                PEP_SESSION session,
vb@690
    89
                «@name»_event event,
vb@690
    90
                Identity partner,
vb@690
    91
                «@name»_state state_partner
vb@690
    92
            );
Edouard@605
    93
vb@654
    94
        #ifdef __cplusplus
vb@654
    95
        }
vb@654
    96
        #endif
vb@654
    97
vb@609
    98
        ||
vb@711
    99
        }
vb@807
   100
        document "../src/{@filename}_driver.c", "text"
vb@690
   101
        ||
vb@690
   102
        // Driver for «@name» state machine
vb@690
   103
vb@690
   104
        #include <assert.h>
vb@690
   105
        #include "pEp_internal.h"
vb@690
   106
vb@690
   107
vb@743
   108
        DYNAMIC_API PEP_STATUS fsm_«@name»_inject(
vb@690
   109
                PEP_SESSION session,
vb@690
   110
                «@name»_event event,
vb@690
   111
                Identity partner,
vb@690
   112
                «@name»_state state_partner
vb@690
   113
            )
vb@690
   114
        {
vb@690
   115
            PEP_STATUS status = PEP_STATUS_OK;
vb@690
   116
vb@807
   117
            session->«@filename»_state = fsm_«@name»(session, session->«@filename»_state,
vb@690
   118
                    event, partner, state_partner);
vb@690
   119
vb@690
   120
            return status;
vb@690
   121
        }
vb@690
   122
vb@690
   123
        ||
vb@807
   124
        document "../src/{@filename}_fsm.c", "text"
vb@609
   125
        ||
vb@807
   126
        #include "«@filename»_fsm.h"
vb@609
   127
vb@609
   128
        // state machine for «@name»
vb@609
   129
vb@609
   130
        «@name»_state fsm_«@name»(
vb@627
   131
                PEP_SESSION session,
vb@609
   132
                «@name»_state state,
vb@609
   133
                «@name»_event event,
vb@690
   134
                const Identity partner,
vb@690
   135
                «@name»_state state_partner
vb@609
   136
            )
vb@609
   137
        {
vb@609
   138
            switch (state) {
vb@609
   139
                `` apply "state"
vb@609
   140
                default:
vb@743
   141
                    return («@name»_state) invalid_state;
vb@609
   142
            }
vb@609
   143
vb@609
   144
            return state;
vb@577
   145
        }
vb@582
   146
vb@609
   147
        ||
vb@577
   148
    }
vb@577
   149
vb@580
   150
    template "state"
vb@577
   151
    ||
vb@577
   152
    case «@name»:
vb@578
   153
        switch (event) {
vb@578
   154
        `` apply "event", 2
vb@578
   155
        default:
vb@743
   156
            return («../@name»_state) invalid_event;
vb@578
   157
        }
vb@577
   158
        break;
vb@577
   159
vb@577
   160
    ||
vb@578
   161
vb@578
   162
    template "event"
vb@578
   163
    ||
vb@578
   164
    case «@name»:
vb@578
   165
    `` apply "action|transition";
vb@582
   166
    `` if "name(*[position()=last()]) != 'transition'" |> break;
vb@578
   167
    ||
vb@578
   168
vb@582
   169
    template "action" {
vb@582
   170
        indent(0);
vb@690
   171
        > «@name»(session, state, 
vb@582
   172
        choose {
vb@582
   173
            when "parm" > «name(parm/*)»
vb@582
   174
            otherwise > NULL
vb@582
   175
        }
vb@582
   176
        > );\n
vb@582
   177
    }
vb@582
   178
vb@578
   179
    template "transition" | return «@target»;
vb@577
   180
}
vb@577
   181