sync/gen_message_func.ysl2
author Krista 'DarthMama' Bennett <krista@pep.foundation>
Wed, 06 Feb 2019 07:17:26 +0100
branchsync
changeset 3270 d8aea79654c3
parent 3123 2475e49c3154
child 3363 9095efc623dd
permissions -rw-r--r--
default with ENGINE-448 and ENGINE-510 merged in, tests updated
vb@2831
     1
// This file is under GNU General Public License 3.0
vb@2831
     2
// see LICENSE.txt
vb@2831
     3
vb@2831
     4
// generate message functions
vb@2831
     5
vb@2864
     6
// Copyleft (c) 2017, 2018, p≡p foundation
vb@2831
     7
vb@2831
     8
// Written by Volker Birk
vb@2831
     9
vb@2831
    10
include yslt.yml2
vb@2831
    11
vb@2831
    12
tstylesheet {
vb@2831
    13
vb@2831
    14
include standardlib.ysl2
vb@2831
    15
include ./functions.ysl2
vb@2831
    16
vb@2831
    17
template "/" {
vb@2831
    18
    apply "protocol", 0, mode=header;
vb@2831
    19
    apply "protocol", 0, mode=impl;
vb@2831
    20
}
vb@2831
    21
vb@2831
    22
template "protocol", mode=header
vb@2831
    23
    document "generated/{@name}_func.h", "text"
vb@2831
    24
||
vb@2831
    25
// This file is under GNU General Public License 3.0
vb@2831
    26
// see LICENSE.txt
vb@2831
    27
vb@2831
    28
#pragma once
vb@2831
    29
vb@2831
    30
#ifdef __cplusplus
vb@2831
    31
extern "C" {
vb@2831
    32
#endif
vb@2831
    33
vb@2831
    34
#include <stdbool.h>
vb@2831
    35
vb@2831
    36
#include "../asn.1/«@name».h"
vb@2831
    37
`` for "func:distinctType(fsm/message/field[not(func:basicType())])" | #include "../asn.1/«@type».h"
vb@2831
    38
vb@2831
    39
// state
vb@2831
    40
vb@2831
    41
struct «@name»_state_s {
vb@2838
    42
    struct common_state_s {
vb@2831
    43
        pEp_identity *from;
vb@2838
    44
    } common;
vb@2831
    45
vb@2831
    46
    `` apply "fsm", mode=state
vb@2831
    47
};
vb@2831
    48
vb@2831
    49
struct own_«@name»_state_s {
vb@2831
    50
    `` for "func:distinctName(fsm/message/field[@type='TID'])" |> «func:ctype()» «@name»;
vb@2831
    51
};
vb@2831
    52
vb@2831
    53
void free_«@name»_state(PEP_SESSION session);
vb@2831
    54
vb@2831
    55
// functions for protocol «@name»
vb@2831
    56
vb@2831
    57
«@name»_t *new_«@name»_message(«@name»_PR fsm, int message_type);
vb@2831
    58
void free_«@name»_message(«@name»_t *msg);
vb@2831
    59
vb@2831
    60
PEP_STATUS update_«@name»_state(PEP_SESSION session, «@name»_t *msg,
vb@2831
    61
        «@name»_PR *fsm, int *message_type);
vb@2831
    62
vb@2854
    63
PEP_STATUS update_«@name»_message(PEP_SESSION session, «@name»_t *msg);
vb@2831
    64
vb@2831
    65
#ifdef __cplusplus
vb@2831
    66
}
vb@2831
    67
#endif
vb@2831
    68
vb@2831
    69
||
vb@2831
    70
vb@2831
    71
template "fsm", mode=state
vb@2831
    72
||
vb@2831
    73
struct _«@name»_state_s {
vb@2831
    74
    int state;
vb@2831
    75
vb@2831
    76
    `` for "func:distinctName(message/field)" |> «func:ctype()» «@name»;
vb@2831
    77
} «yml:lcase(@name)»;
vb@2831
    78
||
vb@2831
    79
vb@2831
    80
template "protocol", mode=impl
vb@2831
    81
    document "generated/{@name}_func.c", "text" {
vb@2831
    82
||
vb@2831
    83
// This file is under GNU General Public License 3.0
vb@2831
    84
// see LICENSE.txt
vb@2831
    85
vb@2831
    86
#include <assert.h>
vb@2831
    87
#include <stdlib.h>
vb@2831
    88
#include "pEp_internal.h"
vb@2831
    89
#include "map_asn1.h"
vb@2831
    90
#include "«@name»_func.h"
vb@3123
    91
`` for "fsm" | #include "«@name»_fsm.h"
vb@2831
    92
vb@2831
    93
void free_«@name»_state(PEP_SESSION session)
vb@2831
    94
{
vb@2831
    95
    if (!session)
vb@2831
    96
        return;
vb@2831
    97
vb@2838
    98
    free_identity(session->«yml:lcase(@name)»_state.common.from);
vb@2831
    99
vb@2831
   100
||
vb@2831
   101
for "fsm"
vb@2831
   102
    for "func:distinctName(message/field[not(func:basicType())])"
vb@2831
   103
        |> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name»);
vb@2831
   104
for "func:distinctName(fsm/message/field[@type='TID'])"
vb@2831
   105
    |> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->own_«yml:lcase(../../../@name)»_state.«@name»);
vb@2831
   106
||
vb@2838
   107
vb@2844
   108
    memset(&session->«yml:lcase(@name)»_state, 0, sizeof(session->«yml:lcase(@name)»_state));
vb@2831
   109
}
vb@2831
   110
