texinfo-commits
[Top][All Lists]
Advanced

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

branch master updated: Get errors from XS code without using eval


From: Gavin D. Smith
Subject: branch master updated: Get errors from XS code without using eval
Date: Wed, 23 Feb 2022 13:27:39 -0500

This is an automated email from the git hooks/post-receive script.

gavin pushed a commit to branch master
in repository texinfo.

The following commit(s) were added to refs/heads/master by this push:
     new da012692a8 Get errors from XS code without using eval
da012692a8 is described below

commit da012692a8a1bff93d7429348b93b1f3ea85002e
Author: Gavin Smith <gavinsmith0123@gmail.com>
AuthorDate: Wed Feb 23 18:27:27 2022 +0000

    Get errors from XS code without using eval
    
    * tp/Texinfo/XS/parsetexi/api.c, tp/Texinfo/XS/parsetexi/Parsetexi.xs
    (get_errors): New function to create error list.
    * tp/Texinfo/XS/parsetexi/errors.c (dump_errors): Function removed.
    * tp/Texinfo/XS/parsetexi/Parsetexi.pm: Call it to get the errors
    and warnings from the XS module.
    
    This allows better control of string encodings for messages
    and filenames.  It may also be faster than calling eval.
---
 ChangeLog                            |  13 +++++
 tp/Texinfo/XS/parsetexi/Parsetexi.pm |  21 +------
 tp/Texinfo/XS/parsetexi/Parsetexi.xs |   6 +-
 tp/Texinfo/XS/parsetexi/api.c        |  88 ++++++++++++++++++++++++++++++
 tp/Texinfo/XS/parsetexi/api.h        |   2 +-
 tp/Texinfo/XS/parsetexi/errors.c     | 103 +----------------------------------
 tp/Texinfo/XS/parsetexi/errors.h     |  10 +++-
 7 files changed, 119 insertions(+), 124 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0aa8a9d706..5b9de52c1a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2022-02-23  Gavin Smith  <gavinsmith0123@gmail.com>
+
+       Get errors from XS code without using eval
+
+       * tp/Texinfo/XS/parsetexi/api.c, tp/Texinfo/XS/parsetexi/Parsetexi.xs
+       (get_errors): New function to create error list.
+       * tp/Texinfo/XS/parsetexi/errors.c (dump_errors): Function removed.
+       * tp/Texinfo/XS/parsetexi/Parsetexi.pm: Call it to get the errors
+       and warnings from the XS module.
+
+       This allows better control of string encodings for messages
+       and filenames.  It may also be faster than calling eval.
+
 2022-02-23  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/XS/parsetexi/Parsetexi.pm (_get_errors): encode
diff --git a/tp/Texinfo/XS/parsetexi/Parsetexi.pm 
b/tp/Texinfo/XS/parsetexi/Parsetexi.pm
index 401fc9c8d7..3ada1cd9a5 100644
--- a/tp/Texinfo/XS/parsetexi/Parsetexi.pm
+++ b/tp/Texinfo/XS/parsetexi/Parsetexi.pm
@@ -1,4 +1,4 @@
-# Copyright 2014-2021 Free Software Foundation, Inc.
+# Copyright 2014-2022 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -245,31 +245,14 @@ sub parse_texi_file ($$)
 }
 
 # Copy the errors into the error list in Texinfo::Report.
