bison-patches
[Top][All Lists]
Advanced

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

02-tags-struniqs.patch


From: Akim Demaille
Subject: 02-tags-struniqs.patch
Date: Tue, 12 Nov 2002 08:44:08 +0100

Index: 0.4/ChangeLog
--- 0.4/ChangeLog Fri, 08 Nov 2002 18:07:03 +0100 akim (bison/d/40_ChangeLog 
1.2 644)
+++ 0.4(w)/ChangeLog Sat, 09 Nov 2002 10:31:21 +0100 akim (bison/d/40_ChangeLog 
1.2 644)
@@ -1,3 +1,38 @@
+2002-11-09  Akim Demaille  <address@hidden>
+
+       * src/struniq.h, src/struniq.c (struniq_t): Is const.
+       (STRUNIQ_EQ, struniq_assert, struniq_assert_p): New.
+
+       Use struniq for symbols.
+
+       * src/symtab.h (symbol_t): The tag member is a struniq.
+       (symbol_type_set): Adjust.
+       * src/symtab.c (symbol_new): Takes a struniq.
+       (symbol_free): Don't free the tag member.
+       (hash_compare_symbol_t, hash_symbol_t): Rename as...
+       (hash_compare_symbol, hash_symbol): these.
+       Use the fact that tags as struniqs.
+       (symbol_get): Use struniq_new.
+       * src/symlist.h, src/symlist.c (symbol_list_n_type_name_get):
+       Returns a strniq.
+       * src/reader.h (merger_list, grammar_currentmerge_set): The name
+       and type members are struniqs.
+       * src/reader.c (get_merge_function)
+       (grammar_current_rule_merge_set): Adjust.
+       (TYPE, current_type): Are struniq.
+
+       Use struniq for file names.
+
+       * src/files.h, src/files.c (infile): Split into...
+       (grammar_file, current_file): these.
+       * src/scan-gram.c (YY_USER_INIT, handle_syncline): Adjust.
+       * src/reduce.c (reduce_print): Likewise.
+       * src/getargs.c (getargs): Likewise.
+       * src/complain.h, src/complain.c: Likewise.
+       * src/main.c (main): Call struniqs_new early enough to use it for
+       file names.
+       Don't free the input file name.
+       
 2002-11-08  Akim Demaille  <address@hidden>
 
        * src/symtab.c (symbol_free): Remove dead deactivated code:
Index: 0.4/src/symtab.h
--- 0.4/src/symtab.h Fri, 08 Nov 2002 18:07:03 +0100 akim (bison/39_symtab.h 
1.2 644)
+++ 0.4(w)/src/symtab.h Fri, 08 Nov 2002 19:16:59 +0100 akim (bison/39_symtab.h 
1.2 644)
@@ -48,7 +48,7 @@
 struct symbol_s
 {
   /* The key, name of the symbol.  */
-  char *tag;
+  struniq_t tag;
   /* The location of its first occurence.  */
   location_t location;
 
@@ -98,7 +98,7 @@
 /* Set the TYPE_NAME associated to SYMBOL. Does nothing if passed 0 as
    TYPE_NAME.  */
 void symbol_type_set (symbol_t *symbol,
-                     char *type_name, location_t location);
+                     struniq_t type_name, location_t location);
 
 /* Set the DESTRUCTOR associated to SYMBOL.  */
 void symbol_destructor_set (symbol_t *symbol,
Index: 0.4/src/symtab.c
--- 0.4/src/symtab.c Fri, 08 Nov 2002 18:07:03 +0100 akim (bison/40_symtab.c 
1.2 644)
+++ 0.4(w)/src/symtab.c Sat, 09 Nov 2002 10:11:46 +0100 akim (bison/40_symtab.c 
1.2 644)
@@ -42,11 +42,12 @@
 `---------------------------------*/
 
 static symbol_t *
-symbol_new (const char *tag, location_t location)
+symbol_new (struniq_t tag, location_t location)
 {
   symbol_t *res = XMALLOC (symbol_t, 1);
 
-  res->tag = xstrdup (tag);
+  struniq_assert (tag);
+  res->tag = tag;
   res->location = location;
 
   res->type_name = NULL;
@@ -72,13 +73,14 @@
 `------------------------------------------------------------------*/
 
 void
-symbol_type_set (symbol_t *symbol, char *type_name, location_t location)
+symbol_type_set (symbol_t *symbol, struniq_t type_name, location_t location)
 {
   if (type_name)
     {
       if (symbol->type_name)
        complain_at (location,
                     _("type redeclaration for %s"), symbol->tag);
+      struniq_assert (type_name);
       symbol->type_name = type_name;
     }
 }
@@ -200,7 +202,6 @@
 static void
 symbol_free (symbol_t *this)
 {
-  free (this->tag);
   free (this);
 }
 
@@ -376,15 +377,17 @@
 static struct hash_table *symbol_table = NULL;
 
 static bool
-hash_compare_symbol_t (const symbol_t *m1, const symbol_t *m2)
+hash_compare_symbol (const symbol_t *m1, const symbol_t *m2)
 {
-  return strcmp (m1->tag, m2->tag) == 0;
+  /* Since tags are unique, we can compare the pointers themselves.  */
+  return STRUNIQ_EQ (m1->tag, m2->tag);
 }
 
 static unsigned int
-hash_symbol_t (const symbol_t *m, unsigned int tablesize)
+hash_symbol (const symbol_t *m, unsigned int tablesize)
 {
-  return hash_string (m->tag, tablesize);
+  /* Since tags are unique, we can hash the pointer itself.  */
+  return ((size_t) m->tag) % tablesize;
 }
 
 
@@ -397,8 +400,8 @@
 {
   symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
                                  NULL,
-                                 (Hash_hasher) hash_symbol_t,
-                                 (Hash_comparator) hash_compare_symbol_t,
+                                 (Hash_hasher) hash_symbol,
+                                 (Hash_comparator) hash_compare_symbol,
                                  (Hash_data_freer) symbol_free);
 }
 
