diff mbox

[1/4,v1.1] Remove Wundef warnings for specification macros

Message ID 20141001091518.GK2217@spoyarek.pnq.redhat.com
State New
Headers show

Commit Message

Siddhesh Poyarekar Oct. 1, 2014, 9:15 a.m. UTC
Hi,

Here's an updated version of this patch based on Florian's feedback.
Tested on x86_64.

Siddhesh

commit 01f70b23d014d27898be8fa3d7a216c671007365
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date:   Wed Oct 1 14:34:08 2014 +0530

    Remove Wundef warnings for specification macros
    
    This patch adds a file conf.list that is used to generate macros to
    determine if a macro is defined as set, unset or not defined.
    gen-conf.awk processes this file and generates a header
    (confdefs-defs.h) with these macros.  A new header confdefs.h includes
    this generated header and defines accessor macros for the generated
    macros.
    
    Tested on x86_64.
    
    	* posix/Makefile (before-compile): Add confdefs-defs.h.
    	($(objpfx)confdefs-defs.h): New target.
    	* posix/conf.list: New file.
    	* posix/confdefs.h: New file.
    	* posix/confstr.c: Include confdefs.h.
    	(confstr): Use CONF_IS_* macros.
    	* posix/posix-envs.def: Include confdefs.h.  Use CONF_IS_*
    	macros.
    	* scripts/gen-conf.awk: New file.

Comments

Roland McGrath Dec. 18, 2014, 12:41 a.m. UTC | #1
"confdefs-defs" just seems like an inane name.  Please find something better.

I think "posix-conf-vars.list" would be a better name than "conf.list",
which sounds too generic.

> +$(objpfx)confdefs-defs.h: conf.list Makefile $(..)scripts/gen-conf.awk
> +	$(make-target-directory)
> +	$(AWK) -f $(..)scripts/gen-conf.awk $< > $@.tmp
> +	mv -f $@.tmp $@

The usual way we do this is:

$(objpfx)confdefs-defs.h: $(..)scripts/gen-conf.awk conf.list Makefile 
[...]
	$(AWK) -f $(filter-out Makefile, $^) > $@.tmp

> --- /dev/null
> +++ b/posix/confdefs.h
> @@ -0,0 +1,15 @@
> +#ifndef __CONFDEFS_H__
> +#define __CONFDEFS_H__

Missing comment and copyright header.  Guard macro is just _FOO_H, no
extra leading underscore and no trailing underscores.

> +#include <posix/confdefs-defs.h>

Where does posix/confdefs-defs.h come from??  Is that just hitting because
of -I$(common-objdir) and the generated code happens to be in the posix/
build subdirectory?

