[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Fix build error due to open_memstream
From: |
Jose E. Marchesi |
Subject: |
Re: Fix build error due to open_memstream |
Date: |
Sun, 21 Feb 2021 23:39:10 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) |
Hi Bruno.
> On Solaris 10, I get a build error:
>
> Undefined first referenced
> symbol in file
> open_memstream ../libpoke/.libs/libpoke.so
> ld: fatal: symbol referencing errors. No output written to .libs/poke
>
> This is because libpoke makes use of the unportable function 'open_memstream'.
> This function exists in
> - Solaris 11.4, but not in Solaris <= 11.3 and Solaris OpenIndiana,
> - macOS 10.13, but not in macOS 10.5,
> - NetBSD 8.0, but not in NetBSD 7.1.1,
> - AIX 7.1, but not in AIX 6.1.
> and is also missing in
> - HP-UX 11.31
> - Minix 3.3.
>
> At least Solaris 11.3 is still supported for 3 more years, see
> <https://en.wikipedia.org/wiki/Solaris_(operating_system)#Version_history> .
>
> Gnulib provides a utility module 'string-buffer', as a replacement for
> 'open_memstream' (since today).
>
> Here's a patch to make use of this module instead of 'open_memstream'.
string-buffer has a nice API.
> The changes to the .c files in the test suite are needed to avoid a link
> error in the test suite programs, caused by the following:
> - The new module relies on vsnprintf().
> - To avoid buggy vsnprintf outputs, I made it depend on 'vsnprintf-posix'
> (poke/bootstrap.conf already relies on 'printf-posix').
> - The redirection "#define vsnprintf rpl_vsnprintf" is only meant for
> libpoke, but is visible also in the test suite.
> - /usr/include/dejagnu.h has a couple of inline functions which reference
> vsnprintf. So, they see the redirection to rpl_vsnprintf.
> - The symbol rpl_vsnprintf is not exported from libpoke.so.
> If you have a better idea how to fix this?
I think
+#undef vsnprintf
+#include <dejagnu.h>
is clear enough, and also robust.
OK for master.
Thanks!
>
>>From 8ca57ac1b85f233a12c1f72dfeefdae37c383025 Mon Sep 17 00:00:00 2001
> From: Bruno Haible <bruno@clisp.org>
> Date: Sun, 21 Feb 2021 23:30:19 +0100
> Subject: [PATCH] Don't use unportable function open_memstream.
>
> * gnulib: Update to newest.
> * bootstrap.conf (libpoke_modules): Add string-buffer.
> * libpoke/pkl-ast.c: Include "string-buffer.h".
> (pkl_type_append_to): New function, based on pkl_print_type.
> (pkl_type_str): Invoke pkl_type_append_to.
> (pkl_print_type): Invoke pkl_type_str.
> * testsuite/poke.libpoke/api.c: Undefine vsnprintf for DejaGnu.
> * testsuite/poke.libpoke/values.c: Likewise.
> * testsuite/poke.mi-json/mi-json.c: Likewise.
> ---
> bootstrap.conf | 1 +
> gnulib | 2 +-
> libpoke/pkl-ast.c | 110
> +++++++++++++++++++++++----------------
> testsuite/poke.libpoke/api.c | 5 +-
> testsuite/poke.libpoke/values.c | 5 +-
> testsuite/poke.mi-json/mi-json.c | 5 +-
> 6 files changed, 78 insertions(+), 50 deletions(-)
>
> diff --git a/bootstrap.conf b/bootstrap.conf
> index 175832b..a7a7666 100644
> --- a/bootstrap.conf
> +++ b/bootstrap.conf
> @@ -79,6 +79,7 @@ libpoke_modules="
> stddef
> strchrnul
> streq
> + string-buffer
> strtoull
> signal-h
> tempname
> diff --git a/gnulib b/gnulib
> index 3b732e7..c9b44f2 160000
> --- a/gnulib
> +++ b/gnulib
> @@ -1 +1 @@
> -Subproject commit 3b732e789cfb83917814aba4446f10b3bd8a9355
> +Subproject commit c9b44f214c7c798c7701c7a281584e262b263655
> diff --git a/libpoke/pkl-ast.c b/libpoke/pkl-ast.c
> index c9355c5..eb7f4ee 100644
> --- a/libpoke/pkl-ast.c
> +++ b/libpoke/pkl-ast.c
> @@ -23,6 +23,7 @@
> #include <stdlib.h>
> #include <stdio.h>
> #include <inttypes.h>
> +#include "string-buffer.h"
> #include "xalloc.h"
>
> #include "pvm.h"
> @@ -1153,12 +1154,13 @@ pkl_ast_type_is_complete (pkl_ast_node type)
> return complete;
> }
>
> -/* Print a textual description of TYPE to the file OUT. If TYPE is a
> +
> +/* Append the textual description of TYPE to BUFFER. If TYPE is a
> named type then its given name is preferred if USE_GIVEN_NAME is
> 1. */
> -
> -void
> -pkl_print_type (FILE *out, pkl_ast_node type, int use_given_name)
> +static void
> +pkl_type_append_to (pkl_ast_node type, int use_given_name,
> + struct string_buffer *buffer)
> {
> assert (PKL_AST_CODE (type) == PKL_AST_TYPE);
>
> @@ -1167,8 +1169,7 @@ pkl_print_type (FILE *out, pkl_ast_node type, int
> use_given_name)
> if (use_given_name
> && PKL_AST_TYPE_NAME (type))
> {
> - fprintf (out, "%s",
> - PKL_AST_IDENTIFIER_POINTER (PKL_AST_TYPE_NAME (type)));
> + sb_append (buffer, PKL_AST_IDENTIFIER_POINTER (PKL_AST_TYPE_NAME
> (type)));
> return;
> }
>
> @@ -1179,26 +1180,26 @@ pkl_print_type (FILE *out, pkl_ast_node type, int
> use_given_name)
> switch (PKL_AST_TYPE_CODE (type))
> {
> case PKL_TYPE_ANY:
> - fprintf (out, "any");
> + sb_append (buffer, "any");
> break;
> case PKL_TYPE_INTEGRAL:
> if (!PKL_AST_TYPE_I_SIGNED_P (type))
> - fputc ('u', out);
> - fprintf (out, "int<%zd>", PKL_AST_TYPE_I_SIZE (type));
> + sb_append (buffer, "u");
> + sb_appendf (buffer, "int<%zd>", PKL_AST_TYPE_I_SIZE (type));
> break;
> case PKL_TYPE_VOID:
> - fprintf (out, "void");
> + sb_append (buffer, "void");
> break;
> case PKL_TYPE_STRING:
> - fprintf (out, "string");
> + sb_append (buffer, "string");
> break;
> case PKL_TYPE_ARRAY:
> {
> pkl_ast_node bound = PKL_AST_TYPE_A_BOUND (type);
>
> - pkl_print_type (out, PKL_AST_TYPE_A_ETYPE (type),
> - use_given_name);
> - fputc ('[', out);
> + pkl_type_append_to (PKL_AST_TYPE_A_ETYPE (type), use_given_name,
> + buffer);
> + sb_append (buffer, "[");
> if (bound != NULL)
> {
> pkl_ast_node bound_type = PKL_AST_TYPE (bound);
> @@ -1207,17 +1208,17 @@ pkl_print_type (FILE *out, pkl_ast_node type, int
> use_given_name)
> && PKL_AST_TYPE_CODE (bound_type) == PKL_TYPE_INTEGRAL
> && PKL_AST_CODE (bound) == PKL_AST_INTEGER)
> {
> - fprintf (out, "%" PRIu64, PKL_AST_INTEGER_VALUE (bound));
> + sb_appendf (buffer, "%" PRIu64, PKL_AST_INTEGER_VALUE
> (bound));
> }
> }
> - fputc (']', out);
> + sb_append (buffer, "]");
> break;
> }
> case PKL_TYPE_STRUCT:
> {
> pkl_ast_node t;
>
> - fputs ("struct {", out);
> + sb_append (buffer, "struct {");
>
> for (t = PKL_AST_TYPE_S_ELEMS (type); t;
> t = PKL_AST_CHAIN (t))
> @@ -1227,14 +1228,16 @@ pkl_print_type (FILE *out, pkl_ast_node type, int
> use_given_name)
> pkl_ast_node ename = PKL_AST_STRUCT_TYPE_FIELD_NAME (t);
> pkl_ast_node etype = PKL_AST_STRUCT_TYPE_FIELD_TYPE (t);
>
> - pkl_print_type (out, etype, use_given_name);
> + pkl_type_append_to (etype, use_given_name, buffer);
> if (ename)
> - fprintf (out, " %s",
> - PKL_AST_IDENTIFIER_POINTER (ename));
> - fputc (';', out);
> + {
> + sb_append (buffer, " ");
> + sb_append (buffer, PKL_AST_IDENTIFIER_POINTER (ename));
> + }
> + sb_append (buffer, ";");
> }
> }
> - fputs ("}", out);
> + sb_append (buffer, "}");
> break;
> }
> case PKL_TYPE_FUNCTION:
> @@ -1243,7 +1246,7 @@ pkl_print_type (FILE *out, pkl_ast_node type, int
> use_given_name)
>
> if (PKL_AST_TYPE_F_NARG (type) > 0)
> {
> - fputc ('(', out);
> + sb_append (buffer, "(");
>
> for (t = PKL_AST_TYPE_F_ARGS (type); t;
> t = PKL_AST_CHAIN (t))
> @@ -1252,45 +1255,44 @@ pkl_print_type (FILE *out, pkl_ast_node type, int
> use_given_name)
> = PKL_AST_FUNC_TYPE_ARG_TYPE (t);
>
> if (PKL_AST_FUNC_TYPE_ARG_VARARG (t))
> - fputs ("...", out);
> + sb_append (buffer, "...");
> else
> {
> if (t != PKL_AST_TYPE_F_ARGS (type))
> - fputc (',', out);
> - pkl_print_type (out, atype, use_given_name);
> + sb_append (buffer, ",");
> + pkl_type_append_to (atype, use_given_name, buffer);
> if (PKL_AST_FUNC_TYPE_ARG_OPTIONAL (t))
> - fputc ('?', out);
> + sb_append (buffer, "?");
> }
> }
>
> - fputc (')', out);
> + sb_append (buffer, ")");
> }
>
> - pkl_print_type (out,
> - PKL_AST_TYPE_F_RTYPE (type),
> - use_given_name);
> - fputc (':', out);
> + pkl_type_append_to (PKL_AST_TYPE_F_RTYPE (type), use_given_name,
> + buffer);
> + sb_append (buffer, ":");
> break;
> }
> case PKL_TYPE_OFFSET:
> {
> pkl_ast_node unit = PKL_AST_TYPE_O_UNIT (type);
>
> - fputs ("offset<", out);
> - pkl_print_type (out, PKL_AST_TYPE_O_BASE_TYPE (type),
> - use_given_name);
> - fputc (',', out);
> + sb_append (buffer, "offset<");
> + pkl_type_append_to (PKL_AST_TYPE_O_BASE_TYPE (type), use_given_name,
> + buffer);
> + sb_append (buffer, ",");
>
> if (PKL_AST_CODE (unit) == PKL_AST_TYPE)
> - pkl_print_type (out, unit, use_given_name);
> + pkl_type_append_to (unit, use_given_name, buffer);
> else if (PKL_AST_CODE (unit) == PKL_AST_IDENTIFIER)
> - fputs (PKL_AST_IDENTIFIER_POINTER (unit), out);
> + sb_append (buffer, PKL_AST_IDENTIFIER_POINTER (unit));
> else if (PKL_AST_CODE (unit) == PKL_AST_INTEGER)
> - fprintf (out, "%" PRIu64, PKL_AST_INTEGER_VALUE (unit));
> + sb_appendf (buffer, "%" PRIu64, PKL_AST_INTEGER_VALUE (unit));
> else
> assert (0);
>
> - fputc ('>', out);
> + sb_append (buffer, ">");
> break;
> }
> case PKL_TYPE_NOTYPE:
> @@ -1300,21 +1302,37 @@ pkl_print_type (FILE *out, pkl_ast_node type, int
> use_given_name)
> }
> }
>
> -/* Like pkl_print_type, but return the string describing the type in a
> - string. It is up to the caller to free the string memory. */
> +/* Return a string with a textual description of TYPE. If TYPE is a
> + named type then its given name is preferred if USE_GIVEN_NAME is
> + 1. It is up to the caller to free the string memory. */
>
> char *
> pkl_type_str (pkl_ast_node type, int use_given_name)
> {
> + struct string_buffer buffer;
> char *str;
> - size_t str_size;
> - FILE *buffer = open_memstream (&str, &str_size);
>
> - pkl_print_type (buffer, type, use_given_name);
> - fclose (buffer);
> + sb_init (&buffer);
> + pkl_type_append_to (type, use_given_name, &buffer);
> + str = sb_dupfree (&buffer);
> + if (str == NULL)
> + /* The only possible error here is out-of-memory. */
> + xalloc_die ();
> return str;
> }
>
> +/* Print a textual description of TYPE to the file OUT. If TYPE is a
> + named type then its given name is preferred if USE_GIVEN_NAME is
> + 1. */
> +
> +void
> +pkl_print_type (FILE *out, pkl_ast_node type, int use_given_name)
> +{
> + char *str = pkl_type_str (type, use_given_name);
> + fputs (str, out);
> + free (str);
> +}
> +
> /* Return a boolean telling whether the given type function only have
> optional arguments, i.e. all arguments have an initializer. */
>
> diff --git a/testsuite/poke.libpoke/api.c b/testsuite/poke.libpoke/api.c
> index efc2d38..c9351f7 100644
> --- a/testsuite/poke.libpoke/api.c
> +++ b/testsuite/poke.libpoke/api.c
> @@ -21,11 +21,14 @@
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> -#include <dejagnu.h>
> #include <err.h>
> #include "read-file.h"
> #include "libpoke.h"
>
> +/* DejaGnu should not use gnulib's vsnprintf replacement here. */
> +#undef vsnprintf
> +#include <dejagnu.h>
> +
> #include "term-if.h"
>
> #define T(name, cond)
> \
> diff --git a/testsuite/poke.libpoke/values.c b/testsuite/poke.libpoke/values.c
> index 9248a42..681160f 100644
> --- a/testsuite/poke.libpoke/values.c
> +++ b/testsuite/poke.libpoke/values.c
> @@ -23,12 +23,15 @@
> #include <stdlib.h>
> #include <string.h>
> #include <stdint.h>
> -#include <dejagnu.h>
> #include <dirent.h>
> #include <err.h>
> #include "read-file.h"
> #include "libpoke.h"
>
> +/* DejaGnu should not use gnulib's vsnprintf replacement here. */
> +#undef vsnprintf
> +#include <dejagnu.h>
> +
> #include "term-if.h"
>
> #define STREQ(a,b) (strcmp (a, b) == 0)
> diff --git a/testsuite/poke.mi-json/mi-json.c
> b/testsuite/poke.mi-json/mi-json.c
> index 666e12d..2ea077f 100644
> --- a/testsuite/poke.mi-json/mi-json.c
> +++ b/testsuite/poke.mi-json/mi-json.c
> @@ -21,11 +21,14 @@
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> -#include <dejagnu.h>
> #include <dirent.h>
> #include <err.h>
> #include <json.h>
>
> +/* DejaGnu should not use gnulib's vsnprintf replacement here. */
> +#undef vsnprintf
> +#include <dejagnu.h>
> +
> #include "pk-mi-msg.h"
> #include "pk-mi-json.h"
> #include "libpoke.h"