@@ -415,7 +418,7 @@
   symbol_t *entry;
 
   /* Keep the symbol in a printable form.  */
-  key = quotearg_style (escape_quoting_style, key);
+  key = struniq_new (quotearg_style (escape_quoting_style, key));
   *(char const **) &probe.tag = key;
   entry = hash_lookup (symbol_table, &probe);
 
Index: 0.4/src/symlist.h
--- 0.4/src/symlist.h Fri, 08 Nov 2002 16:19:16 +0100 akim (bison/41_symlist.h 
1.1 644)
+++ 0.4(w)/src/symlist.h Fri, 08 Nov 2002 18:42:50 +0100 akim 
(bison/41_symlist.h 1.1 644)
@@ -56,7 +56,7 @@
 
 /* Get the data type (alternative in the union) of the value for
    symbol N in rule RULE.  */
-char *symbol_list_n_type_name_get (symbol_list_t *rule,
+struniq_t symbol_list_n_type_name_get (symbol_list_t *rule,
                                   location_t location, int n);
 
 #endif /* !SYMLIST_H_ */
Index: 0.4/src/symlist.c
--- 0.4/src/symlist.c Fri, 08 Nov 2002 16:19:16 +0100 akim (bison/42_symlist.c 
1.1 644)
+++ 0.4(w)/src/symlist.c Fri, 08 Nov 2002 18:42:50 +0100 akim 
(bison/42_symlist.c 1.1 644)
@@ -86,7 +86,7 @@
 | symbol N in rule RULE.                                        |
 `--------------------------------------------------------------*/
 
-char *
+struniq_t
 symbol_list_n_type_name_get (symbol_list_t *rule, location_t location, int n)
 {
   int i;
Index: 0.4/src/scan-gram.l
--- 0.4/src/scan-gram.l Fri, 08 Nov 2002 18:07:03 +0100 akim 
(bison/46_scan-gram. 1.2 644)
+++ 0.4(w)/src/scan-gram.l Fri, 08 Nov 2002 18:42:54 +0100 akim 
(bison/46_scan-gram. 1.2 644)
@@ -36,7 +36,7 @@
 #define YY_USER_INIT                           \
 do {                                           \
   LOCATION_RESET (*yylloc);                    \
-  yylloc->file = infile;                       \
+  yylloc->file = current_file;                 \
    /* This is only to avoid GCC warnings. */   \
   if (yycontrol) {;};                          \
 } while (0)
@@ -928,13 +928,12 @@
   const char *file = NULL;
   file = strchr (args, '"') + 1;
   *strchr (file, '"') = 0;
-  /* FIXME: Leaking...  Can't free, as some locations are still
-     pointing to the old file name.  */
-  infile = xstrdup (file);
-  location->file = infile;
+  current_file = struniq_new (file);
+  location->file = current_file;
   location->last_line = lineno;
 }
 
+
 /*-------------------------.
 | Initialize the scanner.  |
 `-------------------------*/
Index: 0.4/src/reduce.c
--- 0.4/src/reduce.c Fri, 08 Nov 2002 16:19:16 +0100 akim (bison/50_reduce.c 
1.1 644)
+++ 0.4(w)/src/reduce.c Fri, 08 Nov 2002 18:42:50 +0100 akim (bison/50_reduce.c 
1.1 644)
@@ -389,7 +389,7 @@
                               nuseless_productions),
             nuseless_productions);
 
