bug-gnu-emacs
[Top][All Lists]
Advanced

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

bug#5624: 23.1; etags elisp and scheme "=" in names


From: Alex
Subject: bug#5624: 23.1; etags elisp and scheme "=" in names
Date: Sun, 11 Jun 2017 20:44:29 -0600
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux)

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Alex <agrambot@gmail.com>
>> Date: Sat, 10 Jun 2017 19:37:49 -0600
>> Cc: 5624@debbugs.gnu.org

>> This appears to be because in etags.c, all languages use the same
>> `notinname' procedure to determine a valid identifier.
>
> Yes.  But there are exceptions from this rule, where that is deemed
> necessary.  For example, Ruby_functions has this:
>
>        /* Ruby method names can end in a '='.  Also, operator overloading can
>           define operators whose names include '='.  */
>         while (!notinname (*cp) || *cp == '=')
>           cp++;
>
>> Shouldn't each language (optionally) use a different procedure to
>> determine the bounds of an identifier? Lisp and Scheme, for instance,
>> would not have '=' in their respective `notinname' procedures.
>
> Feel free to work on this, if you want to scratch that particular
> itch.  Alternatively, just augment notinname in language-specific
> support code, like some of the supported languages already do.
>
> TIA.

One issue is that the Lisp and Scheme functions use get_tag, which uses
notinname. What do you think about the following diff? It adds a wrapper
to notinname which get_tag uses. I had to add an additional parameter to
get_tag.


diff --git a/lib-src/etags.c b/lib-src/etags.c
index 6f280d8ab4..e354325ad5 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -181,6 +181,20 @@ notinname (unsigned char c)
   return table[c];
 }
 
+/* C is not in a name in language LANG. */
+static bool
+notinname_lang (unsigned char c, char const *lang)
+{
+  if (lang == NULL)
+    return notinname (c);
+
+  else if (streq ("lisp", lang) || streq ("scheme", lang))
+    if (c == '=')
+      return false;
+
+  return notinname (c);
+}
+
 /* C can start a token.  */
 static bool
 begtoken (unsigned char c)
@@ -371,7 +385,7 @@ static language *get_language_from_langname (const char *);
 static void readline (linebuffer *, FILE *);
 static long readline_internal (linebuffer *, FILE *, char const *);
 static bool nocase_tail (const char *);
-static void get_tag (char *, char **);
+static void get_tag (char *, char **, char const *);
 
 static void analyze_regex (char *);
 static void free_regexps (void);
@@ -4715,7 +4729,7 @@ Perl_functions (FILE *inf)
       if (LOOKING_AT (cp, "package"))
        {
          free (package);
-         get_tag (cp, &package);
+         get_tag (cp, &package, NULL);
        }
       else if (LOOKING_AT (cp, "sub"))
        {
@@ -5346,7 +5360,7 @@ L_getit (void)
       /* Ok, then skip "(" before name in (defstruct (foo)) */
       dbp = skip_spaces (dbp);
   }
-  get_tag (dbp, NULL);
+  get_tag (dbp, NULL, "lisp");
 }
 
 static void
@@ -5426,7 +5440,7 @@ Lua_functions (FILE *inf)
        {
          char *tag_name, *tp_dot, *tp_colon;
 
-         get_tag (bp, &tag_name);
+         get_tag (bp, &tag_name, NULL);
          /* If the tag ends with ".foo" or ":foo", make an additional tag for
             "foo".  */
          tp_dot = strrchr (tag_name, '.');
@@ -5436,7 +5450,7 @@ Lua_functions (FILE *inf)
              char *p = tp_dot > tp_colon ? tp_dot : tp_colon;
              int len_add = p - tag_name + 1;
 
-             get_tag (bp + len_add, NULL);
+             get_tag (bp + len_add, NULL, NULL);
            }
        }
     }
@@ -5468,7 +5482,7 @@ PS_functions (FILE *inf)
                    lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
        }
       else if (LOOKING_AT (bp, "defineps"))
-       get_tag (bp, NULL);
+       get_tag (bp, NULL, NULL);
     }
 }
 
@@ -5550,12 +5564,12 @@ Scheme_functions (FILE *inf)
          bp = skip_non_spaces (bp+4);
          /* Skip over open parens and white space.  Don't continue past
             '\0'. */
-         while (*bp && notinname (*bp))
+         while (*bp && notinname_lang (*bp, "scheme"))
            bp++;
-         get_tag (bp, NULL);
+         get_tag (bp, NULL, "scheme");
        }
       if (LOOKING_AT (bp, "(SET!") || LOOKING_AT (bp, "(set!"))
-       get_tag (bp, NULL);
+       get_tag (bp, NULL, "scheme");
     }
 }
 
@@ -6573,14 +6587,14 @@ nocase_tail (const char *cp)
 }
 
 static void
-get_tag (register char *bp, char **namepp)
+get_tag (register char *bp, char **namepp, char const *lang)
 {
   register char *cp = bp;
 
   if (*bp != '\0')
     {
       /* Go till you get to white space or a syntactic break */
-      for (cp = bp + 1; !notinname (*cp); cp++)
+      for (cp = bp + 1; !notinname_lang (*cp, lang); cp++)
        continue;
       make_tag (bp, cp - bp, true,
                lb.buffer, cp - lb.buffer + 1, lineno, linecharno);

reply via email to

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