diff --git a/lm-c99/ig-c99.ysl2 b/lm-c99/ig-c99.ysl2 new file mode 100644 index 0000000..af40ae4 --- /dev/null +++ b/lm-c99/ig-c99.ysl2 @@ -0,0 +1,202 @@ +// p≡p API header generator + +// Copyleft (c) 2019-2020, p≡p foundation +// this file is under GNU General Public License 3.0 +// see LICENSE.txt +// written by Volker Birk + + +include yslt.yml2 + +tstylesheet { + include to_c.ysl2 + include standardlib.ysl2 + + template "/package", "text" { + apply "api", 0 + } + + + template "api" document "{@name}_api.h", "text" { + const "pkg_name", "../@name"; + const "pkg_version", "../version/text()"; + const "pkg_license", "../license/text()"; + const "pkg_copyleft", "../copyleft/text()"; + const "api_name", "@name"; + || + // «yml:ucase($pkg_name)» «$pkg_version» + // «$api_name»_api.h + // «$pkg_license» + // «$pkg_copyleft» + #pragma once + + #ifdef __cplusplus + extern "C" { + #endif + + #include + //#include "idl.h" + + // Types + // ----- + ``apply "type", 0 + + // Enums + // ----- + ``apply "enum", 0 + + // Structs + // ------- + ``apply "struct", 0 + + + #ifdef __cplusplus + } // extern "C" + #endif + || + } + + + // TYPE + // ---- + + def "func:typedef" { + param "is_type"; + param "alias_name"; + result > typedef «$is_type» «$alias_name»;\n + } + + def "func:idl_basetype" { + param "idl_name"; + choose { + when "$idl_name = 'string'" + result > «func:typedef('char*', $idl_name)» + when "$idl_name = 'binary'" + result > «func:typedef('char*', $idl_name)» + when "$idl_name = 'uint'" + result > «func:typedef('unsigned int', $idl_name)» + when "$idl_name = 'size'" + result > «func:typedef('size_t', $idl_name)» + when "$idl_name = 'opaque'" + result > «func:typedef('void*', $idl_name)» + } + } + + + template "type" { + const "alias_name", "@name"; + const "is_type", "is/@type"; + + if 'string-length($is_type) > 0' { + > «func:typedef($is_type, $alias_name)» + } else { + > «func:idl_basetype($alias_name)» + } + + } + + + + // ENUM + // ---- + + def "func:c_name_enum" { + param "pkg_name"; + param "name"; + + result "yml:ucase(concat($pkg_name, '_', $name))" + } + + + template "enum" { + const "idl_name", "@name"; + const "pkg_name", "../../@name"; + const "enum_name", "func:c_name_enum($pkg_name, $idl_name)"; + || + typedef enum _«$enum_name» { + ``apply "item" with "enum_name", "$enum_name" + } «$enum_name»; + + || + } + + template "item" { + param "enum_name"; + const "item_name_idl", "@name"; + const "item_name", "yml:ucase(concat($enum_name, '_', $item_name_idl))"; + + apply "@doc", 0, mode="multiline"; + choose { + when "@output='hex'" + | «$item_name»`if "text()" { " = 0x" value "yml:dec2hex(., 2)" }``if "position()!=last()" > ,``apply "@doc" , 0, mode="oneline"` + otherwise + | «$item_name»`if "text()" { " = " value "." }``if "position()!=last()" > ,``apply "@doc" , 0, mode="oneline"` + } + } + + + + // STRUCT + // ------ + + def "func:c_name_struct" { + param "pkg_name"; + param "idl_name"; + + result "concat(yml:capit($pkg_name), '_', yml:capit($idl_name))" + } + + template "struct" { + const "idl_name", "@name"; + const "pkg_name", "../../@name"; + const "c_name_struct", "func:c_name_struct($pkg_name, $idl_name)"; + || + typedef struct _«$c_name_struct» { + ``apply "field" + } «$c_name_struct»; + || + } + + template "field" { + const "field_name", "@name"; + const "field_type", "@type"; + || + ``apply "@doc", 0, mode="multiline" + «$field_type» «$field_name»;`apply "@doc" , 0, mode="oneline"` + || + } + + + // 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» + } + } + } + } + } + +} +