-  fprintf (stderr, "%s: %s: ", infile, _("warning"));
+  fprintf (stderr, "%s: %s: ", grammar_file, _("warning"));
 
   if (nuseless_nonterminals > 0)
     fprintf (stderr, ngettext ("%d useless nonterminal",
@@ -449,7 +449,7 @@
 
       fprintf (stderr, "reduced %s defines %d terminals, %d nonterminals\
 , and %d productions.\n",
-              infile, ntokens, nvars, nrules);
+              grammar_file, ntokens, nvars, nrules);
     }
 }
 
Index: 0.4/src/reader.h
--- 0.4/src/reader.h Fri, 08 Nov 2002 16:19:16 +0100 akim (bison/51_reader.h 
1.1 644)
+++ 0.4(w)/src/reader.h Sat, 09 Nov 2002 10:24:27 +0100 akim (bison/51_reader.h 
1.1 644)
@@ -27,8 +27,8 @@
 typedef struct merger_list
 {
   struct merger_list* next;
-  const char* name;
-  const char* type;
+  struniq_t name;
+  struniq_t type;
 }
 merger_list;
 
@@ -77,7 +77,7 @@
 void grammar_midrule_action (void);
 void grammar_current_rule_prec_set (symbol_t *precsym, location_t l);
 void grammar_current_rule_dprec_set (int dprec, location_t l);
-void grammar_current_rule_merge_set (const char* name, location_t l);
+void grammar_current_rule_merge_set (struniq_t name, location_t l);
 
 void grammar_current_rule_symbol_append (symbol_t *symbol, location_t l);
 void grammar_current_rule_action_append (const char *action, location_t l);
Index: 0.4/src/reader.c
--- 0.4/src/reader.c Fri, 08 Nov 2002 18:07:03 +0100 akim (bison/b/0_reader.c 
1.2 644)
+++ 0.4(w)/src/reader.c Sat, 09 Nov 2002 10:31:46 +0100 akim 
(bison/b/0_reader.c 1.2 644)
@@ -99,12 +99,11 @@
 /*-------------------------------------------------------------------.
 | Return the merger index for a merging function named NAME, whose   |
 | arguments have type TYPE.  Records the function, if new, in        |
-| merger_list.                                                      |
+| MERGER_LIST.                                                      |
 `-------------------------------------------------------------------*/
 
 static int
