message: Intern file names in msg_location to make them cheaper to copy.
authorBen Pfaff <blp@cs.stanford.edu>
Thu, 25 Nov 2021 01:00:57 +0000 (17:00 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Mon, 6 Dec 2021 17:05:31 +0000 (09:05 -0800)
src/language/control/define.c
src/language/data-io/data-parser.c
src/language/data-io/matrix-data.c
src/language/lexer/lexer.c
src/libpspp/intern.c
src/libpspp/intern.h
src/libpspp/message.c
src/libpspp/message.h

index 4c12ac24935badc7cf8c9b2408a2065cb8996d46..f33e885925a807b67071d1832b2de8442f3c7845 100644 (file)
@@ -23,6 +23,7 @@
 #include "language/lexer/macro.h"
 #include "language/lexer/scan.h"
 #include "language/lexer/token.h"
+#include "libpspp/intern.h"
 #include "libpspp/message.h"
 
 #include "gl/xalloc.h"
@@ -113,7 +114,7 @@ cmd_define (struct lexer *lexer, struct dataset *ds UNUSED)
     .location = xmalloc (sizeof *m->location),
   };
   *m->location = (struct msg_location) {
-    .file_name = xstrdup_if_nonnull (lex_get_file_name (lexer)),
+    .file_name = intern_new_if_nonnull (lex_get_file_name (lexer)),
     .first_line = lex_get_first_line_number (lexer, 0),
   };
   lex_get (lexer);
index 03c6dbbb0ea36a421a956498f2fb4470c14771a3..09af7542bb5750510f402b6ce3ee90bb6e833c01 100644 (file)
@@ -29,6 +29,7 @@
 #include "data/file-handle-def.h"
 #include "data/settings.h"
 #include "language/data-io/data-reader.h"
+#include "libpspp/intern.h"
 #include "libpspp/message.h"
 #include "libpspp/str.h"
 #include "output/pivot-table.h"
