sync/gen_statemachine.ysl2
author Edouard Tisserant
Thu, 12 May 2016 03:10:33 +0200
changeset 605 70e80b27b624
parent 589 bdff8843f086
child 608 3bf69b382303
permissions -rw-r--r--
Syncro encoding/decoding : generating protoypes
     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     ||
    16     // state machine for «@name»
    17 
    18     #include "pEpEngine.h"
    19 
    20     typedef union _param { const pEp_identity *partner; const stringlist_t *keylist; } param_t;
    21 
    22     // error values
    23 
    24     typedef enum _fsm_error {
    25         invalid_state = -1,
    26         invalid_event = -2
    27     } fsm_error;
    28 
    29     // states
    30 
    31     typedef enum _«@name»_state {
    32     `` for "set:distinct(state/@name)" |> «.»`if "position()!=last()" > , `
    33     } «@name»_state;
    34 
    35     // events
    36 
    37     typedef enum _«@name»_event {
    38     `` for "set:distinct(state/event/@name)" |> «.»`if "position()!=last()" > , `
    39     } «@name»_event;
    40 
    41     // actions
    42 
    43     `` for "set:distinct(state/event//action/@name)" | void «.»(const pEp_identity *partner);
    44 
    45     // decoders
    46 
    47     `` apply "$UniqueActions[starts-with(@name,'send')]",0 mode="proto" with "pfx", "'decode'"
    48 
    49     // encoders 
    50 
    51     `` apply "$UniqueActions[starts-with(@name,'send')]",0 mode="proto" with "pfx", "'encode'"
    52 
    53     // state machine
    54 
    55     «@name»_state fsm_«@name»(
    56             «@name»_state state,
    57             «@name»_event event,
    58             const pEp_identity *partner
    59         )
    60     {
    61         switch (state) {
    62             `` apply "state"
    63             default:
    64                 return invalid_state;
    65         }
    66 
    67         return state;
    68     }
    69 
    70     ||
    71 
    72     template "state"
    73     ||
    74     case «@name»:
    75         switch (event) {
    76         `` apply "event", 2
    77         default:
    78             return invalid_event;
    79         }
    80         break;
    81 
    82     ||
    83 
    84     template "event"
    85     ||
    86     case «@name»:
    87     `` apply "action|transition";
    88     `` if "name(*[position()=last()]) != 'transition'" |> break;
    89     ||
    90 
    91     template "action" {
    92         indent(0);
    93         > «@name»(
    94         choose {
    95             when "parm" > «name(parm/*)»
    96             otherwise > NULL
    97         }
    98         > );\n
    99     }
   100 
   101     def "xsl:typeOfActionParam" {
   102         param "n", "name(.)";
   103         result "name(ancestor::event/child::parm[child::*[position()=2 and name(.)=$n]]/child::*[position()=1])";
   104     }
   105 
   106     template "action", mode="proto" {
   107         param "pfx";
   108         > void «$pfx»«substring-after(@name, 'send')»(
   109         if "count(parm/*) = 0"
   110             > void
   111         for "set:distinct(parm/*)" {
   112             > «xsl:typeOfActionParam()» «name(.)»
   113             if "position() != last()" > ,
   114         }
   115         | );
   116     }
   117 
   118     template "transition" | return «@target»;
   119 }
   120