sync/gen_statemachine.ysl2
author Volker Birk <vb@pep-project.org>
Thu, 12 May 2016 11:21:57 +0200
changeset 609 a22a400611ca
parent 608 3bf69b382303
child 610 1e3d39516f43
permissions -rw-r--r--
sync handshake dialog async
     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 
    11     key "ActionByNames", "/protocol/fsm/state/event//action", "@name";
    12     variable "UniqueActions", "/protocol/fsm/state/event//action[generate-id()=generate-id(key('ActionByNames',@name)[1])]";
    13 
    14     template "/protocol/fsm" {
    15         document "../src/sync_fsm.h", "text"
    16         ||
    17         #pragma once
    18 
    19         // state machine for «@name»
    20 
    21         #include "pEpEngine.h"
    22 
    23         // types
    24 
    25         typedef pEp_identity * Identity;
    26         typedef union _param { const Identity partner; const stringlist_t *keylist; } param_t;
    27 
    28         // error values
    29 
    30         typedef enum _fsm_error {
    31             invalid_state = -1,
    32             invalid_event = -2
    33         } fsm_error;
    34 
    35         // states
    36 
    37         typedef enum _«@name»_state {
    38         `` for "set:distinct(state/@name)" |> «.»`if "position()!=last()" > , `
    39         } «@name»_state;
    40 
    41         // events
    42 
    43         typedef enum _«@name»_event {
    44         `` for "set:distinct(state/event/@name)" |> «.»`if "position()!=last()" > , `
    45         } «@name»_event;
    46 
    47         // actions
    48 
    49         `` for "set:distinct(state/event//action/@name)" | void «.»(const Identity partner);
    50 
    51         // driver
    52 
    53         void fsm_«@name»_inject(PEP_SESSION session, «@name»_event event);
    54 
    55         // decoders
    56 
    57         `` apply "$UniqueActions[starts-with(@name,'send')]",0 mode="proto" with "pfx", "'decode'"
    58 
    59         // encoders 
    60 
    61         `` apply "$UniqueActions[starts-with(@name,'send')]",0 mode="proto" with "pfx", "'encode'"
    62         ||
    63         ||
    64         #include "sync_fsm.h"
    65 
    66         // state machine for «@name»
    67 
    68         «@name»_state fsm_«@name»(
    69                 «@name»_state state,
    70                 «@name»_event event,
    71                 const Identity partner
    72             )
    73         {
    74             switch (state) {
    75                 `` apply "state"
    76                 default:
    77                     return invalid_state;
    78             }
    79 
    80             return state;
    81         }
    82 
    83         ||
    84     }
    85 
    86     template "state"
    87     ||
    88     case «@name»:
    89         switch (event) {
    90         `` apply "event", 2
    91         default:
    92             return invalid_event;
    93         }
    94         break;
    95 
    96     ||
    97 
    98     template "event"
    99     ||
   100     case «@name»:
   101     `` apply "action|transition";
   102     `` if "name(*[position()=last()]) != 'transition'" |> break;
   103     ||
   104 
   105     template "action" {
   106         indent(0);
   107         > «@name»(
   108         choose {
   109             when "parm" > «name(parm/*)»
   110             otherwise > NULL
   111         }
   112         > );\n
   113     }
   114 
   115     def "xsl:typeOfActionParam" {
   116         param "n", "name(.)";
   117         result "name(ancestor::event/child::parm[child::*[position()=2 and name(.)=$n]]/child::*[position()=1])";
   118     }
   119 
   120     template "action", mode="proto" {
   121         param "pfx";
   122         > void «$pfx»«substring-after(@name, 'send')»(
   123         if "count(parm/*) = 0"
   124             > void
   125         for "set:distinct(parm/*)" {
   126             > «xsl:typeOfActionParam()» «name(.)»
   127             if "position() != last()" > ,
   128         }
   129         | );
   130     }
   131 
   132     template "transition" | return «@target»;
   133 }
   134