-get_merge_function (const char* name, const char* type,
-                   location_t loc)
+get_merge_function (struniq_t name, struniq_t type, location_t loc)
 {
   merger_list *syms;
   merger_list head;
@@ -118,17 +117,17 @@
 
   head.next = merge_functions;
   for (syms = &head, n = 1; syms->next != NULL; syms = syms->next, n += 1)
-    if (strcmp (name, syms->next->name) == 0)
+    if (STRUNIQ_EQ (name, syms->next->name))
       break;
   if (syms->next == NULL)
     {
       syms->next = XMALLOC (merger_list, 1);
-      syms->next->name = xstrdup (name);
-      syms->next->type = xstrdup (type);
+      syms->next->name = struniq_new (name);
+      syms->next->type = struniq_new (type);
       syms->next->next = NULL;
       merge_functions = head.next;
     }
-  else if (strcmp (type, syms->next->type) != 0)
+  else if (!STRUNIQ_EQ (type, syms->next->type))
     warn_at (loc, _("result type clash on merge function %s: <%s> != <%s>"),
             name, type, syms->next->type);
   return n;
@@ -254,7 +253,7 @@
   if (first_rhs)
     {
       const char *rhs_type = first_rhs->type_name ? first_rhs->type_name : "";
-      if (strcmp (lhs_type, rhs_type))
+      if (!STRUNIQ_EQ (lhs_type, rhs_type))
        complain_at (current_rule->location,
                     _("type clash on default action: <%s> != <%s>"),
                     lhs_type, rhs_type);
@@ -355,7 +354,7 @@
    rule. */
 
 void
-grammar_current_rule_merge_set (const char* name, location_t location)
+grammar_current_rule_merge_set (struniq_t name, location_t location)
 {
   if (! glr_parser)
     warn_at (location, _("%s affects only GLR parsers"), "%merge");
@@ -488,7 +487,7 @@
   obstack_init (&pre_prologue_obstack);
   obstack_init (&post_prologue_obstack);
 
-  finput = xfopen (infile, "r");
+  finput = xfopen (grammar_file, "r");
   gram_in = finput;
 
   gram__flex_debug = trace_flag & trace_scan;
Index: 0.4/src/parse-gram.y
--- 0.4/src/parse-gram.y Fri, 08 Nov 2002 18:07:03 +0100 akim 
(bison/b/5_parse-gram 1.2 644)
+++ 0.4(w)/src/parse-gram.y Fri, 08 Nov 2002 19:17:45 +0100 akim 
(bison/b/5_parse-gram 1.2 644)
@@ -75,7 +75,7 @@
 static void yyprint (FILE *file, int type, const yystype *value);
 
 symbol_class current_class = unknown_sym;
-char *current_type = 0;
+struniq_t current_type = 0;
 symbol_t *current_lhs;
 location_t current_lhs_location;
 assoc_t current_assoc;
@@ -158,8 +158,9 @@
 %token BRACED_CODE     "{...}"
 
 
-%type <string> CHARACTER TYPE STRING string_content
+%type <string> CHARACTER STRING string_content
                BRACED_CODE PROLOGUE EPILOGUE epilogue.opt action
+%type <struniq> TYPE
 %type <integer> INT
 %type <symbol> ID symbol string_as_id
 %type <assoc> precedence_declarator
Index: 0.4/src/output.c
--- 0.4/src/output.c Fri, 08 Nov 2002 16:19:16 +0100 akim (bison/b/8_output.c 
1.1 644)
+++ 0.4(w)/src/output.c Fri, 08 Nov 2002 18:42:50 +0100 akim 
(bison/b/8_output.c 1.1 644)
@@ -181,7 +181,7 @@
 
 /*-------------------------------------------------------------.
 | Prepare the muscles related to the rules: rhs, prhs, r1, r2, |
-| rline, dprec, merger                                         |
+| rline, dprec, merger.                                        |
 `-------------------------------------------------------------*/
 
 static void
@@ -213,9 +213,9 @@
       rhs[i++] = -1;
       /* Line where rule was defined. */
       rline[r] = rules[r].location.first_line;
-      /* Dynamic precedence (GLR) */
+      /* Dynamic precedence (GLR).  */
       dprec[r] = rules[r].dprec;
-      /* Merger-function index (GLR) */
+      /* Merger-function index (GLR).  */
       merger[r] = rules[r].merger;
     }
   assert (i == nritems);
Index: 0.4/src/muscle_tab.c
--- 0.4/src/muscle_tab.c Fri, 08 Nov 2002 16:19:16 +0100 akim 
(bison/b/12_muscle_tab 1.1 644)
+++ 0.4(w)/src/muscle_tab.c Fri, 08 Nov 2002 18:42:50 +0100 akim 
(bison/b/12_muscle_tab 1.1 644)
@@ -64,7 +64,7 @@
 
   /* Version and input file.  */
   MUSCLE_INSERT_STRING ("version", VERSION);
-  MUSCLE_INSERT_STRING ("filename", infile);
+  MUSCLE_INSERT_STRING ("filename", grammar_file);
 }
 
 
Index: 0.4/src/main.c
--- 0.4/src/main.c Fri, 08 Nov 2002 18:07:03 +0100 akim (bison/b/13_main.c 1.2 
644)
+++ 0.4(w)/src/main.c Fri, 08 Nov 2002 18:45:59 +0100 akim (bison/b/13_main.c 
1.2 644)
@@ -55,6 +55,8 @@
   (void) bindtextdomain (PACKAGE, LOCALEDIR);
   (void) textdomain (PACKAGE);
 
+  struniqs_new ();
+
   getargs (argc, argv);
 
   time_report = trace_flag & trace_time;
@@ -64,7 +66,6 @@
   if (trace_flag & trace_bitsets)
     bitset_stats_enable ();
 
-  struniqs_new ();
   muscle_init ();
 
   /* Read the input.  Copy some parts of it to FGUARD, FACTION, FTABLE
@@ -160,8 +161,6 @@
   reduce_free ();
   conflicts_free ();
   grammar_free ();
-  /* FIXME: We are leaking all the other file names.  */
-  free (infile);
 
   /* The scanner memory cannot be released right after parsing, as it
      contains things such as user actions, prologue, epilogue etc.  */
Index: 0.4/src/getargs.c
--- 0.4/src/getargs.c Fri, 08 Nov 2002 16:19:16 +0100 akim 
(bison/b/21_getargs.c 1.1 644)
+++ 0.4(w)/src/getargs.c Fri, 08 Nov 2002 18:47:45 +0100 akim 
(bison/b/21_getargs.c 1.1 644)
@@ -24,6 +24,7 @@
 #include "argmatch.h"
 #include "error.h"
 #include "complain.h"
+#include "struniq.h"
 #include "getargs.h"
 #include "files.h"
 
@@ -419,5 +420,5 @@
       usage (EXIT_FAILURE);
     }
 
