poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] libpoke,poke,poked,pokefmt: add `pk_compiler' to terminal in


From: Jose E. Marchesi
Subject: Re: [PATCH] libpoke,poke,poked,pokefmt: add `pk_compiler' to terminal interface
Date: Wed, 01 Nov 2023 23:14:15 +0100
User-agent: Gnus/5.13 (Gnus v5.13)

Hi Mohammad.

> This patch adds `pk_compiler' paramter to add terminal interface
> function pointers.
> Additionally it adds two new API function to set/get a user-defined
> opaque pointer to a compiler instance.  The user can use these helper
> functions in the terminal interface callbacks to retrieve the pointer.

The change looks generally ok, but for maintenance reasons and to ease
review it would be better to split this into a series, with at least
these parts:

- Patch that turns pk_print_binary into the macro PK_PRINT_BINARY.

- Patch that adds support for an user payload to be registered in
  libpoke, i.e. internal pointer and getter/setter services.

- Patch that changes the terminal interface in libpoke to pass the
  pk_compiler as an argument, and that changes the poke CLI, poked and
  other users.

Would that be possible?

>
> 2023-11-01  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
>
>       * libpoke/libpoke.h (struct pk_term_if): Add `pk_compiler' parameter
>       to all function pointers.
>       (pk_set_user_data): New function to register an opaque data pointer.
>       (pk_get_user_data): New function to retrieve the registered opaque
>       data pointer.
>       * libpoke/libpoke.c (struct _pk_compiler): Add new field `user_data'.
>       (libpoke_term_if): Change the type to `struct pk_term_if_internal'.
>       (pk_compiler_new_with_flags): Populate `libpoke_term_if'.
>       (pk_set_user_data): New function impl.
>       (pk_get_user_data): Likewise.
>       * libpoke/pkt.h (PKT_IF): New macro to convey the terminal interface
>       function pointers.
>       (PK_PKC): New macro to convey the instance of current incremental
>       compiler.
>       (pk_*): Re-write the macro definitions to new paradigm.
>       (struct pk_term_if_internal): New data type.
>       (libpoke_term_if): Change the type of the variable.
>       * common/pk-utils.h (pk_print_binary): Remove function decl.
>       (PK_PRINT_BINARY): New macro for printing in base 2 to make use of
>       `pk_puts' macro easier.
>       * common/pk-utils.c (pk_print_binary): Remove function.
>       (pk_integral_suffix): New function.
>       * libpoke/pvm-val.c (pvm_print_val_1): Change `pk_print_binary' to
>       `PK_PRINT_BINARY'.
>       * libpoke/pvm.jitter (wrapped-functions):
>       s/pk_print_binary/pk_integral_suffix/.
>       (PVM_PRINTI): s/pk_print_binary/PK_PRINT_BINARY/.
>       (PVM_PRINTL): Likewise.
>       * poke/pk-cmd-compiler.c (pk_cmd_compiler_ast): Adapt the new terminal
>       interface.
>       * poke/pk-cmd-def.c (PREP_REGEXP_PAYLOAD): Likewise.
>       (pk_cmd_info_type): Likewise.
>       * poke/pk-cmd-editor.c (pk_cmd_editor): Likewise.
>       * poke/pk-cmd-ios.c (pk_cmd_ios): Likewise.
>       (pk_cmd_sub): Likewise.
>       (pk_cmd_proc): Likewise.
>       (pk_cmd_file): Likewise.
>       (pk_cmd_close): Likewise.
>       (pk_cmd_load_file): Likewise.
>       (pk_cmd_source_file): Likewise.
>       (pk_cmd_mem): Likewise.
>       (pk_cmd_nbd): Likewise.
>       * poke/pk-cmd-map.c (SET_TO_CUR_IOS_ID): Likewise.
>       (pk_cmd_map_create): Likewise.
>       (pk_cmd_map_remove): Likewise.
>       (pk_cmd_show): Likewise.
>       (pk_cmd_map_entry_add): Likewise.
>       (pk_cmd_map_entry_remove): Likewise.
>       (pk_cmd_map_load): Likewise.
>       (pk_cmd_map_save): Likewise.
>       (pk_cmd_info_maps): Likewise.
>       * poke/pk-cmd-misc.c (pk_cmd_doc): Likewise.
>       * poke/pk-cmd-set.c (pk_cmd_set_dump): Likewise.
>       * poke/pk-cmd-vm.c (pk_cmd_vm_disas_exp): Likewise.
>       * poke/pk-cmd.c (pk_cmd_exec_1): Likewise.
>       * poke/pk-hserver.c (read_from_client): Likewise.
>       * poke/pk-ios.c (pk_open_file): Likewise.
>       * poke/pk-map-tab.y (pk_map_printf_error): Likewise.
>       * poke/pk-map.c (pk_map_load_parsed_map): Likewise.
>       * poke/pk-repl.c (banner): Likewise.
>       (pk_repl): Likewise.
>       (pk_repl_display_begin): Likewise.
>       (pk_repl_display_end): Likewise.
>       * poke/pk-table.c (pk_table_print): Likewise.
>       * poke/pk-term.h (pk_term_flush): Add `pk_compiler' parameter.
>       (pk_puts): Likewise.
>       (pk_printf): Likewise.
>       (pk_vprintf): Likewise.
>       (pk_term_indent): Likewise.
>       (pk_term_class): Likewise.
>       (pk_term_end_class): Likewise.
>       (pk_term_hyperlink): Likewise.
>       (pk_term_end_hyperlink): Likewise.
>       (pk_term_get_color): Likewise.
>       (pk_term_get_bgcolor): Likewise.
>       (pk_term_set_color): Likewise.
>       (pk_term_set_bgcolor): Likewise.
>       * poke/pk-term.c (pk_term_flush): Likewise.
>       (pk_puts): Likewise.
>       (pk_printf): Likewise.
>       (pk_vprintf): Likewise.
>       (pk_term_indent): Likewise.
>       (pk_term_class): Likewise.
>       (pk_term_end_class): Likewise.
>       (pk_term_hyperlink): Likewise.
>       (pk_term_end_hyperlink): Likewise.
>       (pk_term_get_color): Likewise.
>       (pk_term_get_bgcolor): Likewise.
>       (pk_term_set_color): Likewise.
>       (pk_term_set_bgcolor): Likewise.
>       * poked/poked.c (tif_flush): Likewise.
>       (tif_puts): Likewise.
>       (tif_printf): Likewise.
>       (tif_indent): Likewise.
>       (tif_class): Likewise.
>       (tif_class_end): Likewise.
>       (tif_hlink): Likewise.
>       (tif_hlink_end): Likewise.
>       (tif_color): Likewise.
>       (tif_bgcolor): Likewise.
>       (tif_color_set): Likewise.
>       (tif_bgcolor_set): Likewise.
>       * pokefmt/pokefmt.l (tif_flush): Likewise.
>       (tif_puts): Likewise.
>       (tif_printf): Likewise.
>       (tif_indent): Likewise.
>       (tif_class): Likewise.
>       (tif_class_end): Likewise.
>       (tif_hlink): Likewise.
>       (tif_hlink_end): Likewise.
>       (tif_color): Likewise.
>       (tif_bgcolor): Likewise.
>       (tif_color_set): Likewise.
>       (tif_bgcolor_set): Likewise.
>       * testsutie/poke.libpoke/term-if.h (pk_term_flush): Likewise.
>       (pk_puts): Likewise.
>       (pk_printf): Likewise.
>       (pk_term_indent): Likewise.
>       (pk_term_class): Likewise.
>       (pk_term_end_class): Likewise.
>       (pk_term_hyperlink): Likewise.
>       (pk_term_end_hyperlink): Likewise.
>       (pk_term_get_color): Likewise.
>       (pk_term_get_bgcolor): Likewise.
>       (pk_term_set_color): Likewise.
>       (pk_term_set_bgcolor): Likewise.
> ---
>
> Hi Jose.
>
> Yet another boring patch :D
> This patch will pass the compiler instance as a new parameter to the
> terminal interface (as we agreed on in GNU40).
>
> I also changed the `libpoke/pkt.h' to be ready for next patches to remove
> global state from libpoke.  This is the first step as we discussed.
>
> Regards,
> Mohammad-Reza
>
>
>  ChangeLog                        | 129 +++++++++++++++++++++++++++++++
>  common/pk-utils.c                |  33 +++-----
>  common/pk-utils.h                |  27 ++++++-
>  libpoke/libpoke.c                |  20 ++++-
>  libpoke/libpoke.h                |  29 ++++---
>  libpoke/pkt.h                    |  46 +++++++----
>  libpoke/pvm-val.c                |  11 +--
>  libpoke/pvm.jitter               |   6 +-
>  poke/pk-cmd-compiler.c           |   2 +-
>  poke/pk-cmd-def.c                |  17 ++--
>  poke/pk-cmd-editor.c             |  38 ++++-----
>  poke/pk-cmd-ios.c                |  39 +++++-----
>  poke/pk-cmd-map.c                |  60 +++++++-------
>  poke/pk-cmd-misc.c               |  11 +--
>  poke/pk-cmd-set.c                |  28 +++----
>  poke/pk-cmd-vm.c                 |  17 ++--
>  poke/pk-cmd.c                    |  19 +++--
>  poke/pk-hserver.c                |  12 +--
>  poke/pk-ios.c                    |  27 +++----
>  poke/pk-map-tab.y                |  11 +--
>  poke/pk-map.c                    |   2 +-
>  poke/pk-repl.c                   |  44 +++++------
>  poke/pk-table.c                  |  22 +++---
>  poke/pk-term.c                   |  38 ++++-----
>  poke/pk-term.h                   |  31 ++++----
>  poked/poked.c                    |  26 ++++---
>  pokefmt/pokefmt.l                |  26 ++++---
>  testsuite/poke.libpoke/term-if.h |  36 ++++-----
>  28 files changed, 500 insertions(+), 307 deletions(-)
>
> diff --git a/ChangeLog b/ChangeLog
> index 5fd7f8c3..03ac15ac 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,132 @@
> +2023-11-01  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
> +
> +     * libpoke/libpoke.h (struct pk_term_if): Add `pk_compiler' parameter
> +     to all function pointers.
> +     (pk_set_user_data): New function to register an opaque data pointer.
> +     (pk_get_user_data): New function to retrieve the registered opaque
> +     data pointer.
> +     * libpoke/libpoke.c (struct _pk_compiler): Add new field `user_data'.
> +     (libpoke_term_if): Change the type to `struct pk_term_if_internal'.
> +     (pk_compiler_new_with_flags): Populate `libpoke_term_if'.
> +     (pk_set_user_data): New function impl.
> +     (pk_get_user_data): Likewise.
> +     * libpoke/pkt.h (PKT_IF): New macro to convey the terminal interface
> +     function pointers.
> +     (PK_PKC): New macro to convey the instance of current incremental
> +     compiler.
> +     (pk_*): Re-write the macro definitions to new paradigm.
> +     (struct pk_term_if_internal): New data type.
> +     (libpoke_term_if): Change the type of the variable.
> +     * common/pk-utils.h (pk_print_binary): Remove function decl.
> +     (PK_PRINT_BINARY): New macro for printing in base 2 to make use of
> +     `pk_puts' macro easier.
> +     * common/pk-utils.c (pk_print_binary): Remove function.
> +     (pk_integral_suffix): New function.
> +     * libpoke/pvm-val.c (pvm_print_val_1): Change `pk_print_binary' to
> +     `PK_PRINT_BINARY'.
> +     * libpoke/pvm.jitter (wrapped-functions):
> +     s/pk_print_binary/pk_integral_suffix/.
> +     (PVM_PRINTI): s/pk_print_binary/PK_PRINT_BINARY/.
> +     (PVM_PRINTL): Likewise.
> +     * poke/pk-cmd-compiler.c (pk_cmd_compiler_ast): Adapt the new terminal
> +     interface.
> +     * poke/pk-cmd-def.c (PREP_REGEXP_PAYLOAD): Likewise.
> +     (pk_cmd_info_type): Likewise.
> +     * poke/pk-cmd-editor.c (pk_cmd_editor): Likewise.
> +     * poke/pk-cmd-ios.c (pk_cmd_ios): Likewise.
> +     (pk_cmd_sub): Likewise.
> +     (pk_cmd_proc): Likewise.
> +     (pk_cmd_file): Likewise.
> +     (pk_cmd_close): Likewise.
> +     (pk_cmd_load_file): Likewise.
> +     (pk_cmd_source_file): Likewise.
> +     (pk_cmd_mem): Likewise.
> +     (pk_cmd_nbd): Likewise.
> +     * poke/pk-cmd-map.c (SET_TO_CUR_IOS_ID): Likewise.
> +     (pk_cmd_map_create): Likewise.
> +     (pk_cmd_map_remove): Likewise.
> +     (pk_cmd_show): Likewise.
> +     (pk_cmd_map_entry_add): Likewise.
> +     (pk_cmd_map_entry_remove): Likewise.
> +     (pk_cmd_map_load): Likewise.
> +     (pk_cmd_map_save): Likewise.
> +     (pk_cmd_info_maps): Likewise.
> +     * poke/pk-cmd-misc.c (pk_cmd_doc): Likewise.
> +     * poke/pk-cmd-set.c (pk_cmd_set_dump): Likewise.
> +     * poke/pk-cmd-vm.c (pk_cmd_vm_disas_exp): Likewise.
> +     * poke/pk-cmd.c (pk_cmd_exec_1): Likewise.
> +     * poke/pk-hserver.c (read_from_client): Likewise.
> +     * poke/pk-ios.c (pk_open_file): Likewise.
> +     * poke/pk-map-tab.y (pk_map_printf_error): Likewise.
> +     * poke/pk-map.c (pk_map_load_parsed_map): Likewise.
> +     * poke/pk-repl.c (banner): Likewise.
> +     (pk_repl): Likewise.
> +     (pk_repl_display_begin): Likewise.
> +     (pk_repl_display_end): Likewise.
> +     * poke/pk-table.c (pk_table_print): Likewise.
> +     * poke/pk-term.h (pk_term_flush): Add `pk_compiler' parameter.
> +     (pk_puts): Likewise.
> +     (pk_printf): Likewise.
> +     (pk_vprintf): Likewise.
> +     (pk_term_indent): Likewise.
> +     (pk_term_class): Likewise.
> +     (pk_term_end_class): Likewise.
> +     (pk_term_hyperlink): Likewise.
> +     (pk_term_end_hyperlink): Likewise.
> +     (pk_term_get_color): Likewise.
> +     (pk_term_get_bgcolor): Likewise.
> +     (pk_term_set_color): Likewise.
> +     (pk_term_set_bgcolor): Likewise.
> +     * poke/pk-term.c (pk_term_flush): Likewise.
> +     (pk_puts): Likewise.
> +     (pk_printf): Likewise.
> +     (pk_vprintf): Likewise.
> +     (pk_term_indent): Likewise.
> +     (pk_term_class): Likewise.
> +     (pk_term_end_class): Likewise.
> +     (pk_term_hyperlink): Likewise.
> +     (pk_term_end_hyperlink): Likewise.
> +     (pk_term_get_color): Likewise.
> +     (pk_term_get_bgcolor): Likewise.
> +     (pk_term_set_color): Likewise.
> +     (pk_term_set_bgcolor): Likewise.
> +     * poked/poked.c (tif_flush): Likewise.
> +     (tif_puts): Likewise.
> +     (tif_printf): Likewise.
> +     (tif_indent): Likewise.
> +     (tif_class): Likewise.
> +     (tif_class_end): Likewise.
> +     (tif_hlink): Likewise.
> +     (tif_hlink_end): Likewise.
> +     (tif_color): Likewise.
> +     (tif_bgcolor): Likewise.
> +     (tif_color_set): Likewise.
> +     (tif_bgcolor_set): Likewise.
> +     * pokefmt/pokefmt.l (tif_flush): Likewise.
> +     (tif_puts): Likewise.
> +     (tif_printf): Likewise.
> +     (tif_indent): Likewise.
> +     (tif_class): Likewise.
> +     (tif_class_end): Likewise.
> +     (tif_hlink): Likewise.
> +     (tif_hlink_end): Likewise.
> +     (tif_color): Likewise.
> +     (tif_bgcolor): Likewise.
> +     (tif_color_set): Likewise.
> +     (tif_bgcolor_set): Likewise.
> +     * testsutie/poke.libpoke/term-if.h (pk_term_flush): Likewise.
> +     (pk_puts): Likewise.
> +     (pk_printf): Likewise.
> +     (pk_term_indent): Likewise.
> +     (pk_term_class): Likewise.
> +     (pk_term_end_class): Likewise.
> +     (pk_term_hyperlink): Likewise.
> +     (pk_term_end_hyperlink): Likewise.
> +     (pk_term_get_color): Likewise.
> +     (pk_term_get_bgcolor): Likewise.
> +     (pk_term_set_color): Likewise.
> +     (pk_term_set_bgcolor): Likewise.
> +
>  2023-11-01  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
>  
>       * libpoke/libpoke.h (pk_ios_search): Add new param: FLAGS to support
> diff --git a/common/pk-utils.c b/common/pk-utils.c
> index 1134251c..d1c7cf90 100644
> --- a/common/pk-utils.c
> +++ b/common/pk-utils.c
> @@ -82,29 +82,18 @@ PK_POW (pk_upow, uint64_t)
>  
>  #undef PK_POW
>  
> -void
> -pk_print_binary (void (*puts_fn) (const char *str),
> -                 uint64_t val, int size, int sign_p, int use_suffix_p)
> +const char *
> +pk_integral_suffix (int size, int sign_p)
>  {
> -  char b[65];
> -
> -  for (int z = 0; z < size; z++)
> -    b[size-1-z] = ((val >> z) & 0x1) + '0';
> -  b[size] = '\0';
> -
> -  puts_fn (b);
> -
> -  if  (use_suffix_p)
> -    {
> -      if (size == 64)
> -        puts_fn (sign_p ? "L" : "UL");
> -      else if (size == 16)
> -        puts_fn (sign_p ? "H" : "UH");
> -      else if (size == 8)
> -        puts_fn (sign_p ? "B" : "UB");
> -      else if (size == 4)
> -        puts_fn (sign_p ? "N" : "UN");
> -    }
> +  if (size == 64)
> +    return sign_p ? "L" : "UL";
> +  if (size == 16)
> +    return sign_p ? "H" : "UH";
> +  if (size == 8)
> +    return sign_p ? "B" : "UB";
> +  if (size == 4)
> +    return sign_p ? "N" : "UN";
> +  return "";
>  }
>  
>  int
> diff --git a/common/pk-utils.h b/common/pk-utils.h
> index 97f5dc0a..78e49a5c 100644
> --- a/common/pk-utils.h
> +++ b/common/pk-utils.h
> @@ -49,9 +49,32 @@ char *pk_file_readable (const char *filename);
>  int64_t pk_ipow (int64_t base, uint32_t exp);
>  uint64_t pk_upow (uint64_t base, uint32_t exp);
>  
> +/* Return one of the following strings based on the SIZE and SIGN_P:
> +     "N", "UN", "B", "UB", "H", "UH", "L", "UL"
> +   which are valid suffix for integral values in Poke.  */
> +
> +const char *pk_integral_suffix (int size, int sign_p);
> +
>  /* Print the given unsigned 64-bit integer in binary. */
> -void pk_print_binary (void (*puts_fn) (const char *str), uint64_t val,
> -                      int size, int sign_p, int use_suffix_p);
> +
> +#define PK_PRINT_BINARY(val, size, sign_p, use_suffix_p)                     
>  \
> +  do                                                                         
>  \
> +    {                                                                        
>  \
> +      char _pkpb_buf[65];                                                    
>  \
> +      uint64_t _pkpb_val = (val);                                            
>  \
> +      int _pkpb_sz = (size);                                                 
>  \
> +                                                                             
>  \
> +      for (int _pkpb_z = 0; _pkpb_z < _pkpb_sz; _pkpb_z++)                   
>  \
> +        _pkpb_buf[_pkpb_sz - 1 - _pkpb_z]                                    
>  \
> +            = ((_pkpb_val >> _pkpb_z) & 0x1) + '0';                          
>  \
> +      _pkpb_buf[_pkpb_sz] = '\0';                                            
>  \
> +                                                                             
>  \
> +      pk_puts (_pkpb_buf);                                                   
>  \
> +                                                                             
>  \
> +      if (use_suffix_p)                                                      
>  \
> +        pk_puts (pk_integral_suffix (_pkpb_sz, (sign_p)));                   
>  \
> +    }                                                                        
>  \
> +  while (0)
>  
>  /* Format the given unsigned 64-bit integer in binary. */
>  int pk_format_binary (char* out, size_t outlen, uint64_t val, int size,
> diff --git a/libpoke/libpoke.c b/libpoke/libpoke.c
> index a0bc7ee9..2c25bc55 100644
> --- a/libpoke/libpoke.c
> +++ b/libpoke/libpoke.c
> @@ -44,9 +44,10 @@ struct _pk_compiler
>    ios completion_ios;
>    int completion_idx;
>    struct pkl_ast_node_iter completion_iter;
> +  void *user_data;
>  };
>  
> -struct pk_term_if libpoke_term_if;
> +struct pk_term_if_internal libpoke_term_if;
>  
>  #define PK_RETURN(code) do { return pkc->status = (code); } while (0)
>  
> @@ -83,7 +84,8 @@ pk_compiler_new_with_flags (struct pk_term_if *term_if, 
> uint32_t flags)
>        if (libpoke_datadir == NULL)
>          libpoke_datadir = PKGDATADIR;
>  
> -      libpoke_term_if = *term_if;
> +      libpoke_term_if.term_if = *term_if;
> +      libpoke_term_if.pkc = pkc;
>  
>        pkc->vm = pvm_init ();
>        if (pkc->vm == NULL)
> @@ -134,6 +136,20 @@ pk_errno (pk_compiler pkc)
>    return PK_ERROR;
>  }
>  
> +void
> +pk_set_user_data (pk_compiler pkc, void *user_data)
> +{
> +  pkc->status = PK_OK;
> +  pkc->user_data = user_data;
> +}
> +
> +void *
> +pk_get_user_data (pk_compiler pkc)
> +{
> +  pkc->status = PK_OK;
> +  return pkc->user_data;
> +}
> +
>  int
>  pk_compile_file (pk_compiler pkc, const char *filename,
>                   pk_val *exit_exception)
> diff --git a/libpoke/libpoke.h b/libpoke/libpoke.h
> index f49a5b30..3d571de3 100644
> --- a/libpoke/libpoke.h
> +++ b/libpoke/libpoke.h
> @@ -83,46 +83,46 @@ struct pk_color
>  struct pk_term_if
>  {
>    /* Flush the output in the terminal.  */
> -  void (*flush_fn) (void);
> +  void (*flush_fn) (pk_compiler pkc);
>  
>    /* Output a NULL-terminated C string.  */
> -  void (*puts_fn) (const char *str);
> +  void (*puts_fn) (pk_compiler pkc, const char *str);
>  
>    /* Output a formatted string.  */
> -  void (*printf_fn) (const char *format, ...);
> +  void (*printf_fn) (pk_compiler pkc, const char *format, ...);
>  
>    /* Output LVL levels of indentation, using STEP white chars in each
>       indentation level.  */
> -  void (*indent_fn) (unsigned int lvl, unsigned int step);
> +  void (*indent_fn) (pk_compiler pkc, unsigned int lvl, unsigned int step);
>  
>    /* Mark the beginning of a styling class with name CLASS.  */
> -  void (*class_fn) (const char *aclass);
> +  void (*class_fn) (pk_compiler pkc, const char *aclass);
>  
>    /* Mark the end of a styling class with name CLASS.  This function
>       returns 0 if the given class is not active and therefore can't be
>       ended.  1 otherwise.  */
> -  int (*end_class_fn) (const char *aclass);
> +  int (*end_class_fn) (pk_compiler pkc, const char *aclass);
>  
>    /* Mark the beginning of an hyperlink with url URL and identifier
>       ID.  The identifier can be NULL.  */
> -  void (*hyperlink_fn) (const char *url, const char *id);
> +  void (*hyperlink_fn) (pk_compiler pkc, const char *url, const char *id);
>  
>    /* Mark the end of the current hyperlink.  This function returns 0
>       if there is no currently an hyperlink open to close.  1
>       otherwise.  */
> -  int (*end_hyperlink_fn) (void);
> +  int (*end_hyperlink_fn) (pk_compiler pkc);
>  
>    /* Get the current foreground color.  */
> -  struct pk_color (*get_color_fn) (void);
> +  struct pk_color (*get_color_fn) (pk_compiler pkc);
>  
>    /* Get the current background color.  */
> -  struct pk_color (*get_bgcolor_fn) (void);
> +  struct pk_color (*get_bgcolor_fn) (pk_compiler pkc);
>  
>    /* Set the foreground color.  */
> -  void (*set_color_fn) (struct pk_color color);
> +  void (*set_color_fn) (pk_compiler pkc, struct pk_color color);
>  
>    /* Set the background color.  */
> -  void (*set_bgcolor_fn) (struct pk_color color);
> +  void (*set_bgcolor_fn) (pk_compiler pkc, struct pk_color color);
>  };
>  
>  /* Create and return a new Poke incremental compiler.
> @@ -166,6 +166,11 @@ void pk_unregister_thread (void) LIBPOKE_API;
>  
>  int pk_errno (pk_compiler pkc) LIBPOKE_API;
>  
> +/* Set/get user-defined opaque data to compiler instance.  */
> +
> +void pk_set_user_data (pk_compiler pkc, void *user_data) LIBPOKE_API;
> +void *pk_get_user_data (pk_compiler pkc) LIBPOKE_API;
> +
>  /* Compile and execute a Poke program from the given file FILENAME.
>  
>     EXIT_EXCEPTION is a pointer to a pk_val variable that is set to an
> diff --git a/libpoke/pkt.h b/libpoke/pkt.h
> index 5be77f68..d5d010db 100644
> --- a/libpoke/pkt.h
> +++ b/libpoke/pkt.h
> @@ -21,21 +21,35 @@
>  
>  #include <config.h>
>  
> -#include "libpoke.h"  /* For struct pk_term_if */
> -
> -extern struct pk_term_if libpoke_term_if;
> -
> -#define pk_puts libpoke_term_if.puts_fn
> -#define pk_printf libpoke_term_if.printf_fn
> -#define pk_term_flush libpoke_term_if.flush_fn
> -#define pk_term_indent libpoke_term_if.indent_fn
> -#define pk_term_class libpoke_term_if.class_fn
> -#define pk_term_end_class libpoke_term_if.end_class_fn
> -#define pk_term_hyperlink libpoke_term_if.hyperlink_fn
> -#define pk_term_end_hyperlink libpoke_term_if.end_hyperlink_fn
> -#define pk_term_get_color libpoke_term_if.get_color_fn
> -#define pk_term_set_color libpoke_term_if.set_color_fn
> -#define pk_term_get_bgcolor libpoke_term_if.get_bgcolor_fn
> -#define pk_term_set_bgcolor libpoke_term_if.set_bgcolor_fn
> +#include "libpoke.h"  /* For struct pk_term_if, pk_compiler.  */
> +
> +struct pk_term_if_internal
> +{
> +  struct pk_term_if term_if;
> +  pk_compiler pkc;
> +};
> +
> +extern struct pk_term_if_internal libpoke_term_if;
> +
> +/* Terminal interface for Poke compiler.  */
> +
> +#define pk_puts(str) (PKT_IF)->puts_fn ((PKT_PKC), str)
> +#define pk_printf(...) (PKT_IF)->printf_fn ((PKT_PKC), __VA_ARGS__)
> +#define pk_term_flush() (PKT_IF)->flush_fn (PKT_PKC)
> +#define pk_term_indent(lvl, step)                                            
>  \
> +  (PKT_IF)->indent_fn ((PKT_PKC), (lvl), (step))
> +#define pk_term_class(cls) (PKT_IF)->class_fn ((PKT_PKC), (cls))
> +#define pk_term_end_class(cls) (PKT_IF)->end_class_fn ((PKT_PKC), (cls))
> +#define pk_term_hyperlink(url, id)                                           
>  \
> +  (PKT_IF)->hyperlink_fn ((PKT_PKC), (url), id)
> +#define pk_term_end_hyperlink() (PKT_IF)->end_hyperlink_fn (PKT_PKC)
> +#define pk_term_get_color() (PKT_IF)->get_color_fn (PKT_PKC)
> +#define pk_term_set_color(color) (PKT_IF)->set_color_fn ((PKT_PKC), (color))
> +#define pk_term_get_bgcolor() (PKT_IF)->get_bgcolor_fn (PKT_PKC)
> +#define pk_term_set_bgcolor(color)                                           
>  \
> +  (PKT_IF)->set_bgcolor_fn ((PKT_PKC), (color))
> +
> +#define PKT_IF (&libpoke_term_if.term_if)
> +#define PKT_PKC (libpoke_term_if.pkc)
>  
>  #endif /* ! PKT_H */
> diff --git a/libpoke/pvm-val.c b/libpoke/pvm-val.c
> index 07e66b2c..e8091c50 100644
> --- a/libpoke/pvm-val.c
> +++ b/libpoke/pvm-val.c
> @@ -1168,8 +1168,7 @@ pvm_print_val_1 (pvm vm, int depth, int mode, int base, 
> int indent,
>        if (base == 2)
>          {
>            pk_puts ("0b");
> -          pk_print_binary (pk_puts, ulongval, size, /*signed_p*/ 1,
> -                           /*use_suffix_p*/ 1);
> +          PK_PRINT_BINARY (ulongval, size, /*signed_p*/ 1, /*use_suffix_p*/ 
> 1);
>          }
>        else
>          {
> @@ -1198,7 +1197,7 @@ pvm_print_val_1 (pvm vm, int depth, int mode, int base, 
> int indent,
>        if (base == 2)
>          {
>            pk_puts ("0b");
> -          pk_print_binary (pk_puts, (uint64_t) uintval, size, /*signed*/ 1,
> +          PK_PRINT_BINARY ((uint64_t) uintval, size, /*signed*/ 1,
>                             /*use_suffix_p*/ 1);
>          }
>        else
> @@ -1228,8 +1227,7 @@ pvm_print_val_1 (pvm vm, int depth, int mode, int base, 
> int indent,
>        if (base == 2)
>          {
>            pk_puts ("0b");
> -          pk_print_binary (pk_puts, ulongval, size, /*signed_p*/ 0,
> -                           /*use_suffix_p*/ 1);
> +          PK_PRINT_BINARY (ulongval, size, /*signed_p*/ 0, /*use_suffix_p*/ 
> 1);
>          }
>        else
>          {
> @@ -1251,8 +1249,7 @@ pvm_print_val_1 (pvm vm, int depth, int mode, int base, 
> int indent,
>        if (base == 2)
>          {
>            pk_puts ("0b");
> -          pk_print_binary (pk_puts, uintval, size, /*signed_p*/ 0,
> -                           /*use_suffix_p*/ 1);
> +          PK_PRINT_BINARY (uintval, size, /*signed_p*/ 0, /*use_suffix_p*/ 
> 1);
>          }
>        else
>          {
> diff --git a/libpoke/pvm.jitter b/libpoke/pvm.jitter
> index 8d44872f..3954345a 100644
> --- a/libpoke/pvm.jitter
> +++ b/libpoke/pvm.jitter
> @@ -90,7 +90,7 @@ wrapped-functions
>    pvm_make_offset_type
>    pvm_make_array_type
>    pk_upow
> -  pk_print_binary
> +  pk_integral_suffix
>    pk_format_binary
>    pvm_alloc
>    pvm_allocate_struct_attrs
> @@ -517,7 +517,7 @@ late-header-c
>        }                                                                     \
>        else if ((BASE) == 2)                                                 \
>        {                                                                     \
> -        pk_print_binary (pk_puts, val, JITTER_ARGN0, 1, 0);                 \
> +        PK_PRINT_BINARY (val, JITTER_ARGN0, 1, 0);                          \
>          JITTER_DROP_STACK ();                                               \
>          JITTER_DROP_STACK ();                                               \
>          break;                                                              \
> @@ -571,7 +571,7 @@ late-header-c
>        }                                                                     \
>        else if ((BASE) == 2)                                                 \
>        {                                                                     \
> -        pk_print_binary (pk_puts, val, JITTER_ARGN0, 1, 0);                 \
> +        PK_PRINT_BINARY (val, JITTER_ARGN0, 1, 0);                          \
>          JITTER_DROP_STACK ();                                               \
>          JITTER_DROP_STACK ();                                               \
>          break;                                                              \
> diff --git a/poke/pk-cmd-compiler.c b/poke/pk-cmd-compiler.c
> index c1357e22..5872f4dd 100644
> --- a/poke/pk-cmd-compiler.c
> +++ b/poke/pk-cmd-compiler.c
> @@ -51,7 +51,7 @@ pk_cmd_compiler_ast (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>          const char *ast_str = pk_get_debug_ast (poke_compiler);
>  
>          assert (ast_str != NULL);
> -        pk_printf ("%s", ast_str);
> +        pk_printf (poke_compiler, "%s", ast_str);
>        }
>      pk_set_debug_p (poke_compiler, 0);
>    }
> diff --git a/poke/pk-cmd-def.c b/poke/pk-cmd-def.c
> index 8adbe0e3..166d915f 100644
> --- a/poke/pk-cmd-def.c
> +++ b/poke/pk-cmd-def.c
> @@ -160,11 +160,11 @@ print_type_decl (int kind,
>                         PK_CMD_ARG_STR (argv[1]),                        \
>                         REG_EXTENDED | REG_NOSUB) != 0)                  \
>              {                                                           \
> -              pk_term_class ("error");                                  \
> -              pk_puts ("error:");                                       \
> -              pk_term_end_class ("error");                              \
> +              pk_term_class (poke_compiler, "error");                   \
> +              pk_puts (poke_compiler, "error:");                        \
> +              pk_term_end_class (poke_compiler, "error");               \
>                                                                          \
> -              pk_printf (" invalid regexp\n");                          \
> +              pk_printf (poke_compiler, " invalid regexp\n");           \
>                return 0;                                                 \
>              }                                                           \
>            payload.regexp_p = 1;                                         \
> @@ -284,10 +284,11 @@ pk_cmd_info_type (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>    return 1;
>  
>   invalid_type:
> -  pk_term_class ("error");
> -  pk_puts ("error:");
> -  pk_term_end_class ("error");
> -  pk_printf (" this command requires a type specifier o an expression\n");
> +  pk_term_class (poke_compiler, "error");
> +  pk_puts (poke_compiler, "error:");
> +  pk_term_end_class (poke_compiler, "error");
> +  pk_printf (poke_compiler,
> +             " this command requires a type specifier o an expression\n");
>  
>    return 0;
>  }
> diff --git a/poke/pk-cmd-editor.c b/poke/pk-cmd-editor.c
> index 76ad7406..4c833776 100644
> --- a/poke/pk-cmd-editor.c
> +++ b/poke/pk-cmd-editor.c
> @@ -63,10 +63,10 @@ pk_cmd_editor (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>      }
>    if (!editor)
>      {
> -      pk_term_class ("error");
> -      pk_puts ("error: ");
> -      pk_term_end_class ("error");
> -      pk_puts ("the EDITOR environment variable is not set.\n");
> +      pk_term_class (poke_compiler, "error");
> +      pk_puts (poke_compiler, "error: ");
> +      pk_term_end_class (poke_compiler, "error");
> +      pk_puts (poke_compiler, "the EDITOR environment variable is not 
> set.\n");
>        return 0;
>      }
>  
> @@ -74,10 +74,10 @@ pk_cmd_editor (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>    if (((des = path_search (tmpfile, PATH_MAX, NULL, "poke", true)) == -1)
>        || ((des = mkstemp (tmpfile)) == -1))
>      {
> -      pk_term_class ("error");
> -      pk_puts ("error: ");
> -      pk_term_end_class ("error");
> -      pk_puts ("determining a temporary file name.\n");
> +      pk_term_class (poke_compiler, "error");
> +      pk_puts (poke_compiler, "error: ");
> +      pk_term_end_class (poke_compiler, "error");
> +      pk_puts (poke_compiler, "determining a temporary file name.\n");
>        return 0;
>      }
>  
> @@ -87,10 +87,10 @@ pk_cmd_editor (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>    /* Start command.  */
>    if (system (cmdline) != 0)
>      {
> -      pk_term_class ("error");
> -      pk_puts ("error: ");
> -      pk_term_end_class ("error");
> -      pk_puts ("executing editor.\n");
> +      pk_term_class (poke_compiler, "error");
> +      pk_puts (poke_compiler, "error: ");
> +      pk_term_end_class (poke_compiler, "error");
> +      pk_puts (poke_compiler, "executing editor.\n");
>        free (cmdline);
>        return 0;
>      }
> @@ -124,10 +124,10 @@ pk_cmd_editor (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>        if (*newline != '\0')
>          {
>            char *prompt = pk_prompt();
> -          pk_puts (prompt);
> +          pk_puts (poke_compiler, prompt);
>            free(prompt);
> -          pk_puts (newline);
> -          pk_puts ("\n");
> +          pk_puts (poke_compiler, newline);
> +          pk_puts (poke_compiler, "\n");
>            pk_cmd_exec (newline);
>          }
>        free (newline);
> @@ -136,10 +136,10 @@ pk_cmd_editor (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>    /* Remove the temporary file.  */
>    if (unlink (tmpfile) != 0)
>      {
> -      pk_term_class ("error");
> -      pk_puts ("error: ");
> -      pk_term_end_class ("error");
> -      pk_printf ("removing temporary file %s\n", tmpfile);
> +      pk_term_class (poke_compiler, "error");
> +      pk_puts (poke_compiler, "error: ");
> +      pk_term_end_class (poke_compiler, "error");
> +      pk_printf (poke_compiler, "removing temporary file %s\n", tmpfile);
>        return 0;
>      }
>  
> diff --git a/poke/pk-cmd-ios.c b/poke/pk-cmd-ios.c
> index c7d1f350..9bc9b140 100644
> --- a/poke/pk-cmd-ios.c
> +++ b/poke/pk-cmd-ios.c
> @@ -83,13 +83,13 @@ pk_cmd_ios (int argc, struct pk_cmd_arg argv[], uint64_t 
> uflags)
>    io = expr_to_ios (PK_CMD_ARG_STR (argv[1]));
>    if (io == NULL)
>      {
> -      pk_puts ("error: no such IO space\n");
> +      pk_puts (poke_compiler, "error: no such IO space\n");
>        return 0;
>      }
>  
>    pk_ios_set_cur (poke_compiler, io);
>    if (poke_interactive_p && !poke_quiet_p)
> -    pk_printf (_("The current IOS is now `%s'.\n"),
> +    pk_printf (poke_compiler, _("The current IOS is now `%s'.\n"),
>                 pk_ios_handler (pk_ios_cur (poke_compiler)));
>    return 1;
>  }
> @@ -128,7 +128,7 @@ pk_cmd_sub (int argc, struct pk_cmd_arg argv[], uint64_t 
> uflags)
>    /* Open the IOS.  */
>    if (pk_ios_open (poke_compiler, handler, 0, 1) == PK_IOS_NOID)
>      {
> -      pk_printf (_("Error creating sub IOS %s\n"), handler);
> +      pk_printf (poke_compiler, _("Error creating sub IOS %s\n"), handler);
>        free (handler);
>        return 0;
>      }
> @@ -162,7 +162,7 @@ pk_cmd_proc (int argc, struct pk_cmd_arg argv[], uint64_t 
> uflags)
>    ios_id = pk_ios_open (poke_compiler, handler, 0, 1);
>    if (ios_id == PK_IOS_NOID)
>      {
> -      pk_printf (_("Error creating proc IOS %s\n"), handler);
> +      pk_printf (poke_compiler, _("Error creating proc IOS %s\n"), handler);
>        free (handler);
>        return 0;
>      }
> @@ -175,10 +175,11 @@ pk_cmd_proc (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>  
>    return 1;
>  #else
> -  pk_term_class ("error");
> -  pk_puts (_("error: "));
> -  pk_term_end_class ("error");
> -  pk_printf (_("this poke hasn't been built with support for .proc\n"));
> +  pk_term_class (poke_compiler, "error");
> +  pk_puts (poke_compiler, _("error: "));
> +  pk_term_end_class (poke_compiler, "error");
> +  pk_printf (poke_compiler,
> +             _("this poke hasn't been built with support for .proc\n"));
>    return 0;
>  #endif /* HAVE_PROC */
>  }
> @@ -213,11 +214,11 @@ pk_cmd_file (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>  
>    if (PK_IOS_NOID == pk_open_file (filename, 1 /* set_cur_p */, create_p))
>      {
> -      pk_term_class ("error");
> -      pk_puts (_("error: "));
> -      pk_term_end_class ("error");
> +      pk_term_class (poke_compiler, "error");
> +      pk_puts (poke_compiler, _("error: "));
> +      pk_term_end_class (poke_compiler, "error");
>  
> -      pk_printf (_("opening %s\n"), filename);
> +      pk_printf (poke_compiler, _("opening %s\n"), filename);
>        return 0;
>      }
>  
> @@ -269,7 +270,7 @@ pk_cmd_close (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>        io = expr_to_ios (expr);
>        if (io == NULL)
>          {
> -          pk_printf (_("error: no such IO space\n"));
> +          pk_printf (poke_compiler, _("error: no such IO space\n"));
>            return 0;
>          }
>      }
> @@ -443,7 +444,7 @@ pk_cmd_load_file (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>    return 1;
>  
>   no_file:
> -  pk_puts (emsg);
> +  pk_puts (poke_compiler, emsg);
>   error:
>    if (filename != arg)
>      free (filename);
> @@ -463,7 +464,7 @@ pk_cmd_source_file (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>  
>    if ((emsg = pk_file_readable (arg)) != NULL)
>      {
> -      pk_puts (emsg);
> +      pk_puts (poke_compiler, emsg);
>        return 0;
>      }
>  
> @@ -518,7 +519,7 @@ pk_cmd_mem (int argc, struct pk_cmd_arg argv[], uint64_t 
> uflags)
>  
>    if (PK_IOS_NOID == pk_ios_open (poke_compiler, mem_name, 0, 1))
>      {
> -      pk_printf (_("Error creating memory IOS %s\n"), mem_name);
> +      pk_printf (poke_compiler, _("Error creating memory IOS %s\n"), 
> mem_name);
>        free (mem_name);
>        return 0;
>      }
> @@ -526,7 +527,7 @@ pk_cmd_mem (int argc, struct pk_cmd_arg argv[], uint64_t 
> uflags)
>    free (mem_name);
>  
>    if (poke_interactive_p && !poke_quiet_p)
> -    pk_printf (_("The current IOS is now `%s'.\n"),
> +    pk_printf (poke_compiler, _("The current IOS is now `%s'.\n"),
>                 pk_ios_handler (pk_ios_cur (poke_compiler)));
>  
>    return 1;
> @@ -555,13 +556,13 @@ pk_cmd_nbd (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>  
>    if (PK_IOS_NOID == pk_ios_open (poke_compiler, nbd_name, 0, 1))
>      {
> -      pk_printf (_("Error creating NBD IOS %s\n"), nbd_name);
> +      pk_printf (poke_compiler, _("Error creating NBD IOS %s\n"), nbd_name);
>        free (nbd_name);
>        return 0;
>      }
>  
>    if (poke_interactive_p && !poke_quiet_p)
> -    pk_printf (_("The current IOS is now `%s'.\n"),
> +    pk_printf (poke_compiler, _("The current IOS is now `%s'.\n"),
>                 pk_ios_handler (pk_ios_cur (poke_compiler)));
>  
>    return 1;
> diff --git a/poke/pk-cmd-map.c b/poke/pk-cmd-map.c
> index 4052aff6..971ee042 100644
> --- a/poke/pk-cmd-map.c
> +++ b/poke/pk-cmd-map.c
> @@ -63,7 +63,7 @@ expr_to_intval (const char *expr, pk_val *retval)
>                                                                               
>  \
>        if (!cur_ios)                                                          
>  \
>          {                                                                    
>  \
> -          pk_printf (_ ("No current IOS\n"));                                
>  \
> +          pk_printf (poke_compiler, _ ("No current IOS\n"));                 
>  \
>            return 0;                                                          
>  \
>          }                                                                    
>  \
>                                                                               
>  \
> @@ -86,7 +86,7 @@ pk_cmd_map_create (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>  
>    if (strlen (mapname) == 0)
>      {
> -      pk_printf (_("Invalid name for map.\n"));
> +      pk_printf (poke_compiler, _("Invalid name for map.\n"));
>        return 0;
>      }
>  
> @@ -102,7 +102,7 @@ pk_cmd_map_create (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>  
>        if (pk_type_code (pk_typeof (val)) != PK_TYPE_INT)
>          {
> -          pk_printf (_("Expected IO space identifier.\n"));
> +          pk_printf (poke_compiler, _("Expected IO space identifier.\n"));
>            return 0;
>          }
>  
> @@ -110,14 +110,14 @@ pk_cmd_map_create (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>  
>        if (pk_ios_search_by_id (poke_compiler, ios_id) == NULL)
>          {
> -          pk_printf (_("No such IOS with Id %d.\n"), ios_id);
> +          pk_printf (poke_compiler, _("No such IOS with Id %d.\n"), ios_id);
>            return 0;
>          }
>      }
>  
>    if (!pk_map_create (ios_id, mapname, NULL /* source */))
>      {
> -      pk_printf (_("The map `%s' already exists in IOS %d\n."),
> +      pk_printf (poke_compiler, _("The map `%s' already exists in IOS 
> %d\n."),
>                   mapname, ios_id);
>        return 0;
>      }
> @@ -140,7 +140,7 @@ pk_cmd_map_remove (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>  
>    if (strlen (mapname) == 0)
>      {
> -      pk_printf (_("Invalid name for map.\n"));
> +      pk_printf (poke_compiler, _("Invalid name for map.\n"));
>        return 0;
>      }
>  
> @@ -156,7 +156,7 @@ pk_cmd_map_remove (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>  
>        if (pk_type_code (pk_typeof (val)) != PK_TYPE_INT)
>          {
> -          pk_printf (_("Expected IO space identifier.\n"));
> +          pk_printf (poke_compiler, _("Expected IO space identifier.\n"));
>            return 0;
>          }
>  
> @@ -164,14 +164,14 @@ pk_cmd_map_remove (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>  
>        if (pk_ios_search_by_id (poke_compiler, ios_id) == NULL)
>          {
> -          pk_printf (_("No such IOS %d.\n"), ios_id);
> +          pk_printf (poke_compiler, _("No such IOS %d.\n"), ios_id);
>            return 0;
>          }
>      }
>  
>    if (!pk_map_remove (ios_id, mapname))
>      {
> -      pk_printf (_("No such map `%s' in IOS %d.\n"),
> +      pk_printf (poke_compiler, _("No such map `%s' in IOS %d.\n"),
>                   mapname, ios_id);
>        return 0;
>      }
> @@ -205,14 +205,14 @@ pk_cmd_map_show (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>  
>        if (pk_type_code (pk_typeof (val)) != PK_TYPE_INT)
>          {
> -          pk_printf (_("Expected IO space identifier.\n"));
> +          pk_printf (poke_compiler, _("Expected IO space identifier.\n"));
>            return 0;
>          }
>  
>        ios_id = pk_int_value (val);
>        if (pk_ios_search_by_id (poke_compiler, ios_id) == NULL)
>          {
> -          pk_printf (_("No such IOS %d.\n"), ios_id);
> +          pk_printf (poke_compiler, _("No such IOS %d.\n"), ios_id);
>            return 0;
>          }
>      }
> @@ -223,7 +223,7 @@ pk_cmd_map_show (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>    map = pk_map_search (ios_id, mapname);
>    if (!map)
>      {
> -      pk_printf (_("No such map `%s' in IOS %d.\n"),
> +      pk_printf (poke_compiler, _("No such map `%s' in IOS %d.\n"),
>                   mapname, ios_id);
>        return 0;
>      }
> @@ -290,14 +290,14 @@ pk_cmd_map_entry_add (int argc, struct pk_cmd_arg 
> argv[], uint64_t uflags)
>  
>        if (pk_type_code (pk_typeof (val)) != PK_TYPE_INT)
>          {
> -          pk_printf (_("Expected IO space identifier.\n"));
> +          pk_printf (poke_compiler, _("Expected IO space identifier.\n"));
>            return 0;
>          }
>  
>        ios_id = pk_int_value (val);
>        if (pk_ios_search_by_id (poke_compiler, ios_id) == NULL)
>          {
> -          pk_printf (_("No such IOS %d.\n"), ios_id);
> +          pk_printf (poke_compiler, _("No such IOS %d.\n"), ios_id);
>            return 0;
>          }
>      }
> @@ -305,7 +305,7 @@ pk_cmd_map_entry_add (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>    /* Make sure the specified map exists in the given IO space.  */
>    if (!pk_map_search (ios_id, mapname))
>      {
> -      pk_printf (_("No such map `%s' in IOS %d.\n"),
> +      pk_printf (poke_compiler, _("No such map `%s' in IOS %d.\n"),
>                   mapname, ios_id);
>        return 0;
>      }
> @@ -313,7 +313,7 @@ pk_cmd_map_entry_add (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>    /* Make sure the variable exists in the top-level environment.  */
>    if (!pk_decl_p (poke_compiler, varname, PK_DECL_KIND_VAR))
>      {
> -      pk_printf ("Variable `%s' doesn't exist.\n", varname);
> +      pk_printf (poke_compiler, "Variable `%s' doesn't exist.\n", varname);
>        return 0;
>      }
>  
> @@ -325,7 +325,7 @@ pk_cmd_map_entry_add (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>    if (!pk_val_mapped_p (val)
>        || pk_int_value (pk_val_ios (val)) != ios_id)
>      {
> -      pk_printf ("Variable `%s' is not mapped in the IOS %d.\n",
> +      pk_printf (poke_compiler, "Variable `%s' is not mapped in the IOS 
> %d.\n",
>                   varname, ios_id);
>        return 0;
>      }
> @@ -334,7 +334,7 @@ pk_cmd_map_entry_add (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>    if (!pk_map_add_entry (ios_id, mapname,
>                           varname, varname, pk_val_offset (val)))
>      {
> -      pk_printf ("The entry `%s' already exists in map `%s'.\n",
> +      pk_printf (poke_compiler, "The entry `%s' already exists in map 
> `%s'.\n",
>                   varname, mapname);
>        return 0;
>      }
> @@ -371,14 +371,14 @@ pk_cmd_map_entry_remove (int argc, struct pk_cmd_arg 
> argv[], uint64_t uflags)
>  
>        if (pk_type_code (pk_typeof (val)) != PK_TYPE_INT)
>          {
> -          pk_printf (_("Expected IO space identifier.\n"));
> +          pk_printf (poke_compiler, _("Expected IO space identifier.\n"));
>            return 0;
>          }
>  
>        ios_id = pk_int_value (val);
>        if (pk_ios_search_by_id (poke_compiler, ios_id) == NULL)
>          {
> -          pk_printf (_("No such IOS %d.\n"), ios_id);
> +          pk_printf (poke_compiler, _("No such IOS %d.\n"), ios_id);
>            return 0;
>          }
>      }
> @@ -386,14 +386,14 @@ pk_cmd_map_entry_remove (int argc, struct pk_cmd_arg 
> argv[], uint64_t uflags)
>    /* Make sure the specified map exists in the given IO space.  */
>    if (!pk_map_search (ios_id, mapname))
>      {
> -      pk_printf (_("No such map `%s' in IOS %d.\n"),
> +      pk_printf (poke_compiler, _("No such map `%s' in IOS %d.\n"),
>                   mapname, ios_id);
>        return 0;
>      }
>  
>    if (!pk_map_remove_entry (ios_id, mapname, entryname))
>      {
> -      pk_printf (_("No entry `%s' in map `%s'.\n"),
> +      pk_printf (poke_compiler, _("No entry `%s' in map `%s'.\n"),
>                   entryname, mapname);
>        return 0;
>      }
> @@ -426,14 +426,14 @@ pk_cmd_map_load (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>  
>        if (pk_type_code (pk_typeof (val)) != PK_TYPE_INT)
>          {
> -          pk_printf (_("Expected IO space identifier.\n"));
> +          pk_printf (poke_compiler, _("Expected IO space identifier.\n"));
>            return 0;
>          }
>  
>        ios_id = pk_int_value (val);
>        if (pk_ios_search_by_id (poke_compiler, ios_id) == NULL)
>          {
> -          pk_printf (_("No such IOS %d.\n"), ios_id);
> +          pk_printf (poke_compiler, _("No such IOS %d.\n"), ios_id);
>            return 0;
>          }
>      }
> @@ -442,7 +442,7 @@ pk_cmd_map_load (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>    filename = pk_map_resolve_map (mapname, filename_p);
>    if (!filename)
>      {
> -      pk_printf (_("No such map `%s'.\n"), mapname);
> +      pk_printf (poke_compiler, _("No such map `%s'.\n"), mapname);
>        return 0;
>      }
>  
> @@ -450,9 +450,9 @@ pk_cmd_map_load (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>      {
>        if (emsg)
>          {
> -          pk_printf ("%s", emsg);
> +          pk_printf (poke_compiler, "%s", emsg);
>            if (emsg[strlen (emsg) - 1] != '\n')
> -            pk_puts ("\n");
> +            pk_puts (poke_compiler, "\n");
>          }
>        return 0;
>      }
> @@ -465,7 +465,7 @@ pk_cmd_map_save (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>  {
>    /* XXX writeme */
>  
> -  pk_printf (".map save is not implemented yet, sorry :/\n");
> +  pk_printf (poke_compiler, ".map save is not implemented yet, sorry :/\n");
>    return 1;
>  }
>  
> @@ -490,14 +490,14 @@ pk_cmd_info_maps (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>  
>        if (pk_type_code (pk_typeof (val)) != PK_TYPE_INT)
>          {
> -          pk_printf (_("Expected IO space identifier.\n"));
> +          pk_printf (poke_compiler, _("Expected IO space identifier.\n"));
>            return 0;
>          }
>  
>        ios_id = pk_int_value (val);
>        if (pk_ios_search_by_id (poke_compiler, ios_id) == NULL)
>          {
> -          pk_printf (_("No such IOS %d.\n"), ios_id);
> +          pk_printf (poke_compiler, _("No such IOS %d.\n"), ios_id);
>            return 0;
>          }
>      }
> diff --git a/poke/pk-cmd-misc.c b/poke/pk-cmd-misc.c
> index db4dd5b3..9d4d4322 100644
> --- a/poke/pk-cmd-misc.c
> +++ b/poke/pk-cmd-misc.c
> @@ -105,10 +105,11 @@ pk_cmd_doc (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>          const char *ip = find_in_path (info_prog_name);
>          if (STREQ (ip, info_prog_name))
>            {
> -            pk_term_class ("error");
> -            pk_puts ("error: ");
> -            pk_term_end_class ("error");
> -            pk_puts ("a suitable documentation viewer is not installed.\n");
> +            pk_term_class (poke_compiler, "error");
> +            pk_puts (poke_compiler, "error: ");
> +            pk_term_end_class (poke_compiler, "error");
> +            pk_puts (poke_compiler,
> +                     "a suitable documentation viewer is not installed.\n");
>              return 0;
>            }
>  
> @@ -171,7 +172,7 @@ pk_cmd_jmd (int argc, struct pk_cmd_arg argv[], uint64_t 
> uflags)
>          num_strings++;
>      }
>  
> -  pk_printf ("%s\n", strings[rand () % num_strings]);
> +  pk_printf (poke_compiler, "%s\n", strings[rand () % num_strings]);
>    return 1;
>  }
>  
> diff --git a/poke/pk-cmd-set.c b/poke/pk-cmd-set.c
> index 64ee2a3f..d523a1ff 100644
> --- a/poke/pk-cmd-set.c
> +++ b/poke/pk-cmd-set.c
> @@ -41,10 +41,11 @@ pk_cmd_set_dump (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>        || exit_exception != PK_NULL)
>      PK_UNREACHABLE (); /* This shouldn't happen.  */
>  
> -  pk_term_class ("setting-header");
> -  pk_puts ("error-on-warning");
> -  pk_term_end_class ("setting-header");
> -  pk_printf (" %s\n", pk_error_on_warning (poke_compiler) ? "yes" : "no");
> +  pk_term_class (poke_compiler, "setting-header");
> +  pk_puts (poke_compiler, "error-on-warning");
> +  pk_term_end_class (poke_compiler, "setting-header");
> +  pk_printf (poke_compiler,
> +             " %s\n", pk_error_on_warning (poke_compiler) ? "yes" : "no");
>  
>    return 0;
>  }
> @@ -76,9 +77,9 @@ pk_cmd_set (int int_p,
>          PK_UNREACHABLE ();
>  
>        if (int_p)
> -        pk_printf ("%" PRId64 "\n", pk_int_value (retval));
> +        pk_printf (poke_compiler, "%" PRId64 "\n", pk_int_value (retval));
>        else
> -        pk_printf ("%s\n", pk_string_str (retval));
> +        pk_printf (poke_compiler, "%s\n", pk_string_str (retval));
>      }
>    else
>      {
> @@ -108,7 +109,7 @@ pk_cmd_set (int int_p,
>        retmsg = pk_string_str (retval);
>        if (*retmsg != '\0')
>          {
> -          pk_printf ("%s\n", retmsg);
> +          pk_printf (poke_compiler, "%s\n", retmsg);
>            return 0;
>          }
>      }
> @@ -149,9 +150,9 @@ pk_cmd_set_error_on_warning (int argc, struct pk_cmd_arg 
> argv[],
>    if (*arg == '\0')
>      {
>        if (pk_error_on_warning (poke_compiler))
> -        pk_puts ("yes\n");
> +        pk_puts (poke_compiler, "yes\n");
>        else
> -        pk_puts ("no\n");
> +        pk_puts (poke_compiler, "no\n");
>      }
>    else
>      {
> @@ -163,10 +164,11 @@ pk_cmd_set_error_on_warning (int argc, struct 
> pk_cmd_arg argv[],
>          error_on_warning = 0;
>        else
>          {
> -          pk_term_class ("error");
> -          pk_puts (_("error: "));
> -          pk_term_end_class ("error");
> -          pk_puts (_("error-on-warning should be one of `yes' or `no'\n"));
> +          pk_term_class (poke_compiler, "error");
> +          pk_puts (poke_compiler, _("error: "));
> +          pk_term_end_class (poke_compiler, "error");
> +          pk_puts (poke_compiler,
> +                   _("error-on-warning should be one of `yes' or `no'\n"));
>            return 0;
>          }
>  
> diff --git a/poke/pk-cmd-vm.c b/poke/pk-cmd-vm.c
> index 51ff59a7..c2806035 100644
> --- a/poke/pk-cmd-vm.c
> +++ b/poke/pk-cmd-vm.c
> @@ -44,10 +44,10 @@ pk_cmd_vm_disas_exp (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>  
>    if (ret == PK_ERROR)
>      {
> -      pk_term_class ("error");
> -      pk_puts ("error: ");
> -      pk_term_end_class ("error");
> -      pk_puts ("invalid expression\n");
> +      pk_term_class (poke_compiler, "error");
> +      pk_puts (poke_compiler, "error: ");
> +      pk_term_end_class (poke_compiler, "error");
> +      pk_puts (poke_compiler, "invalid expression\n");
>        return 0;
>      }
>    return 1;
> @@ -81,10 +81,11 @@ pk_cmd_vm_disas_fun (int argc, struct pk_cmd_arg argv[], 
> uint64_t uflags)
>                                       uflags & PK_VM_DIS_F_NAT);
>    if (ret != PK_OK)
>      {
> -      pk_term_class ("error");
> -      pk_puts ("error: ");
> -      pk_term_end_class ("error");
> -      pk_printf ("given expression doesn't evaluate to a function\n");
> +      pk_term_class (poke_compiler, "error");
> +      pk_puts (poke_compiler, "error: ");
> +      pk_term_end_class (poke_compiler, "error");
> +      pk_printf (poke_compiler,
> +                 "given expression doesn't evaluate to a function\n");
>        return 0;
>      }
>  
> diff --git a/poke/pk-cmd.c b/poke/pk-cmd.c
> index e6825423..b73d1875 100644
> --- a/poke/pk-cmd.c
> +++ b/poke/pk-cmd.c
> @@ -301,7 +301,7 @@ pk_cmd_exec_1 (const char *str, struct pk_trie 
> *cmds_trie, char *prefix)
>      {
>        if (i >= MAX_CMD_NAME - 1)
>          {
> -          pk_printf (_("%s: command not found.\n"), cmd_name);
> +          pk_printf (poke_compiler, _("%s: command not found.\n"), cmd_name);
>            return 0;
>          }
>        cmd_name[i++] = *(p++);
> @@ -312,8 +312,8 @@ pk_cmd_exec_1 (const char *str, struct pk_trie 
> *cmds_trie, char *prefix)
>    if (cmd == NULL)
>      {
>        if (prefix != NULL)
> -        pk_printf ("%s ", prefix);
> -      pk_printf (_("%s: command not found.\n"), cmd_name);
> +        pk_printf (poke_compiler, "%s ", prefix);
> +      pk_printf (poke_compiler, _("%s: command not found.\n"), cmd_name);
>        return 0;
>      }
>    strncpy (cmd_name, cmd->name, MAX_CMD_NAME - 1);
> @@ -340,7 +340,8 @@ pk_cmd_exec_1 (const char *str, struct pk_trie 
> *cmds_trie, char *prefix)
>  
>            if (cmd->uflags[fi] == '\0')
>              {
> -              pk_printf (_("%s: invalid flag `%c'\n"), cmd_name, *p);
> +              pk_printf (poke_compiler,
> +                         _("%s: invalid flag `%c'\n"), cmd_name, *p);
>                return 0;
>              }
>  
> @@ -519,7 +520,9 @@ pk_cmd_exec_1 (const char *str, struct pk_trie 
> *cmds_trie, char *prefix)
>    if (cmd->flags & PK_CMD_F_REQ_IO
>        && pk_ios_cur (poke_compiler) == NULL)
>      {
> -      pk_puts (_("This command requires an IO space.  Use the `file' 
> command.\n"));
> +      pk_puts (
> +          poke_compiler,
> +         _("This command requires an IO space.  Use the `file' command.\n"));
>        return 0;
>      }
>  
> @@ -529,7 +532,7 @@ pk_cmd_exec_1 (const char *str, struct pk_trie 
> *cmds_trie, char *prefix)
>        if (cur_io == NULL
>            || !(pk_ios_flags (cur_io) & PK_IOS_F_READ))
>          {
> -          pk_puts (_("This command requires a writable IO space."));
> +          pk_puts (poke_compiler, _("This command requires a writable IO 
> space."));
>            return 0;
>          }
>      }
> @@ -554,7 +557,7 @@ pk_cmd_exec_1 (const char *str, struct pk_trie 
> *cmds_trie, char *prefix)
>      }
>  
>    if (!besilent && !run_default_handler_p)
> -    pk_printf (_("Usage: %s\n"), cmd->usage);
> +    pk_printf (poke_compiler, _("Usage: %s\n"), cmd->usage);
>  
>    return ret;
>  #undef GOTO_USAGE
> @@ -664,7 +667,7 @@ pk_cmd_exec (const char *str)
>                   exception, in case a pretty-printer is involved.  */
>                pk_print_val (poke_compiler, val, &exit_exception);
>                if (exit_exception == PK_NULL)
> -                pk_puts ("\n");
> +                pk_puts (poke_compiler, "\n");
>              }
>          }
>        pk_set_lexical_cuckolding_p (poke_compiler, 0);
> diff --git a/poke/pk-hserver.c b/poke/pk-hserver.c
> index aa8c3212..dab48aa3 100644
> --- a/poke/pk-hserver.c
> +++ b/poke/pk-hserver.c
> @@ -247,9 +247,9 @@ read_from_client (int filedes)
>            cmd = pk_hserver_cmd (token);
>            pthread_mutex_lock (&hserver_mutex);
>            pk_repl_display_begin ();
> -          pk_puts (p);
> -          pk_puts (cmd);
> -          pk_puts ("\n");
> +          pk_puts (poke_compiler, p);
> +          pk_puts (poke_compiler, cmd);
> +          pk_puts (poke_compiler, "\n");
>            pk_cmd_exec (cmd);
>            pk_repl_display_end ();
>            pthread_mutex_unlock (&hserver_mutex);
> @@ -260,9 +260,9 @@ read_from_client (int filedes)
>            cmd = pk_hserver_cmd (token);
>            pthread_mutex_lock (&hserver_mutex);
>            pk_repl_display_begin ();
> -          pk_puts (p);
> -          pk_puts (cmd);
> -          pk_puts ("\n");
> +          pk_puts (poke_compiler, p);
> +          pk_puts (poke_compiler, cmd);
> +          pk_puts (poke_compiler, "\n");
>            /* Note we just ignore raised exceptions.  */
>            pk_call (poke_compiler, cls, NULL, NULL, 0);
>            pk_repl_display_end ();
> diff --git a/poke/pk-ios.c b/poke/pk-ios.c
> index 5f698dd0..bb5f8919 100644
> --- a/poke/pk-ios.c
> +++ b/poke/pk-ios.c
> @@ -80,11 +80,12 @@ pk_open_file (const char *handler, int set_cur_p, int 
> create_p)
>          if (regcomp (&regexp, pk_string_str (regex),
>                       REG_EXTENDED | REG_NOSUB) != 0)
>            {
> -            pk_term_class ("error");
> -            pk_puts ("error: ");
> -            pk_term_end_class ("error");
> +            pk_term_class (poke_compiler, "error");
> +            pk_puts (poke_compiler, "error: ");
> +            pk_term_end_class (poke_compiler, "error");
>  
> -            pk_printf ("invalid regexp `%s' in auto_map.  Skipping entry.\n",
> +            pk_printf (poke_compiler,
> +                       "invalid regexp `%s' in auto_map.  Skipping entry.\n",
>                         pk_string_str (regex));
>            }
>          else
> @@ -99,11 +100,11 @@ pk_open_file (const char *handler, int set_cur_p, int 
> create_p)
>  
>                  if (!map_handler)
>                    {
> -                    pk_term_class ("error");
> -                    pk_puts ("warning: ");
> -                    pk_term_end_class ("error");
> +                    pk_term_class (poke_compiler, "error");
> +                    pk_puts (poke_compiler, "warning: ");
> +                    pk_term_end_class (poke_compiler, "error");
>  
> -                    pk_printf ("auto-map: unknown map `%s'",
> +                    pk_printf (poke_compiler, "auto-map: unknown map `%s'",
>                                 pk_string_str (mapname));
>                      regfree (&regexp);
>                      break;
> @@ -111,11 +112,11 @@ pk_open_file (const char *handler, int set_cur_p, int 
> create_p)
>  
>                  if (!pk_map_load_file (ios_id, map_handler, NULL))
>                    {
> -                    pk_term_class ("error");
> -                    pk_puts ("error: ");
> -                    pk_term_end_class ("error");
> +                    pk_term_class (poke_compiler, "error");
> +                    pk_puts (poke_compiler, "error: ");
> +                    pk_term_end_class (poke_compiler, "error");
>  
> -                    pk_printf ("auto-map: loading `%s'\n",
> +                    pk_printf (poke_compiler, "auto-map: loading `%s'\n",
>                                 pk_string_str (mapname));
>                      regfree (&regexp);
>                      break;
> @@ -123,7 +124,7 @@ pk_open_file (const char *handler, int set_cur_p, int 
> create_p)
>  
>                  if (poke_interactive_p && !poke_quiet_p
>                      && ! pk_var_int ("pk_prompt_maps_p"))
> -                  pk_printf ("auto-map: map `%s' loaded\n",
> +                  pk_printf (poke_compiler, "auto-map: map `%s' loaded\n",
>                               pk_string_str (mapname));
>                }
>  
> diff --git a/poke/pk-map-tab.y b/poke/pk-map-tab.y
> index 3b9ac6ae..e58603f1 100644
> --- a/poke/pk-map-tab.y
> +++ b/poke/pk-map-tab.y
> @@ -196,24 +196,25 @@ static void
>  pk_map_printf_error (struct pk_map_parser *map_parser,
>                       YYLTYPE loc, const char *format, ...)
>  {
> +  extern pk_compiler poke_compiler;
>  
>    va_list ap;
>  
>    if (map_parser->filename)
> -    pk_printf ("%s:", map_parser->filename);
> +    pk_printf (poke_compiler, "%s:", map_parser->filename);
>  
>    if (loc.first_line != 0
>        || loc.first_column != 0
>        || loc.last_line != 0
>        || loc.last_column != 0)
>      {
> -      pk_term_class ("error-location");
> -      pk_printf ("%d:%d: ", loc.first_line, loc.first_column);
> -      pk_term_end_class ("error-location");
> +      pk_term_class (poke_compiler, "error-location");
> +      pk_printf (poke_compiler, "%d:%d: ", loc.first_line, loc.first_column);
> +      pk_term_end_class (poke_compiler, "error-location");
>      }
>  
>    va_start (ap, format);
> -  pk_vprintf (format, ap);
> +  pk_vprintf (poke_compiler, format, ap);
>    va_end (ap);
>  }
>  
> diff --git a/poke/pk-map.c b/poke/pk-map.c
> index 7f1fb6fc..a49fa8a8 100644
> --- a/poke/pk-map.c
> +++ b/poke/pk-map.c
> @@ -519,7 +519,7 @@ pk_map_load_parsed_map (int ios_id, const char *mapname,
>                && pk_val_kind (val) != PK_VAL_UINT)
>              {
>                /* XXX error location.  */
> -              pk_printf ("error: invalid condition expression\n");
> +              pk_printf (poke_compiler, "error: invalid condition 
> expression\n");
>                goto error;
>              }
>  
> diff --git a/poke/pk-repl.c b/poke/pk-repl.c
> index d8ce4cd1..333c935a 100644
> --- a/poke/pk-repl.c
> +++ b/poke/pk-repl.c
> @@ -177,14 +177,14 @@ banner (void)
>    if (!poke_quiet_p)
>      {
>        pk_print_version (1 /* hand_p */);
> -      pk_puts ("\n");
> +      pk_puts (poke_compiler, "\n");
>  
>  #if HAVE_HSERVER
>        if (poke_hserver_p)
>          {
> -          pk_printf ("hserver listening in port %d.\n",
> +          pk_printf (poke_compiler, "hserver listening in port %d.\n",
>                       pk_hserver_port ());
> -          pk_puts ("\n");
> +          pk_puts (poke_compiler, "\n");
>          }
>  #endif
>  
> @@ -194,22 +194,22 @@ banner (void)
>            char *help_hyperlink
>              = pk_hserver_make_hyperlink ('e', ".help", PK_NULL);
>  
> -          pk_puts (_("For help, type: "));
> -          pk_puts ("\"");
> -          pk_term_class ("hyperlink");
> -          pk_term_hyperlink (help_hyperlink, NULL);
> -          pk_term_end_class ("hyperlink");
> -          pk_term_class ("hyperlink");
> -          pk_puts (".help");
> -          pk_term_end_class ("hyperlink");
> -          pk_term_end_hyperlink ();
> -          pk_puts ("\".\n");
> +          pk_puts (poke_compiler, _("For help, type: "));
> +          pk_puts (poke_compiler, "\"");
> +          pk_term_class (poke_compiler, "hyperlink");
> +          pk_term_hyperlink (poke_compiler, help_hyperlink, NULL);
> +          pk_term_end_class (poke_compiler, "hyperlink");
> +          pk_term_class (poke_compiler, "hyperlink");
> +          pk_puts (poke_compiler, ".help");
> +          pk_term_end_class (poke_compiler, "hyperlink");
> +          pk_term_end_hyperlink (poke_compiler);
> +          pk_puts (poke_compiler, "\".\n");
>            free (help_hyperlink);
>          }
>        else
>  #endif
> -      pk_puts (_("For help, type \".help\".\n"));
> -      pk_puts (_("Type \".exit\" to leave the program.\n"));
> +      pk_puts (poke_compiler, _("For help, type \".help\".\n"));
> +      pk_puts (poke_compiler, _("Type \".exit\" to leave the program.\n"));
>      }
>  
>  }
> @@ -386,17 +386,17 @@ pk_repl (void)
>           that we still have to pass it to the readline call below, so
>           it can update the screen appropiately.  */
>        prompt = pk_prompt ();
> -      pk_term_class ("prompt");
> -      pk_puts (prompt);
> -      pk_term_end_class ("prompt");
> -      pk_term_flush ();
> +      pk_term_class (poke_compiler, "prompt");
> +      pk_puts (poke_compiler, prompt);
> +      pk_term_end_class (poke_compiler, "prompt");
> +      pk_term_flush (poke_compiler);
>        rl_already_prompted = 1;
>        line = readline (prompt);
>        free (prompt);
>        if (line == NULL)
>          {
>            /* EOF in stdin (probably Ctrl-D).  */
> -          pk_puts ("\n");
> +          pk_puts (poke_compiler, "\n");
>            break;
>          }
>  
> @@ -446,13 +446,13 @@ pk_repl_display_begin (void)
>    rl_save_prompt ();
>    rl_clear_message ();
>  
> -  pk_puts (rl_prompt);
> +  pk_puts (poke_compiler, rl_prompt);
>  }
>  
>  void
>  pk_repl_display_end (void)
>  {
> -  pk_term_flush ();
> +  pk_term_flush (poke_compiler);
>    rl_restore_prompt ();
>    rl_point = saved_point;
>    rl_end = saved_end;
> diff --git a/poke/pk-table.c b/poke/pk-table.c
> index c8315fed..653f42c8 100644
> --- a/poke/pk-table.c
> +++ b/poke/pk-table.c
> @@ -212,7 +212,7 @@ pk_table_print (pk_table table)
>    for (i = 0; i < table->num_rows; ++i)
>      {
>        if (table->rows[i].style)
> -        pk_term_class (table->rows[i].style);
> +        pk_term_class (poke_compiler, table->rows[i].style);
>  
>        for (j = 0; j < table->rows[i].num_entries; ++j)
>          {
> @@ -230,34 +230,34 @@ pk_table_print (pk_table table)
>                 : 2);
>  
>            if (class)
> -            pk_term_class (class);
> +            pk_term_class (poke_compiler, class);
>            if (hyperlink)
>              {
> -              pk_term_class ("hyperlink");
> -              pk_term_hyperlink (hyperlink, NULL);
> +              pk_term_class (poke_compiler, "hyperlink");
> +              pk_term_hyperlink (poke_compiler, hyperlink, NULL);
>              }
>  
>            if (str)
> -            pk_puts (str);
> +            pk_puts (poke_compiler, str);
>            else
>              pk_print_val (poke_compiler, val, NULL /* exit_exception */);
>  
>            if (hyperlink)
>              {
> -              pk_term_end_hyperlink ();
> -              pk_term_end_class ("hyperlink");
> +              pk_term_end_hyperlink (poke_compiler);
> +              pk_term_end_class (poke_compiler, "hyperlink");
>              }
>            if (class)
> -            pk_term_end_class (class);
> +            pk_term_end_class (poke_compiler, class);
>  
>            if (j < table->rows[i].num_entries - 1)
>              for (k = 0; k < fill; ++k)
> -              pk_puts (" ");
> +              pk_puts (poke_compiler, " ");
>          }
>  
>        if (table->rows[i].style)
> -        pk_term_end_class (table->rows[i].style);
> +        pk_term_end_class (poke_compiler, table->rows[i].style);
>  
> -      pk_puts ("\n");
> +      pk_puts (poke_compiler, "\n");
>      }
>  }
> diff --git a/poke/pk-term.c b/poke/pk-term.c
> index 71f83a7a..f8adbd80 100644
> --- a/poke/pk-term.c
> +++ b/poke/pk-term.c
> @@ -364,7 +364,7 @@ pk_term_shutdown ()
>  }
>  
>  void
> -pk_term_flush ()
> +pk_term_flush (pk_compiler pkc __attribute__ ((unused)))
>  {
>    ostream_flush (pk_ostream, FLUSH_THIS_STREAM);
>  }
> @@ -470,7 +470,7 @@ pk_puts_paged (const char *lines)
>  }
>  
>  void
> -pk_puts (const char *str)
> +pk_puts (pk_compiler pkc __attribute__ ((unused)), const char *str)
>  {
>    if (pager_active_p)
>      pk_puts_paged (str);
> @@ -478,9 +478,9 @@ pk_puts (const char *str)
>      ostream_write_str (pk_ostream, str);
>  }
>  
> -__attribute__ ((__format__ (__printf__, 1, 2)))
> +__attribute__ ((__format__ (__printf__, 2, 3)))
>  void
> -pk_printf (const char *format, ...)
> +pk_printf (pk_compiler pkc, const char *format, ...)
>  {
>    va_list ap;
>    char *str;
> @@ -491,12 +491,12 @@ pk_printf (const char *format, ...)
>    assert (r != -1);
>    va_end (ap);
>  
> -  pk_puts (str);
> +  pk_puts (pkc, str);
>    free (str);
>  }
>  
>  void
> -pk_vprintf (const char *format, va_list ap)
> +pk_vprintf (pk_compiler pkc, const char *format, va_list ap)
>  {
>    char *str;
>    int r;
> @@ -504,27 +504,26 @@ pk_vprintf (const char *format, va_list ap)
>    r = vasprintf (&str, format, ap);
>    assert (r != -1);
>  
> -  pk_puts (str);
> +  pk_puts (pkc, str);
>    free (str);
>  }
>  
>  
>  void
> -pk_term_indent (unsigned int lvl,
> -                unsigned int step)
> +pk_term_indent (pk_compiler pkc, unsigned int lvl, unsigned int step)
>  {
> -  pk_printf ("\n%*s", (step * lvl), "");
> +  pk_printf (pkc, "\n%*s", (step * lvl), "");
>  }
>  
>  void
> -pk_term_class (const char *class)
> +pk_term_class (pk_compiler pkc __attribute__ ((unused)), const char *class)
>  {
>    styled_ostream_begin_use_class (pk_ostream, class);
>    push_active_class (class);
>  }
>  
>  int
> -pk_term_end_class (const char *class)
> +pk_term_end_class (pk_compiler pkc __attribute__ ((unused)), const char 
> *class)
>  {
>    if (!pop_active_class (class))
>      return 0;
> @@ -537,7 +536,8 @@ pk_term_end_class (const char *class)
>  static int hlcount = 0;
>  
>  void
> -pk_term_hyperlink (const char *url, const char *id)
> +pk_term_hyperlink (pk_compiler pkc __attribute__ ((unused)),
> +                   const char *url, const char *id)
>  {
>  #ifdef HAVE_TEXTSTYLE_HYPERLINK_SUPPORT
>    styled_ostream_set_hyperlink (pk_ostream, url, id);
> @@ -546,7 +546,7 @@ pk_term_hyperlink (const char *url, const char *id)
>  }
>  
>  int
> -pk_term_end_hyperlink (void)
> +pk_term_end_hyperlink (pk_compiler pkc __attribute__ ((unused)))
>  {
>  #ifdef HAVE_TEXTSTYLE_HYPERLINK_SUPPORT
>    if (hlcount == 0)
> @@ -568,7 +568,7 @@ pk_term_color_p (void)
>  }
>  
>  struct pk_color
> -pk_term_get_color (void)
> +pk_term_get_color (pk_compiler pkc __attribute__ ((unused)))
>  {
>  #if defined HAVE_TEXTSTYLE_ACCESSORS_SUPPORT
>     if (color_mode != color_html
> @@ -591,7 +591,7 @@ pk_term_get_color (void)
>  }
>  
>  struct pk_color
> -pk_term_get_bgcolor ()
> +pk_term_get_bgcolor (pk_compiler pkc __attribute__ ((unused)))
>  {
>  #if defined HAVE_TEXTSTYLE_ACCESSORS_SUPPORT
>    if (color_mode != color_html
> @@ -614,7 +614,8 @@ pk_term_get_bgcolor ()
>  }
>  
>  void
> -pk_term_set_color (struct pk_color color)
> +pk_term_set_color (pk_compiler pkc __attribute__ ((unused)),
> +                   struct pk_color color)
>  {
>  #if defined HAVE_TEXTSTYLE_ACCESSORS_SUPPORT
>    if (color_mode != color_html)
> @@ -642,7 +643,8 @@ pk_term_set_color (struct pk_color color)
>  }
>  
>  void
> -pk_term_set_bgcolor (struct pk_color color)
> +pk_term_set_bgcolor (pk_compiler pkc __attribute__ ((unused)),
> +                     struct pk_color color)
>  {
>  #if defined HAVE_TEXTSTYLE_ACCESSORS_SUPPORT
>    if (color_mode != color_html)
> diff --git a/poke/pk-term.h b/poke/pk-term.h
> index 8516dc30..d176f87a 100644
> --- a/poke/pk-term.h
> +++ b/poke/pk-term.h
> @@ -23,6 +23,9 @@
>  
>  #include <textstyle.h>
>  
> +/* From libpoke.h.  */
> +typedef struct _pk_compiler *pk_compiler;
> +
>  /* Initialize and finalize the terminal subsystem.  */
>  void pk_term_init (int argc, char *argv[]);
>  void pk_term_shutdown (void);
> @@ -32,33 +35,33 @@ void pk_term_shutdown (void);
>  extern int pk_term_color_p (void);
>  
>  /* Flush the terminal output.  */
> -extern void pk_term_flush (void);
> +extern void pk_term_flush (pk_compiler pkc);
>  
>  /* Print a string to the terminal.  */
> -extern void pk_puts (const char *str);
> +extern void pk_puts (pk_compiler pkc, const char *str);
>  
>  /* Print a formatted string to the terminal.  */
> -extern void pk_printf (const char *format, ...)
> -  __attribute__ ((format (printf, 1, 2)));
> -extern void pk_vprintf (const char *format, va_list ap);
> +extern void pk_printf (pk_compiler pkc, const char *format, ...)
> +  __attribute__ ((format (printf, 2, 3)));
> +extern void pk_vprintf (pk_compiler pkc, const char *format, va_list ap);
>  
>  /* Print indentation.  */
> -extern void pk_term_indent (unsigned int lvl,
> +extern void pk_term_indent (pk_compiler pkc, unsigned int lvl,
>                              unsigned int step);
>  
>  /* Class handling.  */
> -extern void pk_term_class (const char *class);
> -extern int pk_term_end_class (const char *class);
> +extern void pk_term_class (pk_compiler pkc, const char *class);
> +extern int pk_term_end_class (pk_compiler pkc, const char *class);
>  
>  /* Hyperlinks.  */
> -extern void pk_term_hyperlink (const char *url, const char *id);
> -extern int pk_term_end_hyperlink (void);
> +extern void pk_term_hyperlink (pk_compiler pkc, const char *url, const char 
> *id);
> +extern int pk_term_end_hyperlink (pk_compiler pkc);
>  
>  /* Color handling.  */
> -extern struct pk_color pk_term_get_color (void);
> -extern struct pk_color pk_term_get_bgcolor (void);
> -extern void pk_term_set_color (struct pk_color color);
> -extern void pk_term_set_bgcolor (struct pk_color color);
> +extern struct pk_color pk_term_get_color (pk_compiler pkc);
> +extern struct pk_color pk_term_get_bgcolor (pk_compiler pkc);
> +extern void pk_term_set_color (pk_compiler pkc, struct pk_color color);
> +extern void pk_term_set_bgcolor (pk_compiler pkc, struct pk_color color);
>  
>  /* Paging.  */
>  extern void pk_term_start_pager (void);
> diff --git a/poked/poked.c b/poked/poked.c
> index 7e087c6a..0d377b1c 100644
> --- a/poked/poked.c
> +++ b/poked/poked.c
> @@ -701,18 +701,18 @@ tifbuf_init(void)
>  #endif
>  
>  static void
> -tif_flush (void)
> +tif_flush (pk_compiler pkc __attribute__ ((unused)))
>  {
>  }
>  static void
> -tif_puts (const char *s)
> +tif_puts (pk_compiler pkc __attribute__ ((unused)), const char *s)
>  {
>    if (poked_options.debug_p)
>      printf (">(p) '%s'\n", s);
>    usock_out (srv, termout_chan, termout_cmdkind, s, strlen (s) + 1);
>  }
>  static void
> -tif_printf (const char *fmt, ...)
> +tif_printf (pk_compiler pkc __attribute__ ((unused)), const char *fmt, ...)
>  {
>    va_list ap;
>    char *data = NULL;
> @@ -730,7 +730,8 @@ tif_printf (const char *fmt, ...)
>    free (data);
>  }
>  static void
> -tif_indent (unsigned int level, unsigned int step)
> +tif_indent (pk_compiler pkc __attribute__ ((unused)), unsigned int level,
> +            unsigned int step)
>  {
>    size_t len = /*newline*/ 1u + step * level;
>    char *data;
> @@ -743,31 +744,32 @@ tif_indent (unsigned int level, unsigned int step)
>    free (data);
>  }
>  static void
> -tif_class (const char *name)
> +tif_class (pk_compiler pkc __attribute__ ((unused)), const char *name)
>  {
>    if (termout_chan == USOCK_CHAN_OUT_OUT)
>      usock_out (srv, termout_chan, OUTCMD_CLS_BEGIN, name, strlen (name) + 1);
>  }
>  static int
> -tif_class_end (const char *name)
> +tif_class_end (pk_compiler pkc __attribute__ ((unused)), const char *name)
>  {
>    if (termout_chan == USOCK_CHAN_OUT_OUT)
>      usock_out (srv, termout_chan, OUTCMD_CLS_END, name, strlen (name) + 1);
>    return 1;
>  }
>  static void
> -tif_hlink (const char *name, const char *id)
> +tif_hlink (pk_compiler pkc __attribute__ ((unused)), const char *name,
> +           const char *id)
>  {
>    (void)name;
>    (void)id;
>  }
>  static int
> -tif_hlink_end (void)
> +tif_hlink_end (pk_compiler pkc __attribute__ ((unused)))
>  {
>    return 1;
>  }
>  static struct pk_color
> -tif_color (void)
> +tif_color (pk_compiler pkc __attribute__ ((unused)))
>  {
>    static struct pk_color c = {
>      .red = 0,
> @@ -777,7 +779,7 @@ tif_color (void)
>    return c;
>  }
>  static struct pk_color
> -tif_bgcolor (void)
> +tif_bgcolor (pk_compiler pkc __attribute__ ((unused)))
>  {
>    static struct pk_color c = {
>      .red = 255,
> @@ -787,12 +789,12 @@ tif_bgcolor (void)
>    return c;
>  }
>  static void
> -tif_color_set (struct pk_color c)
> +tif_color_set (pk_compiler pkc __attribute__ ((unused)), struct pk_color c)
>  {
>    (void)c;
>  }
>  static void
> -tif_bgcolor_set (struct pk_color c)
> +tif_bgcolor_set (pk_compiler pkc __attribute__ ((unused)), struct pk_color c)
>  {
>    (void)c;
>  }
> diff --git a/pokefmt/pokefmt.l b/pokefmt/pokefmt.l
> index fe57fbf7..74505134 100644
> --- a/pokefmt/pokefmt.l
> +++ b/pokefmt/pokefmt.l
> @@ -362,17 +362,17 @@ pokefmt_opts_free ()
>  
>  // terminal IO functions
>  static void
> -tif_flush (void)
> +tif_flush (pk_compiler pkc __attribute__ ((unused)))
>  {
>    fflush (stdout);
>  }
>  static void
> -tif_puts (const char *s)
> +tif_puts (pk_compiler pkc __attribute__ ((unused)), const char *s)
>  {
>    printf ("%s", s);
>  }
>  static void
> -tif_printf (const char *fmt, ...)
> +tif_printf (pk_compiler pkc __attribute__ ((unused)), const char *fmt, ...)
>  {
>    va_list ap;
>  
> @@ -381,36 +381,38 @@ tif_printf (const char *fmt, ...)
>    va_end (ap);
>  }
>  static void
> -tif_indent (unsigned int level, unsigned int step)
> +tif_indent (pk_compiler pkc __attribute__ ((unused)), unsigned int level,
> +            unsigned int step)
>  {
>    putchar ('\n');
>    for (unsigned int i = 0; i < step * level; ++i)
>      putchar (' ');
>  }
>  static void
> -tif_class (const char *name)
> +tif_class (pk_compiler pkc __attribute__ ((unused)), const char *name)
>  {
>    (void)name;
>  }
>  static int
> -tif_class_end (const char *name)
> +tif_class_end (pk_compiler pkc __attribute__ ((unused)), const char *name)
>  {
>    (void)name;
>    return 1;
>  }
>  static void
> -tif_hlink (const char *name, const char *id)
> +tif_hlink (pk_compiler pkc __attribute__ ((unused)), const char *name,
> +           const char *id)
>  {
>    (void)name;
>    (void)id;
>  }
>  static int
> -tif_hlink_end (void)
> +tif_hlink_end (pk_compiler pkc __attribute__ ((unused)))
>  {
>    return 1;
>  }
>  static struct pk_color
> -tif_color (void)
> +tif_color (pk_compiler pkc __attribute__ ((unused)))
>  {
>    static struct pk_color c = {
>      .red = 0,
> @@ -420,7 +422,7 @@ tif_color (void)
>    return c;
>  }
>  static struct pk_color
> -tif_bgcolor (void)
> +tif_bgcolor (pk_compiler pkc __attribute__ ((unused)))
>  {
>    static struct pk_color c = {
>      .red = 255,
> @@ -430,12 +432,12 @@ tif_bgcolor (void)
>    return c;
>  }
>  static void
> -tif_color_set (struct pk_color c)
> +tif_color_set (pk_compiler pkc __attribute__ ((unused)), struct pk_color c)
>  {
>    (void)c;
>  }
>  static void
> -tif_bgcolor_set (struct pk_color c)
> +tif_bgcolor_set (pk_compiler pkc __attribute__ ((unused)), struct pk_color c)
>  {
>    (void)c;
>  }
> diff --git a/testsuite/poke.libpoke/term-if.h 
> b/testsuite/poke.libpoke/term-if.h
> index dfcece14..0f9d20e6 100644
> --- a/testsuite/poke.libpoke/term-if.h
> +++ b/testsuite/poke.libpoke/term-if.h
> @@ -20,19 +20,18 @@
>  #include <stdio.h>
>  
>  static void
> -pk_term_flush ()
> +pk_term_flush (pk_compiler pkc __attribute__ ((unused)))
>  {
>  }
>  
>  void
> -pk_puts (const char *str)
> +pk_puts (pk_compiler pkc __attribute__ ((unused)), const char *str)
>  {
>    printf ("%s", str);
>  }
>  
> -__attribute__ ((__format__ (__printf__, 1, 2)))
> -void
> -pk_printf (const char *format, ...)
> +__attribute__ ((__format__ (__printf__, 2, 3))) void
> +pk_printf (pk_compiler pkc __attribute__ ((unused)), const char *format, ...)
>  {
>    va_list ap;
>  
> @@ -42,58 +41,59 @@ pk_printf (const char *format, ...)
>  }
>  
>  void
> -pk_term_indent (unsigned int lvl,
> +pk_term_indent (pk_compiler pkc __attribute__ ((unused)), unsigned int lvl,
>                  unsigned int step)
>  {
>    printf ("\n%*s", (step * lvl), "");
>  }
>  
>  void
> -pk_term_class (const char *class)
> +pk_term_class (pk_compiler pkc __attribute__ ((unused)), const char *class)
>  {
>  }
>  
>  int
> -pk_term_end_class (const char *class)
> +pk_term_end_class (pk_compiler pkc __attribute__ ((unused)), const char 
> *class)
>  {
>    return 1;
>  }
>  
>  void
> -pk_term_hyperlink (const char *url, const char *id)
> +pk_term_hyperlink (pk_compiler pkc __attribute__ ((unused)), const char *url,
> +                   const char *id)
>  {
>  }
>  
>  int
> -pk_term_end_hyperlink (void)
> +pk_term_end_hyperlink (pk_compiler pkc __attribute__ ((unused)))
>  {
>    return 1;
>  }
>  
>  struct pk_color
> -pk_term_get_color (void)
> +pk_term_get_color (pk_compiler pkc __attribute__ ((unused)))
>  {
> -  struct pk_color inv = {-1,-1,-1};
> +  struct pk_color inv = { -1, -1, -1 };
>    return inv;
>  }
>  
>  struct pk_color
> -pk_term_get_bgcolor (void)
> +pk_term_get_bgcolor (pk_compiler pkc __attribute__ ((unused)))
>  {
> -  struct pk_color inv = {-1,-1,-1};
> +  struct pk_color inv = { -1, -1, -1 };
>    return inv;
>  }
>  
>  void
> -pk_term_set_color (struct pk_color color)
> +pk_term_set_color (pk_compiler pkc __attribute__ ((unused)),
> +                   struct pk_color color)
>  {
> -
>  }
>  
>  void
> -pk_term_set_bgcolor (struct pk_color color)
> +pk_term_set_bgcolor (pk_compiler pkc __attribute__ ((unused)),
> +                     struct pk_color color)
>  {
> -
>  }
>  
>  static struct pk_term_if poke_term_if =



reply via email to

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