vb@2831
   111
«@name»_t *new_«@name»_message(«@name»_PR fsm, int message_type)
vb@2831
   112
{
vb@2831
   113
    «@name»_t *msg = calloc(sizeof(«@name»_t), 1);
vb@2831
   114
    assert(msg);
vb@2831
   115
    if (!msg)
vb@2831
   116
        return NULL;
vb@2831
   117
vb@2841
   118
    if (fsm) {
vb@2841
   119
        msg->present = fsm;
vb@2841
   120
        if (message_type) {
vb@2841
   121
            switch (fsm) {
vb@2841
   122
                `` apply "fsm", 4, mode=impl
vb@2841
   123
                default:
vb@2841
   124
                    free(msg);
vb@2841
   125
                    return NULL;
vb@2841
   126
            }
vb@2841
   127
        }
vb@2831
   128
    }
vb@2831
   129
vb@2831
   130
    return msg;
vb@2831
   131
}
vb@2831
   132
vb@2831
   133
void free_«@name»_message(«@name»_t *msg)
vb@2831
   134
{
vb@2831
   135
    ASN_STRUCT_FREE(asn_DEF_«@name», msg);
vb@2831
   136
}
vb@2831
   137
vb@2831
   138
PEP_STATUS update_«@name»_state(PEP_SESSION session, «@name»_t *msg,
vb@2831
   139
        «@name»_PR *fsm, int *message_type)
vb@2831
   140
{
vb@2831
   141
    int result = 0;
vb@2831
   142
vb@2831
   143
    assert(session && msg && fsm && message_type);
vb@2831
   144
    if (!(session && msg && fsm && message_type))
vb@2831
   145
        return PEP_ILLEGAL_VALUE;
vb@2831
   146
vb@2831
   147
    *fsm = 0;
vb@3123
   148
    *message_type = None;
vb@2831
   149
vb@2831
   150
    switch (msg->present) {
vb@2831
   151
        case «@name»_PR_NOTHING:
vb@2831
   152
            return PEP_ILLEGAL_VALUE;
vb@2831
   153
vb@2831
   154
        `` apply "fsm", 2, mode=update_state
vb@2831
   155
        default:
vb@2831
   156
            return PEP_ILLEGAL_VALUE;
vb@2831
   157
    }
vb@2831
   158
vb@2831
   159
    *fsm = msg->present;
vb@2831
   160
    return PEP_STATUS_OK;
vb@2831
   161
}
vb@2831
   162
vb@2854
   163
PEP_STATUS update_«@name»_message(PEP_SESSION session, «@name»_t *msg)
vb@2831
   164
{
vb@2831
   165
    assert(session && msg);
vb@2831
   166
    if (!(session && msg))
vb@2831
   167
        return PEP_ILLEGAL_VALUE;
vb@2831
   168
vb@2854
   169
    int fsm = msg->present;
vb@2831
   170
    switch (fsm) {
vb@2831
   171
        case «@name»_PR_NOTHING:
vb@2831
   172
            return PEP_ILLEGAL_VALUE;
vb@2831
   173
vb@2831
   174
        `` apply "fsm", 2, mode=update_message
vb@2831
   175
        default:
vb@2831
   176
            return PEP_ILLEGAL_VALUE;
vb@2831
   177
    }
vb@2831
   178
vb@2831
   179
    return PEP_STATUS_OK;
vb@2831
   180
}
vb@2831
   181