-  infile = xstrdup (argv[optind]);
+  current_file = grammar_file = struniq_new (argv[optind]);
 }
Index: 0.4/src/files.h
--- 0.4/src/files.h Fri, 08 Nov 2002 16:19:16 +0100 akim (bison/b/22_files.h 
1.1 644)
+++ 0.4(w)/src/files.h Fri, 08 Nov 2002 18:44:02 +0100 akim (bison/b/22_files.h 
1.1 644)
@@ -21,6 +21,8 @@
 #ifndef FILES_H_
 # define FILES_H_
 
+# include "struniq.h"
+
 /* File name specified with -o for the output file, or 0 if no -o.  */
 extern char *spec_outfile;
 
@@ -50,7 +52,13 @@
 extern struct obstack pre_prologue_obstack;
 extern struct obstack post_prologue_obstack;
 
-extern char *infile;
+/* The file name as given on the command line.
+   Not named "input_file" because Flex uses this name for an argument,
+   and therefore GCC warns about a name clash. */
+extern struniq_t grammar_file;
+
+/* The current file name.  Might change with %include, or with #line.  */
+extern struniq_t current_file;
 
 void compute_output_file_names (void);
 
Index: 0.4/src/files.c
--- 0.4/src/files.c Fri, 08 Nov 2002 16:19:16 +0100 akim (bison/b/23_files.c 
1.1 644)
+++ 0.4(w)/src/files.c Fri, 08 Nov 2002 18:42:50 +0100 akim (bison/b/23_files.c 
1.1 644)
@@ -50,7 +50,8 @@
 char *spec_defines_file = NULL; /* for --defines. */
 char *parser_file_name = NULL;
 
-char *infile = NULL;
+struniq_t grammar_file = NULL;
+struniq_t current_file = NULL;
 
 static char *full_base_name = NULL;
 
@@ -287,7 +288,7 @@
        {
          /* Otherwise, the short base name is computed from the input
             grammar: `foo/bar.yy' => `bar'.  */
-         filename_split (infile, &base, &tab, &ext);
+         filename_split (grammar_file, &base, &tab, &ext);
          short_base_name =
            xstrndup (base,
                      (strlen (base) - (ext ? strlen (ext) : 0)));
@@ -302,7 +303,7 @@
       stpcpy (stpcpy (full_base_name, short_base_name), EXT_TAB);
 
       /* Computes the extensions from the grammar file name.  */
-      filename_split (infile, &base, &tab, &ext);
+      filename_split (grammar_file, &base, &tab, &ext);
       if (ext && !yacc_flag)
        compute_exts_from_gf (ext);
     }
Index: 0.4/src/complain.h
--- 0.4/src/complain.h Fri, 08 Nov 2002 16:19:16 +0100 akim 
(bison/b/28_complain.h 1.1 644)
+++ 0.4(w)/src/complain.h Fri, 08 Nov 2002 18:42:50 +0100 akim 
(bison/b/28_complain.h 1.1 644)
@@ -50,7 +50,7 @@
   __attribute__ ((__noreturn__, __format__ (__printf__, 2, 3)));
 
 /* Position in the current input file. */
