From 5d787b698e3e182dfb186f7dfc61eb0236ed71d8 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 22 Jun 2016 15:16:40 +0200 Subject: [PATCH] compiler: add "C::nameinfix" annotation allows changing output filenames from "foo.capnp.c" to "foo.capnpSOMETHING.c" where SOMETHING is the argument to the annotation. --- Makefile.am | 3 +++ compiler/c.capnp | 32 ++++++++++++++++++++++++++++++++ compiler/capnpc-c.c | 30 +++++++++++++++++++++++++++--- configure.ac | 9 +++++++++ 4 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 compiler/c.capnp diff --git a/Makefile.am b/Makefile.am index 2690646..4d81510 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,6 +15,9 @@ EXTRA_DIST += c-capnproto.pc.in pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = c-capnproto.pc +EXTRA_DIST += compiler/c.capnp +capnp_DATA = compiler/c.capnp + AM_CPPFLAGS = -I${srcdir}/lib lib_LTLIBRARIES += libcapnp_c.la diff --git a/compiler/c.capnp b/compiler/c.capnp new file mode 100644 index 0000000..f244105 --- /dev/null +++ b/compiler/c.capnp @@ -0,0 +1,32 @@ +# Copyright (c) 2016 NetDEF, Inc. and contributors +# Licensed under the MIT License: +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +@0xc0183dd65ffef0f3; + +# add an infix (middle insert) for output file names +# +# "make" generally has implicit rules for compiling "foo.c" => "foo". This +# is very annoying with capnp since the rule will be "foo" => "foo.c", leading +# to a loop. $nameinfix (recommended parameter: "-gen") inserts its parameter +# before the ".c", so the filename becomes "foo-gen.c" +# +# ("foo" is really "foo.capnp", so it's foo.capnp-gen.c) +annotation nameinfix @0x85a8d86d736ba637 (file): Text; diff --git a/compiler/capnpc-c.c b/compiler/capnpc-c.c index 95f927f..9b82314 100644 --- a/compiler/capnpc-c.c +++ b/compiler/capnpc-c.c @@ -1243,6 +1243,7 @@ int main() { struct CodeGeneratorRequest_RequestedFile file_req; static struct str b = STR_INIT; char *p; + const char *nameinfix = NULL; FILE *srcf, *hdrf; g_valc = 0; @@ -1259,6 +1260,29 @@ int main() { exit(2); } + for (j = capn_len(file_node->n.annotations)-1; j >= 0; j--) { + struct Annotation a; + struct Value v; + get_Annotation(&a, file_node->n.annotations, j); + read_Value(&v, a.value); + + switch (a.id) { + case 0x85a8d86d736ba637UL: /* $C::nameinfix */ + if (v.which != Value_text) { + fprintf(stderr, "schema breakage on $C::nameinfix annotation\n"); + exit(2); + } + if (nameinfix) { + fprintf(stderr, "$C::nameinfix annotation appears more than once\n"); + exit(2); + } + nameinfix = v.text.str ? v.text.str : ""; + break; + } + } + if (!nameinfix) + nameinfix = ""; + str_reset(&HDR); str_reset(&SRC); @@ -1311,7 +1335,7 @@ int main() { /* write out the header */ - hdrf = fopen(strf(&b, "%s.h", file_node->n.displayName.str), "w"); + hdrf = fopen(strf(&b, "%s%s.h", file_node->n.displayName.str, nameinfix), "w"); if (!hdrf) { fprintf(stderr, "failed to open %s: %s\n", b.str, strerror(errno)); exit(2); @@ -1321,13 +1345,13 @@ int main() { /* write out the source */ - srcf = fopen(strf(&b, "%s.c", file_node->n.displayName.str), "w"); + srcf = fopen(strf(&b, "%s%s.c", file_node->n.displayName.str, nameinfix), "w"); if (!srcf) { fprintf(stderr, "failed to open %s: %s\n", b.str, strerror(errno)); exit(2); } p = strrchr(file_node->n.displayName.str, '/'); - fprintf(srcf, "#include \"%s.h\"\n", p ? p+1 : file_node->n.displayName.str); + fprintf(srcf, "#include \"%s%s.h\"\n", p ? p+1 : file_node->n.displayName.str, nameinfix); fprintf(srcf, "/* AUTO GENERATED - DO NOT EDIT */\n"); if (g_val0used) diff --git a/configure.ac b/configure.ac index 60ac622..cc8f35a 100755 --- a/configure.ac +++ b/configure.ac @@ -31,6 +31,15 @@ if test x"${enable_werror}" = x"yes" ; then fi AC_SUBST(WERROR) +AC_ARG_WITH(capnpdir, + AS_HELP_STRING([--with-capnpdir=DIR], [directory to install c.capnp file in (default: $includedir/capnp)])) +if test x"${with_capnpdir}" != x ; then + capnpdir="${with_capnpdir}" +else + capnpdir="${includedir}/capnp" +fi +AC_SUBST(capnpdir) + #PKG_CHECK_MODULES(CAPNP, [capnp >= 0.5.2], [], [ # AC_MSG_ERROR([capnproto base package (0.5.2 or newer) not found]) #])