-# TODO: Could we just access the error list directly instead of going
-# through Texinfo::Report line_error?
 sub _get_errors($)
 {
   my $self = shift;
   my ($registrar, $configuration_information) = _get_error_registrar($self);
 
-  my $ERRORS;
-  my $tree_stream = dump_errors();
+  my $ERRORS = get_errors ();
 
-  # dump_errors outputs error messages in UTF-8 and we want to read them in
-  # as Perl strings
-  utf8::decode($tree_stream);
-  eval $tree_stream;
   for my $error (@{$ERRORS}) {
-    my $error_location_info = $error->{'line_nr'};
-    if (defined($error_location_info)
-        and defined($error_location_info->{'file_name'})) {
-      # When dealing with file names, we want Perl strings representing
-      # sequences of bytes, not codepoints.
-      # FIXME this is not really correct, the final encoding may not be utf-8
-      # but this should be better handled, without decoding followed by
-      # encoding when a better interface is implemented.
-      utf8::encode($error_location_info->{'file_name'});
-    }
     if ($error->{'type'} eq 'error') {
       $registrar->line_error ($configuration_information,
                               $error->{'message'}, $error->{'line_nr'});
diff --git a/tp/Texinfo/XS/parsetexi/Parsetexi.xs 
b/tp/Texinfo/XS/parsetexi/Parsetexi.xs
index 1f00ab76bd..2d19445587 100644
--- a/tp/Texinfo/XS/parsetexi/Parsetexi.xs
+++ b/tp/Texinfo/XS/parsetexi/Parsetexi.xs
@@ -26,9 +26,6 @@ init (texinfo_uninstalled, srcdir)
      int texinfo_uninstalled
      char *srcdir
 
-char *
-dump_errors ()
-
 void
 wipe_errors ()
 
@@ -118,3 +115,6 @@ set_debug (int i)
 
 void
 set_accept_internalvalue()
+
+AV *
+get_errors ()
diff --git a/tp/Texinfo/XS/parsetexi/api.c b/tp/Texinfo/XS/parsetexi/api.c
index 9711eb1c7e..1b06962e3e 100644
--- a/tp/Texinfo/XS/parsetexi/api.c
+++ b/tp/Texinfo/XS/parsetexi/api.c
@@ -1095,3 +1095,91 @@ set_documentlanguage_override (char *value)
   global_documentlanguage_fixed = 1;
 }
 
+
+
+static SV *
+build_line_nr_hash (LINE_NR line_nr)
+{
+  HV *hv;
+
+  dTHX;
+
+  hv = newHV ();
+
+  if (line_nr.file_name)
+    {
+      hv_store (hv, "file_name", strlen ("file_name"),
+                newSVpv (line_nr.file_name, 0), 0);
+    }
+  else
+    {
+      hv_store (hv, "file_name", strlen ("file_name"),
+                newSVpv ("", 0), 0);
+    }
+  if (line_nr.line_nr)
+    {
+      hv_store (hv, "line_nr", strlen ("line_nr"),
+                newSViv (line_nr.line_nr), 0);
+    }
+  if (line_nr.macro)
+    {
+      hv_store (hv, "macro", strlen ("macro"),
+                newSVpv (line_nr.macro, 0), 0);
+    }
+  else
+    {
+      hv_store (hv, "macro", strlen ("macro"),
+                newSVpv ("", 0), 0);
+    }
+
+  return newRV_inc ((SV *) hv);
+}
+
+static SV *
+convert_error (int i)
+{
+  ERROR_MESSAGE e;
+  HV *hv;
+  SV *msg;
+
+  dTHX;
+
+  e = error_list[i];
+  hv = newHV ();
+
+  msg = newSVpv (e.message, 0);
+  SvUTF8_on (msg);
+
+  hv_store (hv, "message", strlen ("message"), msg, 0);
+  hv_store (hv, "type", strlen ("type"),
+              e.type == error ? newSVpv("error", strlen("error"))
+                              : newSVpv("warning", strlen("warning")),
+            0);
+
+  hv_store (hv, "line_nr", strlen ("line_nr"),
+            build_line_nr_hash(e.line_nr), 0);
+
+  return newRV_inc ((SV *) hv);
+
+}
+
+/* Errors */
+AV *
+get_errors (void)
+{
+  AV *av;
+  int i;
+
+  dTHX;
+
+  av = newAV ();
+
+  for (i = 0; i < error_number; i++)
+    {
+      SV *sv = convert_error (i);
+      av_push (av, sv);
+    }
+
+  return av;
+
+}
diff --git a/tp/Texinfo/XS/parsetexi/api.h b/tp/Texinfo/XS/parsetexi/api.h
index 7c328d06be..361d68d8de 100644
--- a/tp/Texinfo/XS/parsetexi/api.h
+++ b/tp/Texinfo/XS/parsetexi/api.h
@@ -24,6 +24,6 @@ HV *build_float_list (void);
 HV *build_index_data (void);
 HV *build_global_info (void);
 HV *build_global_info2 (void);
-
+AV *get_errors (void);
 
 #endif
diff --git a/tp/Texinfo/XS/parsetexi/errors.c b/tp/Texinfo/XS/parsetexi/errors.c
index 8633979e9d..32999cce53 100644
--- a/tp/Texinfo/XS/parsetexi/errors.c
+++ b/tp/Texinfo/XS/parsetexi/errors.c
@@ -1,4 +1,4 @@
-/* Copyright 2010-2021 Free Software Foundation, Inc.
+/* Copyright 2010-2022 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -60,14 +60,8 @@ void fatal (char *message)
 }
 
 
-typedef struct {
-    char *message;
-    enum error_type type;
-    LINE_NR line_nr;
-} ERROR_MESSAGE;
-
-static ERROR_MESSAGE *error_list = 0;
-static size_t error_number = 0;
+ERROR_MESSAGE *error_list = 0;
+size_t error_number = 0;
 static size_t error_space = 0;
 
 static void
@@ -181,94 +175,3 @@ bug_message (char *format, ...)
   va_start (v, format);
   bug_message_internal (format, v);
 }
-
-static int indent = 0;
-
-/* Output INDENT spaces. */
-static void
-dump_indent (TEXT *text)
-{
-  int i;
-
-  for (i = 0; i < indent; i++)
-    text_append_n (text, " ", 1);
-}
-
-/* Ouput S escaping single quotes and backslashes, so that
-   Perl can read it in when it is surrounded by single quotes.  */
-void
-dump_string (char *s, TEXT *text)
-{
- while (*s)
-   {
-     if (*s == '\''
-       || *s == '\\')
-       text_append_n (text, "\\", 1);
-     text_append_n (text, s++, 1);
-   }
-}
-
-static void
-dump_line_nr (LINE_NR *line_nr, TEXT *text)
-{
-  text_append_n (text, "{\n", 2);
-  indent += 2;
-
-  dump_indent (text);
-  text_printf (text, "'file_name' => '%s',\n",
-               line_nr->file_name ?
-               line_nr->file_name : "");
-
-  if (line_nr->line_nr)
-    {
-      dump_indent (text);
-      text_append (text, "'line_nr' => ");
-      text_printf (text, "%d", line_nr->line_nr);
-      text_append (text, ",\n");
-    }
-
-  /* TODO: macro. */
-  if (line_nr->macro)
-    {
-      dump_indent (text);
-      text_append (text, "'macro' => ");
-      text_printf (text, "'%s'", line_nr->macro);
-      text_append (text, ",\n");
-    }
-  else
-    {
-      dump_indent (text);
-      text_append (text, "'macro' => ''\n");
-    }
-
-
-  indent -= 2;
-  dump_indent (text);
-  text_append_n (text, "},\n", 3);
-}
-
-char *
-dump_errors (void)
-{
-  int i;
-  static TEXT t;
-  
-  text_reset (&t);
-  text_append (&t, "$ERRORS = [\n");
-  for (i = 0; i < error_number; i++)
-    {
-      text_append (&t, "{ 'message' =>\n'");
-      dump_string (error_list[i].message, &t);
-      text_append (&t, "',\n");
-      text_printf (&t, "'type' => '%s',", error_list[i].type == error ? "error"
-                                                                : "warning");
-      text_append (&t, "'line_nr' => ");
-      dump_line_nr (&error_list[i].line_nr, &t);
-      text_append (&t, "},\n");
-    }
-  text_append (&t, "];\n");
-
-  return t.text;
-}
-
-
diff --git a/tp/Texinfo/XS/parsetexi/errors.h b/tp/Texinfo/XS/parsetexi/errors.h
index e9c0682f20..a74ad1b318 100644
--- a/tp/Texinfo/XS/parsetexi/errors.h
+++ b/tp/Texinfo/XS/parsetexi/errors.h
@@ -22,5 +22,13 @@ void line_error_ext (enum error_type type, LINE_NR 
*cmd_line_nr,
                      char *format, ...);
 void bug_message (char *format, ...);
 
-char *dump_errors (void);
+typedef struct {
+    char *message;
+    enum error_type type;
+    LINE_NR line_nr;
+} ERROR_MESSAGE;
+
+extern ERROR_MESSAGE *error_list;
+extern size_t error_number;
+
 #endif



reply via email to

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