changeset 5277:d804e621add0

Simplify the API of PARSE_KEYWORDS for callers. src/ChangeLog addition: 2010-09-18 Aidan Kehoe <kehoea@parhasard.net> Simplify the API of PARSE_KEYWORDS for callers. * lisp.h (PARSE_KEYWORDS): Simply the API, while making the implementation a little more complex; work out KEYWORDS_OFFSET from the appropriate Lisp_Subr struct, take the function name as the C name of the DEFUN rather than a symbol visible as a Lisp_Object, on debug builds assert that we're actually in the function so we choke on badly-done copy-and-pasting, * lisp.h (PARSE_KEYWORDS_8): New. This is the old PARSE_KEYWORDS. * fns.c (Fmerge, FsortX, Ffill, Freduce, Freplace): Change to use the new PARSE_KEYWORDS syntax. * elhash.c (Fmake_hash_table): Chance to the new PARSE_KEYWORDS syntax, rename a define to correspond to what other files use. * symbols.c (intern_massaging_name): * buffer.c (ADD_INT): Rename intern_converting_underscores_to_dashes() to intern_massaging_name(), now it does a little more.
author Aidan Kehoe <kehoea@parhasard.net>
date Sat, 18 Sep 2010 15:57:20 +0100
parents dd2976af8783
children d9e65b48e2bf
files src/ChangeLog src/buffer.c src/elhash.c src/fns.c src/lisp.h src/symbols.c
diffstat 6 files changed, 114 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Sat Sep 18 15:03:54 2010 +0100
+++ b/src/ChangeLog	Sat Sep 18 15:57:20 2010 +0100
@@ -1,3 +1,26 @@
+2010-09-18  Aidan Kehoe  <kehoea@parhasard.net>
+
+	Simplify the API of PARSE_KEYWORDS for callers.
+
+	* lisp.h (PARSE_KEYWORDS): Simply the API, while making the
+	implementation a little more complex; work out KEYWORDS_OFFSET
+	from the appropriate Lisp_Subr struct, take the function name as
+	the C name of the DEFUN rather than a symbol visible as a
+	Lisp_Object, on debug builds assert that we're actually in the
+	function so we choke on badly-done copy-and-pasting,
+
+	* lisp.h (PARSE_KEYWORDS_8): New. This is the old PARSE_KEYWORDS.
+
+	* fns.c (Fmerge, FsortX, Ffill, Freduce, Freplace):
+	Change to use the new PARSE_KEYWORDS syntax.
+	* elhash.c (Fmake_hash_table): Chance to the new PARSE_KEYWORDS
+	syntax, rename a define to correspond to what other files use.
+	
+	* symbols.c (intern_massaging_name):
+	* buffer.c (ADD_INT):
+	Rename intern_converting_underscores_to_dashes() to
+	intern_massaging_name(), now it does a little more.
+
 2010-09-18  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* termcap.c:
