Implement attrs: extendedattribute and extraheader
This commit is contained in:
parent
d64f4d1c62
commit
014d4ea4df
7 changed files with 283 additions and 45 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -35,4 +35,7 @@ subprojects/googletest-*
|
||||||
subprojects/packagecache
|
subprojects/packagecache
|
||||||
|
|
||||||
/build/
|
/build/
|
||||||
|
/build_dev/
|
||||||
/.ci/
|
/.ci/
|
||||||
|
|
||||||
|
/CMakeUserPresets.json
|
||||||
|
|
|
||||||
10
.vscode/settings.json
vendored
10
.vscode/settings.json
vendored
|
|
@ -1,10 +1,4 @@
|
||||||
{
|
{
|
||||||
"files.associations": {
|
"cmake.configureOnOpen": false,
|
||||||
"*.rst": "restructuredtext",
|
"sonarlint.pathToCompileCommands": "${workspaceFolder}/build_dev/compile_commands.json"
|
||||||
"*.make": "makefile",
|
|
||||||
"opam": "ocaml.opam",
|
|
||||||
"schema.capnp.h": "c",
|
|
||||||
"stdbool.h": "c"
|
|
||||||
},
|
|
||||||
"cmake.configureOnOpen": false
|
|
||||||
}
|
}
|
||||||
|
|
@ -8,6 +8,11 @@
|
||||||
The variable should be explicitly set to `ON` if a shared library must
|
The variable should be explicitly set to `ON` if a shared library must
|
||||||
be created, and `OFF` if a static library must be created.
|
be created, and `OFF` if a static library must be created.
|
||||||
- Use GoogleTest 1.14.0 and enable tests only when C++14 compiler available.
|
- Use GoogleTest 1.14.0 and enable tests only when C++14 compiler available.
|
||||||
|
- Support building into shared libraries on Windows:
|
||||||
|
- `extraheader` attribute: Extra `#include <stdio.h>` or any other
|
||||||
|
preprocessor statements in auto-generated header file.
|
||||||
|
- `extendedattribute` attribute: Text in front of auto-generated functions,
|
||||||
|
like `__declspec(dllexport)`
|
||||||
|
|
||||||
## 0.9.0
|
## 0.9.0
|
||||||
|
|
||||||
|
|
|
||||||
86
CMakeUserPresets-SUGGESTED.json
Normal file
86
CMakeUserPresets-SUGGESTED.json
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"name": "dev-AppleSilicon",
|
||||||
|
"inherits": [
|
||||||
|
"ci-host-darwin_arm64",
|
||||||
|
"ci-target-darwin_arm64"
|
||||||
|
],
|
||||||
|
"displayName": "Dev Apple Silicon",
|
||||||
|
"generator": "Ninja",
|
||||||
|
"binaryDir": "build_dev",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
|
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
|
||||||
|
},
|
||||||
|
"vendor": {
|
||||||
|
"microsoft.com/VisualStudioSettings/CMake/1.0": {
|
||||||
|
"hostOS": [
|
||||||
|
"macOS"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dev-Linux-x86_64",
|
||||||
|
"inherits": [
|
||||||
|
"ci-host-linux_x86_64",
|
||||||
|
"ci-target-linux_x86_64"
|
||||||
|
],
|
||||||
|
"displayName": "Dev Linux x86_64",
|
||||||
|
"generator": "Ninja",
|
||||||
|
"binaryDir": "build_dev",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
|
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
|
||||||
|
},
|
||||||
|
"vendor": {
|
||||||
|
"microsoft.com/VisualStudioSettings/CMake/1.0": {
|
||||||
|
"hostOS": [
|
||||||
|
"Linux"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dev-Windows64",
|
||||||
|
"inherits": [
|
||||||
|
"ci-host-windows_x86_64",
|
||||||
|
"ci-target-windows_x86_64"
|
||||||
|
],
|
||||||
|
"binaryDir": "build_dev",
|
||||||
|
"displayName": "Dev Windows 64-bit",
|
||||||
|
"generator": "Ninja",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
|
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
|
||||||
|
},
|
||||||
|
"vendor": {
|
||||||
|
"microsoft.com/VisualStudioSettings/CMake/1.0": {
|
||||||
|
"hostOS": [
|
||||||
|
"Windows"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dev-Windows64-with-env-ninja",
|
||||||
|
"inherits": [
|
||||||
|
"dev-Windows64"
|
||||||
|
],
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_MAKE_PROGRAM": "$env{DKSDK_NINJA_PROGRAM}",
|
||||||
|
"CMAKE_MAKE_PROGRAM_REASON": "Set DKSDK_NINJA_PROGRAM environment variable to specify ninja.exe"
|
||||||
|
},
|
||||||
|
"displayName": "Dev Windows 64-bit + env DKSDK_NINJA_PROGRAM",
|
||||||
|
"vendor": {
|
||||||
|
"microsoft.com/VisualStudioSettings/CMake/1.0": {
|
||||||
|
"hostOS": [
|
||||||
|
"Windows"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
28
README.md
28
README.md
|
|
@ -68,7 +68,9 @@ capnp compile -o ./capnpc-c myschema.capnp
|
||||||
|
|
||||||
`capnp` generates a C struct that corresponds to each capn proto struct, along with read/write functions that convert to/from capn proto form.
|
`capnp` generates a C struct that corresponds to each capn proto struct, along with read/write functions that convert to/from capn proto form.
|
||||||
|
|
||||||
If you want accessor functions for struct members, use attribute `fieldgetset` in your `.capnp` file as follows:
|
#### fieldgetset
|
||||||
|
|
||||||
|
If you want accessor functions for struct members, use the attribute `fieldgetset` in your `.capnp` file as follows:
|
||||||
|
|
||||||
```capnp
|
```capnp
|
||||||
using C = import "${c-capnproto}/compiler/c.capnp";
|
using C = import "${c-capnproto}/compiler/c.capnp";
|
||||||
|
|
@ -78,6 +80,30 @@ $C.fieldgetset;
|
||||||
struct MyStruct {}
|
struct MyStruct {}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### extraheader
|
||||||
|
|
||||||
|
If you want to add `#include <...>` or any other preprocessor statements in your generated C file, use the attribute `extraheader` in your `.capnp` file as follows:
|
||||||
|
|
||||||
|
```capnp
|
||||||
|
using C = import "${c-capnproto}/compiler/c.capnp";
|
||||||
|
|
||||||
|
$C.extraheader("include <stdio.h>");
|
||||||
|
|
||||||
|
struct MyStruct {}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### extendedattribute
|
||||||
|
|
||||||
|
If you want to add an `__declspec(dllexport)` or some other extended attribute to your generated C functions and structs, use the attribute `extendedattribute` in your `.capnp` file as follows:
|
||||||
|
|
||||||
|
```capnp
|
||||||
|
using C = import "${c-capnproto}/compiler/c.capnp";
|
||||||
|
|
||||||
|
$C.extendedattribute("__declspec(dllexport)");
|
||||||
|
|
||||||
|
struct MyStruct {}
|
||||||
|
```
|
||||||
|
|
||||||
### Example C code
|
### Example C code
|
||||||
|
|
||||||
See the unit tests in [`tests/example-test.cpp`](tests/example-test.cpp).
|
See the unit tests in [`tests/example-test.cpp`](tests/example-test.cpp).
|
||||||
|
|
|
||||||
|
|
@ -49,3 +49,9 @@ annotation typedefto @0xcefaf27713042144 (struct, enum): Text;
|
||||||
|
|
||||||
annotation namespace @0xf2c035025fec7c2b (file): Text;
|
annotation namespace @0xf2c035025fec7c2b (file): Text;
|
||||||
# prefix structs with a name space string
|
# prefix structs with a name space string
|
||||||
|
|
||||||
|
annotation extraheader @0xbadb496d09cf4612 (file): Text;
|
||||||
|
# add extra preprocessor directives to the header
|
||||||
|
|
||||||
|
annotation extendedattribute @0xd187bca5c6844c24 (file): Text;
|
||||||
|
# add an extended attribute to each generated function
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,12 @@ struct id_bst {
|
||||||
struct id_bst *right;
|
struct id_bst *right;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct string_list {
|
||||||
|
const char* string;
|
||||||
|
struct string_list *prev;
|
||||||
|
struct string_list *next;
|
||||||
|
};
|
||||||
|
|
||||||
static struct str SRC = STR_INIT, HDR = STR_INIT;
|
static struct str SRC = STR_INIT, HDR = STR_INIT;
|
||||||
static struct capn g_valcapn;
|
static struct capn g_valcapn;
|
||||||
static struct capn_segment g_valseg;
|
static struct capn_segment g_valseg;
|
||||||
|
|
@ -87,6 +93,8 @@ static void insert_node(struct node *s) {
|
||||||
g_node_tree = capn_tree_insert(g_node_tree, &s->hdr);
|
g_node_tree = capn_tree_insert(g_node_tree, &s->hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* id_bst implementation */
|
||||||
|
|
||||||
static struct id_bst * insert_id(struct id_bst * bst, uint64_t id)
|
static struct id_bst * insert_id(struct id_bst * bst, uint64_t id)
|
||||||
{
|
{
|
||||||
struct id_bst ** current = &bst;
|
struct id_bst ** current = &bst;
|
||||||
|
|
@ -148,6 +156,35 @@ static void free_id_bst(struct id_bst * bst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* string_list implementation */
|
||||||
|
|
||||||
|
static struct string_list * insert_file(struct string_list * list, const char* string)
|
||||||
|
{
|
||||||
|
struct string_list ** current = &list;
|
||||||
|
struct string_list ** prev = NULL;
|
||||||
|
|
||||||
|
while (*current)
|
||||||
|
{
|
||||||
|
prev = current;
|
||||||
|
current = &(*current)->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
*current = malloc(sizeof **current);
|
||||||
|
(*current)->string = string;
|
||||||
|
(*current)->prev = prev == NULL ? NULL : *prev;
|
||||||
|
(*current)->next = NULL;
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_string_list(struct string_list * list)
|
||||||
|
{
|
||||||
|
if (list)
|
||||||
|
{
|
||||||
|
free_string_list(list->next);
|
||||||
|
free(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* resolve_names recursively follows the nestedNodes tree in order to
|
/* resolve_names recursively follows the nestedNodes tree in order to
|
||||||
* set node->name.
|
* set node->name.
|
||||||
|
|
@ -815,9 +852,11 @@ static void declare_slot(struct strings *s, struct field *f) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void define_group(struct strings *s, struct node *n, const char *group_name, bool enclose_unions);
|
static void define_group(struct strings *s, struct node *n, const char *group_name, bool enclose_unions,
|
||||||
|
const char* extattr, const char* extattr_space);
|
||||||
|
|
||||||
static void do_union(struct strings *s, struct node *n, struct field *first_field, const char *union_name) {
|
static void do_union(struct strings *s, struct node *n, struct field *first_field, const char *union_name,
|
||||||
|
const char* extattr, const char* extattr_space) {
|
||||||
int tagoff = 2 * n->n._struct.discriminantOffset;
|
int tagoff = 2 * n->n._struct.discriminantOffset;
|
||||||
struct field *f;
|
struct field *f;
|
||||||
static struct str tag = STR_INIT;
|
static struct str tag = STR_INIT;
|
||||||
|
|
@ -875,7 +914,7 @@ static void do_union(struct strings *s, struct node *n, struct field *first_fiel
|
||||||
// When we add a union inside a union, we need to enclose it in its
|
// When we add a union inside a union, we need to enclose it in its
|
||||||
// own struct so that its members do not overwrite its own
|
// own struct so that its members do not overwrite its own
|
||||||
// discriminant.
|
// discriminant.
|
||||||
define_group(s, f->group, field_name(f), true);
|
define_group(s, f->group, field_name(f), true, extattr, extattr_space);
|
||||||
str_addf(&s->get, "%sbreak;\n", s->ftab.str);
|
str_addf(&s->get, "%sbreak;\n", s->ftab.str);
|
||||||
str_addf(&s->set, "%sbreak;\n", s->ftab.str);
|
str_addf(&s->set, "%sbreak;\n", s->ftab.str);
|
||||||
str_setlen(&s->ftab, s->ftab.len-1);
|
str_setlen(&s->ftab, s->ftab.len-1);
|
||||||
|
|
@ -911,7 +950,7 @@ static void do_union(struct strings *s, struct node *n, struct field *first_fiel
|
||||||
str_release(&enums);
|
str_release(&enums);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void define_field(struct strings *s, struct field *f) {
|
static void define_field(struct strings *s, struct field *f, const char* extattr, const char* extattr_space) {
|
||||||
static struct str buf = STR_INIT;
|
static struct str buf = STR_INIT;
|
||||||
|
|
||||||
switch (f->f.which) {
|
switch (f->f.which) {
|
||||||
|
|
@ -922,20 +961,24 @@ static void define_field(struct strings *s, struct field *f) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Field_group:
|
case Field_group:
|
||||||
define_group(s, f->group, field_name(f), false);
|
define_group(s, f->group, field_name(f), false, extattr, extattr_space);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void define_getter_functions(struct node* node, struct field* field,
|
static void define_getter_functions(struct node* node, struct field* field,
|
||||||
struct strings* s)
|
struct strings* s, const char* extattr, const char* extattr_space)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* define getter
|
* define getter
|
||||||
*/
|
*/
|
||||||
str_addf(&s->pub_get_header, "\n%s %s_get_%s(%s_ptr p);\n", field->v.tname, node->name.str,
|
str_addf(&s->pub_get_header, "\n%s%s%s %s_get_%s(%s_ptr p);\n",
|
||||||
|
extattr, extattr_space,
|
||||||
|
field->v.tname, node->name.str,
|
||||||
field_name(field), node->name.str);
|
field_name(field), node->name.str);
|
||||||
str_addf(&s->pub_get, "\n%s %s_get_%s(%s_ptr p)\n", field->v.tname, node->name.str,
|
str_addf(&s->pub_get, "\n%s%s%s %s_get_%s(%s_ptr p)\n",
|
||||||
|
extattr, extattr_space,
|
||||||
|
field->v.tname, node->name.str,
|
||||||
field_name(field), node->name.str);
|
field_name(field), node->name.str);
|
||||||
struct str getter_body = STR_INIT;
|
struct str getter_body = STR_INIT;
|
||||||
get_member(&getter_body, field, "p.p", "", field_name(field));
|
get_member(&getter_body, field, "p.p", "", field_name(field));
|
||||||
|
|
@ -949,12 +992,16 @@ static void define_getter_functions(struct node* node, struct field* field,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void define_setter_functions(struct node* node, struct field* field,
|
static void define_setter_functions(struct node* node, struct field* field,
|
||||||
struct strings* s)
|
struct strings* s, const char* extattr, const char* extattr_space)
|
||||||
{
|
{
|
||||||
str_addf(&s->pub_set_header, "\nvoid %s_set_%s(%s_ptr p, %s %s);\n",node->name.str,
|
str_addf(&s->pub_set_header, "\n%s%svoid %s_set_%s(%s_ptr p, %s %s);\n",
|
||||||
|
extattr, extattr_space,
|
||||||
|
node->name.str,
|
||||||
field_name(field), node->name.str, field->v.tname,
|
field_name(field), node->name.str, field->v.tname,
|
||||||
field_name(field));
|
field_name(field));
|
||||||
str_addf(&s->pub_set, "\nvoid %s_set_%s(%s_ptr p, %s %s)\n",node->name.str,
|
str_addf(&s->pub_set, "\n%s%svoid %s_set_%s(%s_ptr p, %s %s)\n",
|
||||||
|
extattr, extattr_space,
|
||||||
|
node->name.str,
|
||||||
field_name(field), node->name.str, field->v.tname,
|
field_name(field), node->name.str, field->v.tname,
|
||||||
field_name(field));
|
field_name(field));
|
||||||
struct str setter_body = STR_INIT;
|
struct str setter_body = STR_INIT;
|
||||||
|
|
@ -963,7 +1010,8 @@ static void define_setter_functions(struct node* node, struct field* field,
|
||||||
str_release(&setter_body);
|
str_release(&setter_body);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void define_group(struct strings *s, struct node *n, const char *group_name, bool enclose_unions) {
|
static void define_group(struct strings *s, struct node *n, const char *group_name, bool enclose_unions,
|
||||||
|
const char* extattr, const char* extattr_space) {
|
||||||
struct field *f;
|
struct field *f;
|
||||||
int flen = capn_len(n->n._struct.fields);
|
int flen = capn_len(n->n._struct.fields);
|
||||||
int ulen = n->n._struct.discriminantCount;
|
int ulen = n->n._struct.discriminantCount;
|
||||||
|
|
@ -994,7 +1042,7 @@ static void define_group(struct strings *s, struct node *n, const char *group_na
|
||||||
|
|
||||||
/* fields before the union members */
|
/* fields before the union members */
|
||||||
for (f = n->fields; f < n->fields + flen && !in_union(f); f++) {
|
for (f = n->fields; f < n->fields + flen && !in_union(f); f++) {
|
||||||
define_field(s, f);
|
define_field(s, f, extattr, extattr_space);
|
||||||
|
|
||||||
if (!g_fieldgetset) {
|
if (!g_fieldgetset) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1012,8 +1060,8 @@ static void define_group(struct strings *s, struct node *n, const char *group_na
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
define_getter_functions(n, f, s);
|
define_getter_functions(n, f, s, extattr, extattr_space);
|
||||||
define_setter_functions(n, f, s);
|
define_setter_functions(n, f, s, extattr, extattr_space);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ulen > 0) {
|
if (ulen > 0) {
|
||||||
|
|
@ -1027,14 +1075,14 @@ static void define_group(struct strings *s, struct node *n, const char *group_na
|
||||||
|
|
||||||
const bool keep_union_name = named_union && !enclose_unions;
|
const bool keep_union_name = named_union && !enclose_unions;
|
||||||
|
|
||||||
do_union(s, n, f, keep_union_name ? group_name : NULL);
|
do_union(s, n, f, keep_union_name ? group_name : NULL, extattr, extattr_space);
|
||||||
|
|
||||||
while (f < n->fields + flen && in_union(f))
|
while (f < n->fields + flen && in_union(f))
|
||||||
f++;
|
f++;
|
||||||
|
|
||||||
/* fields after the unnamed union */
|
/* fields after the unnamed union */
|
||||||
for (;f < n->fields + flen; f++) {
|
for (;f < n->fields + flen; f++) {
|
||||||
define_field(s, f);
|
define_field(s, f, extattr, extattr_space);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enclose_unions)
|
if (enclose_unions)
|
||||||
|
|
@ -1054,7 +1102,7 @@ static void define_group(struct strings *s, struct node *n, const char *group_na
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void define_struct(struct node *n) {
|
static void define_struct(struct node *n, const char* extattr, const char* extattr_space) {
|
||||||
static struct strings s;
|
static struct strings s;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
@ -1074,12 +1122,13 @@ static void define_struct(struct node *n) {
|
||||||
str_add(&s.ftab, "\t", -1);
|
str_add(&s.ftab, "\t", -1);
|
||||||
str_add(&s.var, "s->", -1);
|
str_add(&s.var, "s->", -1);
|
||||||
|
|
||||||
define_group(&s, n, NULL, false);
|
define_group(&s, n, NULL, false, extattr, extattr_space);
|
||||||
|
|
||||||
str_add(&HDR, s.enums.str, s.enums.len);
|
str_add(&HDR, s.enums.str, s.enums.len);
|
||||||
|
|
||||||
str_addf(&HDR, "\n%sstruct %s {\n",
|
str_addf(&HDR, "\n%sstruct %s%s%s {\n",
|
||||||
s.decl.len == 0 ? "capnp_nowarn " : "",
|
s.decl.len == 0 ? "capnp_nowarn " : "",
|
||||||
|
extattr, extattr_space,
|
||||||
n->name.str);
|
n->name.str);
|
||||||
str_add(&HDR, s.decl.str, s.decl.len);
|
str_add(&HDR, s.decl.str, s.decl.len);
|
||||||
str_addf(&HDR, "};\n");
|
str_addf(&HDR, "};\n");
|
||||||
|
|
@ -1102,7 +1151,7 @@ static void define_struct(struct node *n) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
str_addf(&SRC, "\n%s_ptr new_%s(struct capn_segment *s) {\n", n->name.str, n->name.str);
|
str_addf(&SRC, "\n%s%s%s_ptr new_%s(struct capn_segment *s) {\n", extattr, extattr_space, n->name.str, n->name.str);
|
||||||
str_addf(&SRC, "\t%s_ptr p;\n", n->name.str);
|
str_addf(&SRC, "\t%s_ptr p;\n", n->name.str);
|
||||||
str_addf(&SRC, "\tp.p = capn_new_struct(s, %d, %d);\n", 8*n->n._struct.dataWordCount, n->n._struct.pointerCount);
|
str_addf(&SRC, "\tp.p = capn_new_struct(s, %d, %d);\n", 8*n->n._struct.dataWordCount, n->n._struct.pointerCount);
|
||||||
str_addf(&SRC, "\treturn p;\n");
|
str_addf(&SRC, "\treturn p;\n");
|
||||||
|
|
@ -1113,29 +1162,29 @@ static void define_struct(struct node *n) {
|
||||||
str_addf(&HDR, "\nstatic const size_t %s_pointer_count = %d;\n", n->name.str, n->n._struct.pointerCount);
|
str_addf(&HDR, "\nstatic const size_t %s_pointer_count = %d;\n", n->name.str, n->n._struct.pointerCount);
|
||||||
str_addf(&HDR, "\nstatic const size_t %s_struct_bytes_count = %d;\n\n", n->name.str, 8 * (n->n._struct.pointerCount + n->n._struct.dataWordCount));
|
str_addf(&HDR, "\nstatic const size_t %s_struct_bytes_count = %d;\n\n", n->name.str, 8 * (n->n._struct.pointerCount + n->n._struct.dataWordCount));
|
||||||
|
|
||||||
str_addf(&SRC, "%s_list new_%s_list(struct capn_segment *s, int len) {\n", n->name.str, n->name.str);
|
str_addf(&SRC, "%s%s%s_list new_%s_list(struct capn_segment *s, int len) {\n", extattr, extattr_space, n->name.str, n->name.str);
|
||||||
str_addf(&SRC, "\t%s_list p;\n", n->name.str);
|
str_addf(&SRC, "\t%s_list p;\n", n->name.str);
|
||||||
str_addf(&SRC, "\tp.p = capn_new_list(s, len, %d, %d);\n", 8*n->n._struct.dataWordCount, n->n._struct.pointerCount);
|
str_addf(&SRC, "\tp.p = capn_new_list(s, len, %d, %d);\n", 8*n->n._struct.dataWordCount, n->n._struct.pointerCount);
|
||||||
str_addf(&SRC, "\treturn p;\n");
|
str_addf(&SRC, "\treturn p;\n");
|
||||||
str_addf(&SRC, "}\n");
|
str_addf(&SRC, "}\n");
|
||||||
|
|
||||||
str_addf(&SRC, "void read_%s(struct %s *s capnp_unused, %s_ptr p) {\n", n->name.str, n->name.str, n->name.str);
|
str_addf(&SRC, "%s%svoid read_%s(struct %s *s capnp_unused, %s_ptr p) {\n", extattr, extattr_space, n->name.str, n->name.str, n->name.str);
|
||||||
str_addf(&SRC, "\tcapn_resolve(&p.p);\n\tcapnp_use(s);\n");
|
str_addf(&SRC, "\tcapn_resolve(&p.p);\n\tcapnp_use(s);\n");
|
||||||
str_add(&SRC, s.get.str, s.get.len);
|
str_add(&SRC, s.get.str, s.get.len);
|
||||||
str_addf(&SRC, "}\n");
|
str_addf(&SRC, "}\n");
|
||||||
|
|
||||||
str_addf(&SRC, "void write_%s(const struct %s *s capnp_unused, %s_ptr p) {\n", n->name.str, n->name.str, n->name.str);
|
str_addf(&SRC, "%s%svoid write_%s(const struct %s *s capnp_unused, %s_ptr p) {\n", extattr, extattr_space, n->name.str, n->name.str, n->name.str);
|
||||||
str_addf(&SRC, "\tcapn_resolve(&p.p);\n\tcapnp_use(s);\n");
|
str_addf(&SRC, "\tcapn_resolve(&p.p);\n\tcapnp_use(s);\n");
|
||||||
str_add(&SRC, s.set.str, s.set.len);
|
str_add(&SRC, s.set.str, s.set.len);
|
||||||
str_addf(&SRC, "}\n");
|
str_addf(&SRC, "}\n");
|
||||||
|
|
||||||
str_addf(&SRC, "void get_%s(struct %s *s, %s_list l, int i) {\n", n->name.str, n->name.str, n->name.str);
|
str_addf(&SRC, "%s%svoid get_%s(struct %s *s, %s_list l, int i) {\n", extattr, extattr_space, n->name.str, n->name.str, n->name.str);
|
||||||
str_addf(&SRC, "\t%s_ptr p;\n", n->name.str);
|
str_addf(&SRC, "\t%s_ptr p;\n", n->name.str);
|
||||||
str_addf(&SRC, "\tp.p = capn_getp(l.p, i, 0);\n");
|
str_addf(&SRC, "\tp.p = capn_getp(l.p, i, 0);\n");
|
||||||
str_addf(&SRC, "\tread_%s(s, p);\n", n->name.str);
|
str_addf(&SRC, "\tread_%s(s, p);\n", n->name.str);
|
||||||
str_addf(&SRC, "}\n");
|
str_addf(&SRC, "}\n");
|
||||||
|
|
||||||
str_addf(&SRC, "void set_%s(const struct %s *s, %s_list l, int i) {\n", n->name.str, n->name.str, n->name.str);
|
str_addf(&SRC, "%s%svoid set_%s(const struct %s *s, %s_list l, int i) {\n", extattr, extattr_space, n->name.str, n->name.str, n->name.str);
|
||||||
str_addf(&SRC, "\t%s_ptr p;\n", n->name.str);
|
str_addf(&SRC, "\t%s_ptr p;\n", n->name.str);
|
||||||
str_addf(&SRC, "\tp.p = capn_getp(l.p, i, 0);\n");
|
str_addf(&SRC, "\tp.p = capn_getp(l.p, i, 0);\n");
|
||||||
str_addf(&SRC, "\twrite_%s(s, p);\n", n->name.str);
|
str_addf(&SRC, "\twrite_%s(s, p);\n", n->name.str);
|
||||||
|
|
@ -1308,6 +1357,30 @@ static void declare(struct node *file_node, const char *format, int num) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void declare_ext(struct node *file_node, const char *format, int num,
|
||||||
|
const char* extattr, const char* extattr_space) {
|
||||||
|
struct node *n;
|
||||||
|
str_addf(&HDR, "\n");
|
||||||
|
for (n = file_node->file_nodes; n != NULL; n = n->next_file_node) {
|
||||||
|
if (n->n.which == Node__struct && !n->n._struct.isGroup) {
|
||||||
|
switch (num) {
|
||||||
|
case 3:
|
||||||
|
str_addf(&HDR, format, extattr, extattr_space,
|
||||||
|
n->name.str, n->name.str, n->name.str);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
str_addf(&HDR, format, extattr, extattr_space,
|
||||||
|
n->name.str, n->name.str);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
str_addf(&HDR, format, extattr, extattr_space,
|
||||||
|
n->name.str);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define ANNOTATION_NAMESPACE 0xf2c035025fec7c2bUL
|
#define ANNOTATION_NAMESPACE 0xf2c035025fec7c2bUL
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
@ -1451,6 +1524,9 @@ int main() {
|
||||||
const char *nameinfix = NULL;
|
const char *nameinfix = NULL;
|
||||||
FILE *srcf, *hdrf;
|
FILE *srcf, *hdrf;
|
||||||
struct id_bst * donotinclude_ids = NULL;
|
struct id_bst * donotinclude_ids = NULL;
|
||||||
|
struct string_list * extraheader_strings = NULL;
|
||||||
|
const char* extattr = NULL;
|
||||||
|
const char* extattr_space = "";
|
||||||
|
|
||||||
g_valc = 0;
|
g_valc = 0;
|
||||||
g_valseg.len = 0;
|
g_valseg.len = 0;
|
||||||
|
|
@ -1495,10 +1571,35 @@ int main() {
|
||||||
}
|
}
|
||||||
donotinclude_ids = insert_id(donotinclude_ids, v.uint64);
|
donotinclude_ids = insert_id(donotinclude_ids, v.uint64);
|
||||||
break;
|
break;
|
||||||
|
case 0xbadb496d09cf4612UL: /* $C::extraheader("...") */
|
||||||
|
if (v.which != Value_text)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "schema breakage on $C::extraheader annotation\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
extraheader_strings = insert_file(extraheader_strings, v.text.str ? v.text.str : "");
|
||||||
|
break;
|
||||||
|
case 0xd187bca5c6844c24UL: /* $C::extendedattribute("...") */
|
||||||
|
if (v.which != Value_text)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "schema breakage on $C::extendedattribute annotation\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
if (extattr) {
|
||||||
|
fprintf(stderr, "$C::extendedattribute annotation appears more than once\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
if (v.text.str && strlen(v.text.str)) {
|
||||||
|
extattr = v.text.str;
|
||||||
|
extattr_space = " ";
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!nameinfix)
|
if (!nameinfix)
|
||||||
nameinfix = "";
|
nameinfix = "";
|
||||||
|
if (!extattr)
|
||||||
|
extattr = "";
|
||||||
|
|
||||||
str_reset(&HDR);
|
str_reset(&HDR);
|
||||||
str_reset(&SRC);
|
str_reset(&SRC);
|
||||||
|
|
@ -1506,7 +1607,23 @@ int main() {
|
||||||
str_addf(&HDR, "#ifndef CAPN_%X%X\n", (uint32_t) (file_node->n.id >> 32), (uint32_t) file_node->n.id);
|
str_addf(&HDR, "#ifndef CAPN_%X%X\n", (uint32_t) (file_node->n.id >> 32), (uint32_t) file_node->n.id);
|
||||||
str_addf(&HDR, "#define CAPN_%X%X\n", (uint32_t) (file_node->n.id >> 32), (uint32_t) file_node->n.id);
|
str_addf(&HDR, "#define CAPN_%X%X\n", (uint32_t) (file_node->n.id >> 32), (uint32_t) file_node->n.id);
|
||||||
str_addf(&HDR, "/* AUTO GENERATED - DO NOT EDIT */\n");
|
str_addf(&HDR, "/* AUTO GENERATED - DO NOT EDIT */\n");
|
||||||
str_addf(&HDR, "#include <capnp_c.h>\n\n");
|
str_addf(&HDR, "#include <capnp_c.h>\n");
|
||||||
|
/* Do [extraheader] in declaration order. */
|
||||||
|
struct string_list ** current = &extraheader_strings;
|
||||||
|
struct string_list ** prev = &extraheader_strings;
|
||||||
|
while (*current)
|
||||||
|
{
|
||||||
|
prev = current;
|
||||||
|
current = &(*current)->next;
|
||||||
|
}
|
||||||
|
current = prev;
|
||||||
|
while (*current)
|
||||||
|
{
|
||||||
|
str_addf(&HDR, "%s\n", (*current)->string);
|
||||||
|
current = &(*current)->prev;
|
||||||
|
}
|
||||||
|
str_addf(&HDR, "\n");
|
||||||
|
|
||||||
str_addf(&HDR, "#if CAPN_VERSION != 1\n");
|
str_addf(&HDR, "#if CAPN_VERSION != 1\n");
|
||||||
str_addf(&HDR, "#error \"version mismatch between capnp_c.h and generated code\"\n");
|
str_addf(&HDR, "#error \"version mismatch between capnp_c.h and generated code\"\n");
|
||||||
str_addf(&HDR, "#endif\n\n");
|
str_addf(&HDR, "#endif\n\n");
|
||||||
|
|
@ -1541,10 +1658,11 @@ int main() {
|
||||||
|
|
||||||
free_id_bst(used_import_ids);
|
free_id_bst(used_import_ids);
|
||||||
free_id_bst(donotinclude_ids);
|
free_id_bst(donotinclude_ids);
|
||||||
|
free_string_list(extraheader_strings);
|
||||||
|
|
||||||
str_addf(&HDR, "\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
|
str_addf(&HDR, "\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
|
||||||
|
|
||||||
declare(file_node, "struct %s;\n", 1);
|
declare_ext(file_node, "struct %s%s%s;\n", 1, extattr, extattr_space);
|
||||||
declare(file_node, "typedef struct {capn_ptr p;} %s_ptr;\n", 1);
|
declare(file_node, "typedef struct {capn_ptr p;} %s_ptr;\n", 1);
|
||||||
declare(file_node, "typedef struct {capn_ptr p;} %s_list;\n", 1);
|
declare(file_node, "typedef struct {capn_ptr p;} %s_list;\n", 1);
|
||||||
|
|
||||||
|
|
@ -1562,16 +1680,16 @@ int main() {
|
||||||
|
|
||||||
for (n = file_node->file_nodes; n != NULL; n = n->next_file_node) {
|
for (n = file_node->file_nodes; n != NULL; n = n->next_file_node) {
|
||||||
if (n->n.which == Node__struct && !n->n._struct.isGroup) {
|
if (n->n.which == Node__struct && !n->n._struct.isGroup) {
|
||||||
define_struct(n);
|
define_struct(n, extattr, extattr_space);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare(file_node, "%s_ptr new_%s(struct capn_segment*);\n", 2);
|
declare_ext(file_node, "%s%s%s_ptr new_%s(struct capn_segment*);\n", 2, extattr, extattr_space);
|
||||||
declare(file_node, "%s_list new_%s_list(struct capn_segment*, int len);\n", 2);
|
declare_ext(file_node, "%s%s%s_list new_%s_list(struct capn_segment*, int len);\n", 2, extattr, extattr_space);
|
||||||
declare(file_node, "void read_%s(struct %s*, %s_ptr);\n", 3);
|
declare_ext(file_node, "%s%svoid read_%s(struct %s*, %s_ptr);\n", 3, extattr, extattr_space);
|
||||||
declare(file_node, "void write_%s(const struct %s*, %s_ptr);\n", 3);
|
declare_ext(file_node, "%s%svoid write_%s(const struct %s*, %s_ptr);\n", 3, extattr, extattr_space);
|
||||||
declare(file_node, "void get_%s(struct %s*, %s_list, int i);\n", 3);
|
declare_ext(file_node, "%s%svoid get_%s(struct %s*, %s_list, int i);\n", 3, extattr, extattr_space);
|
||||||
declare(file_node, "void set_%s(const struct %s*, %s_list, int i);\n", 3);
|
declare_ext(file_node, "%s%svoid set_%s(const struct %s*, %s_list, int i);\n", 3, extattr, extattr_space);
|
||||||
|
|
||||||
str_addf(&HDR, "\n#ifdef __cplusplus\n}\n#endif\n#endif\n");
|
str_addf(&HDR, "\n#ifdef __cplusplus\n}\n#endif\n#endif\n");
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue