// pEpACIDLang - IG-C99 // TODO: Lic. etc... include yslt.yml2 tstylesheet { include standardlib.ysl2 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()"; if "func:c99_typename_of_idltype($name) != $name" { | «func:typedef(func:c99_typename_of_idltype($name), $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" || } template "method" { call "method" with "idl_method_name", "@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» } } } } } }