unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Tak Ota <Takaaki.Ota@am.sony.com>
Cc: eliz@is.elta.co.il, lektu@terra.es, emacs-devel@gnu.org, andrewi@gnu.org
Subject: Re: lost argument and doc string
Date: Wed, 13 Feb 2002 23:36:51 -0800 (PST)	[thread overview]
Message-ID: <20020213.233651.60851324.Takaaki.Ota@am.sony.com> (raw)
In-Reply-To: <m3heolccy5.fsf@nyaumo.btinternet.com>

13 Feb 2002 21:02:42 +0000: Jason Rumney <jasonr@gnu.org> wrote:

> > > Be careful that the following does the right thing:
> > > 
> > >     (defvar string-variable "String value" "\
> > >     This is the documentation for a string variable.")
> > > 
> > > 
> > > That seems like the only logical reason for the current convention.
> > 
> > But my point is that they are all eventually processed by
> > `read_c_string_or_comment' later, which takes care of backslash
> 
> The backslash wasn't what I was concerned about. We need to make sure
> that "String value" is not picked up as a documentation string in the
> above case.  That is the only reason I can think of where the current
> convention might be useful.

Thanks for the advice.  How about the change below?  It does more
elaborate lisp object parsing.  Also it consolidates some redundant
code repetitions.

-Tak


Index: make-docfile.c
===================================================================
RCS file: /cvsroot/emacs/emacs/lib-src/make-docfile.c,v
retrieving revision 1.50
diff -u -r1.50 make-docfile.c
--- make-docfile.c	5 Jan 2002 23:37:58 -0000	1.50
+++ make-docfile.c	14 Feb 2002 07:33:43 -0000
@@ -323,7 +323,7 @@
    at the beginning of a line will be removed, and *SAW_USAGE set to
    true if any were encountered.  */
 
-int
+static int
 read_c_string_or_comment (infile, printflag, comment, saw_usage)
      FILE *infile;
      int printflag;
@@ -414,7 +414,7 @@
 /* Write to file OUT the argument names of function FUNC, whose text is in BUF.
    MINARGS and MAXARGS are the minimum and maximum number of arguments.  */
 
-void
+static void
 write_c_args (out, func, buf, minargs, maxargs)
      FILE *out;
      char *func, *buf;
@@ -501,7 +501,7 @@
    Looks for DEFUN constructs such as are defined in ../src/lisp.h.
    Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED.  */
 
-int
+static int
 scan_c_file (filename, mode)
      char *filename, *mode;
 {
@@ -765,7 +765,7 @@
  An entry is output only if DOCSTRING has \ newline just after the opening "
  */
 
-void
+static void
 skip_white (infile)
      FILE *infile;
 {
@@ -775,10 +775,10 @@
   ungetc (c, infile);
 }
 
-void
-read_lisp_symbol (infile, buffer)
+static void
+read_lisp_symbol (infile, buffer, filename)
      FILE *infile;
-     char *buffer;
+     char *buffer, *filename;
 {
   char c;
   char *fillp = buffer;
@@ -789,7 +789,7 @@
       c = getc (infile);
       if (c == '\\')
 	*(++fillp) = getc (infile);
-      else if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '(' || c == ')')
+      else if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '(' || c == ')' || c == '[' || c == ']')
 	{
 	  ungetc (c, infile);
 	  *fillp = 0;
@@ -800,11 +800,138 @@
     }
 
   if (! buffer[0])
-    fprintf (stderr, "## expected a symbol, got '%c'\n", c);
+    fprintf (stderr, "## expected a symbol, got '%c' in %s\n", c, filename);
 
   skip_white (infile);
 }
 
+static int
+read_quoted_lisp_symbol (infile, buffer, filename, form)
+     FILE *infile;
+     char *buffer, *filename, *form;
+{
+  register int c;
+
+  c = getc (infile);
+  if (c == '\'')
+    read_lisp_symbol (infile, buffer, filename);
+  else
+    {
+      if (c != '(')
+        {
+          fprintf (stderr,
+                   "## unparsable name in %s in %s\n",
+                   form, filename);
+          return 1;
+        }
+      read_lisp_symbol (infile, buffer, filename);
+      if (strcmp (buffer, "quote"))
+        {
+          fprintf (stderr,
+                   "## unparsable name in %s in %s\n",
+                   form, filename);
+          return 1;
+        }
+      read_lisp_symbol (infile, buffer, filename);
+      c = getc (infile);
+      if (c != ')')
+        {
+          fprintf (stderr,
+                   "## unparsable quoted name in %s in %s\n",
+                   form, filename);
+          return 1;
+        }
+    }
+  return 0;
+}
+
+static int
+read_lisp_char (infile)
+     FILE *infile;
+{
+  int c;
+
+ continuation:
+  if ((c = getc (infile)) != '\\')
+    return c;
+
+  switch (c = getc (infile))
+    {
+    case '\n': case '\r':
+      goto continuation;
+    case 'a': return 7;
+    case 'b': return 8;
+    case 't': return 9;
+    case 'n': return 10;
+    case 'v': return 11;
+    case 'f': return 12;
+    case 'r': return 13;
+    case 'e': return 27;
+    case '\\': return 92;
+    case 'd': return 127;
+    case 'C':
+      if ((c = getc (infile)) != '-')
+        return c; /* ignore the syntax error */
+      /* follow through */
+    case '^':
+      c = getc (infile);
+      return ((c < 'a' ? c : c - 32) - '@') & 127;
+    }
+  return c;
+}
+
+static int
+skip_lisp_object (infile, filename)
+     FILE *infile;
+     char *filename;
+{
+  int c;
+
+  skip_white (infile);
+  c = getc (infile);
+  switch (c)
+    {
+    case EOF:
+      return 0;
+    case '?':
+      read_lisp_char (infile);
+      return 1;
+    case '\'':
+      return skip_lisp_object (infile, filename);
+    case '\"':
+      do
+        {
+          c = read_lisp_char (infile);
+        }
+      while (c != '\"' && c != EOF);
+      return 1;
+    case '(': case '[':
+      {
+        int term = c == '(' ? ')' : ']';
+        while (1)
+          {
+            skip_white (infile);
+            c = getc (infile);
+            if (c == term)
+              return 1;
+            if (c == EOF)
+              return 0;
+            ungetc (c, infile);
+            skip_lisp_object (infile, filename);
+          }
+      }
+    case ')': case ']':
+      return 0;
+    default:
+      ungetc (c, infile);
+      {
+        char buffer[BUFSIZ];
+        read_lisp_symbol (infile, buffer, filename);
+      }
+      return 1;
+    }
+}
+
 int
 scan_lisp_file (filename, mode)
      char *filename, *mode;
@@ -880,46 +1007,21 @@
       if (c != '(')
 	continue;
 
-      read_lisp_symbol (infile, buffer);
+      read_lisp_symbol (infile, buffer, filename);
 
       if (! strcmp (buffer, "defun")
 	  || ! strcmp (buffer, "defmacro")
 	  || ! strcmp (buffer, "defsubst"))
 	{
 	  type = 'F';
-	  read_lisp_symbol (infile, buffer);
+	  read_lisp_symbol (infile, buffer, filename);
 
-	  /* Skip the arguments: either "nil" or a list in parens */
+	  /* Skip the arguments */
+          skip_lisp_object (infile, filename);
 
-	  c = getc (infile);
-	  if (c == 'n') /* nil */
-	    {
-	      if ((c = getc (infile)) != 'i'
-		  || (c = getc (infile)) != 'l')
-		{
-		  fprintf (stderr, "## unparsable arglist in %s (%s)\n",
-			   buffer, filename);
-		  continue;
-		}
-	    }
-	  else if (c != '(')
-	    {
-	      fprintf (stderr, "## unparsable arglist in %s (%s)\n",
-		       buffer, filename);
-	      continue;
-	    }
-	  else
-	    while (c != ')')
-	      c = getc (infile);
 	  skip_white (infile);
-
-	  /* If the next three characters aren't `dquote bslash newline'
-	     then we're not reading a docstring.
-	   */
-	  if ((c = getc (infile)) != '"'
-	      || (c = getc (infile)) != '\\'
-	      || ((c = getc (infile)) != '\n' && c != '\r'))
-	    {
+	  if ((c = getc (infile)) != '\"')
+            {
 #ifdef DEBUG
 	      fprintf (stderr, "## non-docstring in %s (%s)\n",
 		       buffer, filename);
@@ -931,24 +1033,16 @@
       else if (! strcmp (buffer, "defvar")
 	       || ! strcmp (buffer, "defconst"))
 	{
-	  char c1 = 0, c2 = 0;
 	  type = 'V';
-	  read_lisp_symbol (infile, buffer);
+	  read_lisp_symbol (infile, buffer, filename);
 
 	  if (saved_string == 0)
 	    {
+              /* Skip the value */
+              skip_lisp_object (infile, filename);
 
-	      /* Skip until the end of line; remember two previous chars.  */
-	      while (c != '\n' && c != '\r' && c >= 0)
-		{
-		  c2 = c1;
-		  c1 = c;
-		  c = getc (infile);
-		}
-
-	      /* If two previous characters were " and \,
-		 this is a doc string.  Otherwise, there is none.  */
-	      if (c2 != '"' || c1 != '\\')
+              skip_white (infile);
+              if ((c = getc (infile)) != '\"')
 		{
 #ifdef DEBUG
 		  fprintf (stderr, "## non-docstring in %s (%s)\n",
@@ -961,53 +1055,15 @@
 
       else if (! strcmp (buffer, "custom-declare-variable"))
 	{
-	  char c1 = 0, c2 = 0;
 	  type = 'V';
 
-	  c = getc (infile);
-	  if (c == '\'')
-	    read_lisp_symbol (infile, buffer);
-	  else
-	    {
-	      if (c != '(')
-		{
-		  fprintf (stderr,
-			   "## unparsable name in custom-declare-variable in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      if (strcmp (buffer, "quote"))
-		{
-		  fprintf (stderr,
-			   "## unparsable name in custom-declare-variable in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      c = getc (infile);
-	      if (c != ')')
-		{
-		  fprintf (stderr,
-			   "## unparsable quoted name in custom-declare-variable in %s\n",
-			   filename);
-		  continue;
-		}
-	    }
+          if (read_quoted_lisp_symbol (infile, buffer, filename, "custom-declare-variable"))
+            continue;
 
 	  if (saved_string == 0)
 	    {
-	      /* Skip to end of line; remember the two previous chars.  */
-	      while (c != '\n' && c != '\r' && c >= 0)
-		{
-		  c2 = c1;
-		  c1 = c;
-		  c = getc (infile);
-		}
-
-	      /* If two previous characters were " and \,
-		 this is a doc string.  Otherwise, there is none.  */
-	      if (c2 != '"' || c1 != '\\')
+              skip_white (infile);
+              if ((c = getc (infile)) != '\"')
 		{
 #ifdef DEBUG
 		  fprintf (stderr, "## non-docstring in %s (%s)\n",
@@ -1020,51 +1076,15 @@
 
       else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
 	{
-	  char c1 = 0, c2 = 0;
 	  type = 'F';
 
-	  c = getc (infile);
-	  if (c == '\'')
-	    read_lisp_symbol (infile, buffer);
-	  else
-	    {
-	      if (c != '(')
-		{
-		  fprintf (stderr, "## unparsable name in fset in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      if (strcmp (buffer, "quote"))
-		{
-		  fprintf (stderr, "## unparsable name in fset in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      c = getc (infile);
-	      if (c != ')')
-		{
-		  fprintf (stderr,
-			   "## unparsable quoted name in fset in %s\n",
-			   filename);
-		  continue;
-		}
-	    }
+          if (read_quoted_lisp_symbol (infile, buffer, filename, "fset"))
+            continue;
 
 	  if (saved_string == 0)
 	    {
-	      /* Skip to end of line; remember the two previous chars.  */
-	      while (c != '\n' && c != '\r' && c >= 0)
-		{
-		  c2 = c1;
-		  c1 = c;
-		  c = getc (infile);
-		}
-
-	      /* If two previous characters were " and \,
-		 this is a doc string.  Otherwise, there is none.  */
-	      if (c2 != '"' || c1 != '\\')
+              skip_white (infile);
+              if ((c = getc (infile)) != '\"')
 		{
 #ifdef DEBUG
 		  fprintf (stderr, "## non-docstring in %s (%s)\n",
@@ -1078,34 +1098,10 @@
       else if (! strcmp (buffer, "autoload"))
 	{
 	  type = 'F';
-	  c = getc (infile);
-	  if (c == '\'')
-	    read_lisp_symbol (infile, buffer);
-	  else
-	    {
-	      if (c != '(')
-		{
-		  fprintf (stderr, "## unparsable name in autoload in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      if (strcmp (buffer, "quote"))
-		{
-		  fprintf (stderr, "## unparsable name in autoload in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      c = getc (infile);
-	      if (c != ')')
-		{
-		  fprintf (stderr,
-			   "## unparsable quoted name in autoload in %s\n",
-			   filename);
-		  continue;
-		}
-	    }
+
+          if (read_quoted_lisp_symbol (infile, buffer, filename, "autoload"))
+            continue;
+
 	  skip_white (infile);
 	  if ((c = getc (infile)) != '\"')
 	    {
@@ -1117,13 +1113,10 @@
 	  skip_white (infile);
 
 	  if (saved_string == 0)
-	    {
-	      /* If the next three characters aren't `dquote bslash newline'
-		 then we're not reading a docstring.  */
-	      if ((c = getc (infile)) != '"'
-		  || (c = getc (infile)) != '\\'
-		  || ((c = getc (infile)) != '\n' && c != '\r'))
-		{
+            {
+              skip_white (infile);
+              if ((c = getc (infile)) != '\"')
+                {
 #ifdef DEBUG
 		  fprintf (stderr, "## non-docstring in %s (%s)\n",
 			   buffer, filename);
@@ -1152,8 +1145,8 @@
 	 dynamic doc string in saved_string
 	 or gobble a doc string from the input file.
 
-	 In the latter case, the opening quote (and leading
-	 backslash-newline) have already been read.  */
+	 In the latter case, the opening quote has already been
+	 read.  */
 
       putc (037, outfile);
       putc (type, outfile);

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel


  reply	other threads:[~2002-02-14  7:36 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-02-10  6:59 lost argument and doc string Tak Ota
2002-02-10 17:08 ` Eli Zaretskii
2002-02-10 17:32   ` Pavel Janík
2002-02-10 23:28     ` Tak Ota
2002-02-11  5:48       ` Pavel Janík
2002-02-11  5:48       ` Eli Zaretskii
2002-02-11 16:34         ` Juanma Barranquero
2002-02-11 19:37           ` Eli Zaretskii
2002-02-12  2:32             ` Tak Ota
2002-02-12  8:35               ` Eli Zaretskii
2002-02-12 14:23                 ` Tak Ota
2002-02-12 18:57                   ` Jason Rumney
2002-02-12 19:48                     ` Tak Ota
2002-02-13  5:43                       ` Eli Zaretskii
2002-02-13  6:01                         ` Tak Ota
2002-02-13 13:40                         ` Andreas Schwab
2002-02-13 14:23                           ` Eli Zaretskii
2002-02-13 19:50                       ` Jason Rumney
2002-02-13 20:22                         ` Tak Ota
2002-02-13 21:02                           ` Jason Rumney
2002-02-14  7:36                             ` Tak Ota [this message]
2002-02-15 10:36                               ` Richard Stallman
2002-02-15 20:36                                 ` Tak Ota
2002-02-13 21:00                         ` Tak Ota
2002-02-14  3:11                     ` Richard Stallman
2002-02-14 15:13                       ` Tak Ota
2002-02-13 15:37                 ` Richard Stallman
2002-02-11 18:48       ` Richard Stallman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20020213.233651.60851324.Takaaki.Ota@am.sony.com \
    --to=takaaki.ota@am.sony.com \
    --cc=andrewi@gnu.org \
    --cc=eliz@is.elta.co.il \
    --cc=emacs-devel@gnu.org \
    --cc=lektu@terra.es \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).