-extern char *infile;
+extern const char *current_file;
 
 /* This variable is set each time `warn' is called.  */
 extern bool warning_issued;
Index: 0.4/src/complain.c
--- 0.4/src/complain.c Fri, 08 Nov 2002 16:19:16 +0100 akim 
(bison/b/29_complain.c 1.1 644)
+++ 0.4(w)/src/complain.c Fri, 08 Nov 2002 18:42:50 +0100 akim 
(bison/b/29_complain.c 1.1 644)
@@ -117,7 +117,7 @@
   va_list args;
 
   fflush (stdout);
-  fprintf (stderr, "%s: %s", infile ? infile : program_name, _("warning: "));
+  fprintf (stderr, "%s: %s", current_file ? current_file : program_name, 
_("warning: "));
 
   va_start (args, message);
   vfprintf (stderr, message, args);
@@ -156,7 +156,7 @@
   va_list args;
 
   fflush (stdout);
-  fprintf (stderr, "%s: ", infile ? infile : program_name);
+  fprintf (stderr, "%s: ", current_file ? current_file : program_name);
 
   va_start (args, message);
   vfprintf (stderr, message, args);
@@ -195,7 +195,7 @@
   va_list args;
 
   fflush (stdout);
-  fprintf (stderr, "%s: ", infile ? infile : program_name);
+  fprintf (stderr, "%s: ", current_file ? current_file : program_name);
 
   fputs (_("fatal error: "), stderr);
 
Index: 0.4/src/struniq.h
--- 0.4/src/struniq.h Fri, 08 Nov 2002 18:07:03 +0100 akim 
(bison/e/14_struniq.h 1.1 644)
+++ 0.4(w)/src/struniq.h Fri, 08 Nov 2002 19:25:11 +0100 akim 
(bison/e/14_struniq.h 1.1 644)
@@ -25,11 +25,14 @@
 | struniq_t -- pointers to unique copies of C strings.  |
 `------------------------------------------------------*/
 
-typedef char *struniq_t;
+typedef const char *struniq_t;
 
 /* Return the struniq for S.  */
 const struniq_t struniq_new (const char *s);
 
+/* Two struniq have the same value iff they are the same.  */
+#define STRUNIQ_EQ(S1, S2) ((S1) == (S2))
+
 /*--------------------------------------.
 | Initializing, destroying, debugging.  |
 `--------------------------------------*/
@@ -37,6 +40,10 @@
 /* Create the string table.  */
 void struniqs_new (void);
 
+/* Die if S is not a struniq.  */
+#define struniq_assert(S) assert (struniq_assert_p (S));
+bool struniq_assert_p (const char *s);
+
 /* Free all the memory allocated for symbols.  */
 void struniqs_free (void);
 
Index: 0.4/src/struniq.c
--- 0.4/src/struniq.c Fri, 08 Nov 2002 18:07:03 +0100 akim 
(bison/e/15_struniq.c 1.1 644)
+++ 0.4(w)/src/struniq.c Sat, 09 Nov 2002 09:36:22 +0100 akim 
(bison/e/15_struniq.c 1.1 644)
@@ -20,6 +20,7 @@
 
 #include "system.h"
 #include "quotearg.h"
+#include "error.h"
 #include "hash.h"
 #include "struniq.h"
 
@@ -39,20 +40,36 @@
 const struniq_t
 struniq_new (const char *s)
 {
-  /* Keep the struniqs in a printable form.  */
-  struniq_t res = hash_lookup (struniqs_table, 
-                              quotearg_style (escape_quoting_style, s));
-
+  struniq_t res = hash_lookup (struniqs_table, s);
   if (!res)
     {
       /* First insertion in the hash. */
-      res = xstrdup (quotearg_style (escape_quoting_style, s));
+      res = xstrdup (s);
       hash_insert (struniqs_table, res);
     }
   return res;
 }
 
 
+/*---------------------------------.
+| Return TRUE iff S is a struniq.  |
+`---------------------------------*/
+
+bool
+struniq_assert_p (const char *s)
+{
+  if (!hash_lookup (struniqs_table, s))
+    {
+      error (0, 0, "not a struniq: %s", quotearg (s));
+      return false;
+    }
+  else
+    {
+      return true;
+    }
+}
+
+
 /*--------------------.
 | Print the struniq.  |
 `--------------------*/




reply via email to

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