You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
573 lines
17 KiB
573 lines
17 KiB
// pEpACIDLang - IG-C99
|
|
// TODO: Lic. etc...
|
|
|
|
include yslt.yml2
|
|
|
|
tstylesheet {
|
|
include idl_api.ysl2
|
|
|
|
// ----------------------------------------------------------------------
|
|
// pEpACIDLang LM-C99-API
|
|
// The C99 Language mapping API
|
|
// ----------------------------------------------------------------------
|
|
|
|
def "func:c99_typename_of_basetype" {
|
|
param "idltype";
|
|
|
|
choose {
|
|
when "func:idl_type_is_defined($idltype)"
|
|
choose {
|
|
when "$idltype = 'string'"
|
|
result > char*
|
|
when "$idltype = 'binary'"
|
|
result > char*
|
|
when "$idltype = 'uint'"
|
|
result > unsigned int
|
|
when "$idltype = 'size'"
|
|
result > size_t
|
|
when "$idltype = 'opaque'"
|
|
result > void*
|
|
when "$idltype = 'int'"
|
|
result > int
|
|
when "$idltype = 'bool'"
|
|
result > bool
|
|
otherwise
|
|
error > func:c99_typename_of_basetype - basetype not supported by ig-c99: «$idltype»
|
|
}
|
|
otherwise
|
|
error > func:c99_typename_of_basetype - idltype: «$idltype» is not defined
|
|
}
|
|
}
|
|
|
|
def "func:c99_typename_of_enum" {
|
|
param "idl_enum_name";
|
|
result "yml:ucase(concat(func:idl_get_package_name(), '_', $idl_enum_name))";
|
|
}
|
|
|
|
def "func:c99_typename_of_struct" {
|
|
param "idl_struct_name";
|
|
result > «yml:capit(func:idl_get_package_name())»_«yml:capit($idl_struct_name)»
|
|
}
|
|
|
|
def "func:c99_typename_of_idltype" {
|
|
param "idltype";
|
|
const "idl_typekind", "func:idl_type_get_typekind_of_type($idltype)";
|
|
|
|
choose {
|
|
when "func:idl_type_is_defined($idltype)"
|
|
choose {
|
|
when "$idl_typekind = 'basetype'"
|
|
result "func:c99_typename_of_basetype($idltype)";
|
|
when "$idl_typekind = 'deftype'"
|
|
result "$idltype";
|
|
when "$idl_typekind = 'enum'"
|
|
result "func:c99_typename_of_enum($idltype)";
|
|
when "$idl_typekind = 'struct'"
|
|
result "func:c99_typename_of_struct($idltype)";
|
|
when "$idl_typekind = 'generic'"
|
|
error > c99_typename_of_type - idltype «$idltype» is a generic type and can only be used in deftype declarations.
|
|
otherwise
|
|
error > c99_typename_of_type - cant determine c99 typename for idltype: «$idltype»
|
|
}
|
|
otherwise
|
|
error > c99_typename_of_idltype - is not an idltype: «$idltype»
|
|
}
|
|
}
|
|
|
|
// typeclass is either
|
|
// * primitive
|
|
// * object
|
|
def "func:c99_typeclass_of_idltype" {
|
|
param "idltype";
|
|
const "resolved_type", "func:idl_type_get_resolved_type($idltype)";
|
|
const "resolved_typekind", "func:idl_type_get_typekind_of_type($resolved_type)";
|
|
|
|
choose {
|
|
when "func:idl_type_is_defined($idltype)"
|
|
choose {
|
|
when "$resolved_typekind = 'basetype'"
|
|
choose {
|
|
when "$resolved_type = 'string'"
|
|
result > object
|
|
when "$resolved_type = 'binary'"
|
|
result > object
|
|
otherwise
|
|
result > primitive
|
|
}
|
|
when "$resolved_typekind = 'enum'"
|
|
result > primitive
|
|
when "$resolved_typekind = 'struct'"
|
|
result > object
|
|
when "$resolved_typekind = 'generic'"
|
|
result > object
|
|
otherwise
|
|
error > c99_typeclass_of_idltype - cant determine typeclass of: «$idltype»
|
|
}
|
|
otherwise
|
|
error > c99_typeclass_of_idltype - is not an idltype: «$idltype»
|
|
}
|
|
};
|
|
|
|
|
|
def "func:c99_itemname_of_enumitem" {
|
|
param "idl_enum_name";
|
|
param "idl_item_name";
|
|
result "yml:ucase(concat($idl_enum_name, '_', $idl_item_name))";
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------
|
|
// pEpACIDLang IG-C99
|
|
// The C99 Interface Generator for pEpACIDLang
|
|
// ----------------------------------------------------------------------
|
|
|
|
// The idl-api owns the root template and executes validation
|
|
// of the interface description.
|
|
// Errors will be printed to stdout.
|
|
// After successful validation, the idl-api applies the
|
|
// template called "pEpACIDLang"
|
|
template "pEpACIDLang" {
|
|
apply "idl|package", 0
|
|
}
|
|
|
|
// generate basetype declarations defined by the idl
|
|
template "idl" document "ig-c99/idl_core.h", "text" {
|
|
||
|
|
#pragma once
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
// idl basetypes
|
|
// -------------
|
|
``call "basetypes"
|
|
|
|
|
|
#ifdef __cplusplus
|
|
} // extern "C"
|
|
#endif
|
|
||
|
|
}
|
|
|
|
function "basetypes" {
|
|
for "func:idl_get_basetypes()" {
|
|
const "name", "name()";
|
|
choose {
|
|
when "func:c99_typename_of_idltype($name) != $name"
|
|
| «func:typedef(func:c99_typename_of_idltype($name), $name)»
|
|
otherwise
|
|
| // no typedef required for idl-basetype: «$name»
|
|
}
|
|
}
|
|
}
|
|
|
|
template "package" {
|
|
apply "api", 0
|
|
}
|
|
|
|
template "api" document "ig-c99/{@name}_api.h", "text" {
|
|
const "api_name", "@name";
|
|
||
|
|
// «yml:ucase(func:idl_get_package_name())» version «func:idl_get_package_version()»
|
|
// «$api_name»_api.h
|
|
// «func:idl_get_package_license()»
|
|
#pragma once
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include "idl_core.h"
|
|
|
|
``call "deftypes"
|
|
``call "enums"
|
|
``call "structs"
|
|
``call "methods"
|
|
|
|
#ifdef __cplusplus
|
|
} // extern "C"
|
|
#endif
|
|
||
|
|
}
|
|
|
|
|
|
|
|
// DEFTYPE
|
|
// -------
|
|
|
|
function "deftypes" {
|
|
||
|
|
// Deftypes
|
|
// --------
|
|
|
|
``apply "deftype"
|
|
|
|
||
|
|
}
|
|
|
|
template "deftype" {
|
|
call "deftype"
|
|
with "new_typename", "@name",
|
|
with "aliased_type_or_typekind", "as/@type";
|
|
}
|
|
|
|
function "deftype" {
|
|
param "new_typename";
|
|
param "aliased_type_or_typekind";
|
|
|
|
choose {
|
|
when 'func:idl_typekind_is_generic($aliased_type_or_typekind)'
|
|
choose {
|
|
when "$aliased_type_or_typekind = 'list'"
|
|
| «func:typedef($aliased_type_or_typekind, $new_typename)»
|
|
otherwise
|
|
error > deftype - typekind must be generic «$type_or_typeind»
|
|
}
|
|
otherwise
|
|
| «func:typedef($aliased_type_or_typekind, $new_typename)»
|
|
}
|
|
}
|
|
|
|
def "func:typedef" {
|
|
param "is_type";
|
|
param "new_typename";
|
|
result > typedef «$is_type» «$new_typename»;
|
|
}
|
|
|
|
|
|
|
|
// ENUM
|
|
// ----
|
|
|
|
function "enums" {
|
|
||
|
|
// Enums
|
|
// -----
|
|
|
|
``apply "enum"
|
|
|
|
||
|
|
}
|
|
|
|
template "enum" {
|
|
call "enum" with "idl_enum_name", "@name";
|
|
}
|
|
|
|
function "enum" {
|
|
param "idl_enum_name";
|
|
const "enum_name", "func:c99_typename_of_idltype($idl_enum_name)";
|
|
||
|
|
typedef enum _«$enum_name» {
|
|
``apply "item" with "enum_name", "$enum_name"
|
|
} «$enum_name»;
|
|
|
|
||
|
|
}
|
|
|
|
template "item" {
|
|
param "enum_name";
|
|
const "idl_item_name", "@name";
|
|
const "c99_item_name", "func:c99_itemname_of_enumitem($enum_name, $idl_item_name)";
|
|
const "idl_value", "text()";
|
|
const "c99_value", "func:c99_enum_item_value($idl_value)";
|
|
|
|
apply "@doc", 0, mode="multiline";
|
|
| «$c99_item_name»«$c99_value»«func:autocomma()»`apply "@doc" , 0, mode="oneline"`
|
|
}
|
|
|
|
def "func:c99_enum_item_value" {
|
|
param "idl_value";
|
|
choose {
|
|
when "string-length($idl_value) > 0"
|
|
result > = «$idl_value»
|
|
otherwise
|
|
result >
|
|
}
|
|
}
|
|
|
|
// STRUCT
|
|
// ------
|
|
|
|
function "structs" {
|
|
||
|
|
// Structs
|
|
// -------
|
|
|
|
``apply "struct"
|
|
|
|
||
|
|
}
|
|
|
|
template "struct" {
|
|
call "struct" with "idl_struct_name", "@name";
|
|
}
|
|
|
|
function "struct" {
|
|
param "idl_struct_name";
|
|
const "c99_struct_name", "func:c99_typename_of_idltype($idl_struct_name)";
|
|
||
|
|
typedef struct _«$c99_struct_name» {
|
|
``apply "field"
|
|
} «$c99_struct_name»;
|
|
|
|
||
|
|
}
|
|
|
|
template "field" {
|
|
const "field_name", "@name";
|
|
const "field_type", "@type";
|
|
||
|
|
``apply "@doc", 0, mode="multiline"
|
|
«$field_type» «$field_name»;`apply "@doc" , 0, mode="oneline"`
|
|
||
|
|
}
|
|
|
|
|
|
// METHOD
|
|
// ------
|
|
|
|
function "methods" {
|
|
||
|
|
// Functions
|
|
// ---------
|
|
|
|
``apply "method"
|
|
|
|
||
|
|
}
|
|
|
|
def "func:c99_normalize_docstring" {
|
|
param "docstring";
|
|
result call "c99_normalize_docstring" with "docstring", "$docstring";
|
|
}
|
|
function "c99_normalize_docstring" {
|
|
param "docstring";
|
|
for "str:split($docstring, '\n')" {
|
|
const "doc_line", "normalize-space(.)";
|
|
if "string-length($doc_line) > 0" {
|
|
| «$doc_line»
|
|
}
|
|
}
|
|
}
|
|
|
|
template "method" {
|
|
const "cont", "'@brief Like send_ping_to_unknown_pEp_identiti\nes_in_incoming_message,\n for outgoing messages. Rationale: an identity may be known to use pEp even if we do not know anything about it, thanks to media keys. This is useful when composing a message: we might be able to receive a Pong, and therefore a recipient key,even before sending; this is a way to improve the outgoing message rating.'";
|
|
call "method_doc" with "idl_method_name", "@name";
|
|
call "method" with "idl_method_name", "@name";
|
|
|
|
|
}
|
|
|
|
|
|
// DOC METHOD
|
|
// ----------
|
|
|
|
function "method_doc" {
|
|
param "idl_method_name";
|
|
| /*
|
|
> «func:c99_method_doc_title($idl_method_name)»
|
|
> «func:c99_method_doc_brief($idl_method_name)»
|
|
> «func:c99_method_doc_params($idl_method_name)»
|
|
> «func:c99_method_doc_throws($idl_method_name)»
|
|
> «func:c99_method_doc_note($idl_method_name)»
|
|
|
|
|
| */
|
|
}
|
|
|
|
|
|
def "func:c99_method_doc_title" {
|
|
param "idl_method_name";
|
|
result > <!-- «$idl_method_name»() -->\n\n
|
|
}
|
|
|
|
def "func:c99_method_doc_brief" {
|
|
param "idl_method_name";
|
|
const "header", "'@brief'";
|
|
const "cont", "func:idl_method_doc_get_brief($idl_method_name)";
|
|
choose {
|
|
when "$cont" {
|
|
const "cont_normalized", "func:c99_normalize_docstring($cont)";
|
|
result > «func:column_paragraph($header, $cont_normalized, 80)»\n
|
|
}
|
|
}
|
|
}
|
|
|
|
def "func:c99_method_doc_note" {
|
|
param "idl_method_name";
|
|
const "header", "'@note'";
|
|
const "cont", "func:idl_method_doc_get_note($idl_method_name)";
|
|
choose {
|
|
when "$cont" {
|
|
const "cont_normalized", "func:c99_normalize_docstring($cont)";
|
|
result > «func:column_paragraph($header, $cont_normalized, 80)»
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// DOC METHOD PARAMS
|
|
// -----------------
|
|
|
|
def "func:c99_method_doc_params" {
|
|
param "idl_method_name";
|
|
result call "c99_method_doc_params" with "idl_method_name", "$idl_method_name";
|
|
}
|
|
function "c99_method_doc_params" {
|
|
param "idl_method_name";
|
|
|
|
for "func:idl_method_get_params($idl_method_name)" {
|
|
const "param_name", ".";
|
|
| «func:c99_method_doc_param($idl_method_name, $param_name)»
|
|
}
|
|
}
|
|
|
|
def "func:c99_method_doc_param" {
|
|
param "method_name";
|
|
param "param_name";
|
|
const "mode", "func:idl_method_param_get_mode($method_name, $param_name)";
|
|
const "type", "func:idl_method_param_get_type($method_name, $param_name)";
|
|
const "doc", "func:idl_method_param_get_doc($method_name, $param_name)";
|
|
const "header", "func:c99_method_doc_param_header($param_name, $mode)";
|
|
choose {
|
|
when "$doc" {
|
|
const "doc_normalized", "func:c99_normalize_docstring($doc)";
|
|
result > «func:column_paragraph($header, $doc_normalized, 80)»
|
|
} otherwise {
|
|
result > «$header»
|
|
}
|
|
}
|
|
}
|
|
|
|
def "func:c99_method_doc_param_header" {
|
|
param "name";
|
|
param "mode";
|
|
result > @param[«$mode»] «$name»
|
|
}
|
|
|
|
|
|
|
|
// METHOD DOC THROWS
|
|
// -----------------
|
|
|
|
def "func:c99_method_doc_throws" {
|
|
param "idl_method_name";
|
|
result call "c99_method_doc_throws" with "idl_method_name", "$idl_method_name";
|
|
}
|
|
function "c99_method_doc_throws" {
|
|
param "idl_method_name";
|
|
|
|
for "func:idl_method_get_throws($idl_method_name)" {
|
|
const "throw_name", ".";
|
|
| «func:c99_method_doc_throw($idl_method_name, $throw_name)»
|
|
}
|
|
}
|
|
|
|
def "func:c99_method_doc_throw" {
|
|
param "method_name";
|
|
param "throw_name";
|
|
const "doc", "func:idl_method_throw_get_doc($method_name, $throw_name)";
|
|
const "header", "func:c99_method_doc_throw_header($throw_name)";
|
|
choose {
|
|
when "$doc" {
|
|
const "doc_normalized", "func:c99_normalize_docstring($doc)";
|
|
result > «func:column_paragraph($header, $doc_normalized, 80)»
|
|
} otherwise {
|
|
result > «$header»
|
|
}
|
|
}
|
|
}
|
|
|
|
def "func:c99_method_doc_throw_header" {
|
|
param "name";
|
|
result > @retval «$name»
|
|
}
|
|
|
|
|
|
|
|
function "method" {
|
|
param "idl_method_name";
|
|
||
|
|
PEP_STATUS «$idl_method_name»(
|
|
``apply "param", 0
|
|
);
|
|
|
|
||
|
|
}
|
|
|
|
template "param" {
|
|
const "name", "@name";
|
|
const "type", "@type";
|
|
const "mode", "@mode";
|
|
|> «func:idlparam_to_cparam($type, $mode)» «@name»«func:autocomma()»
|
|
}
|
|
|
|
def "func:idlparam_to_cparam" {
|
|
param "idltype";
|
|
param "mode";
|
|
const "typeclass", "func:c99_typeclass_of_idltype($idltype)";
|
|
|
|
choose {
|
|
when "$mode = 'borrow'"
|
|
choose {
|
|
when "$typeclass = 'primitive'"
|
|
result > «$idltype»
|
|
when "$typeclass = 'object'"
|
|
result > «$idltype»
|
|
}
|
|
when "$mode = 'mborrow'"
|
|
choose {
|
|
when "$typeclass = 'primitive'"
|
|
result > «$idltype»*
|
|
when "$typeclass = 'object'"
|
|
result > «$idltype»*
|
|
}
|
|
when "$mode = 'claim'"
|
|
choose {
|
|
when "$typeclass = 'primitive'"
|
|
error > invalid mode «$mode» for typeclass «$typeclass»
|
|
when "$typeclass = 'object'"
|
|
result > «$idltype»
|
|
}
|
|
when "$mode = 'provide'"
|
|
choose {
|
|
when "$typeclass = 'primitive'"
|
|
error > invalid mode «$mode» for typeclass «$typeclass»
|
|
when "$typeclass = 'object'"
|
|
result > «$idltype»*
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// DOC
|
|
// ---
|
|
|
|
template "doc|@doc", mode="oneline" {
|
|
const "docstring", ".";
|
|
const "doc_lines_count", "count(str:split($docstring, '\n'))";
|
|
if "$doc_lines_count = 1" {
|
|
const "doc_line", "normalize-space($docstring)";
|
|
if "string-length($doc_line) > 0" {
|
|
> // «$doc_line»
|
|
}
|
|
}
|
|
}
|
|
|
|
template "doc|@doc", mode="multiline" {
|
|
const "docstring", ".";
|
|
const "doc_lines_count", "count(str:split($docstring, '\n'))";
|
|
|
|
if "$doc_lines_count > 1" {
|
|
if "string-length($docstring) > 0" {
|
|
|
|
|
for "str:split($docstring, '\n')" {
|
|
const "doc_line", "normalize-space(.)";
|
|
if "string-length($doc_line) > 0" {
|
|
| // «$doc_line»
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|