--- a/src/buffer.c	Sat Sep 18 15:03:54 2010 +0100
+++ b/src/buffer.c	Sat Sep 18 15:57:20 2010 +0100
@@ -1819,10 +1819,10 @@
 
 #define ADD_INT(field) \
   plist = cons3 (make_int (b->text->field), \
-		 intern_converting_underscores_to_dashes (#field), plist)
+		 intern_massaging_name (#field), plist)
 #define ADD_BOOL(field) \
   plist = cons3 (b->text->field ? Qt : Qnil, \
-		 intern_converting_underscores_to_dashes (#field), plist)
+		 intern_massaging_name (#field), plist)
   ADD_INT (bufz);
   ADD_INT (z);
 #ifdef OLD_BYTE_CHAR
--- a/src/elhash.c	Sat Sep 18 15:03:54 2010 +0100
+++ b/src/elhash.c	Sat Sep 18 15:57:20 2010 +0100
@@ -962,7 +962,7 @@
           else if (EQ (key, Qrehash_threshold)) rehash_threshold = value;
           else if (EQ (key, Qweakness))	    weakness	     = value;
           else if (EQ (key, Qdata))		    data	     = value;
-#ifndef NO_NEED_TO_HANDLE_21_4_CODE
+#ifdef NEED_TO_HANDLE_21_4_CODE
           else if (EQ (key, Qtype))/*obsolete*/ weakness	     = value;
 #endif
           else if (KEYWORDP (key))
@@ -1109,14 +1109,14 @@
 */
        (int nargs, Lisp_Object *args))
 {
-#ifdef NO_NEED_TO_HANDLE_21_4_CODE
-  PARSE_KEYWORDS (Qmake_hash_table, nargs, args, 0, 5,
+#ifndef NEED_TO_HANDLE_21_4_CODE
+  PARSE_KEYWORDS (Fmake_hash_table, nargs, args, 5,
                   (test, size, rehash_size, rehash_threshold, weakness),
-                  NULL, 0);
+                  NULL);
 #else
-  PARSE_KEYWORDS (Qmake_hash_table, nargs, args, 0, 6,
+  PARSE_KEYWORDS (Fmake_hash_table, nargs, args, 6,
                   (test, size, rehash_size, rehash_threshold, weakness,
-		   type), (type = Qunbound, weakness = Qunbound), 0);
+		   type), (type = Qunbound, weakness = Qunbound));
 
   if (EQ (weakness, Qunbound))
     {
--- a/src/fns.c	Sat Sep 18 15:03:54 2010 +0100
+++ b/src/fns.c	Sat Sep 18 15:57:20 2010 +0100
@@ -2575,7 +2575,7 @@
   Lisp_Object (*c_predicate) (Lisp_Object, Lisp_Object, Lisp_Object,
 			      Lisp_Object);
 
-  PARSE_KEYWORDS (Qmerge, nargs, args, 4, 1, (key), NULL, 0);
+  PARSE_KEYWORDS (Fmerge, nargs, args, 1, (key), NULL);
 
   CHECK_SEQUENCE (sequence_one);
   CHECK_SEQUENCE (sequence_two);
@@ -2827,7 +2827,7 @@
                               Lisp_Object);
   Elemcount sequence_len, i;
 
-  PARSE_KEYWORDS (QsortX, nargs, args, 2, 1, (key), NULL, 0);
+  PARSE_KEYWORDS (FsortX, nargs, args, 1, (key), NULL);
 
   CHECK_SEQUENCE (sequence);
 
@@ -4002,7 +4002,7 @@
   Lisp_Object item = args[1];
   Elemcount starting = 0, ending = EMACS_INT_MAX, ii, len;
 
-  PARSE_KEYWORDS (Qfill, nargs, args, 2, 2, (start, end), (start = Qzero), 0);
+  PARSE_KEYWORDS (Ffill, nargs, args, 2, (start, end), (start = Qzero));
 
   CHECK_NATNUM (start);
   starting = XINT (start);
@@ -5005,9 +5005,9 @@
   Lisp_Object function = args[0], sequence = args[1], accum = Qunbound;
   Elemcount starting, ending = EMACS_INT_MAX, ii = 0;
 
-  PARSE_KEYWORDS (Qreduce, nargs, args, 2, 5,
+  PARSE_KEYWORDS (Freduce, nargs, args, 5,
                   (start, end, from_end, initial_value, key),
-                  (start = Qzero, initial_value = Qunbound), 0);
+                  (start = Qzero, initial_value = Qunbound));
 
   CHECK_SEQUENCE (sequence);
   CHECK_NATNUM (start);
@@ -5541,8 +5541,8 @@
   Boolint sequence1_listp, sequence2_listp,
     overwriting = EQ (sequence1, sequence2);
 
-  PARSE_KEYWORDS (Qreplace, nargs, args, 2, 4, (start1, end1, start2, end2),
-                  (start1 = start2 = Qzero), 0);
+  PARSE_KEYWORDS (Freplace, nargs, args, 4, (start1, end1, start2, end2),
+                  (start1 = start2 = Qzero));
 
   CHECK_SEQUENCE (sequence1);
   CHECK_LISP_WRITEABLE (sequence1);
--- a/src/lisp.h	Sat Sep 18 15:03:54 2010 +0100
+++ b/src/lisp.h	Sat Sep 18 15:57:20 2010 +0100
@@ -3494,17 +3494,21 @@
 /************************************************************************/
 
 /* The C subr must have been declared with MANY as its max args, and this
-   PARSE_KEYWORDS call must come before any statements.
-
-   FUNCTION is the name of the current function, as a symbol.
+   PARSE_KEYWORDS call must come before any statements. Equivalently, it
+   can appear within braces.
+
+   FUNCTION is the C name of the current DEFUN.  If there is no current
+   DEFUN, use the PARSE_KEYWORDS_8 macro, not PARSE_KEYWORDS.  If the
+   current DEFUN has optional arguments that are not keywords, you also need
+   to use the PARSE_KEYWORDS_8 macro.  This is also the case if there are
+   optional arguments that come before the keywords, as Common Lisp
+   specifies for #'parse-integer.
 
    NARGS is the count of arguments supplied to FUNCTION.
 
    ARGS is a pointer to the argument vector (not a Lisp vector) supplied to
    FUNCTION.
 
-   KEYWORDS_OFFSET is the offset into ARGS where the keyword arguments start.
-
    KEYWORD_COUNT is the number of keywords FUNCTION is normally prepared to
    handle.
 
@@ -3516,11 +3520,6 @@
    by parentheses and separated by the comma operator. If you don't need
    this, supply NULL as KEYWORD_DEFAULTS.
 
-   ALLOW_OTHER_KEYS corresponds to the &allow-other-keys argument list
-   entry in defun*; it is 1 if other keys are normally allowed, 0
-   otherwise. This may be overridden in the caller by specifying
-   :allow-other-keys t in the argument list.
-
    For keywords which appear multiple times in the called argument list, the
    leftmost one overrides, as specified in section 7.1.1 of the CLHS.
 
@@ -3534,26 +3533,70 @@
    and an unrelated name for the local variable, as is possible with the
    ((:keyword unrelated-var)) syntax in defun* and in Common Lisp. That
    shouldn't matter in practice. */
- 
-#define PARSE_KEYWORDS(function, nargs, args, keywords_offset,          \
-                       keyword_count, keywords, keyword_defaults,       \
-                       allow_other_keys)                                \
+#if defined (DEBUG_XEMACS) && defined (__STDC_VERSION__) &&	\
+  __STDC_VERSION__ >= 199901L
+
+/* This version has the advantage that DEFUN without DEFSUBR still provokes
+   a defined but not used warning, and it provokes an assertion failure at
+   runtime if someone has copied and pasted the PARSE_KEYWORDS macro from
+   another function without changing FUNCTION; that would lead to an
+   incorrect determination of KEYWORDS_OFFSET. */
+
+#define PARSE_KEYWORDS(function, nargs, args, keyword_count, keywords,	\
+		       keyword_defaults)				\
+	PARSE_KEYWORDS_8 (intern_massaging_name (1 + #function),	\
+			  nargs, args,					\
+			  keyword_count, keywords,			\
+			  keyword_defaults,				\
+			  /* Can't XSUBR (Fsymbol_function (...))->min_args, \
+			     the function may be advised. */		\
+			  XINT (Ffunction_min_args			\
+				(intern_massaging_name (1 + #function))), \
+			  0);						\
+	assert (0 == strcmp (__func__, #function))
+#else
+#define PARSE_KEYWORDS(function, nargs, args, keyword_count, keywords,	\
+		       keyword_defaults)				\
+	PARSE_KEYWORDS_8 (intern (S##function.name), nargs, args,	\
+			  keyword_count, keywords,			\
+			  keyword_defaults, S##function.min_args, 0)
+#endif
+
+/* PARSE_KEYWORDS_8 is a more fine-grained version of PARSE_KEYWORDS. The
+   differences are as follows:
+
+   FUNC_SYM is a symbol reflecting the name of the function for which
+   keywords are being parsed.  In PARSE_KEYWORDS, it is the Lisp-visible
+   name of C_FUNC, interned as a symbol in obarray.
+
+   KEYWORDS_OFFSET is the offset into ARGS where the keyword arguments
+   start.  In PARSE_KEYWORDS, this is the index of the first optional
+   argument, determined from the information known about C_FUNC.
+
+   ALLOW_OTHER_KEYS corresponds to the &allow-other-keys argument list entry
+   in defun*; it is 1 if other keys are normally allowed, 0 otherwise. This
+   may be overridden in the caller by specifying :allow-other-keys t in the
+   argument list. In PARSE_KEYWORDS, ALLOW_OTHER_KEYS is always 0. */
+
+#define PARSE_KEYWORDS_8(func_sym, nargs, args,				\
+			 keyword_count, keywords, keyword_defaults,	\
+			 keywords_offset, allow_other_keys)		\
   DECLARE_N_KEYWORDS_##keyword_count keywords;                          \
                                                                         \
   do                                                                    \
     {                                                                   \
       Lisp_Object pk_key, pk_value;                                     \
-      Elemcount pk_i = nargs - 1;                                       \
+      Elemcount pk_i = nargs - 1, pk_offset = keywords_offset;		\
       Boolint pk_allow_other_keys = allow_other_keys;                   \
                                                                         \
-      if ((nargs - keywords_offset) & 1)                                \
+      if ((nargs - pk_offset) & 1)					\
         {                                                               \
           if (!allow_other_keys                                         \
               && !(pk_allow_other_keys                                  \
-                   = non_nil_allow_other_keys_p (keywords_offset,       \
+                   = non_nil_allow_other_keys_p (pk_offset,		\
                                                  nargs, args)))         \
             {                                                           \
-              signal_wrong_number_of_arguments_error (function, nargs); \
+              signal_wrong_number_of_arguments_error (func_sym, nargs); \
             }                                                           \
           else                                                          \
             {                                                           \
@@ -3566,7 +3609,7 @@
       (void)(keyword_defaults);                                         \
                                                                         \
       /* Start from the end, because the leftmost element overrides. */ \
-      while (pk_i > keywords_offset)                                    \
+      while (pk_i > pk_offset)						\
         {                                                               \
           pk_value = args[pk_i--];                                      \
           pk_key = args[pk_i--];                                        \
@@ -3578,7 +3621,7 @@
               continue;                                                 \
             }                                                           \
           else if ((pk_allow_other_keys                                 \
-                    = non_nil_allow_other_keys_p (keywords_offset,      \
+                    = non_nil_allow_other_keys_p (pk_offset,		\
                                                   nargs, args)))        \
             {                                                           \
               continue;                                                 \
@@ -3590,7 +3633,7 @@
             }                                                           \
           else                                                          \
             {                                                           \
-              invalid_keyword_argument (function, pk_key);              \
+              invalid_keyword_argument (func_sym, pk_key);              \
             }                                                           \
         }                                                               \
     } while (0)
@@ -5649,7 +5692,7 @@
 unsigned int hash_string (const Ibyte *, Bytecount);
 Lisp_Object intern_istring (const Ibyte *str);
 MODULE_API Lisp_Object intern (const CIbyte *str);
-Lisp_Object intern_converting_underscores_to_dashes (const CIbyte *str);
+Lisp_Object intern_massaging_name (const CIbyte *str);
 Lisp_Object oblookup (Lisp_Object, const Ibyte *, Bytecount);
 void map_obarray (Lisp_Object, int (*) (Lisp_Object, void *), void *);
 Lisp_Object indirect_function (Lisp_Object, int);
--- a/src/symbols.c	Sat Sep 18 15:03:54 2010 +0100
+++ b/src/symbols.c	Sat Sep 18 15:57:20 2010 +0100
@@ -198,15 +198,23 @@
 }
 
 Lisp_Object
-intern_converting_underscores_to_dashes (const CIbyte *str)
+intern_massaging_name (const CIbyte *str)
 {
   Bytecount len = strlen (str);
   CIbyte *tmp = alloca_extbytes (len + 1);
   Bytecount i;
   strcpy (tmp, str);
   for (i = 0; i < len; i++)
-    if (tmp[i] == '_')
-      tmp[i] = '-';
+    {
+      if (tmp[i] == '_')
+	{
+	  tmp[i] = '-';
+	}
+      else if (tmp[i] == 'X')
+	{
+	  tmp[i] = '*';
+	}
+    }
   return intern_istring ((Ibyte *) tmp);
 }