sync/gen_statemachine.ysl2
author Volker Birk <vb@pep-project.org>
Sat, 09 Jul 2016 14:27:11 +0200
changeset 811 71418dbb493c
parent 807 a33a5f760372
child 939 ed7dfdae3031
permissions -rw-r--r--
getting more abstract
     1 // generate state machine code
     2 
     3 // Copyleft (c) 2016, p≡p foundation
     4 
     5 // Written by Volker Birk
     6 
     7 include yslt.yml2
     8 
     9 tstylesheet {
    10     include ./functions.ysl2
    11 
    12     template "/protocol" {
    13         document "../src/Makefile.protocols", "text"
    14             apply "fsm", 0, mode="make";
    15         apply "fsm", 0, mode=gen;
    16     }
    17 
    18     template "fsm", mode=make
    19     ||
    20     «@filename»_fsm.c: ../sync/devicegroup.fsm
    21     \tmake -C ../«@filename»
    22     ||
    23 
    24     template "fsm", mode=gen {
    25         document "../src/{@filename}_fsm.h", "text" {
    26         ||
    27         #pragma once
    28 
    29         // state machine for «@name»
    30 
    31         #include "pEpEngine.h"
    32         
    33         #ifdef __cplusplus
    34         extern "C" {
    35         #endif
    36 
    37         // types
    38 
    39         typedef pEp_identity * Identity;
    40         typedef union _param { const Identity partner; const stringlist_t *keylist; } param_t;
    41 
    42         // error values
    43 
    44         typedef enum _fsm_error {
    45             invalid_state = -2,
    46             invalid_event = -3
    47         } fsm_error;
    48 
    49         // states
    50 
    51         typedef enum _«@name»_state {
    52             «@name»_state_NONE = -1,
    53         `` for "func:distinctName(state)" |> «@name»`if "position()!=last()" > , `
    54         } «@name»_state;
    55 
    56         // events
    57 
    58         typedef enum _«@name»_event {
    59             «@name»_event_NONE = -1,
    60         ||
    61         for "func:distinctName(state/event[not(not(/protocol/fsm/tag/@name=@name))])" {
    62             const "name", "@name";
    63             |> «$name» = «/protocol/fsm/tag[@name=$name]/@id»,
    64         }
    65         for "func:distinctName(state/event[not(/protocol/fsm/tag/@name=@name)])"
    66             |> «@name»`if "position()!=last()" > , `
    67         ||
    68         } «@name»_event;
    69 
    70         // actions
    71 
    72         `` const "name", "@name"
    73         `` for "func:distinctName(//action)" | PEP_STATUS «@name»(PEP_SESSION session, «$name»_state state, const Identity partner);
    74 
    75         // state machine
    76 
    77         «@name»_state fsm_«@name»(
    78                 PEP_SESSION session,
    79                 «@name»_state state,
    80                 «@name»_event event,
    81                 const Identity partner,
    82                 «@name»_state state_partner
    83             );
    84 
    85         // driver
    86 
    87         DYNAMIC_API PEP_STATUS fsm_«@name»_inject(
    88                 PEP_SESSION session,
    89                 «@name»_event event,
    90                 Identity partner,
    91                 «@name»_state state_partner
    92             );
    93 
    94         #ifdef __cplusplus
    95         }
    96         #endif
    97 
    98         ||
    99         }
   100         document "../src/{@filename}_driver.c", "text"
   101         ||
   102         // Driver for «@name» state machine
   103 
   104         #include <assert.h>
   105         #include "pEp_internal.h"
   106 
   107 
   108         DYNAMIC_API PEP_STATUS fsm_«@name»_inject(
   109                 PEP_SESSION session,
   110                 «@name»_event event,
   111                 Identity partner,
   112                 «@name»_state state_partner
   113             )
   114         {
   115             PEP_STATUS status = PEP_STATUS_OK;
   116 
   117             session->«@filename»_state = fsm_«@name»(session, session->«@filename»_state,
   118                     event, partner, state_partner);
   119 
   120             return status;
   121         }
   122 
   123         ||
   124         document "../src/{@filename}_fsm.c", "text"
   125         ||
   126         #include "«@filename»_fsm.h"
   127 
   128         // state machine for «@name»
   129 
   130         «@name»_state fsm_«@name»(
   131                 PEP_SESSION session,
   132                 «@name»_state state,
   133                 «@name»_event event,
   134                 const Identity partner,
   135                 «@name»_state state_partner
   136             )
   137         {
   138             switch (state) {
   139                 `` apply "state"
   140                 default:
   141                     return («@name»_state) invalid_state;
   142             }
   143 
   144             return state;
   145         }
   146 
   147         ||
   148     }
   149 
   150     template "state"
   151     ||
   152     case «@name»:
   153         switch (event) {
   154         `` apply "event", 2
   155         default:
   156             return («../@name»_state) invalid_event;
   157         }
   158         break;
   159 
   160     ||
   161 
   162     template "event"
   163     ||
   164     case «@name»:
   165     `` apply "action|transition";
   166     `` if "name(*[position()=last()]) != 'transition'" |> break;
   167     ||
   168 
   169     template "action" {
   170         indent(0);
   171         > «@name»(session, state, 
   172         choose {
   173             when "parm" > «name(parm/*)»
   174             otherwise > NULL
   175         }
   176         > );\n
   177     }
   178 
   179     template "transition" | return «@target»;
   180 }
   181