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 ();