vb@2831
   182
||
vb@2831
   183
}
vb@2831
   184
vb@2831
   185
template "fsm", mode=update_message
vb@2831
   186
||
vb@2831
   187
case «../@name»_PR_«yml:lcase(@name)»:
vb@2854
   188
    {
vb@2855
   189
        static long sequence = 0;
vb@2855
   190
        msg->choice.«yml:lcase(@name)».header.sequence = ++sequence;
vb@2854
   191
        int message_type = msg->choice.«yml:lcase(@name)».payload.present;
vb@2854
   192
        switch (message_type) {
vb@2854
   193
            case «@name»__payload_PR_NOTHING:
vb@2854
   194
                return PEP_ILLEGAL_VALUE;
vb@2831
   195
vb@2854
   196
            `` apply "message", 2, mode=update_message
vb@2854
   197
            default:
vb@2854
   198
                return PEP_ILLEGAL_VALUE;
vb@2854
   199
        }
vb@2854
   200
        break;
vb@2831
   201
    }
vb@2831
   202
||
vb@2831
   203
vb@2831
   204
template "message", mode=update_message {
vb@2831
   205
    ||
vb@2856
   206
    case «../@name»__payload_PR_«yml:mixedCase(@name)»:
vb@2855
   207
        `` apply "auto"
vb@2856
   208
        `` apply "field", mode=update_message
vb@2831
   209
        break;
vb@2831
   210
vb@2831
   211
    ||
vb@2831
   212
}
vb@2831
   213
vb@2855
   214
template "auto" choose {
vb@2856
   215
    when "@type = 'Version'" {
vb@2856
   216
        const "fsm", "ancestor::fsm";
vb@2855
   217
        ||
vb@2855
   218
        {
vb@2855
   219
            long *major = (long *) malloc(sizeof(long));
vb@2855
   220
            long *minor = (long *) malloc(sizeof(long));
vb@2855
   221
            assert(major && minor);
vb@2855
   222
            if (!(major && minor))
vb@2855
   223
                return PEP_OUT_OF_MEMORY;
vb@2855
   224
vb@2856
   225
            *major = «$fsm/version/@major»;
vb@2856
   226
            *minor = «$fsm/version/@minor»;
vb@2855
   227
vb@2856
   228
            msg->choice.«yml:lcase($fsm/@name)».payload.choice.«yml:mixedCase(../@name)».«@name».major = major;
vb@2856
   229
            msg->choice.«yml:lcase($fsm/@name)».payload.choice.«yml:mixedCase(../@name)».«@name».minor = minor;
vb@2855
   230
        }
vb@2855
   231
vb@2855
   232
        ||
vb@2856
   233
    }
vb@2855
   234
vb@2855
   235
    otherwise
vb@2855
   236
        error "unkown type for auto in message: {@type}; allowed types: Version";
vb@2855
   237
}
vb@2855
   238
vb@2831
   239
template "field", mode=update_message {
vb@2856
   240
    const "message_name", "yml:mixedCase(../@name)";
vb@2856
   241
    const "state" choose {
vb@2856
   242
        when "@type='TID'"
vb@2856
   243
            > own_«yml:lcase(ancestor::protocol/@name)»_state
vb@2856
   244
        otherwise
vb@2856
   245
            > «yml:lcase(ancestor::protocol/@name)»_state.«yml:lcase(ancestor::fsm/@name)»
vb@2856
   246
    }
vb@2856
   247
vb@2831
   248
    choose {
vb@2831
   249
        when "func:basicType()" // copyable
vb@2831
   250
        ||
vb@2831
   251
        msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name»
vb@2856
   252
                 = session->«$state».«@name»;
vb@2831
   253
vb@2831
   254
        ||
vb@2831
   255
        when "@type='IdentityList'"
vb@2831
   256
        ||
vb@2831
   257
        {
vb@2831
   258
            identity_list *il = IdentityList_to_identity_list(
vb@2856
   259
                    &session->«$state».«@name», NULL);
vb@2831
   260
            if (!il)
vb@2831
   261
                return PEP_OUT_OF_MEMORY;
vb@2831
   262
            IdentityList_t *_il = IdentityList_from_identity_list(il,
vb@2831
   263
                    &msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name»);
vb@2831
   264
            free_identity_list(il);
vb@2831
   265
            if (!_il)
vb@2831
   266
                return PEP_OUT_OF_MEMORY;
vb@2831
   267
        }
vb@2831
   268
vb@2831
   269
        ||
vb@2831
   270
        otherwise // string based
vb@2831
   271
        ||
vb@2856
   272
        {
vb@2856
   273
            int result = OCTET_STRING_fromBuf(
vb@2856
   274
                    &msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name»,
vb@2856
   275
                    (char *) session->«$state».«@name».buf,
vb@2856
   276
                    session->«$state».«@name».size
vb@2856
   277
                );
vb@2856
   278
            if (result)
vb@2856
   279
                return PEP_OUT_OF_MEMORY;
vb@2856
   280
        }
vb@2831
   281
        ||
vb@2831
   282
    }
vb@2831
   283
}
vb@2831
   284
