// 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 > \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» } } } } } }