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