poke-devel
[Top][All Lists]
Advanced

[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"



reply via email to

[Prev in Thread] Current Thread [Next in Thread]