If you're including the generated file, just <confdefs-defs.h> is the right
syntax.  If it needs to be used by code compiled outside the posix/
subdirectory (which I don't think it should), then put the generated file
in $(common-objdir) directly.

As well as a new name for both this file and the generated file, this file
needs substantial commentary explaining the rationale and how to use the
macros.

> +#define CONF_DEF_UNDEFINED 1
> +#define CONF_DEF_DEFINED_SET 2
> +#define CONF_DEF_DEFINED_UNSET 3
> +
> +#define CONF_IS_DEFINED_SET(conf) (conf##_DEF == CONF_DEF_DEFINED_SET)
> +#define CONF_IS_DEFINED_UNSET(conf) (conf##_DEF == CONF_DEF_DEFINED_UNSET)
> +#define CONF_IS_UNDEFINED(conf) (conf##_DEF == CONF_DEF_UNDEFINED)
> +#define CONF_IS_DEFINED(conf) (conf##_DEF != CONF_DEF_UNDEFINED)

Style is to use tabs between the lhs and rhs to line up all the rhs.

Incidentally, it seems more proper to me to use a prefix for the
constructed magic macro names, rather than a suffix.  
i.e. CONF_DEF_##conf or the like.

> --- a/posix/confstr.c
> +++ b/posix/confstr.c
> @@ -21,6 +21,7 @@
>  #include <string.h>
>  #include <confstr.h>
>  #include "../version.h"
> +#include "confdefs.h"

Use <> syntax for generated files (or sysdeps files, or almost any case in
libc).

> --- /dev/null
> +++ b/scripts/gen-conf.awk

Let's give it a less generic-sounding name.  Maybe "posix-conf-vars"?

> +  PROCINFO["sorted_in"] = "@val_type_asc"

I couldn't even find what this means in the Gawk manual.  It's probably
better to avoid such obscure features if it's not prohibitive.  At the very
least, you need a clear comment about what this magic does.

> +# Begin a new prefix.
> +$2 == "{" {
> +  split ($1, arr, ":")
> +  type = arr[1]
> +  prefix = arr[2]
> +  next
> +}

Why not just make the syntax use separate words rather than splitting on a
colon?  If some are optional, match with $NF == "{".

> +{
> +  if (prefix == "" && type == "" && sc_prefix == "") {
> +    print "Syntax error" > "/dev/stderr"
> +    exit 1
> +  }

You can use FILENAME and FNR to produce C-x `-compatible error messages.

> +ENDFILE {

Just use END.

> +  print "/* Autogenerated by gen-conf.awk.  */\n"

Include "DO NOT EDIT!".

This is OK with those cleanups.


Thanks,
Roland
diff mbox

Patch

diff --git a/posix/Makefile b/posix/Makefile
index e6b69b4..bdf6e73 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -99,7 +99,7 @@  others		:= getconf
 install-bin	:= getconf
 install-others-programs	:= $(inst_libexecdir)/getconf
 
-before-compile	+= testcases.h ptestcases.h
+before-compile	+= testcases.h ptestcases.h confdefs-defs.h
 
 # So they get cleaned up.
 generated += $(addprefix wordexp-test-result, 1 2 3 4 5 6 7 8 9 10) \
@@ -325,3 +325,8 @@  $(objpfx)getconf.speclist: getconf-speclist.c posix-envs.def
 # be built both makes it available for eyeball inspection and avoids the
 # surprise of things that look like compilation being done by 'make install'.
 others: $(objpfx)getconf.speclist
+
+$(objpfx)confdefs-defs.h: conf.list Makefile $(..)scripts/gen-conf.awk
+	$(make-target-directory)
+	$(AWK) -f $(..)scripts/gen-conf.awk $< > $@.tmp
+	mv -f $@.tmp $@
diff --git a/posix/conf.list b/posix/conf.list
new file mode 100644
index 0000000..3470895
--- /dev/null
+++ b/posix/conf.list
@@ -0,0 +1,22 @@ 
+# Configuration variables identified by getconf.  The heading of each section
+# is of the format TYPE:PREFIX with the opening curly brace on the same line.
+# TYPE can either be SYSCONF, PATHCONF, CONFSTR or SPEC.  Variable names are
+# put one on each line with a curly brace on its own line ending the section.
+
+SPEC:POSIX {
+  V6_ILP32_OFF32
+  V6_ILP32_OFFBIG
+  V6_LP64_OFF64
+  V6_LPBIG_OFFBIG
+  V7_ILP32_OFF32
+  V7_ILP32_OFFBIG
+  V7_LP64_OFF64
+  V7_LPBIG_OFFBIG
+}
+
+SPEC:XBS5 {
+  ILP32_OFF32
+  ILP32_OFFBIG
+  LP64_OFF64
+  LPBIG_OFFBIG
+}
diff --git a/posix/confdefs.h b/posix/confdefs.h
new file mode 100644
index 0000000..64f0e03
--- /dev/null
+++ b/posix/confdefs.h
@@ -0,0 +1,15 @@ 
+#ifndef __CONFDEFS_H__
+#define __CONFDEFS_H__
+
+#include <posix/confdefs-defs.h>
+
+#define CONF_DEF_UNDEFINED 1
+#define CONF_DEF_DEFINED_SET 2
+#define CONF_DEF_DEFINED_UNSET 3
+
+#define CONF_IS_DEFINED_SET(conf) (conf##_DEF == CONF_DEF_DEFINED_SET)
+#define CONF_IS_DEFINED_UNSET(conf) (conf##_DEF == CONF_DEF_DEFINED_UNSET)
+#define CONF_IS_UNDEFINED(conf) (conf##_DEF == CONF_DEF_UNDEFINED)
+#define CONF_IS_DEFINED(conf) (conf##_DEF != CONF_DEF_UNDEFINED)
+
+#endif
diff --git a/posix/confstr.c b/posix/confstr.c
index a2a1bf2..1accfee 100644
--- a/posix/confstr.c
+++ b/posix/confstr.c
@@ -21,6 +21,7 @@ 
 #include <string.h>
 #include <confstr.h>
 #include "../version.h"
+#include "confdefs.h"
 
 /* If BUF is not NULL and LEN > 0, fill in at most LEN - 1 bytes
    of BUF with the value corresponding to NAME and zero-terminate BUF.
@@ -100,9 +101,9 @@  confstr (name, buf, len)
     case _CS_POSIX_V6_ILP32_OFF32_CFLAGS:
     case _CS_POSIX_V7_ILP32_OFF32_CFLAGS:
 #ifdef __ILP32_OFF32_CFLAGS
-# if _POSIX_V7_ILP32_OFF32 == -1
+# if CONF_IS_DEFINED_UNSET (_POSIX_V7_ILP32_OFF32)
 #  error "__ILP32_OFF32_CFLAGS should not be defined"
-# elif !defined _POSIX_V7_ILP32_OFF32
+# elif CONF_IS_UNDEFINED (_POSIX_V7_ILP32_OFF32)
       if (__sysconf (_SC_V7_ILP32_OFF32) < 0)
 	break;
 # endif
@@ -115,9 +116,9 @@  confstr (name, buf, len)
     case _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS:
     case _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS:
 #ifdef __ILP32_OFFBIG_CFLAGS
-# if _POSIX_V7_ILP32_OFFBIG == -1
+# if CONF_IS_DEFINED_UNSET (_POSIX_V7_ILP32_OFFBIG)
 #  error "__ILP32_OFFBIG_CFLAGS should not be defined"
-# elif !defined _POSIX_V7_ILP32_OFFBIG
+# elif CONF_IS_UNDEFINED (_POSIX_V7_ILP32_OFFBIG)
       if (__sysconf (_SC_V7_ILP32_OFFBIG) < 0)
 	break;
 # endif
@@ -130,9 +131,9 @@  confstr (name, buf, len)
     case _CS_POSIX_V6_LP64_OFF64_CFLAGS:
     case _CS_POSIX_V7_LP64_OFF64_CFLAGS:
 #ifdef __LP64_OFF64_CFLAGS
-# if _POSIX_V7_LP64_OFF64 == -1
+# if CONF_IS_DEFINED_UNSET (_POSIX_V7_LP64_OFF64)
 #  error "__LP64_OFF64_CFLAGS should not be defined"
-# elif !defined _POSIX_V7_LP64_OFF64
+# elif CONF_IS_UNDEFINED (_POSIX_V7_LP64_OFF64)
       if (__sysconf (_SC_V7_LP64_OFF64) < 0)
 	break;
 # endif
@@ -145,9 +146,9 @@  confstr (name, buf, len)
     case _CS_POSIX_V6_ILP32_OFF32_LDFLAGS:
     case _CS_POSIX_V7_ILP32_OFF32_LDFLAGS:
 #ifdef __ILP32_OFF32_LDFLAGS
-# if _POSIX_V7_ILP32_OFF32 == -1
+# if CONF_IS_DEFINED_UNSET (_POSIX_V7_ILP32_OFF32 )
 #  error "__ILP32_OFF32_LDFLAGS should not be defined"
-# elif !defined _POSIX_V7_ILP32_OFF32
+# elif CONF_IS_UNDEFINED (_POSIX_V7_ILP32_OFF32)
       if (__sysconf (_SC_V7_ILP32_OFF32) < 0)
 	break;
 # endif
@@ -160,9 +161,9 @@  confstr (name, buf, len)
     case _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS:
     case _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS:
 #ifdef __ILP32_OFFBIG_LDFLAGS
-# if _POSIX_V7_ILP32_OFFBIG == -1
+# if CONF_IS_DEFINED_UNSET (_POSIX_V7_ILP32_OFFBIG)
 #  error "__ILP32_OFFBIG_LDFLAGS should not be defined"
-# elif !defined _POSIX_V7_ILP32_OFFBIG
+# elif CONF_IS_UNDEFINED (_POSIX_V7_ILP32_OFFBIG)
       if (__sysconf (_SC_V7_ILP32_OFFBIG) < 0)
 	break;
 # endif
@@ -175,9 +176,9 @@  confstr (name, buf, len)
     case _CS_POSIX_V6_LP64_OFF64_LDFLAGS:
     case _CS_POSIX_V7_LP64_OFF64_LDFLAGS:
 #ifdef __LP64_OFF64_LDFLAGS
-# if _POSIX_V7_LP64_OFF64 == -1
+# if CONF_IS_DEFINED_UNSET (_POSIX_V7_LP64_OFF64)
 #  error "__LP64_OFF64_LDFLAGS should not be defined"
-# elif !defined _POSIX_V7_LP64_OFF64
+# elif CONF_IS_UNDEFINED (_POSIX_V7_LP64_OFF64)
       if (__sysconf (_SC_V7_LP64_OFF64) < 0)
 	break;
 # endif
@@ -188,7 +189,8 @@  confstr (name, buf, len)
 
     case _CS_LFS_CFLAGS:
     case _CS_LFS_LINTFLAGS:
-#if _POSIX_V6_ILP32_OFF32 == 1 && _POSIX_V6_ILP32_OFFBIG == 1
+#if (CONF_IS_DEFINED_SET (_POSIX_V6_ILP32_OFF32) \
+     && CONF_IS_DEFINED_SET (_POSIX_V6_ILP32_OFFBIG))
 # define __LFS_CFLAGS "-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
       /* Signal that we want the new ABI.  */
       string = __LFS_CFLAGS;
diff --git a/posix/posix-envs.def b/posix/posix-envs.def
index 05043e9..9047d0c 100644
--- a/posix/posix-envs.def
+++ b/posix/posix-envs.def
@@ -42,35 +42,37 @@ 
    defined.  These are called with arguments V5, V6, V7 before and
    after the relevant groups of environments.  */
 
+#include "confdefs.h"
+
 START_ENV_GROUP (V7)
 
-#if _POSIX_V7_ILP32_OFF32 > 0
+#if CONF_IS_DEFINED_SET (_POSIX_V7_ILP32_OFF32)
 KNOWN_PRESENT_ENVIRONMENT (V7, POSIX_V7, ILP32_OFF32)
-#elif defined _POSIX_V7_ILP32_OFF32
+#elif CONF_IS_DEFINED (_POSIX_V7_ILP32_OFF32)
 KNOWN_ABSENT_ENVIRONMENT (V7, POSIX_V7, ILP32_OFF32)
 #else
 UNKNOWN_ENVIRONMENT (V7, POSIX_V7, ILP32_OFF32)
 #endif
 
-#if _POSIX_V7_ILP32_OFFBIG > 0
+#if CONF_IS_DEFINED_SET (_POSIX_V7_ILP32_OFFBIG)
 KNOWN_PRESENT_ENVIRONMENT (V7, POSIX_V7, ILP32_OFFBIG)
-#elif defined _POSIX_V7_ILP32_OFFBIG
+#elif CONF_IS_DEFINED (_POSIX_V7_ILP32_OFFBIG)
 KNOWN_ABSENT_ENVIRONMENT (V7, POSIX_V7, ILP32_OFFBIG)
 #else
 UNKNOWN_ENVIRONMENT (V7, POSIX_V7, ILP32_OFFBIG)
 #endif
 
-#if _POSIX_V7_LP64_OFF64 > 0
+#if CONF_IS_DEFINED_SET (_POSIX_V7_LP64_OFF64)
 KNOWN_PRESENT_ENVIRONMENT (V7, POSIX_V7, LP64_OFF64)
-#elif defined _POSIX_V7_LP64_OFF64
+#elif CONF_IS_DEFINED (_POSIX_V7_LP64_OFF64)
 KNOWN_ABSENT_ENVIRONMENT (V7, POSIX_V7, LP64_OFF64)
 #else
 UNKNOWN_ENVIRONMENT (V7, POSIX_V7, LP64_OFF64)
 #endif
 
-#if _POSIX_V7_LPBIG_OFFBIG > 0
+#if CONF_IS_DEFINED_SET (_POSIX_V7_LPBIG_OFFBIG)
 KNOWN_PRESENT_ENVIRONMENT (V7, POSIX_V7, LPBIG_OFFBIG)
-#elif defined _POSIX_V7_LPBIG_OFFBIG
+#elif CONF_IS_DEFINED (_POSIX_V7_LPBIG_OFFBIG)
 KNOWN_ABSENT_ENVIRONMENT (V7, POSIX_V7, LPBIG_OFFBIG)
 #else
 UNKNOWN_ENVIRONMENT (V7, POSIX_V7, LPBIG_OFFBIG)
@@ -80,33 +82,33 @@  END_ENV_GROUP (V7)
 
 START_ENV_GROUP (V6)
 
-#if _POSIX_V6_ILP32_OFF32 > 0
+#if CONF_IS_DEFINED_SET (_POSIX_V6_ILP32_OFF32)
 KNOWN_PRESENT_ENVIRONMENT (V6, POSIX_V6, ILP32_OFF32)
-#elif defined _POSIX_V6_ILP32_OFF32
+#elif CONF_IS_DEFINED (_POSIX_V6_ILP32_OFF32)
 KNOWN_ABSENT_ENVIRONMENT (V6, POSIX_V6, ILP32_OFF32)
 #else
 UNKNOWN_ENVIRONMENT (V6, POSIX_V6, ILP32_OFF32)
 #endif
 
-#if _POSIX_V6_ILP32_OFFBIG > 0
+#if CONF_IS_DEFINED_SET (_POSIX_V6_ILP32_OFFBIG)
 KNOWN_PRESENT_ENVIRONMENT (V6, POSIX_V6, ILP32_OFFBIG)
-#elif defined _POSIX_V6_ILP32_OFFBIG
+#elif CONF_IS_DEFINED (_POSIX_V6_ILP32_OFFBIG)
 KNOWN_ABSENT_ENVIRONMENT (V6, POSIX_V6, ILP32_OFFBIG)
 #else
 UNKNOWN_ENVIRONMENT (V6, POSIX_V6, ILP32_OFFBIG)
 #endif
 
-#if _POSIX_V6_LP64_OFF64 > 0
+#if CONF_IS_DEFINED_SET (_POSIX_V6_LP64_OFF64)
 KNOWN_PRESENT_ENVIRONMENT (V6, POSIX_V6, LP64_OFF64)
-#elif defined _POSIX_V6_LP64_OFF64
+#elif CONF_IS_DEFINED (_POSIX_V6_LP64_OFF64)
 KNOWN_ABSENT_ENVIRONMENT (V6, POSIX_V6, LP64_OFF64)
 #else
 UNKNOWN_ENVIRONMENT (V6, POSIX_V6, LP64_OFF64)
 #endif
 
-#if _POSIX_V6_LPBIG_OFFBIG > 0
+#if CONF_IS_DEFINED_SET (_POSIX_V6_LPBIG_OFFBIG)
 KNOWN_PRESENT_ENVIRONMENT (V6, POSIX_V6, LPBIG_OFFBIG)
-#elif defined _POSIX_V6_LPBIG_OFFBIG
+#elif CONF_IS_DEFINED (_POSIX_V6_LPBIG_OFFBIG)
 KNOWN_ABSENT_ENVIRONMENT (V6, POSIX_V6, LPBIG_OFFBIG)
 #else
 UNKNOWN_ENVIRONMENT (V6, POSIX_V6, LPBIG_OFFBIG)
@@ -116,33 +118,33 @@  END_ENV_GROUP (V6)
 
 START_ENV_GROUP (V5)
 
-#if _XBS5_ILP32_OFF32 > 0
+#if CONF_IS_DEFINED_SET (_XBS5_ILP32_OFF32)
 KNOWN_PRESENT_ENVIRONMENT (XBS5, XBS5, ILP32_OFF32)
-#elif defined _XBS5_ILP32_OFF32
+#elif CONF_IS_DEFINED (_XBS5_ILP32_OFF32)
 KNOWN_ABSENT_ENVIRONMENT (XBS5, XBS5, ILP32_OFF32)
 #else
 UNKNOWN_ENVIRONMENT (XBS5, XBS5, ILP32_OFF32)
 #endif
 
-#if _XBS5_ILP32_OFFBIG > 0
+#if CONF_IS_DEFINED_SET (_XBS5_ILP32_OFFBIG)
 KNOWN_PRESENT_ENVIRONMENT (XBS5, XBS5, ILP32_OFFBIG)
-#elif defined _XBS5_ILP32_OFFBIG
+#elif CONF_IS_DEFINED (_XBS5_ILP32_OFFBIG)
 KNOWN_ABSENT_ENVIRONMENT (XBS5, XBS5, ILP32_OFFBIG)
 #else
 UNKNOWN_ENVIRONMENT (XBS5, XBS5, ILP32_OFFBIG)
 #endif
 
-#if _XBS5_LP64_OFF64 > 0
+#if CONF_IS_DEFINED_SET (_XBS5_LP64_OFF64)
 KNOWN_PRESENT_ENVIRONMENT (XBS5, XBS5, LP64_OFF64)
-#elif defined _XBS5_LP64_OFF64
+#elif CONF_IS_DEFINED (_XBS5_LP64_OFF64)
 KNOWN_ABSENT_ENVIRONMENT (XBS5, XBS5, LP64_OFF64)
 #else
 UNKNOWN_ENVIRONMENT (XBS5, XBS5, LP64_OFF64)
 #endif
 
-#if _XBS5_LPBIG_OFFBIG > 0
+#if CONF_IS_DEFINED_SET (_XBS5_LPBIG_OFFBIG)
 KNOWN_PRESENT_ENVIRONMENT (XBS5, XBS5, LPBIG_OFFBIG)
-#elif defined _XBS5_LPBIG_OFFBIG
+#elif CONF_IS_DEFINED (_XBS5_LPBIG_OFFBIG)
 KNOWN_ABSENT_ENVIRONMENT (XBS5, XBS5, LPBIG_OFFBIG)
 #else
 UNKNOWN_ENVIRONMENT (XBS5, XBS5, LPBIG_OFFBIG)
diff --git a/scripts/gen-conf.awk b/scripts/gen-conf.awk
new file mode 100644
index 0000000..45a4d44
--- /dev/null
+++ b/scripts/gen-conf.awk
@@ -0,0 +1,63 @@ 
+# Generate confdefs-defs.h with definitions for {CONF}_DEF for each
+# configuration variable that getconf or sysconf may use.  Currently it is
+# equipped only to generate such macros for specification macros and for
+# SYSCONF macros in the _POSIX namespace.
+
+BEGIN {
+  PROCINFO["sorted_in"] = "@val_type_asc"
+  prefix = ""
+}
+
+$1 ~ /^#/ || $0 ~ /^\s*$/ {
+  next
+}
+
+# Begin a new prefix.
+$2 == "{" {
+  split ($1, arr, ":")
+  type = arr[1]
+  prefix = arr[2]
+  next
+}
+
+$1 == "}" {
+  prefix = ""
+  type = ""
+  next
+}
+
+{
+  if (prefix == "" && type == "" && sc_prefix == "") {
+    print "Syntax error" > "/dev/stderr"
+    exit 1
+  }
+
+  # The prefix and variable names are indices and the value indicates what type
+  # of variable it is.  The possible options are:
+  # CONFSTR: A configuration string
+  # SYSCONF: A numeric value
+  # SPEC: A specification
+  conf[prefix][$1] = type
+}
+
+ENDFILE {
+  print "/* Autogenerated by gen-conf.awk.  */\n"
+
+  # Generate macros that specify if a sysconf macro is defined and/or set.
+  for (p in conf) {
+    for (c in conf[p]) {
+      printf "#ifndef _%s_%s\n", p, c
+      printf "# define _%s_%s_DEF CONF_DEF_UNDEFINED\n", p, c
+      # CONFSTR have string values and they are not set or unset.
+      if (conf[p][c] != "CONFSTR") {
+	printf "#else\n"
+	printf "# if _%s_%s > 0\n", p, c
+	printf "#  define _%s_%s_DEF CONF_DEF_DEFINED_SET\n", p, c
+	printf "# else\n"
+	printf "#  define _%s_%s_DEF CONF_DEF_DEFINED_UNSET\n", p, c
+	printf "# endif\n"
+      }
+      printf "#endif\n\n"
+    }
+  }
+}