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