vb@2831
   285
template "fsm", mode=update_state
vb@2831
   286
||
vb@2831
   287
case «../@name»_PR_«yml:lcase(@name)»:
vb@2831
   288
    switch (msg->choice.«yml:lcase(@name)».payload.present) {
vb@2831
   289
        case «@name»__payload_PR_NOTHING:
vb@2831
   290
            return PEP_ILLEGAL_VALUE;
vb@2831
   291
vb@2831
   292
        `` apply "message", 2, mode=update_state
vb@2831
   293
        default:
vb@2831
   294
            return PEP_ILLEGAL_VALUE;
vb@2831
   295
    }
vb@2831
   296
    break;
vb@2831
   297
vb@2831
   298
||
vb@2831
   299
vb@2831
   300
template "message", mode=update_state {
vb@2831
   301
    const "message_name", "concat(yml:lcase(substring(@name,1,1)), substring(@name,2))";
vb@2831
   302
    ||
vb@2831
   303
    case «../@name»__payload_PR_«$message_name»:
vb@2831
   304
        `` apply "field", mode=update_state with "message_name", "$message_name"
vb@3123
   305
        *message_type = «yml:capit($message_name)»;
vb@2831
   306
        break;
vb@2831
   307
vb@2831
   308
    ||
vb@2831
   309
}
vb@2831
   310
vb@2831
   311
template "field", mode=update_state {
vb@2831
   312
    param "message_name";
vb@2831
   313
    choose {
vb@2831
   314
        when "func:basicType()" // copyable
vb@2831
   315
        ||
vb@2831
   316
        session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name» = msg->choice.«yml:lcase(../../@name)»
vb@2831
   317
                .payload.choice.«$message_name».«@name»;
vb@2831
   318
vb@2831
   319
        ||
vb@2831
   320
        when "@type='IdentityList'"
vb@2831
   321
        ||
vb@2831
   322
        {
vb@2831
   323
            identity_list *il = IdentityList_to_identity_list(
vb@2831
   324
                    &msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name», NULL);
vb@2831
   325
            if (!il)
vb@2831
   326
                return PEP_OUT_OF_MEMORY;
vb@2831
   327
            IdentityList_t *_il = IdentityList_from_identity_list(il,
vb@2831
   328
                    &session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name»);
vb@2831
   329
            free_identity_list(il);
vb@2831
   330
            if (!_il)
vb@2831
   331
                return PEP_OUT_OF_MEMORY;
vb@2831
   332
        }
vb@2831
   333
vb@2831
   334
        ||
vb@2831
   335
        otherwise // string based
vb@2831
   336
        ||
vb@2831
   337
        result = OCTET_STRING_fromBuf(&session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name»,
vb@2831
   338
                (char *) msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name».buf,
vb@2831
   339
                msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name».size);
vb@2831
   340
        if (result)
vb@2831
   341
            return PEP_OUT_OF_MEMORY;
vb@2831
   342
vb@2831
   343
        ||
vb@2831
   344
    }
vb@2831
   345
}
vb@2831
   346
vb@2831
   347
template "fsm", mode=impl
vb@2831
   348
||
vb@2831
   349
case «../@name»_PR_«yml:lcase(@name)»:
vb@2831
   350
    msg->choice.«yml:lcase(@name)».payload.present = message_type;
vb@2831
   351
        break;
vb@2831
   352
vb@2831
   353
||
vb@2831
   354
vb@2831
   355
}
vb@2831
   356