X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/0cdbf84521791935fdfeabf2e84f585cc64db325..7d652d97681c4f1b67018f44f64c619ef5edd990:/src/doc.c
diff --git a/src/doc.c b/src/doc.c
index 1d3d1e6444..d3f8fde08f 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -1,6 +1,7 @@
/* Record indices of function doc strings stored in a file.
-Copyright (C) 1985-1986, 1993-1995, 1997-2012 Free Software Foundation, Inc.
+Copyright (C) 1985-1986, 1993-1995, 1997-2013 Free Software Foundation,
+Inc.
This file is part of GNU Emacs.
@@ -20,6 +21,7 @@ along with GNU Emacs. If not, see . */
#include
+#include
#include
#include /* Must be after sys/types.h for USG. */
#include
@@ -32,7 +34,6 @@ along with GNU Emacs. If not, see . */
#include "buffer.h"
#include "keyboard.h"
#include "keymap.h"
-#include "buildobj.h"
Lisp_Object Qfunction_documentation;
@@ -57,7 +58,7 @@ read_bytecode_char (bool unreadflag)
}
/* Extract a doc string from a file. FILEPOS says where to get it.
- If it is an integer, use that position in the standard DOC-... file.
+ If it is an integer, use that position in the standard DOC file.
If it is (FILE . INTEGER), use FILE as the file name
and INTEGER as the position in that file.
But if INTEGER is negative, make it positive.
@@ -83,24 +84,24 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
ptrdiff_t minsize;
int offset;
EMACS_INT position;
- Lisp_Object file, tem;
+ Lisp_Object file, tem, pos;
+ ptrdiff_t count;
USE_SAFE_ALLOCA;
if (INTEGERP (filepos))
{
file = Vdoc_file_name;
- position = XINT (filepos);
+ pos = filepos;
}
else if (CONSP (filepos))
{
file = XCAR (filepos);
- position = XINT (XCDR (filepos));
+ pos = XCDR (filepos);
}
else
return Qnil;
- if (position < 0)
- position = - position;
+ position = eabs (XINT (pos));
if (!STRINGP (Vdoc_directory))
return Qnil;
@@ -144,9 +145,14 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
}
#endif
if (fd < 0)
- return concat3 (build_string ("Cannot open doc string file \""),
- file, build_string ("\"\n"));
+ {
+ SAFE_FREE ();
+ return concat3 (build_string ("Cannot open doc string file \""),
+ file, build_string ("\"\n"));
+ }
}
+ count = SPECPDL_INDEX ();
+ record_unwind_protect_int (close_file_unwind, fd);
/* Seek only to beginning of disk block. */
/* Make sure we read at least 1024 bytes before `position'
@@ -154,13 +160,8 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
offset = min (position, max (1024, position % (8 * 1024)));
if (TYPE_MAXIMUM (off_t) < position
|| lseek (fd, position - offset, 0) < 0)
- {
- emacs_close (fd);
- error ("Position %"pI"d out of range in doc string file \"%s\"",
- position, name);
- }
-
- SAFE_FREE ();
+ error ("Position %"pI"d out of range in doc string file \"%s\"",
+ position, name);
/* Read the doc string into get_doc_string_buffer.
P points beyond the data just read. */
@@ -176,9 +177,9 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
if (space_left <= 0)
{
ptrdiff_t in_buffer = p - get_doc_string_buffer;
- get_doc_string_buffer =
- xpalloc (get_doc_string_buffer, &get_doc_string_buffer_size,
- 16 * 1024, -1, 1);
+ get_doc_string_buffer
+ = xpalloc (get_doc_string_buffer, &get_doc_string_buffer_size,
+ 16 * 1024, -1, 1);
p = get_doc_string_buffer + in_buffer;
space_left = (get_doc_string_buffer_size - 1
- (p - get_doc_string_buffer));
@@ -190,10 +191,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
space_left = 1024 * 8;
nread = emacs_read (fd, p, space_left);
if (nread < 0)
- {
- emacs_close (fd);
- error ("Read error on documentation file");
- }
+ report_file_error ("Read error on documentation file", file);
p[nread] = 0;
if (!nread)
break;
@@ -209,20 +207,27 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
}
p += nread;
}
- emacs_close (fd);
+ unbind_to (count, Qnil);
+ SAFE_FREE ();
/* Sanity checking. */
if (CONSP (filepos))
{
int test = 1;
- if (get_doc_string_buffer[offset - test++] != ' ')
- return Qnil;
- while (get_doc_string_buffer[offset - test] >= '0'
- && get_doc_string_buffer[offset - test] <= '9')
- test++;
- if (get_doc_string_buffer[offset - test++] != '@'
- || get_doc_string_buffer[offset - test] != '#')
- return Qnil;
+ /* A dynamic docstring should be either at the very beginning of a "#@
+ comment" or right after a dynamic docstring delimiter (in case we
+ pack several such docstrings within the same comment). */
+ if (get_doc_string_buffer[offset - test] != '\037')
+ {
+ if (get_doc_string_buffer[offset - test++] != ' ')
+ return Qnil;
+ while (get_doc_string_buffer[offset - test] >= '0'
+ && get_doc_string_buffer[offset - test] <= '9')
+ test++;
+ if (get_doc_string_buffer[offset - test++] != '@'
+ || get_doc_string_buffer[offset - test] != '#')
+ return Qnil;
+ }
}
else
{
@@ -279,10 +284,10 @@ Invalid data in documentation file -- %c followed by code %03o",
else
{
/* The data determines whether the string is multibyte. */
- ptrdiff_t nchars =
- multibyte_chars_in_text (((unsigned char *) get_doc_string_buffer
- + offset),
- to - (get_doc_string_buffer + offset));
+ ptrdiff_t nchars
+ = multibyte_chars_in_text (((unsigned char *) get_doc_string_buffer
+ + offset),
+ to - (get_doc_string_buffer + offset));
return make_string_from_bytes (get_doc_string_buffer + offset,
nchars,
to - (get_doc_string_buffer + offset));
@@ -338,6 +343,14 @@ string is passed through `substitute-command-keys'. */)
doc = Qnil;
+ if (SYMBOLP (function))
+ {
+ Lisp_Object tem = Fget (function, Qfunction_documentation);
+ if (!NILP (tem))
+ return Fdocumentation_property (function, Qfunction_documentation,
+ raw);
+ }
+
fun = Findirect_function (function, Qnil);
if (CONSP (fun) && EQ (XCAR (fun), Qmacro))
fun = XCDR (fun);
@@ -541,7 +554,6 @@ store_function_docstring (Lisp_Object obj, ptrdiff_t offset)
}
}
-static const char buildobj[] = BUILDOBJ;
DEFUN ("Snarf-documentation", Fsnarf_documentation, Ssnarf_documentation,
1, 1, 0,
@@ -561,6 +573,7 @@ the same file name is found in the `doc-directory'. */)
Lisp_Object sym;
char *p, *name;
bool skip_file = 0;
+ ptrdiff_t count;
CHECK_STRING (filename);
@@ -584,32 +597,26 @@ the same file name is found in the `doc-directory'. */)
/* Vbuild_files is nil when temacs is run, and non-nil after that. */
if (NILP (Vbuild_files))
- {
- const char *beg, *end;
-
- for (beg = buildobj; *beg; beg = end)
- {
- ptrdiff_t len;
-
- while (*beg && c_isspace (*beg)) ++beg;
-
- for (end = beg; *end && ! c_isspace (*end); ++end)
- if (*end == '/') beg = end+1; /* skip directory part */
-
- len = end - beg;
- if (len > 4 && end[-4] == '.' && end[-3] == 'o')
- len -= 2; /* Just take .o if it ends in .obj */
-
- if (len > 0)
- Vbuild_files = Fcons (make_string (beg, len), Vbuild_files);
- }
- Vbuild_files = Fpurecopy (Vbuild_files);
- }
+ {
+ static char const *const buildobj[] =
+ {
+ #include "buildobj.h"
+ };
+ int i = sizeof buildobj / sizeof *buildobj;
+ while (0 <= --i)
+ Vbuild_files = Fcons (build_string (buildobj[i]), Vbuild_files);
+ Vbuild_files = Fpurecopy (Vbuild_files);
+ }
fd = emacs_open (name, O_RDONLY, 0);
if (fd < 0)
- report_file_error ("Opening doc string file",
- Fcons (build_string (name), Qnil));
+ {
+ int open_errno = errno;
+ report_file_errno ("Opening doc string file", build_string (name),
+ open_errno);
+ }
+ count = SPECPDL_INDEX ();
+ record_unwind_protect_int (close_file_unwind, fd);
Vdoc_file_name = filename;
filled = 0;
pos = 0;
@@ -622,11 +629,10 @@ the same file name is found in the `doc-directory'. */)
break;
buf[filled] = 0;
- p = buf;
end = buf + (filled < 512 ? filled : filled - 128);
- while (p != end && *p != '\037') p++;
+ p = memchr (buf, '\037', end - buf);
/* p points to ^_Ffunctionname\n or ^_Vvarname\n or ^_Sfilename\n. */
- if (p != end)
+ if (p)
{
end = strchr (p, '\n');
@@ -688,8 +694,7 @@ the same file name is found in the `doc-directory'. */)
filled -= end - buf;
memmove (buf, end, filled);
}
- emacs_close (fd);
- return Qnil;
+ return unbind_to (count, Qnil);
}
DEFUN ("substitute-command-keys", Fsubstitute_command_keys,
@@ -745,9 +750,7 @@ Otherwise, return a new string, without any text properties. */)
or a specified local map (which means search just that and the
global map). If non-nil, it might come from Voverriding_local_map,
or from a \\ construct in STRING itself.. */
- keymap = KVAR (current_kboard, Voverriding_terminal_local_map);
- if (NILP (keymap))
- keymap = Voverriding_local_map;
+ keymap = Voverriding_local_map;
bsize = SBYTES (string);
bufp = buf = xmalloc (bsize);
@@ -902,7 +905,7 @@ Otherwise, return a new string, without any text properties. */)
If this one's not active, get nil. */
earlier_maps = Fcdr (Fmemq (tem, Freverse (active_maps)));
describe_map_tree (tem, 1, Fnreverse (earlier_maps),
- Qnil, (char *)0, 1, 0, 0, 1);
+ Qnil, 0, 1, 0, 0, 1);
}
tem = Fbuffer_string ();
Ferase_buffer ();