@@ -498,7 +499,7 @@ parse_error (const struct dfm_reader *reader, const struct field *field,
   int line_number = dfm_get_line_number (reader);
   struct msg_location *location = xmalloc (sizeof *location);
   *location = (struct msg_location) {
-    .file_name = xstrdup (dfm_get_file_name (reader)),
+    .file_name = intern_new (dfm_get_file_name (reader)),
     .first_line = line_number,
     .last_line = line_number + 1,
     .first_column = first_column,
index bffdd92cb7f463d0183181196b9e920f7e1a2fe9..31d6b710b0ba68a54402d33e50e559b9f581bf2e 100644 (file)
@@ -39,6 +39,7 @@
 #include "language/lexer/variable-parser.h"
 #include "libpspp/assertion.h"
 #include "libpspp/i18n.h"
+#include "libpspp/intern.h"
 #include "libpspp/message.h"
 #include "libpspp/str.h"
 
@@ -253,7 +254,7 @@ parse_msg (struct dfm_reader *reader, const struct substring *token,
   int line_number = dfm_get_line_number (reader);
   struct msg_location *location = xmalloc (sizeof *location);
   *location = (struct msg_location) {
-    .file_name = xstrdup (dfm_get_file_name (reader)),
+    .file_name = intern_new (dfm_get_file_name (reader)),
     .first_line = line_number,
     .last_line = line_number + 1,
     .first_column = first_column,
index 782c399f701d663d21cf8b1bb153bc1e2a04ae40..805d6fa4965829187087a1574553986f55105707 100644 (file)
@@ -38,6 +38,7 @@
 #include "libpspp/cast.h"
 #include "libpspp/deque.h"
 #include "libpspp/i18n.h"
+#include "libpspp/intern.h"
 #include "libpspp/ll.h"
 #include "libpspp/message.h"
 #include "libpspp/misc.h"
@@ -1261,7 +1262,7 @@ lex_token_location (const struct lex_source *src,
                     const struct lex_token *t1)
 {
   return (struct msg_location) {
-    .file_name = src->reader->file_name,
+    .file_name = intern_new_if_nonnull (src->reader->file_name),
     .first_line = t0->first_line,
     .last_line = lex_token_get_last_line_number (src, t1),
     .first_column = lex_token_get_first_column (src, t0),
@@ -1377,7 +1378,7 @@ lex_get_lines (const struct lexer *lexer, int n0, int n1)
 {
   struct msg_location *loc = xmalloc (sizeof *loc);
   *loc = (struct msg_location) {
-    .file_name = xstrdup_if_nonnull (lex_get_file_name (lexer)),
+    .file_name = intern_new_if_nonnull (lex_get_file_name (lexer)),
     .first_line = lex_get_first_line_number (lexer, n0),
     .last_line = lex_get_last_line_number (lexer, n1),
   };
index fc31acf0b439fec19c339296abe3e5fe8f5ce314..b8eb5198b4d9ac902ef2ce67c2fd1c994b5f0de2 100644 (file)
@@ -77,6 +77,13 @@ intern_new (const char *s)
   return is->string;
 }
 
+const char *
+intern_new_if_nonnull (const char *s)
+{
+  return s ? intern_new (s) : NULL;
+}
+
+
 static struct interned_string *
 interned_string_from_string (const char *s_)
 {
@@ -96,17 +103,26 @@ intern_ref (const char *s)
   return s;
 }
 
+const char *
+intern_ref_if_nonnull (const char *s)
+{
+  return s ? intern_ref (s) : NULL;
+}
+
 /* Decreases the reference count on S, which must be an interned string
    returned by intern_new().  If the reference count reaches 0, frees the
    interned string. */
 void
 intern_unref (const char *s)
 {
-  struct interned_string *is = interned_string_from_string (s);
-  if (--is->ref_cnt == 0)
+  if (s)
     {
-      hmap_delete (&interns, &is->node);
-      free (is);
+      struct interned_string *is = interned_string_from_string (s);
+      if (--is->ref_cnt == 0)
+        {
+          hmap_delete (&interns, &is->node);
+          free (is);
+        }
     }
 }
 
index 2f07a9ef77808b17f19e85adc2ffc9dc8d024262..2192c66d8c650afa058a2b8bc0be896da2a2c2be 100644 (file)
@@ -34,7 +34,9 @@
 #include <stddef.h>
 
 const char *intern_new (const char *);
+const char *intern_new_if_nonnull (const char *);
 const char *intern_ref (const char *);
+const char *intern_ref_if_nonnull (const char *);
 void intern_unref (const char *);
 
 size_t intern_strlen (const char *);
index 41a1da17502ea5e18386cdecb5c0d99df2c3afae..faeb83a449d3e3058507e163d9bd7049192ea917 100644 (file)
@@ -27,6 +27,7 @@
 #include <unistd.h>
 
 #include "libpspp/cast.h"
+#include "libpspp/intern.h"
 #include "libpspp/str.h"
 #include "libpspp/version.h"
 #include "data/settings.h"
@@ -108,7 +109,7 @@ msg_set_handler (void (*handler) (const struct msg *, void *aux), void *aux)
 void
 msg_location_uninit (struct msg_location *loc)
 {
-  free (loc->file_name);
+  intern_unref (loc->file_name);
 }
 
 void
@@ -129,7 +130,7 @@ msg_location_dup (const struct msg_location *src)
 
   struct msg_location *dst = xmalloc (sizeof *dst);
   *dst = (struct msg_location) {
-    .file_name = xstrdup_if_nonnull (src->file_name),
+    .file_name = intern_new_if_nonnull (src->file_name),
     .first_line = src->first_line,
     .last_line = src->last_line,
     .first_column = src->first_column,
index 6cfbde7c5019ba2740a01c80bde5266edc7b06fc..a99b0818e3438fd6514be202a46c3d6e0f6f8185 100644 (file)
@@ -74,7 +74,7 @@ msg_class_from_category_and_severity (enum msg_category category,
 
 struct msg_location
   {
-    char *file_name;            /* Name of file containing error, or NULL. */
+    const char *file_name;      /* Interned file name, or NULL. */
     int first_line;             /* 1-based line number, or 0 if none. */
     int last_line;              /* 1-based exclusive last line (0=none). */
     int first_column;           /* 1-based first column, or 0 if none. */