aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-04-25 23:17:52 -0700
committerPaul Eggert2011-04-25 23:17:52 -0700
commit671875dac181f7f1337f21d013a9c3d5f235ddf2 (patch)
tree4091c2537439713df8efe8d3376116a6db3eb1c5 /src
parentf904488ff40dcee3e340b63a6386dde124d1241c (diff)
parent0c6b7b19e52ba18b5d4fd2d4b73b133a0a721603 (diff)
downloademacs-671875dac181f7f1337f21d013a9c3d5f235ddf2.tar.gz
emacs-671875dac181f7f1337f21d013a9c3d5f235ddf2.zip
Merge from mainline.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog178
-rw-r--r--src/Makefile.in6
-rw-r--r--src/buffer.c3
-rw-r--r--src/callint.c7
-rw-r--r--src/character.c35
-rw-r--r--src/charset.c10
-rw-r--r--src/coding.c4
-rw-r--r--src/deps.mk4
-rw-r--r--src/dispextern.h2
-rw-r--r--src/doc.c4
-rw-r--r--src/doprnt.c193
-rw-r--r--src/eval.c30
-rw-r--r--src/font.c6
-rw-r--r--src/gnutls.c360
-rw-r--r--src/gnutls.h2
-rw-r--r--src/lisp.h3
-rw-r--r--src/makefile.w32-in16
-rw-r--r--src/msdos.c12
-rw-r--r--src/msdos.h8
-rw-r--r--src/process.c16
-rw-r--r--src/s/ms-w32.h1
-rw-r--r--src/syntax.c2
-rw-r--r--src/sysdep.c2
-rw-r--r--src/term.c4
-rw-r--r--src/textprop.c14
-rw-r--r--src/w32.c91
-rw-r--r--src/w32.h12
-rw-r--r--src/xdisp.c27
-rw-r--r--src/xfaces.c2
29 files changed, 859 insertions, 195 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 87e703b3dab..6614375a7c6 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,4 +1,4 @@
12011-04-25 Paul Eggert <eggert@cs.ucla.edu> 12011-04-26 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 lisp.h: Fix a problem with aliasing and vector headers. 3 lisp.h: Fix a problem with aliasing and vector headers.
4 GCC 4.6.0 optimizes based on type-based alias analysis. For 4 GCC 4.6.0 optimizes based on type-based alias analysis. For
@@ -50,12 +50,8 @@
50 * process.c (Fformat_network_address): Use local var for size, 50 * process.c (Fformat_network_address): Use local var for size,
51 for brevity. 51 for brevity.
52 52
532011-04-24 Paul Eggert <eggert@cs.ucla.edu>
54
55 * bytecode.c (exec_byte_code): Don't use XVECTOR before CHECK_VECTOR. 53 * bytecode.c (exec_byte_code): Don't use XVECTOR before CHECK_VECTOR.
56 54
572011-04-21 Paul Eggert <eggert@cs.ucla.edu>
58
59 Make the Lisp reader and string-to-float more consistent. 55 Make the Lisp reader and string-to-float more consistent.
60 * data.c (atof): Remove decl; no longer used or needed. 56 * data.c (atof): Remove decl; no longer used or needed.
61 (digit_to_number): Move to lread.c. 57 (digit_to_number): Move to lread.c.
@@ -86,8 +82,6 @@
86 so that overflow for non-base-10 numbers is reported only when 82 so that overflow for non-base-10 numbers is reported only when
87 there's no portable and simple way to convert to floating point. 83 there's no portable and simple way to convert to floating point.
88 84
892011-04-20 Paul Eggert <eggert@cs.ucla.edu>
90
91 * textprop.c (set_text_properties_1): Rewrite for clarity, 85 * textprop.c (set_text_properties_1): Rewrite for clarity,
92 and to avoid GCC warning about integer overflow. 86 and to avoid GCC warning about integer overflow.
93 87
@@ -188,6 +182,176 @@
188 alignof(EMACS_INT) < sizeof (EMACS_INT). 182 alignof(EMACS_INT) < sizeof (EMACS_INT).
189 (check_sblock, check_string_bytes, check_string_free_list): Protoize. 183 (check_sblock, check_string_bytes, check_string_free_list): Protoize.
190 184
1852011-04-25 Dan Nicolaescu <dann@ics.uci.edu>
186
187 * alloc.c (check_sblock, check_string_bytes)
188 (check_string_free_list): Convert to standard C.
189
1902011-04-25 Teodor Zlatanov <tzz@lifelogs.com>
191
192 * w32.c (emacs_gnutls_push): Fix typo.
193
1942011-04-25 Eli Zaretskii <eliz@gnu.org>
195
196 * gnutls.c (emacs_gnutls_handshake): Avoid compiler warnings about
197 "cast to pointer from integer of different size".
198
199 Improve doprnt and its use in verror. (Bug#8545)
200 * doprnt.c (doprnt): Document the set of format control sequences
201 supported by the function. Use SAFE_ALLOCA instead of always
202 using `alloca'.
203
204 * eval.c (verror): Don't limit the buffer size at size_max-1, that
205 is one byte too soon. Don't use xrealloc; instead xfree and
206 xmalloc anew.
207
2082011-04-24 Teodor Zlatanov <tzz@lifelogs.com>
209
210 * gnutls.h: Add GNUTLS_STAGE_CALLBACKS enum to denote we're in the
211 callbacks stage.
212
213 * gnutls.c: Renamed global_initialized to
214 gnutls_global_initialized. Added internals for the
215 :verify-hostname-error, :verify-error, and :verify-flags
216 parameters of `gnutls-boot' and documented those parameters in the
217 docstring. Start callback support.
218 (emacs_gnutls_handshake): Add Woe32 support. Retry handshake
219 unless a fatal error occured. Call gnutls_alert_send_appropriate
220 on error. Return error code.
221 (emacs_gnutls_write): Call emacs_gnutls_handle_error.
222 (emacs_gnutls_read): Likewise.
223 (Fgnutls_boot): Return handshake error code.
224 (emacs_gnutls_handle_error): New function.
225 (wsaerror_to_errno): Likewise.
226
227 * w32.h (emacs_gnutls_pull): Add prototype.
228 (emacs_gnutls_push): Likewise.
229
230 * w32.c (emacs_gnutls_pull): New function for GnuTLS on Woe32.
231 (emacs_gnutls_push): Likewise.
232
2332011-04-24 Claudio Bley <claudio.bley@gmail.com> (tiny change)
234
235 * process.c (wait_reading_process_output): Check if GnuTLS
236 buffered some data internally if no FDs are set for TLS
237 connections.
238
239 * makefile.w32-in (OBJ2): Add gnutls.$(O).
240 (LIBS): Link to USER_LIBS.
241 ($(BLD)/gnutls.$(0)): New target.
242
2432011-04-24 Eli Zaretskii <eliz@gnu.org>
244
245 * xdisp.c (handle_single_display_spec): Rename the
246 display_replaced_before_p argument into display_replaced_p, to
247 make it consistent with the commentary. Fix typos in the
248 commentary.
249
250 * textprop.c (syms_of_textprop): Remove dead code.
251 (copy_text_properties): Delete obsolete commentary about an
252 interface that was deleted long ago. Fix typos in the description
253 of arguments.
254
255 * msdos.c (XMenuActivate, XMenuAddSelection): Adjust argument list
256 to changes in oldXMenu/XMenu.h from 2011-04-16.
257 <menu_help_message, prev_menu_help_message>: Constify.
258 (IT_menu_make_room): menu->help_text is now `const char **';
259 adjust.
260
261 * msdos.h (XMenuActivate, XMenuAddSelection): Adjust prototypes
262 to changes in oldXMenu/XMenu.h from 2011-04-16.
263 (struct XMenu): Declare `help_text' `const char **'.
264
265 * xfaces.c <Qunspecified>: Make extern again.
266
267 * syntax.c: Include sys/types.h before including regex.h, as
268 required by Posix.
269
270 * doc.c (get_doc_string): Improve the format passed to `error'.
271
272 * doprnt.c (doprnt): Improve commentary.
273
274 * term.c (init_tty) [MSDOS]: Fix 1st argument to maybe_fatal.
275
276 * Makefile.in (TAGS): Depend on $(M_FILE) and $(S_FILE), and scan
277 them with etags.
278
279 * makefile.w32-in (globals.h): Add a dummy recipe, to make any
280 changes in globals.h immediately force recompilation.
281 (TAGS): Depend on $(CURDIR)/m/intel386.h and
282 $(CURDIR)/s/ms-w32.h.
283 (TAGS-gmake): Scan $(CURDIR)/m/intel386.h and $(CURDIR)/s/ms-w32.h.
284
285 * character.c (Fchar_direction): Function deleted.
286 (syms_of_character): Don't defsubr it.
287 <char-direction-table>: Deleted.
288
2892011-04-23 Eli Zaretskii <eliz@gnu.org>
290
291 Fix doprnt so it could be used again safely in `verror'. (Bug#8435)
292 * doprnt.c: Include limits.h.
293 (SIZE_MAX): New macro.
294 (doprnt): Return a size_t value. 2nd arg is now size_t. Many
295 local variables are now size_t instead of int or unsigned.
296 Improve overflow protection. Support `l' modifier for integer
297 conversions. Support %l conversion. Don't assume an EMACS_INT
298 argument for integer conversions and for %c.
299
300 * lisp.h (doprnt): Restore prototype.
301
302 * makefile.w32-in ($(BLD)/callint.$(O)): Depend on
303 $(SRC)/character.h.
304
305 * Makefile.in (base_obj): Add back doprnt.o.
306
307 * deps.mk (doprnt.o): Add back prerequisites.
308 (callint.o): Depend on character.h.
309
310 * eval.c (internal_lisp_condition_case): Include the handler
311 representation in the error message.
312 (verror): Call doprnt instead of vsnprintf. Fix an off-by-one bug
313 when breaking from the loop.
314
315 * xdisp.c (vmessage): Call doprnt instead of vsnprintf.
316
317 * callint.c (Fcall_interactively): When displaying error message
318 about invalid control letter, pass the character's codepoint, not
319 a pointer to its multibyte form. Improve display of the character
320 in octal and display also its hex code.
321
322 * character.c (char_string): Use %x to display the (unsigned)
323 codepoint of an invalid character, to avoid displaying a bogus
324 negative value.
325
326 * font.c (check_otf_features): Pass SDATA of SYMBOL_NAME to
327 `error', not SYMBOL_NAME itself.
328
329 * coding.c (Fencode_sjis_char, Fencode_big5_char): Use %c for
330 character arguments to `error'.
331
332 * charset.c (check_iso_charset_parameter): Fix incorrect argument
333 to `error' in error message about FINAL_CHAR argument. Make sure
334 FINAL_CHAR is a character, and use %c when it is passed as
335 argument to `error'.
336
3372011-04-23 Eli Zaretskii <eliz@gnu.org>
338
339 * s/ms-w32.h (localtime): Redirect to sys_localtime.
340
341 * w32.c: Include <time.h>.
342 (sys_localtime): New function.
343
3442011-04-23 Chong Yidong <cyd@stupidchicken.com>
345
346 * xdisp.c (init_xdisp): Initialize echo_area_window (Bug#6451).
347
348 * buffer.c (syms_of_buffer): Doc fix (Bug#6902).
349
3502011-04-23 Samuel Thibault <sthibault@debian.org> (tiny change)
351
352 * sysdep.c (wait_for_termination): On GNU Hurd, kill returns -1 on
353 zombies (Bug#8467).
354
1912011-04-19 Eli Zaretskii <eliz@gnu.org> 3552011-04-19 Eli Zaretskii <eliz@gnu.org>
192 356
193 * syntax.h (SETUP_SYNTAX_TABLE_FOR_OBJECT): Fix setting of 357 * syntax.h (SETUP_SYNTAX_TABLE_FOR_OBJECT): Fix setting of
diff --git a/src/Makefile.in b/src/Makefile.in
index 154d6abba4e..8b596430cf5 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -354,7 +354,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
354 syntax.o $(UNEXEC_OBJ) bytecode.o \ 354 syntax.o $(UNEXEC_OBJ) bytecode.o \
355 process.o gnutls.o callproc.o \ 355 process.o gnutls.o callproc.o \
356 region-cache.o sound.o atimer.o \ 356 region-cache.o sound.o atimer.o \
357 intervals.o textprop.o composite.o xml.o \ 357 doprnt.o intervals.o textprop.o composite.o xml.o \
358 $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) 358 $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ)
359obj = $(base_obj) $(NS_OBJC_OBJ) 359obj = $(base_obj) $(NS_OBJC_OBJ)
360 360
@@ -748,10 +748,10 @@ extraclean: distclean
748ctagsfiles1 = [xyzXYZ]*.[hcm] 748ctagsfiles1 = [xyzXYZ]*.[hcm]
749ctagsfiles2 = [a-wA-W]*.[hcm] 749ctagsfiles2 = [a-wA-W]*.[hcm]
750 750
751TAGS: $(srcdir)/$(ctagsfiles1) $(srcdir)/$(ctagsfiles2) 751TAGS: $(srcdir)/$(ctagsfiles1) $(srcdir)/$(ctagsfiles2) $(M_FILE) $(S_FILE)
752 ../lib-src/etags --include=TAGS-LISP --include=$(lwlibdir)/TAGS \ 752 ../lib-src/etags --include=TAGS-LISP --include=$(lwlibdir)/TAGS \
753 --regex='/[ ]*DEFVAR_[A-Z_ (]+"\([^"]+\)"/' \ 753 --regex='/[ ]*DEFVAR_[A-Z_ (]+"\([^"]+\)"/' \
754 $(srcdir)/$(ctagsfiles1) $(srcdir)/$(ctagsfiles2) 754 $(srcdir)/$(ctagsfiles1) $(srcdir)/$(ctagsfiles2) $(M_FILE) $(S_FILE)
755frc: 755frc:
756TAGS-LISP: frc 756TAGS-LISP: frc
757 $(MAKE) -f $(lispdir)/Makefile TAGS-LISP ETAGS=../lib-src/etags 757 $(MAKE) -f $(lispdir)/Makefile TAGS-LISP ETAGS=../lib-src/etags
diff --git a/src/buffer.c b/src/buffer.c
index ddaacd93707..d9949045444 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -5551,7 +5551,8 @@ Linefeed indents to this column in Fundamental mode. */);
5551 5551
5552 DEFVAR_PER_BUFFER ("tab-width", &BVAR (current_buffer, tab_width), 5552 DEFVAR_PER_BUFFER ("tab-width", &BVAR (current_buffer, tab_width),
5553 make_number (LISP_INT_TAG), 5553 make_number (LISP_INT_TAG),
5554 doc: /* *Distance between tab stops (for display of tab characters), in columns. */); 5554 doc: /* *Distance between tab stops (for display of tab characters), in columns.
5555This should be an integer greater than zero. */);
5555 5556
5556 DEFVAR_PER_BUFFER ("ctl-arrow", &BVAR (current_buffer, ctl_arrow), Qnil, 5557 DEFVAR_PER_BUFFER ("ctl-arrow", &BVAR (current_buffer, ctl_arrow), Qnil,
5557 doc: /* *Non-nil means display control chars with uparrow. 5558 doc: /* *Non-nil means display control chars with uparrow.
diff --git a/src/callint.c b/src/callint.c
index 44d7a02f6bf..2cc3a7cb537 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -27,6 +27,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
27#include "keyboard.h" 27#include "keyboard.h"
28#include "window.h" 28#include "window.h"
29#include "keymap.h" 29#include "keymap.h"
30#include "character.h"
30 31
31Lisp_Object Qminus, Qplus; 32Lisp_Object Qminus, Qplus;
32Lisp_Object Qcall_interactively; 33Lisp_Object Qcall_interactively;
@@ -786,8 +787,10 @@ invoke it. If KEYS is omitted or nil, the return value of
786 if anyone tries to define one here. */ 787 if anyone tries to define one here. */
787 case '+': 788 case '+':
788 default: 789 default:
789 error ("Invalid control letter `%c' (%03o) in interactive calling string", 790 error ("Invalid control letter `%c' (#o%03o, #x%04x) in interactive calling string",
790 *tem, (unsigned char) *tem); 791 STRING_CHAR ((unsigned char *) tem),
792 (unsigned) STRING_CHAR ((unsigned char *) tem),
793 (unsigned) STRING_CHAR ((unsigned char *) tem));
791 } 794 }
792 795
793 if (varies[i] == 0) 796 if (varies[i] == 0)
diff --git a/src/character.c b/src/character.c
index 12888e0f806..64ea2625abb 100644
--- a/src/character.c
+++ b/src/character.c
@@ -156,17 +156,17 @@ char_string (unsigned int c, unsigned char *p)
156 bytes = BYTE8_STRING (c, p); 156 bytes = BYTE8_STRING (c, p);
157 } 157 }
158 else 158 else
159 error ("Invalid character: %d", c); 159 error ("Invalid character: %x", c);
160 160
161 return bytes; 161 return bytes;
162} 162}
163 163
164 164
165/* Return a character whose multibyte form is at P. Set LEN is not 165/* Return a character whose multibyte form is at P. If LEN is not
166 NULL, it must be a pointer to integer. In that case, set *LEN to 166 NULL, it must be a pointer to integer. In that case, set *LEN to
167 the byte length of the multibyte form. If ADVANCED is not NULL, is 167 the byte length of the multibyte form. If ADVANCED is not NULL, it
168 must be a pointer to unsigned char. In that case, set *ADVANCED to 168 must be a pointer to unsigned char. In that case, set *ADVANCED to
169 the ending address (i.e. the starting address of the next 169 the ending address (i.e., the starting address of the next
170 character) of the multibyte form. */ 170 character) of the multibyte form. */
171 171
172int 172int
@@ -206,11 +206,10 @@ string_char (const unsigned char *p, const unsigned char **advanced, int *len)
206} 206}
207 207
208 208
209/* Translate character C by translation table TABLE. If C is 209/* Translate character C by translation table TABLE. If no translation is
210 negative, translate a character specified by CHARSET and CODE. If 210 found in TABLE, return the untranslated character. If TABLE is a list,
211 no translation is found in TABLE, return the untranslated 211 elements are char tables. In that case, recursively translate C by all the
212 character. If TABLE is a list, elements are char tables. In this 212 tables in the list. */
213 case, translace C by all tables. */
214 213
215int 214int
216translate_char (Lisp_Object table, int c) 215translate_char (Lisp_Object table, int c)
@@ -494,19 +493,6 @@ usage: (string-width STRING) */)
494 return val; 493 return val;
495} 494}
496 495
497DEFUN ("char-direction", Fchar_direction, Schar_direction, 1, 1, 0,
498 doc: /* Return the direction of CHAR.
499The returned value is 0 for left-to-right and 1 for right-to-left.
500usage: (char-direction CHAR) */)
501 (Lisp_Object ch)
502{
503 int c;
504
505 CHECK_CHARACTER (ch);
506 c = XINT (ch);
507 return CHAR_TABLE_REF (Vchar_direction_table, c);
508}
509
510/* Return the number of characters in the NBYTES bytes at PTR. 496/* Return the number of characters in the NBYTES bytes at PTR.
511 This works by looking at the contents and checking for multibyte 497 This works by looking at the contents and checking for multibyte
512 sequences while assuming that there's no invalid sequence. 498 sequences while assuming that there's no invalid sequence.
@@ -1038,7 +1024,6 @@ syms_of_character (void)
1038 defsubr (&Smultibyte_char_to_unibyte); 1024 defsubr (&Smultibyte_char_to_unibyte);
1039 defsubr (&Schar_width); 1025 defsubr (&Schar_width);
1040 defsubr (&Sstring_width); 1026 defsubr (&Sstring_width);
1041 defsubr (&Schar_direction);
1042 defsubr (&Sstring); 1027 defsubr (&Sstring);
1043 defsubr (&Sunibyte_string); 1028 defsubr (&Sunibyte_string);
1044 defsubr (&Schar_resolve_modifiers); 1029 defsubr (&Schar_resolve_modifiers);
@@ -1067,10 +1052,6 @@ A char-table for width (columns) of each character. */);
1067 char_table_set_range (Vchar_width_table, MAX_5_BYTE_CHAR + 1, MAX_CHAR, 1052 char_table_set_range (Vchar_width_table, MAX_5_BYTE_CHAR + 1, MAX_CHAR,
1068 make_number (4)); 1053 make_number (4));
1069 1054
1070 DEFVAR_LISP ("char-direction-table", Vchar_direction_table,
1071 doc: /* A char-table for direction of each character. */);
1072 Vchar_direction_table = Fmake_char_table (Qnil, make_number (1));
1073
1074 DEFVAR_LISP ("printable-chars", Vprintable_chars, 1055 DEFVAR_LISP ("printable-chars", Vprintable_chars,
1075 doc: /* A char-table for each printable character. */); 1056 doc: /* A char-table for each printable character. */);
1076 Vprintable_chars = Fmake_char_table (Qnil, Qnil); 1057 Vprintable_chars = Fmake_char_table (Qnil, Qnil);
diff --git a/src/charset.c b/src/charset.c
index 9a7a56d9379..52c2ebdcc4e 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -1436,7 +1436,7 @@ check_iso_charset_parameter (Lisp_Object dimension, Lisp_Object chars, Lisp_Obje
1436{ 1436{
1437 CHECK_NATNUM (dimension); 1437 CHECK_NATNUM (dimension);
1438 CHECK_NATNUM (chars); 1438 CHECK_NATNUM (chars);
1439 CHECK_NATNUM (final_char); 1439 CHECK_CHARACTER (final_char);
1440 1440
1441 if (XINT (dimension) > 3) 1441 if (XINT (dimension) > 3)
1442 error ("Invalid DIMENSION %"pI"d, it should be 1, 2, or 3", 1442 error ("Invalid DIMENSION %"pI"d, it should be 1, 2, or 3",
@@ -1444,12 +1444,8 @@ check_iso_charset_parameter (Lisp_Object dimension, Lisp_Object chars, Lisp_Obje
1444 if (XINT (chars) != 94 && XINT (chars) != 96) 1444 if (XINT (chars) != 94 && XINT (chars) != 96)
1445 error ("Invalid CHARS %"pI"d, it should be 94 or 96", XINT (chars)); 1445 error ("Invalid CHARS %"pI"d, it should be 94 or 96", XINT (chars));
1446 if (XINT (final_char) < '0' || XINT (final_char) > '~') 1446 if (XINT (final_char) < '0' || XINT (final_char) > '~')
1447 { 1447 error ("Invalid FINAL-CHAR %c, it should be `0'..`~'",
1448 unsigned char str[MAX_MULTIBYTE_LENGTH + 1]; 1448 (int)XINT (final_char));
1449 int len = CHAR_STRING (XINT (chars), str);
1450 str[len] = '\0';
1451 error ("Invalid FINAL-CHAR %s, it should be `0'..`~'", str);
1452 }
1453} 1449}
1454 1450
1455 1451
diff --git a/src/coding.c b/src/coding.c
index 6cd039a0903..c14a41036ac 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -9071,7 +9071,7 @@ Return the corresponding code in SJIS. */)
9071 charset_list = CODING_ATTR_CHARSET_LIST (attrs); 9071 charset_list = CODING_ATTR_CHARSET_LIST (attrs);
9072 charset = char_charset (c, charset_list, &code); 9072 charset = char_charset (c, charset_list, &code);
9073 if (code == CHARSET_INVALID_CODE (charset)) 9073 if (code == CHARSET_INVALID_CODE (charset))
9074 error ("Can't encode by shift_jis encoding: %d", c); 9074 error ("Can't encode by shift_jis encoding: %c", c);
9075 JIS_TO_SJIS (code); 9075 JIS_TO_SJIS (code);
9076 9076
9077 return make_number (code); 9077 return make_number (code);
@@ -9142,7 +9142,7 @@ Return the corresponding character code in Big5. */)
9142 charset_list = CODING_ATTR_CHARSET_LIST (attrs); 9142 charset_list = CODING_ATTR_CHARSET_LIST (attrs);
9143 charset = char_charset (c, charset_list, &code); 9143 charset = char_charset (c, charset_list, &code);
9144 if (code == CHARSET_INVALID_CODE (charset)) 9144 if (code == CHARSET_INVALID_CODE (charset))
9145 error ("Can't encode by Big5 encoding: %d", c); 9145 error ("Can't encode by Big5 encoding: %c", c);
9146 9146
9147 return make_number (code); 9147 return make_number (code);
9148} 9148}
diff --git a/src/deps.mk b/src/deps.mk
index 2df1577ef78..8d0e0e69589 100644
--- a/src/deps.mk
+++ b/src/deps.mk
@@ -44,7 +44,8 @@ buffer.o: buffer.c buffer.h region-cache.h commands.h window.h \
44 $(INTERVALS_H) blockinput.h atimer.h systime.h character.h ../lib/unistd.h \ 44 $(INTERVALS_H) blockinput.h atimer.h systime.h character.h ../lib/unistd.h \
45 indent.h keyboard.h coding.h keymap.h frame.h lisp.h globals.h $(config_h) 45 indent.h keyboard.h coding.h keymap.h frame.h lisp.h globals.h $(config_h)
46callint.o: callint.c window.h commands.h buffer.h keymap.h globals.h msdos.h \ 46callint.o: callint.c window.h commands.h buffer.h keymap.h globals.h msdos.h \
47 keyboard.h dispextern.h systime.h coding.h composite.h lisp.h $(config_h) 47 keyboard.h dispextern.h systime.h coding.h composite.h lisp.h \
48 character.h $(config_h)
48callproc.o: callproc.c epaths.h buffer.h commands.h lisp.h $(config_h) \ 49callproc.o: callproc.c epaths.h buffer.h commands.h lisp.h $(config_h) \
49 process.h systty.h syssignal.h character.h coding.h ccl.h msdos.h \ 50 process.h systty.h syssignal.h character.h coding.h ccl.h msdos.h \
50 composite.h w32.h blockinput.h atimer.h systime.h frame.h termhooks.h \ 51 composite.h w32.h blockinput.h atimer.h systime.h frame.h termhooks.h \
@@ -82,6 +83,7 @@ dispnew.o: dispnew.c systime.h commands.h process.h frame.h coding.h \
82# doc.o's dependency on buildobj.h is in src/Makefile.in. 83# doc.o's dependency on buildobj.h is in src/Makefile.in.
83doc.o: doc.c lisp.h $(config_h) buffer.h keyboard.h keymap.h \ 84doc.o: doc.c lisp.h $(config_h) buffer.h keyboard.h keymap.h \
84 character.h systime.h coding.h composite.h ../lib/unistd.h globals.h 85 character.h systime.h coding.h composite.h ../lib/unistd.h globals.h
86doprnt.o: doprnt.c character.h lisp.h globals.h ../lib/unistd.h $(config_h)
85dosfns.o: buffer.h termchar.h termhooks.h frame.h blockinput.h window.h \ 87dosfns.o: buffer.h termchar.h termhooks.h frame.h blockinput.h window.h \
86 msdos.h dosfns.h dispextern.h charset.h coding.h atimer.h systime.h \ 88 msdos.h dosfns.h dispextern.h charset.h coding.h atimer.h systime.h \
87 lisp.h $(config_h) 89 lisp.h $(config_h)
diff --git a/src/dispextern.h b/src/dispextern.h
index 1f2189adeca..72e23e6642a 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -62,7 +62,7 @@ typedef HDC XImagePtr_or_DC;
62 62
63#ifdef HAVE_NS 63#ifdef HAVE_NS
64#include "nsgui.h" 64#include "nsgui.h"
65/* following typedef needed to accomodate the MSDOS port, believe it or not */ 65/* Following typedef needed to accommodate the MSDOS port, believe it or not. */
66typedef struct ns_display_info Display_Info; 66typedef struct ns_display_info Display_Info;
67typedef Pixmap XImagePtr; 67typedef Pixmap XImagePtr;
68typedef XImagePtr XImagePtr_or_DC; 68typedef XImagePtr XImagePtr_or_DC;
diff --git a/src/doc.c b/src/doc.c
index 29f232e666d..d27fa3f792d 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -253,7 +253,9 @@ get_doc_string (Lisp_Object filepos, int unibyte, int definition)
253 else if (c == '_') 253 else if (c == '_')
254 *to++ = 037; 254 *to++ = 037;
255 else 255 else
256 error ("Invalid data in documentation file -- ^A followed by code 0%o", c); 256 error ("\
257Invalid data in documentation file -- %c followed by code %03o",
258 1, (unsigned)c);
257 } 259 }
258 else 260 else
259 *to++ = *from++; 261 *to++ = *from++;
diff --git a/src/doprnt.c b/src/doprnt.c
index 36eb272caae..3ac1d9963a9 100644
--- a/src/doprnt.c
+++ b/src/doprnt.c
@@ -1,6 +1,6 @@
1/* Output like sprintf to a buffer of specified size. 1/* Output like sprintf to a buffer of specified size.
2 Also takes args differently: pass one pointer to an array of strings 2 Also takes args differently: pass one pointer to the end
3 in addition to the format string which is separate. 3 of the format string in addition to the format string itself.
4 Copyright (C) 1985, 2001-2011 Free Software Foundation, Inc. 4 Copyright (C) 1985, 2001-2011 Free Software Foundation, Inc.
5 5
6This file is part of GNU Emacs. 6This file is part of GNU Emacs.
@@ -18,6 +18,79 @@ GNU General Public License for more details.
18You should have received a copy of the GNU General Public License 18You should have received a copy of the GNU General Public License
19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 20
21/* If you think about replacing this with some similar standard C function of
22 the printf family (such as vsnprintf), please note that this function
23 supports the following Emacs-specific features:
24
25 . For %c conversions, it produces a string with the multibyte representation
26 of the (`int') argument, suitable for display in an Emacs buffer.
27
28 . For %s and %c, when field width is specified (e.g., %25s), it accounts for
29 the diplay width of each character, according to char-width-table. That
30 is, it does not assume that each character takes one column on display.
31
32 . If the size of the buffer is not enough to produce the formatted string in
33 its entirety, it makes sure that truncation does not chop the last
34 character in the middle of its multibyte sequence, producing an invalid
35 sequence.
36
37 . It accepts a pointer to the end of the format string, so the format string
38 could include embedded null characters.
39
40 . It signals an error if the length of the formatted string is about to
41 overflow MOST_POSITIVE_FIXNUM, to avoid producing strings longer than what
42 Emacs can handle.
43
44 OTOH, this function supports only a small subset of the standard C formatted
45 output facilities. E.g., %u and %ll are not supported, and precision is
46 ignored %s and %c conversions. (See below for the detailed documentation of
47 what is supported.) However, this is okay, as this function is supposed to
48 be called from `error' and similar functions, and thus does not need to
49 support features beyond those in `Fformat', which is used by `error' on the
50 Lisp level. */
51
52/* This function supports the following %-sequences in the `format'
53 argument:
54
55 %s means print a string argument.
56 %S is silently treated as %s, for loose compatibility with `Fformat'.
57 %d means print a `signed int' argument in decimal.
58 %l means print a `long int' argument in decimal.
59 %o means print an `unsigned int' argument in octal.
60 %x means print an `unsigned int' argument in hex.
61 %e means print a `double' argument in exponential notation.
62 %f means print a `double' argument in decimal-point notation.
63 %g means print a `double' argument in exponential notation
64 or in decimal-point notation, whichever uses fewer characters.
65 %c means print a `signed int' argument as a single character.
66 %% means produce a literal % character.
67
68 A %-sequence may contain optional flag, width, and precision specifiers, as
69 follows:
70
71 %<flags><width><precision>character
72
73 where flags is [+ -0l], width is [0-9]+, and precision is .[0-9]+
74
75 The + flag character inserts a + before any positive number, while a space
76 inserts a space before any positive number; these flags only affect %d, %l,
77 %o, %x, %e, %f, and %g sequences. The - and 0 flags affect the width
78 specifier, as described below.
79
80 The l (lower-case letter ell) flag is a `long' data type modifier: it is
81 supported for %d, %o, and %x conversions of integral arguments, and means
82 that the respective argument is to be treated as `long int' or `unsigned
83 long int'. The EMACS_INT data type should use this modifier.
84
85 The width specifier supplies a lower limit for the length of the printed
86 representation. The padding, if any, normally goes on the left, but it goes
87 on the right if the - flag is present. The padding character is normally a
88 space, but (for numerical arguments only) it is 0 if the 0 flag is present.
89 The - flag takes precedence over the 0 flag.
90
91 For %e, %f, and %g sequences, the number after the "." in the precision
92 specifier says how many decimal places to show; if zero, the decimal point
93 itself is omitted. For %s and %S, the precision specifier is ignored. */
21 94
22#include <config.h> 95#include <config.h>
23#include <stdio.h> 96#include <stdio.h>
@@ -30,6 +103,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
30 103
31#include <unistd.h> 104#include <unistd.h>
32 105
106#include <limits.h>
107#ifndef SIZE_MAX
108# define SIZE_MAX ((size_t) -1)
109#endif
110
33#include "lisp.h" 111#include "lisp.h"
34 112
35/* Since we use the macro CHAR_HEAD_P, we have to include this, but 113/* Since we use the macro CHAR_HEAD_P, we have to include this, but
@@ -45,14 +123,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
45 terminated at position FORMAT_END. 123 terminated at position FORMAT_END.
46 Output goes in BUFFER, which has room for BUFSIZE chars. 124 Output goes in BUFFER, which has room for BUFSIZE chars.
47 If the output does not fit, truncate it to fit. 125 If the output does not fit, truncate it to fit.
48 Returns the number of bytes stored into BUFFER. 126 Returns the number of bytes stored into BUFFER, excluding
49 ARGS points to the vector of arguments, and NARGS says how many. 127 the terminating null byte. Output is always null-terminated.
50 A double counts as two arguments.
51 String arguments are passed as C strings. 128 String arguments are passed as C strings.
52 Integers are passed as C integers. */ 129 Integers are passed as C integers. */
53 130
54EMACS_INT 131size_t
55doprnt (char *buffer, register int bufsize, const char *format, 132doprnt (char *buffer, register size_t bufsize, const char *format,
56 const char *format_end, va_list ap) 133 const char *format_end, va_list ap)
57{ 134{
58 const char *fmt = format; /* Pointer into format string */ 135 const char *fmt = format; /* Pointer into format string */
@@ -62,20 +139,21 @@ doprnt (char *buffer, register int bufsize, const char *format,
62 char tembuf[DBL_MAX_10_EXP + 100]; 139 char tembuf[DBL_MAX_10_EXP + 100];
63 140
64 /* Size of sprintf_buffer. */ 141 /* Size of sprintf_buffer. */
65 unsigned size_allocated = sizeof (tembuf); 142 size_t size_allocated = sizeof (tembuf);
66 143
67 /* Buffer to use for sprintf. Either tembuf or same as BIG_BUFFER. */ 144 /* Buffer to use for sprintf. Either tembuf or same as BIG_BUFFER. */
68 char *sprintf_buffer = tembuf; 145 char *sprintf_buffer = tembuf;
69 146
70 /* Buffer we have got with malloc. */ 147 /* Buffer we have got with malloc. */
71 char *big_buffer = 0; 148 char *big_buffer = NULL;
72 149
73 register int tem; 150 register size_t tem;
74 char *string; 151 char *string;
75 char fixed_buffer[20]; /* Default buffer for small formatting. */ 152 char fixed_buffer[20]; /* Default buffer for small formatting. */
76 char *fmtcpy; 153 char *fmtcpy;
77 int minlen; 154 int minlen;
78 char charbuf[MAX_MULTIBYTE_LENGTH + 1]; /* Used for %c. */ 155 char charbuf[MAX_MULTIBYTE_LENGTH + 1]; /* Used for %c. */
156 USE_SAFE_ALLOCA;
79 157
80 if (format_end == 0) 158 if (format_end == 0)
81 format_end = format + strlen (format); 159 format_end = format + strlen (format);
@@ -83,7 +161,7 @@ doprnt (char *buffer, register int bufsize, const char *format,
83 if ((format_end - format + 1) < sizeof (fixed_buffer)) 161 if ((format_end - format + 1) < sizeof (fixed_buffer))
84 fmtcpy = fixed_buffer; 162 fmtcpy = fixed_buffer;
85 else 163 else
86 fmtcpy = (char *) alloca (format_end - format + 1); 164 SAFE_ALLOCA (fmtcpy, char *, format_end - format + 1);
87 165
88 bufsize--; 166 bufsize--;
89 167
@@ -92,8 +170,9 @@ doprnt (char *buffer, register int bufsize, const char *format,
92 { 170 {
93 if (*fmt == '%') /* Check for a '%' character */ 171 if (*fmt == '%') /* Check for a '%' character */
94 { 172 {
95 unsigned size_bound = 0; 173 size_t size_bound = 0;
96 EMACS_INT width; /* Columns occupied by STRING. */ 174 EMACS_INT width; /* Columns occupied by STRING on display. */
175 int long_flag = 0;
97 176
98 fmt++; 177 fmt++;
99 /* Copy this one %-spec into fmtcpy. */ 178 /* Copy this one %-spec into fmtcpy. */
@@ -108,10 +187,11 @@ doprnt (char *buffer, register int bufsize, const char *format,
108 This might be a field width or a precision; e.g. 187 This might be a field width or a precision; e.g.
109 %1.1000f and %1000.1f both might need 1000+ bytes. 188 %1.1000f and %1000.1f both might need 1000+ bytes.
110 Parse the width or precision, checking for overflow. */ 189 Parse the width or precision, checking for overflow. */
111 unsigned n = *fmt - '0'; 190 size_t n = *fmt - '0';
112 while ('0' <= fmt[1] && fmt[1] <= '9') 191 while ('0' <= fmt[1] && fmt[1] <= '9')
113 { 192 {
114 if (n * 10 + fmt[1] - '0' < n) 193 if (n >= SIZE_MAX / 10
194 || n * 10 > SIZE_MAX - (fmt[1] - '0'))
115 error ("Format width or precision too large"); 195 error ("Format width or precision too large");
116 n = n * 10 + fmt[1] - '0'; 196 n = n * 10 + fmt[1] - '0';
117 *string++ = *++fmt; 197 *string++ = *++fmt;
@@ -122,6 +202,13 @@ doprnt (char *buffer, register int bufsize, const char *format,
122 } 202 }
123 else if (*fmt == '-' || *fmt == ' ' || *fmt == '.' || *fmt == '+') 203 else if (*fmt == '-' || *fmt == ' ' || *fmt == '.' || *fmt == '+')
124 ; 204 ;
205 else if (*fmt == 'l')
206 {
207 long_flag = 1;
208 if (!strchr ("dox", fmt[1]))
209 /* %l as conversion specifier, not as modifier. */
210 break;
211 }
125 else 212 else
126 break; 213 break;
127 fmt++; 214 fmt++;
@@ -130,7 +217,7 @@ doprnt (char *buffer, register int bufsize, const char *format,
130 217
131 /* Make the size bound large enough to handle floating point formats 218 /* Make the size bound large enough to handle floating point formats
132 with large numbers. */ 219 with large numbers. */
133 if (size_bound + DBL_MAX_10_EXP + 50 < size_bound) 220 if (size_bound > SIZE_MAX - DBL_MAX_10_EXP - 50)
134 error ("Format width or precision too large"); 221 error ("Format width or precision too large");
135 size_bound += DBL_MAX_10_EXP + 50; 222 size_bound += DBL_MAX_10_EXP + 50;
136 223
@@ -151,23 +238,47 @@ doprnt (char *buffer, register int bufsize, const char *format,
151 error ("Invalid format operation %%%c", fmt[-1]); 238 error ("Invalid format operation %%%c", fmt[-1]);
152 239
153/* case 'b': */ 240/* case 'b': */
241 case 'l':
154 case 'd': 242 case 'd':
243 {
244 int i;
245 long l;
246
247 if (long_flag)
248 {
249 l = va_arg(ap, long);
250 sprintf (sprintf_buffer, fmtcpy, l);
251 }
252 else
253 {
254 i = va_arg(ap, int);
255 sprintf (sprintf_buffer, fmtcpy, i);
256 }
257 /* Now copy into final output, truncating as necessary. */
258 string = sprintf_buffer;
259 goto doit;
260 }
261
155 case 'o': 262 case 'o':
156 case 'x': 263 case 'x':
157 if (sizeof (int) == sizeof (EMACS_INT)) 264 {
158 ; 265 unsigned u;
159 else if (sizeof (long) == sizeof (EMACS_INT)) 266 unsigned long ul;
160 /* Insert an `l' the right place. */ 267
161 string[1] = string[0], 268 if (long_flag)
162 string[0] = string[-1], 269 {
163 string[-1] = 'l', 270 ul = va_arg(ap, unsigned long);
164 string++; 271 sprintf (sprintf_buffer, fmtcpy, ul);
165 else 272 }
166 abort (); 273 else
167 sprintf (sprintf_buffer, fmtcpy, va_arg(ap, char *)); 274 {
168 /* Now copy into final output, truncating as nec. */ 275 u = va_arg(ap, unsigned);
169 string = sprintf_buffer; 276 sprintf (sprintf_buffer, fmtcpy, u);
170 goto doit; 277 }
278 /* Now copy into final output, truncating as necessary. */
279 string = sprintf_buffer;
280 goto doit;
281 }
171 282
172 case 'f': 283 case 'f':
173 case 'e': 284 case 'e':
@@ -175,7 +286,7 @@ doprnt (char *buffer, register int bufsize, const char *format,
175 { 286 {
176 double d = va_arg(ap, double); 287 double d = va_arg(ap, double);
177 sprintf (sprintf_buffer, fmtcpy, d); 288 sprintf (sprintf_buffer, fmtcpy, d);
178 /* Now copy into final output, truncating as nec. */ 289 /* Now copy into final output, truncating as necessary. */
179 string = sprintf_buffer; 290 string = sprintf_buffer;
180 goto doit; 291 goto doit;
181 } 292 }
@@ -187,13 +298,18 @@ doprnt (char *buffer, register int bufsize, const char *format,
187 minlen = atoi (&fmtcpy[1]); 298 minlen = atoi (&fmtcpy[1]);
188 string = va_arg (ap, char *); 299 string = va_arg (ap, char *);
189 tem = strlen (string); 300 tem = strlen (string);
301 if (tem > MOST_POSITIVE_FIXNUM)
302 error ("String for %%s or %%S format is too long");
190 width = strwidth (string, tem); 303 width = strwidth (string, tem);
191 goto doit1; 304 goto doit1;
192 305
193 /* Copy string into final output, truncating if no room. */ 306 /* Copy string into final output, truncating if no room. */
194 doit: 307 doit:
195 /* Coming here means STRING contains ASCII only. */ 308 /* Coming here means STRING contains ASCII only. */
196 width = tem = strlen (string); 309 tem = strlen (string);
310 if (tem > MOST_POSITIVE_FIXNUM)
311 error ("Format width or precision too large");
312 width = tem;
197 doit1: 313 doit1:
198 /* We have already calculated: 314 /* We have already calculated:
199 TEM -- length of STRING, 315 TEM -- length of STRING,
@@ -236,13 +352,8 @@ doprnt (char *buffer, register int bufsize, const char *format,
236 352
237 case 'c': 353 case 'c':
238 { 354 {
239 /* Sometimes for %c we pass a char, which would widen 355 int chr = va_arg(ap, int);
240 to int. Sometimes we pass XFASTINT() or XINT() 356 tem = CHAR_STRING (chr, (unsigned char *) charbuf);
241 values, which would be EMACS_INT. Let's hope that
242 both are passed the same way, otherwise we'll need
243 to rewrite callers. */
244 EMACS_INT chr = va_arg(ap, EMACS_INT);
245 tem = CHAR_STRING ((int) chr, (unsigned char *) charbuf);
246 string = charbuf; 357 string = charbuf;
247 string[tem] = 0; 358 string[tem] = 0;
248 width = strwidth (string, tem); 359 width = strwidth (string, tem);
@@ -274,6 +385,8 @@ doprnt (char *buffer, register int bufsize, const char *format,
274 /* If we had to malloc something, free it. */ 385 /* If we had to malloc something, free it. */
275 xfree (big_buffer); 386 xfree (big_buffer);
276 387
277 *bufptr = 0; /* Make sure our string end with a '\0' */ 388 *bufptr = 0; /* Make sure our string ends with a '\0' */
389
390 SAFE_FREE ();
278 return bufptr - buffer; 391 return bufptr - buffer;
279} 392}
diff --git a/src/eval.c b/src/eval.c
index b843ca5b2ec..d1f327021e6 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1416,7 +1416,8 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform,
1416 || (CONSP (tem) 1416 || (CONSP (tem)
1417 && (SYMBOLP (XCAR (tem)) 1417 && (SYMBOLP (XCAR (tem))
1418 || CONSP (XCAR (tem)))))) 1418 || CONSP (XCAR (tem))))))
1419 error ("Invalid condition handler"); 1419 error ("Invalid condition handler: %s",
1420 SDATA (Fprin1_to_string (tem, Qt)));
1420 } 1421 }
1421 1422
1422 c.tag = Qnil; 1423 c.tag = Qnil;
@@ -1995,27 +1996,26 @@ verror (const char *m, va_list ap)
1995 size_t size = sizeof buf; 1996 size_t size = sizeof buf;
1996 size_t size_max = 1997 size_t size_max =
1997 min (MOST_POSITIVE_FIXNUM, min (INT_MAX, SIZE_MAX - 1)) + 1; 1998 min (MOST_POSITIVE_FIXNUM, min (INT_MAX, SIZE_MAX - 1)) + 1;
1999 size_t mlen = strlen (m);
1998 char *buffer = buf; 2000 char *buffer = buf;
1999 int used; 2001 size_t used;
2000 Lisp_Object string; 2002 Lisp_Object string;
2001 2003
2002 while (1) 2004 while (1)
2003 { 2005 {
2004 used = vsnprintf (buffer, size, m, ap); 2006 used = doprnt (buffer, size, m, m + mlen, ap);
2005 2007
2006 if (used < 0) 2008 /* Note: the -1 below is because `doprnt' returns the number of bytes
2007 { 2009 excluding the terminating null byte, and it always terminates with a
2008 /* Non-C99 vsnprintf, such as w32, returns -1 when SIZE is too small. 2010 null byte, even when producing a truncated message. */
2009 Guess a larger USED to work around the incompatibility. */ 2011 if (used < size - 1)
2010 used = (size <= size_max / 2 ? 2 * size
2011 : size < size_max ? size_max - 1
2012 : size_max);
2013 }
2014 else if (used < size)
2015 break; 2012 break;
2016 if (size_max <= used) 2013 if (size <= size_max / 2)
2017 memory_full (); 2014 size *= 2;
2018 size = used + 1; 2015 else if (size < size_max)
2016 size = size_max;
2017 else
2018 break; /* and leave the message truncated */
2019 2019
2020 if (buffer != buf) 2020 if (buffer != buf)
2021 xfree (buffer); 2021 xfree (buffer);
diff --git a/src/font.c b/src/font.c
index 12b280f6c36..edbdc958539 100644
--- a/src/font.c
+++ b/src/font.c
@@ -1794,14 +1794,16 @@ check_otf_features (otf_features)
1794 { 1794 {
1795 CHECK_SYMBOL (Fcar (val)); 1795 CHECK_SYMBOL (Fcar (val));
1796 if (SBYTES (SYMBOL_NAME (XCAR (val))) > 4) 1796 if (SBYTES (SYMBOL_NAME (XCAR (val))) > 4)
1797 error ("Invalid OTF GSUB feature: %s", SYMBOL_NAME (XCAR (val))); 1797 error ("Invalid OTF GSUB feature: %s",
1798 SDATA (SYMBOL_NAME (XCAR (val))));
1798 } 1799 }
1799 otf_features = XCDR (otf_features); 1800 otf_features = XCDR (otf_features);
1800 for (val = Fcar (otf_features); ! NILP (val); val = Fcdr (val)) 1801 for (val = Fcar (otf_features); ! NILP (val); val = Fcdr (val))
1801 { 1802 {
1802 CHECK_SYMBOL (Fcar (val)); 1803 CHECK_SYMBOL (Fcar (val));
1803 if (SBYTES (SYMBOL_NAME (XCAR (val))) > 4) 1804 if (SBYTES (SYMBOL_NAME (XCAR (val))) > 4)
1804 error ("Invalid OTF GPOS feature: %s", SYMBOL_NAME (XCAR (val))); 1805 error ("Invalid OTF GPOS feature: %s",
1806 SDATA (SYMBOL_NAME (XCAR (val))));
1805 } 1807 }
1806} 1808}
1807 1809
diff --git a/src/gnutls.c b/src/gnutls.c
index 38932c9fa47..ea0a9857035 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -26,11 +26,20 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
26#ifdef HAVE_GNUTLS 26#ifdef HAVE_GNUTLS
27#include <gnutls/gnutls.h> 27#include <gnutls/gnutls.h>
28 28
29#ifdef WINDOWSNT
30#include <windows.h>
31#include "w32.h"
32#endif
33
34static int
35emacs_gnutls_handle_error (gnutls_session_t, int err);
36
37Lisp_Object Qgnutls_log_level;
29Lisp_Object Qgnutls_code; 38Lisp_Object Qgnutls_code;
30Lisp_Object Qgnutls_anon, Qgnutls_x509pki; 39Lisp_Object Qgnutls_anon, Qgnutls_x509pki;
31Lisp_Object Qgnutls_e_interrupted, Qgnutls_e_again, 40Lisp_Object Qgnutls_e_interrupted, Qgnutls_e_again,
32 Qgnutls_e_invalid_session, Qgnutls_e_not_ready_for_handshake; 41 Qgnutls_e_invalid_session, Qgnutls_e_not_ready_for_handshake;
33int global_initialized; 42int gnutls_global_initialized;
34 43
35/* The following are for the property list of `gnutls-boot'. */ 44/* The following are for the property list of `gnutls-boot'. */
36Lisp_Object Qgnutls_bootprop_priority; 45Lisp_Object Qgnutls_bootprop_priority;
@@ -38,8 +47,27 @@ Lisp_Object Qgnutls_bootprop_trustfiles;
38Lisp_Object Qgnutls_bootprop_keyfiles; 47Lisp_Object Qgnutls_bootprop_keyfiles;
39Lisp_Object Qgnutls_bootprop_callbacks; 48Lisp_Object Qgnutls_bootprop_callbacks;
40Lisp_Object Qgnutls_bootprop_loglevel; 49Lisp_Object Qgnutls_bootprop_loglevel;
50Lisp_Object Qgnutls_bootprop_hostname;
51Lisp_Object Qgnutls_bootprop_verify_flags;
52Lisp_Object Qgnutls_bootprop_verify_error;
53Lisp_Object Qgnutls_bootprop_verify_hostname_error;
54
55/* Callback keys for `gnutls-boot'. Unused currently. */
56Lisp_Object Qgnutls_bootprop_callbacks_verify;
41 57
42static void 58static void
59gnutls_log_function (int level, const char* string)
60{
61 message ("gnutls.c: [%d] %s", level, string);
62}
63
64static void
65gnutls_log_function2 (int level, const char* string, const char* extra)
66{
67 message ("gnutls.c: [%d] %s %s", level, string, extra);
68}
69
70static int
43emacs_gnutls_handshake (struct Lisp_Process *proc) 71emacs_gnutls_handshake (struct Lisp_Process *proc)
44{ 72{
45 gnutls_session_t state = proc->gnutls_state; 73 gnutls_session_t state = proc->gnutls_state;
@@ -50,24 +78,55 @@ emacs_gnutls_handshake (struct Lisp_Process *proc)
50 78
51 if (proc->gnutls_initstage < GNUTLS_STAGE_TRANSPORT_POINTERS_SET) 79 if (proc->gnutls_initstage < GNUTLS_STAGE_TRANSPORT_POINTERS_SET)
52 { 80 {
81#ifdef WINDOWSNT
82 /* On W32 we cannot transfer socket handles between different runtime
83 libraries, so we tell GnuTLS to use our special push/pull
84 functions. */
85 gnutls_transport_set_ptr2 (state,
86 (gnutls_transport_ptr_t) proc,
87 (gnutls_transport_ptr_t) proc);
88 gnutls_transport_set_push_function (state, &emacs_gnutls_push);
89 gnutls_transport_set_pull_function (state, &emacs_gnutls_pull);
90
91 /* For non blocking sockets or other custom made pull/push
92 functions the gnutls_transport_set_lowat must be called, with
93 a zero low water mark value. (GnuTLS 2.10.4 documentation)
94
95 (Note: this is probably not strictly necessary as the lowat
96 value is only used when no custom pull/push functions are
97 set.) */
98 gnutls_transport_set_lowat (state, 0);
99#else
53 /* This is how GnuTLS takes sockets: as file descriptors passed 100 /* This is how GnuTLS takes sockets: as file descriptors passed
54 in. For an Emacs process socket, infd and outfd are the 101 in. For an Emacs process socket, infd and outfd are the
55 same but we use this two-argument version for clarity. */ 102 same but we use this two-argument version for clarity. */
56 gnutls_transport_set_ptr2 (state, 103 gnutls_transport_set_ptr2 (state,
57 (gnutls_transport_ptr_t) (long) proc->infd, 104 (gnutls_transport_ptr_t) (long) proc->infd,
58 (gnutls_transport_ptr_t) (long) proc->outfd); 105 (gnutls_transport_ptr_t) (long) proc->outfd);
106#endif
59 107
60 proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET; 108 proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET;
61 } 109 }
62 110
63 ret = gnutls_handshake (state); 111 do
112 {
113 ret = gnutls_handshake (state);
114 emacs_gnutls_handle_error (state, ret);
115 }
116 while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
117
64 proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED; 118 proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED;
65 119
66 if (ret == GNUTLS_E_SUCCESS) 120 if (ret == GNUTLS_E_SUCCESS)
67 { 121 {
68 /* here we're finally done. */ 122 /* Here we're finally done. */
69 proc->gnutls_initstage = GNUTLS_STAGE_READY; 123 proc->gnutls_initstage = GNUTLS_STAGE_READY;
70 } 124 }
125 else
126 {
127 gnutls_alert_send_appropriate (state, ret);
128 }
129 return ret;
71} 130}
72 131
73EMACS_INT 132EMACS_INT
@@ -107,6 +166,7 @@ emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf,
107 bytes_written += rtnval; 166 bytes_written += rtnval;
108 } 167 }
109 168
169 emacs_gnutls_handle_error (state, rtnval);
110 return (bytes_written); 170 return (bytes_written);
111} 171}
112 172
@@ -122,19 +182,68 @@ emacs_gnutls_read (int fildes, struct Lisp_Process *proc, char *buf,
122 emacs_gnutls_handshake (proc); 182 emacs_gnutls_handshake (proc);
123 return -1; 183 return -1;
124 } 184 }
125
126 rtnval = gnutls_read (state, buf, nbyte); 185 rtnval = gnutls_read (state, buf, nbyte);
127 if (rtnval >= 0) 186 if (rtnval >= 0)
128 return rtnval; 187 return rtnval;
188 else if (emacs_gnutls_handle_error (state, rtnval) == 0)
189 /* non-fatal error */
190 return -1;
129 else { 191 else {
130 if (rtnval == GNUTLS_E_AGAIN || 192 /* a fatal error occured */
131 rtnval == GNUTLS_E_INTERRUPTED) 193 return 0;
132 return -1;
133 else
134 return 0;
135 } 194 }
136} 195}
137 196
197/* report a GnuTLS error to the user.
198 Returns zero if the error code was successfully handled. */
199static int
200emacs_gnutls_handle_error (gnutls_session_t session, int err)
201{
202 Lisp_Object gnutls_log_level = Fsymbol_value (Qgnutls_log_level);
203 int max_log_level = 0;
204
205 int alert, ret;
206 const char *str;
207
208 /* TODO: use a Lisp_Object generated by gnutls_make_error? */
209 if (err >= 0)
210 return 0;
211
212 if (NUMBERP (gnutls_log_level))
213 max_log_level = XINT (gnutls_log_level);
214
215 /* TODO: use gnutls-error-fatalp and gnutls-error-string. */
216
217 str = gnutls_strerror (err);
218 if (!str)
219 str = "unknown";
220
221 if (gnutls_error_is_fatal (err))
222 {
223 ret = err;
224 GNUTLS_LOG2 (0, max_log_level, "fatal error:", str);
225 }
226 else
227 {
228 ret = 0;
229 GNUTLS_LOG2 (1, max_log_level, "non-fatal error:", str);
230 /* TODO: EAGAIN AKA Qgnutls_e_again should be level 2. */
231 }
232
233 if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
234 || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
235 {
236 int alert = gnutls_alert_get (session);
237 int level = (err == GNUTLS_E_FATAL_ALERT_RECEIVED) ? 0 : 1;
238 str = gnutls_alert_get_name (alert);
239 if (!str)
240 str = "unknown";
241
242 GNUTLS_LOG2 (level, max_log_level, "Received alert: ", str);
243 }
244 return ret;
245}
246
138/* convert an integer error to a Lisp_Object; it will be either a 247/* convert an integer error to a Lisp_Object; it will be either a
139 known symbol like `gnutls_e_interrupted' and `gnutls_e_again' or 248 known symbol like `gnutls_e_interrupted' and `gnutls_e_again' or
140 simply the integer value of the error. GNUTLS_E_SUCCESS is mapped 249 simply the integer value of the error. GNUTLS_E_SUCCESS is mapped
@@ -262,14 +371,14 @@ See also `gnutls-init'. */)
262Call `gnutls-global-deinit' when GnuTLS usage is no longer needed. 371Call `gnutls-global-deinit' when GnuTLS usage is no longer needed.
263Returns zero on success. */ 372Returns zero on success. */
264static Lisp_Object 373static Lisp_Object
265gnutls_emacs_global_init (void) 374emacs_gnutls_global_init (void)
266{ 375{
267 int ret = GNUTLS_E_SUCCESS; 376 int ret = GNUTLS_E_SUCCESS;
268 377
269 if (!global_initialized) 378 if (!gnutls_global_initialized)
270 ret = gnutls_global_init (); 379 ret = gnutls_global_init ();
271 380
272 global_initialized = 1; 381 gnutls_global_initialized = 1;
273 382
274 return gnutls_make_error (ret); 383 return gnutls_make_error (ret);
275} 384}
@@ -278,29 +387,17 @@ gnutls_emacs_global_init (void)
278/* Deinitializes global GnuTLS state. 387/* Deinitializes global GnuTLS state.
279See also `gnutls-global-init'. */ 388See also `gnutls-global-init'. */
280static Lisp_Object 389static Lisp_Object
281gnutls_emacs_global_deinit (void) 390emacs_gnutls_global_deinit (void)
282{ 391{
283 if (global_initialized) 392 if (gnutls_global_initialized)
284 gnutls_global_deinit (); 393 gnutls_global_deinit ();
285 394
286 global_initialized = 0; 395 gnutls_global_initialized = 0;
287 396
288 return gnutls_make_error (GNUTLS_E_SUCCESS); 397 return gnutls_make_error (GNUTLS_E_SUCCESS);
289} 398}
290#endif 399#endif
291 400
292static void
293gnutls_log_function (int level, const char* string)
294{
295 message ("gnutls.c: [%d] %s", level, string);
296}
297
298static void
299gnutls_log_function2 (int level, const char* string, const char* extra)
300{
301 message ("gnutls.c: [%d] %s %s", level, string, extra);
302}
303
304DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 3, 0, 401DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 3, 0,
305 doc: /* Initialize GnuTLS client for process PROC with TYPE+PROPLIST. 402 doc: /* Initialize GnuTLS client for process PROC with TYPE+PROPLIST.
306Currently only client mode is supported. Returns a success/failure 403Currently only client mode is supported. Returns a success/failure
@@ -309,12 +406,27 @@ value you can check with `gnutls-errorp'.
309TYPE is a symbol, either `gnutls-anon' or `gnutls-x509pki'. 406TYPE is a symbol, either `gnutls-anon' or `gnutls-x509pki'.
310PROPLIST is a property list with the following keys: 407PROPLIST is a property list with the following keys:
311 408
409:hostname is a string naming the remote host.
410
312:priority is a GnuTLS priority string, defaults to "NORMAL". 411:priority is a GnuTLS priority string, defaults to "NORMAL".
412
313:trustfiles is a list of PEM-encoded trust files for `gnutls-x509pki'. 413:trustfiles is a list of PEM-encoded trust files for `gnutls-x509pki'.
414
314:keyfiles is a list of PEM-encoded key files for `gnutls-x509pki'. 415:keyfiles is a list of PEM-encoded key files for `gnutls-x509pki'.
315:callbacks is an alist of callback functions (TODO). 416
417:callbacks is an alist of callback functions, see below.
418
316:loglevel is the debug level requested from GnuTLS, try 4. 419:loglevel is the debug level requested from GnuTLS, try 4.
317 420
421:verify-flags is a bitset as per GnuTLS'
422gnutls_certificate_set_verify_flags.
423
424:verify-error, if non-nil, makes failure of the certificate validation
425an error. Otherwise it will be just a series of warnings.
426
427:verify-hostname-error, if non-nil, makes a hostname mismatch an
428error. Otherwise it will be just a warning.
429
318The debug level will be set for this process AND globally for GnuTLS. 430The debug level will be set for this process AND globally for GnuTLS.
319So if you set it higher or lower at any point, it affects global 431So if you set it higher or lower at any point, it affects global
320debugging. 432debugging.
@@ -327,6 +439,9 @@ Processes must be initialized with this function before other GnuTLS
327functions are used. This function allocates resources which can only 439functions are used. This function allocates resources which can only
328be deallocated by calling `gnutls-deinit' or by calling it again. 440be deallocated by calling `gnutls-deinit' or by calling it again.
329 441
442The callbacks alist can have a `verify' key, associated with a
443verification function (UNUSED).
444
330Each authentication type may need additional information in order to 445Each authentication type may need additional information in order to
331work. For X.509 PKI (`gnutls-x509pki'), you probably need at least 446work. For X.509 PKI (`gnutls-x509pki'), you probably need at least
332one trustfile (usually a CA bundle). */) 447one trustfile (usually a CA bundle). */)
@@ -339,12 +454,19 @@ one trustfile (usually a CA bundle). */)
339 /* TODO: GNUTLS_X509_FMT_DER is also an option. */ 454 /* TODO: GNUTLS_X509_FMT_DER is also an option. */
340 int file_format = GNUTLS_X509_FMT_PEM; 455 int file_format = GNUTLS_X509_FMT_PEM;
341 456
457 unsigned int gnutls_verify_flags = GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
458 gnutls_x509_crt_t gnutls_verify_cert;
459 unsigned int gnutls_verify_cert_list_size;
460 const gnutls_datum_t *gnutls_verify_cert_list;
461
342 gnutls_session_t state; 462 gnutls_session_t state;
343 gnutls_certificate_credentials_t x509_cred; 463 gnutls_certificate_credentials_t x509_cred;
344 gnutls_anon_client_credentials_t anon_cred; 464 gnutls_anon_client_credentials_t anon_cred;
345 Lisp_Object global_init; 465 Lisp_Object global_init;
346 char const *priority_string_ptr = "NORMAL"; /* default priority string. */ 466 char const *priority_string_ptr = "NORMAL"; /* default priority string. */
347 Lisp_Object tail; 467 Lisp_Object tail;
468 int peer_verification;
469 char* c_hostname;
348 470
349 /* Placeholders for the property list elements. */ 471 /* Placeholders for the property list elements. */
350 Lisp_Object priority_string; 472 Lisp_Object priority_string;
@@ -352,16 +474,29 @@ one trustfile (usually a CA bundle). */)
352 Lisp_Object keyfiles; 474 Lisp_Object keyfiles;
353 /* Lisp_Object callbacks; */ 475 /* Lisp_Object callbacks; */
354 Lisp_Object loglevel; 476 Lisp_Object loglevel;
477 Lisp_Object hostname;
478 Lisp_Object verify_flags;
479 Lisp_Object verify_error;
480 Lisp_Object verify_hostname_error;
355 481
356 CHECK_PROCESS (proc); 482 CHECK_PROCESS (proc);
357 CHECK_SYMBOL (type); 483 CHECK_SYMBOL (type);
358 CHECK_LIST (proplist); 484 CHECK_LIST (proplist);
359 485
360 priority_string = Fplist_get (proplist, Qgnutls_bootprop_priority); 486 hostname = Fplist_get (proplist, Qgnutls_bootprop_hostname);
361 trustfiles = Fplist_get (proplist, Qgnutls_bootprop_trustfiles); 487 priority_string = Fplist_get (proplist, Qgnutls_bootprop_priority);
362 keyfiles = Fplist_get (proplist, Qgnutls_bootprop_keyfiles); 488 trustfiles = Fplist_get (proplist, Qgnutls_bootprop_trustfiles);
363 /* callbacks = Fplist_get (proplist, Qgnutls_bootprop_callbacks); */ 489 keyfiles = Fplist_get (proplist, Qgnutls_bootprop_keyfiles);
364 loglevel = Fplist_get (proplist, Qgnutls_bootprop_loglevel); 490 /* callbacks = Fplist_get (proplist, Qgnutls_bootprop_callbacks); */
491 loglevel = Fplist_get (proplist, Qgnutls_bootprop_loglevel);
492 verify_flags = Fplist_get (proplist, Qgnutls_bootprop_verify_flags);
493 verify_error = Fplist_get (proplist, Qgnutls_bootprop_verify_error);
494 verify_hostname_error = Fplist_get (proplist, Qgnutls_bootprop_verify_hostname_error);
495
496 if (!STRINGP (hostname))
497 error ("gnutls-boot: invalid :hostname parameter");
498
499 c_hostname = SSDATA (hostname);
365 500
366 state = XPROCESS (proc)->gnutls_state; 501 state = XPROCESS (proc)->gnutls_state;
367 XPROCESS (proc)->gnutls_p = 1; 502 XPROCESS (proc)->gnutls_p = 1;
@@ -375,7 +510,7 @@ one trustfile (usually a CA bundle). */)
375 } 510 }
376 511
377 /* always initialize globals. */ 512 /* always initialize globals. */
378 global_init = gnutls_emacs_global_init (); 513 global_init = emacs_gnutls_global_init ();
379 if (! NILP (Fgnutls_errorp (global_init))) 514 if (! NILP (Fgnutls_errorp (global_init)))
380 return global_init; 515 return global_init;
381 516
@@ -419,6 +554,23 @@ one trustfile (usually a CA bundle). */)
419 x509_cred = XPROCESS (proc)->gnutls_x509_cred; 554 x509_cred = XPROCESS (proc)->gnutls_x509_cred;
420 if (gnutls_certificate_allocate_credentials (&x509_cred) < 0) 555 if (gnutls_certificate_allocate_credentials (&x509_cred) < 0)
421 memory_full (); 556 memory_full ();
557
558 if (NUMBERP (verify_flags))
559 {
560 gnutls_verify_flags = XINT (verify_flags);
561 GNUTLS_LOG (2, max_log_level, "setting verification flags");
562 }
563 else if (NILP (verify_flags))
564 {
565 /* The default is already GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT. */
566 GNUTLS_LOG (2, max_log_level, "using default verification flags");
567 }
568 else
569 {
570 /* The default is already GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT. */
571 GNUTLS_LOG (2, max_log_level, "ignoring invalid verify-flags");
572 }
573 gnutls_certificate_set_verify_flags (x509_cred, gnutls_verify_flags);
422 } 574 }
423 else if (EQ (type, Qgnutls_anon)) 575 else if (EQ (type, Qgnutls_anon))
424 { 576 {
@@ -487,6 +639,14 @@ one trustfile (usually a CA bundle). */)
487 639
488 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_FILES; 640 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_FILES;
489 641
642 GNUTLS_LOG (1, max_log_level, "gnutls callbacks");
643
644 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CALLBACKS;
645
646#ifdef HAVE_GNUTLS_CALLBACK_CERTIFICATE_VERIFY
647#else
648#endif
649
490 GNUTLS_LOG (1, max_log_level, "gnutls_init"); 650 GNUTLS_LOG (1, max_log_level, "gnutls_init");
491 651
492 ret = gnutls_init (&state, GNUTLS_CLIENT); 652 ret = gnutls_init (&state, GNUTLS_CLIENT);
@@ -544,9 +704,113 @@ one trustfile (usually a CA bundle). */)
544 704
545 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_SET; 705 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_SET;
546 706
547 emacs_gnutls_handshake (XPROCESS (proc)); 707 ret = emacs_gnutls_handshake (XPROCESS (proc));
548 708
549 return gnutls_make_error (GNUTLS_E_SUCCESS); 709 if (ret < GNUTLS_E_SUCCESS)
710 return gnutls_make_error (ret);
711
712 /* Now verify the peer, following
713 http://www.gnu.org/software/gnutls/manual/html_node/Verifying-peer_0027s-certificate.html.
714 The peer should present at least one certificate in the chain; do a
715 check of the certificate's hostname with
716 gnutls_x509_crt_check_hostname() against :hostname. */
717
718 ret = gnutls_certificate_verify_peers2 (state, &peer_verification);
719
720 if (ret < GNUTLS_E_SUCCESS)
721 return gnutls_make_error (ret);
722
723 if (XINT (loglevel) > 0 && peer_verification & GNUTLS_CERT_INVALID)
724 message ("%s certificate could not be verified.",
725 c_hostname);
726
727 if (peer_verification & GNUTLS_CERT_REVOKED)
728 GNUTLS_LOG2 (1, max_log_level, "certificate was revoked (CRL):",
729 c_hostname);
730
731 if (peer_verification & GNUTLS_CERT_SIGNER_NOT_FOUND)
732 GNUTLS_LOG2 (1, max_log_level, "certificate signer was not found:",
733 c_hostname);
734
735 if (peer_verification & GNUTLS_CERT_SIGNER_NOT_CA)
736 GNUTLS_LOG2 (1, max_log_level, "certificate signer is not a CA:",
737 c_hostname);
738
739 if (peer_verification & GNUTLS_CERT_INSECURE_ALGORITHM)
740 GNUTLS_LOG2 (1, max_log_level,
741 "certificate was signed with an insecure algorithm:",
742 c_hostname);
743
744 if (peer_verification & GNUTLS_CERT_NOT_ACTIVATED)
745 GNUTLS_LOG2 (1, max_log_level, "certificate is not yet activated:",
746 c_hostname);
747
748 if (peer_verification & GNUTLS_CERT_EXPIRED)
749 GNUTLS_LOG2 (1, max_log_level, "certificate has expired:",
750 c_hostname);
751
752 if (peer_verification != 0)
753 {
754 if (NILP (verify_hostname_error))
755 {
756 GNUTLS_LOG2 (1, max_log_level, "certificate validation failed:",
757 c_hostname);
758 }
759 else
760 {
761 error ("Certificate validation failed %s, verification code %d",
762 c_hostname, peer_verification);
763 }
764 }
765
766 /* Up to here the process is the same for X.509 certificates and
767 OpenPGP keys. From now on X.509 certificates are assumed. This
768 can be easily extended to work with openpgp keys as well. */
769 if (gnutls_certificate_type_get (state) == GNUTLS_CRT_X509)
770 {
771 ret = gnutls_x509_crt_init (&gnutls_verify_cert);
772
773 if (ret < GNUTLS_E_SUCCESS)
774 return gnutls_make_error (ret);
775
776 gnutls_verify_cert_list =
777 gnutls_certificate_get_peers (state, &gnutls_verify_cert_list_size);
778
779 if (NULL == gnutls_verify_cert_list)
780 {
781 error ("No x509 certificate was found!\n");
782 }
783
784 /* We only check the first certificate in the given chain. */
785 ret = gnutls_x509_crt_import (gnutls_verify_cert,
786 &gnutls_verify_cert_list[0],
787 GNUTLS_X509_FMT_DER);
788
789 if (ret < GNUTLS_E_SUCCESS)
790 {
791 gnutls_x509_crt_deinit (gnutls_verify_cert);
792 return gnutls_make_error (ret);
793 }
794
795 if (!gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname))
796 {
797 if (NILP (verify_hostname_error))
798 {
799 GNUTLS_LOG2 (1, max_log_level, "x509 certificate does not match:",
800 c_hostname);
801 }
802 else
803 {
804 gnutls_x509_crt_deinit (gnutls_verify_cert);
805 error ("The x509 certificate does not match \"%s\"",
806 c_hostname);
807 }
808 }
809
810 gnutls_x509_crt_deinit (gnutls_verify_cert);
811 }
812
813 return gnutls_make_error (ret);
550} 814}
551 815
552DEFUN ("gnutls-bye", Fgnutls_bye, 816DEFUN ("gnutls-bye", Fgnutls_bye,
@@ -581,7 +845,10 @@ This function may also return `gnutls-e-again', or
581void 845void
582syms_of_gnutls (void) 846syms_of_gnutls (void)
583{ 847{
584 global_initialized = 0; 848 gnutls_global_initialized = 0;
849
850 Qgnutls_log_level = intern_c_string ("gnutls-log-level");
851 staticpro (&Qgnutls_log_level);
585 852
586 Qgnutls_code = intern_c_string ("gnutls-code"); 853 Qgnutls_code = intern_c_string ("gnutls-code");
587 staticpro (&Qgnutls_code); 854 staticpro (&Qgnutls_code);
@@ -592,6 +859,9 @@ syms_of_gnutls (void)
592 Qgnutls_x509pki = intern_c_string ("gnutls-x509pki"); 859 Qgnutls_x509pki = intern_c_string ("gnutls-x509pki");
593 staticpro (&Qgnutls_x509pki); 860 staticpro (&Qgnutls_x509pki);
594 861
862 Qgnutls_bootprop_hostname = intern_c_string (":hostname");
863 staticpro (&Qgnutls_bootprop_hostname);
864
595 Qgnutls_bootprop_priority = intern_c_string (":priority"); 865 Qgnutls_bootprop_priority = intern_c_string (":priority");
596 staticpro (&Qgnutls_bootprop_priority); 866 staticpro (&Qgnutls_bootprop_priority);
597 867
@@ -604,9 +874,21 @@ syms_of_gnutls (void)
604 Qgnutls_bootprop_callbacks = intern_c_string (":callbacks"); 874 Qgnutls_bootprop_callbacks = intern_c_string (":callbacks");
605 staticpro (&Qgnutls_bootprop_callbacks); 875 staticpro (&Qgnutls_bootprop_callbacks);
606 876
877 Qgnutls_bootprop_callbacks_verify = intern_c_string ("verify");
878 staticpro (&Qgnutls_bootprop_callbacks_verify);
879
607 Qgnutls_bootprop_loglevel = intern_c_string (":loglevel"); 880 Qgnutls_bootprop_loglevel = intern_c_string (":loglevel");
608 staticpro (&Qgnutls_bootprop_loglevel); 881 staticpro (&Qgnutls_bootprop_loglevel);
609 882
883 Qgnutls_bootprop_verify_flags = intern_c_string (":verify-flags");
884 staticpro (&Qgnutls_bootprop_verify_flags);
885
886 Qgnutls_bootprop_verify_hostname_error = intern_c_string (":verify-error");
887 staticpro (&Qgnutls_bootprop_verify_error);
888
889 Qgnutls_bootprop_verify_hostname_error = intern_c_string (":verify-hostname-error");
890 staticpro (&Qgnutls_bootprop_verify_hostname_error);
891
610 Qgnutls_e_interrupted = intern_c_string ("gnutls-e-interrupted"); 892 Qgnutls_e_interrupted = intern_c_string ("gnutls-e-interrupted");
611 staticpro (&Qgnutls_e_interrupted); 893 staticpro (&Qgnutls_e_interrupted);
612 Fput (Qgnutls_e_interrupted, Qgnutls_code, 894 Fput (Qgnutls_e_interrupted, Qgnutls_code,
diff --git a/src/gnutls.h b/src/gnutls.h
index 5240d94c2ad..6c2e4c69523 100644
--- a/src/gnutls.h
+++ b/src/gnutls.h
@@ -21,6 +21,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 21
22#ifdef HAVE_GNUTLS 22#ifdef HAVE_GNUTLS
23#include <gnutls/gnutls.h> 23#include <gnutls/gnutls.h>
24#include <gnutls/x509.h>
24 25
25typedef enum 26typedef enum
26{ 27{
@@ -28,6 +29,7 @@ typedef enum
28 GNUTLS_STAGE_EMPTY = 0, 29 GNUTLS_STAGE_EMPTY = 0,
29 GNUTLS_STAGE_CRED_ALLOC, 30 GNUTLS_STAGE_CRED_ALLOC,
30 GNUTLS_STAGE_FILES, 31 GNUTLS_STAGE_FILES,
32 GNUTLS_STAGE_CALLBACKS,
31 GNUTLS_STAGE_INIT, 33 GNUTLS_STAGE_INIT,
32 GNUTLS_STAGE_PRIORITY, 34 GNUTLS_STAGE_PRIORITY,
33 GNUTLS_STAGE_CRED_SET, 35 GNUTLS_STAGE_CRED_SET,
diff --git a/src/lisp.h b/src/lisp.h
index 4af12fb2f51..4b7973939ef 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2782,6 +2782,9 @@ extern Lisp_Object internal_with_output_to_temp_buffer
2782extern void float_to_string (char *, double); 2782extern void float_to_string (char *, double);
2783extern void syms_of_print (void); 2783extern void syms_of_print (void);
2784 2784
2785/* Defined in doprnt.c */
2786extern size_t doprnt (char *, size_t, const char *, const char *, va_list);
2787
2785/* Defined in lread.c. */ 2788/* Defined in lread.c. */
2786extern Lisp_Object Qvariable_documentation, Qstandard_input; 2789extern Lisp_Object Qvariable_documentation, Qstandard_input;
2787extern Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction; 2790extern Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction;
diff --git a/src/makefile.w32-in b/src/makefile.w32-in
index 62c40ca1f94..4ba314318db 100644
--- a/src/makefile.w32-in
+++ b/src/makefile.w32-in
@@ -105,6 +105,7 @@ OBJ2 = $(BLD)/sysdep.$(O) \
105 $(BLD)/floatfns.$(O) \ 105 $(BLD)/floatfns.$(O) \
106 $(BLD)/frame.$(O) \ 106 $(BLD)/frame.$(O) \
107 $(BLD)/gmalloc.$(O) \ 107 $(BLD)/gmalloc.$(O) \
108 $(BLD)/gnutls.$(O) \
108 $(BLD)/intervals.$(O) \ 109 $(BLD)/intervals.$(O) \
109 $(BLD)/composite.$(O) \ 110 $(BLD)/composite.$(O) \
110 $(BLD)/ralloc.$(O) \ 111 $(BLD)/ralloc.$(O) \
@@ -150,6 +151,7 @@ LIBS = $(TLIB0) \
150 $(OLE32) \ 151 $(OLE32) \
151 $(COMCTL32) \ 152 $(COMCTL32) \
152 $(UNISCRIBE) \ 153 $(UNISCRIBE) \
154 $(USER_LIBS) \
153 $(libc) 155 $(libc)
154 156
155# 157#
@@ -225,6 +227,7 @@ SOME_MACHINE_OBJECTS = dosfns.o msdos.o \
225obj = $(GLOBAL_SOURCES:.c=.o) 227obj = $(GLOBAL_SOURCES:.c=.o)
226 228
227globals.h: gl-stamp 229globals.h: gl-stamp
230 @cmd /c rem true
228 231
229gl-stamp: ../lib-src/$(BLD)/make-docfile.exe $(GLOBAL_SOURCES) 232gl-stamp: ../lib-src/$(BLD)/make-docfile.exe $(GLOBAL_SOURCES)
230 - $(DEL) gl-tmp 233 - $(DEL) gl-tmp
@@ -329,7 +332,7 @@ cleanall: clean
329## 332##
330## This works only with GNU Make. 333## This works only with GNU Make.
331 334
332TAGS: $(OBJ0) $(OBJ1) $(OBJ2) 335TAGS: $(OBJ0) $(OBJ1) $(OBJ2) $(CURDIR)/m/intel386.h $(CURDIR)/s/ms-w32.h
333 $(MAKE) $(MFLAGS) TAGS-$(MAKETYPE) 336 $(MAKE) $(MFLAGS) TAGS-$(MAKETYPE)
334 337
335TAGS-LISP: $(OBJ0) $(OBJ1) $(OBJ2) 338TAGS-LISP: $(OBJ0) $(OBJ1) $(OBJ2)
@@ -343,7 +346,7 @@ TAGS-gmake:
343 $(patsubst $(BLD)%.$(O),$(CURDIR)%.c,$(OBJ1)) 346 $(patsubst $(BLD)%.$(O),$(CURDIR)%.c,$(OBJ1))
344 ../lib-src/$(BLD)/etags.exe -a --regex=@../nt/emacs-src.tags \ 347 ../lib-src/$(BLD)/etags.exe -a --regex=@../nt/emacs-src.tags \
345 $(patsubst $(BLD)%.$(O),$(CURDIR)%.c,$(OBJ2)) \ 348 $(patsubst $(BLD)%.$(O),$(CURDIR)%.c,$(OBJ2)) \
346 $(CURDIR)/*.h 349 $(CURDIR)/*.h $(CURDIR)/m/intel386.h $(CURDIR)/s/ms-w32.h
347 350
348TAGS-nmake: 351TAGS-nmake:
349 echo This target is not supported with NMake 352 echo This target is not supported with NMake
@@ -469,6 +472,7 @@ $(BLD)/callint.$(O) : \
469 $(EMACS_ROOT)/nt/inc/sys/time.h \ 472 $(EMACS_ROOT)/nt/inc/sys/time.h \
470 $(LISP_H) \ 473 $(LISP_H) \
471 $(SRC)/buffer.h \ 474 $(SRC)/buffer.h \
475 $(SRC)/character.h \
472 $(SRC)/coding.h \ 476 $(SRC)/coding.h \
473 $(SRC)/commands.h \ 477 $(SRC)/commands.h \
474 $(SRC)/composite.h \ 478 $(SRC)/composite.h \
@@ -948,6 +952,14 @@ $(BLD)/gmalloc.$(O) : \
948 $(EMACS_ROOT)/nt/inc/unistd.h \ 952 $(EMACS_ROOT)/nt/inc/unistd.h \
949 $(SRC)/getpagesize.h 953 $(SRC)/getpagesize.h
950 954
955$(BLD)/gnutls.$(O) : \
956 $(SRC)/gnutls.h \
957 $(SRC)/gnutls.c \
958 $(CONFIG_H) \
959 $(EMACS_ROOT)/nt/inc/sys/socket.h \
960 $(SRC)/lisp.h \
961 $(SRC)/process.h
962
951$(BLD)/image.$(O) : \ 963$(BLD)/image.$(O) : \
952 $(SRC)/image.c \ 964 $(SRC)/image.c \
953 $(CONFIG_H) \ 965 $(CONFIG_H) \
diff --git a/src/msdos.c b/src/msdos.c
index e02e64b9ece..3dc586e42f5 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -842,7 +842,7 @@ IT_set_face (int face)
842 842
843/* According to RBIL (INTERRUP.A, V-1000), 160 is the maximum possible 843/* According to RBIL (INTERRUP.A, V-1000), 160 is the maximum possible
844 width of a DOS display in any known text mode. We multiply by 2 to 844 width of a DOS display in any known text mode. We multiply by 2 to
845 accomodate the screen attribute byte. */ 845 accommodate the screen attribute byte. */
846#define MAX_SCREEN_BUF 160*2 846#define MAX_SCREEN_BUF 160*2
847 847
848extern unsigned char *encode_terminal_code (struct glyph *, int, 848extern unsigned char *encode_terminal_code (struct glyph *, int,
@@ -2812,7 +2812,7 @@ dos_keyread (void)
2812 left), but I don't think it's worth the effort. */ 2812 left), but I don't think it's worth the effort. */
2813 2813
2814/* These hold text of the current and the previous menu help messages. */ 2814/* These hold text of the current and the previous menu help messages. */
2815static char *menu_help_message, *prev_menu_help_message; 2815static const char *menu_help_message, *prev_menu_help_message;
2816/* Pane number and item number of the menu item which generated the 2816/* Pane number and item number of the menu item which generated the
2817 last menu help message. */ 2817 last menu help message. */
2818static int menu_help_paneno, menu_help_itemno; 2818static int menu_help_paneno, menu_help_itemno;
@@ -2839,7 +2839,7 @@ IT_menu_make_room (XMenu *menu)
2839 menu->text = (char **) xmalloc (count * sizeof (char *)); 2839 menu->text = (char **) xmalloc (count * sizeof (char *));
2840 menu->submenu = (XMenu **) xmalloc (count * sizeof (XMenu *)); 2840 menu->submenu = (XMenu **) xmalloc (count * sizeof (XMenu *));
2841 menu->panenumber = (int *) xmalloc (count * sizeof (int)); 2841 menu->panenumber = (int *) xmalloc (count * sizeof (int));
2842 menu->help_text = (char **) xmalloc (count * sizeof (char *)); 2842 menu->help_text = (const char **) xmalloc (count * sizeof (char *));
2843 } 2843 }
2844 else if (menu->allocated == menu->count) 2844 else if (menu->allocated == menu->count)
2845 { 2845 {
@@ -2851,7 +2851,7 @@ IT_menu_make_room (XMenu *menu)
2851 menu->panenumber 2851 menu->panenumber
2852 = (int *) xrealloc (menu->panenumber, count * sizeof (int)); 2852 = (int *) xrealloc (menu->panenumber, count * sizeof (int));
2853 menu->help_text 2853 menu->help_text
2854 = (char **) xrealloc (menu->help_text, count * sizeof (char *)); 2854 = (const char **) xrealloc (menu->help_text, count * sizeof (char *));
2855 } 2855 }
2856} 2856}
2857 2857
@@ -3033,7 +3033,7 @@ XMenuAddPane (Display *foo, XMenu *menu, const char *txt, int enable)
3033 3033
3034int 3034int
3035XMenuAddSelection (Display *bar, XMenu *menu, int pane, 3035XMenuAddSelection (Display *bar, XMenu *menu, int pane,
3036 int foo, char *txt, int enable, char *help_text) 3036 int foo, char *txt, int enable, char const *help_text)
3037{ 3037{
3038 int len; 3038 int len;
3039 char *p; 3039 char *p;
@@ -3086,7 +3086,7 @@ struct IT_menu_state
3086int 3086int
3087XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx, 3087XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx,
3088 int x0, int y0, unsigned ButtonMask, char **txt, 3088 int x0, int y0, unsigned ButtonMask, char **txt,
3089 void (*help_callback)(char *, int, int)) 3089 void (*help_callback)(char const *, int, int))
3090{ 3090{
3091 struct IT_menu_state *state; 3091 struct IT_menu_state *state;
3092 int statecount, x, y, i, b, screensize, leave, result, onepane; 3092 int statecount, x, y, i, b, screensize, leave, result, onepane;
diff --git a/src/msdos.h b/src/msdos.h
index 5051f2f3837..3048b5f7e35 100644
--- a/src/msdos.h
+++ b/src/msdos.h
@@ -101,16 +101,16 @@ typedef struct x_menu_struct
101 int allocated; 101 int allocated;
102 int panecount; 102 int panecount;
103 int width; 103 int width;
104 char **help_text; 104 const char **help_text;
105} XMenu; 105} XMenu;
106 106
107XMenu *XMenuCreate (Display *, Window, char *); 107XMenu *XMenuCreate (Display *, Window, char *);
108int XMenuAddPane (Display *, XMenu *, const char *, int); 108int XMenuAddPane (Display *, XMenu *, char const *, int);
109int XMenuAddSelection (Display *, XMenu *, int, int, char *, int, char *); 109int XMenuAddSelection (Display *, XMenu *, int, int, char *, int, char const *);
110void XMenuLocate (Display *, XMenu *, int, int, int, int, 110void XMenuLocate (Display *, XMenu *, int, int, int, int,
111 int *, int *, int *, int *); 111 int *, int *, int *, int *);
112int XMenuActivate (Display *, XMenu *, int *, int *, int, int, unsigned, 112int XMenuActivate (Display *, XMenu *, int *, int *, int, int, unsigned,
113 char **, void (*callback)(char *, int, int)); 113 char **, void (*callback)(char const *, int, int));
114void XMenuDestroy (Display *, XMenu *); 114void XMenuDestroy (Display *, XMenu *);
115 115
116#endif /* not HAVE_X_WINDOWS */ 116#endif /* not HAVE_X_WINDOWS */
diff --git a/src/process.c b/src/process.c
index 89a5f3e0386..1544522ff55 100644
--- a/src/process.c
+++ b/src/process.c
@@ -4533,6 +4533,22 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
4533 &Available, 4533 &Available,
4534 (check_write ? &Writeok : (SELECT_TYPE *)0), 4534 (check_write ? &Writeok : (SELECT_TYPE *)0),
4535 (SELECT_TYPE *)0, &timeout); 4535 (SELECT_TYPE *)0, &timeout);
4536
4537#ifdef HAVE_GNUTLS
4538 /* GnuTLS buffers data internally. In lowat mode it leaves
4539 some data in the TCP buffers so that select works, but
4540 with custom pull/push functions we need to check if some
4541 data is available in the buffers manually. */
4542 if (nfds == 0 &&
4543 wait_proc && wait_proc->gnutls_p /* Check for valid process. */
4544 /* Do we have pending data? */
4545 && gnutls_record_check_pending (wait_proc->gnutls_state) > 0)
4546 {
4547 nfds = 1;
4548 /* Set to Available. */
4549 FD_SET (wait_proc->infd, &Available);
4550 }
4551#endif
4536 } 4552 }
4537 4553
4538 xerrno = errno; 4554 xerrno = errno;
diff --git a/src/s/ms-w32.h b/src/s/ms-w32.h
index 8b189baea46..bf6cc66798c 100644
--- a/src/s/ms-w32.h
+++ b/src/s/ms-w32.h
@@ -204,6 +204,7 @@ struct sigaction {
204#define dup2 sys_dup2 204#define dup2 sys_dup2
205#define fopen sys_fopen 205#define fopen sys_fopen
206#define link sys_link 206#define link sys_link
207#define localtime sys_localtime
207#define mkdir sys_mkdir 208#define mkdir sys_mkdir
208#undef mktemp 209#undef mktemp
209#define mktemp sys_mktemp 210#define mktemp sys_mktemp
diff --git a/src/syntax.c b/src/syntax.c
index 3bc9cdbd66d..cff6d50f510 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -19,7 +19,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19 19
20 20
21#include <config.h> 21#include <config.h>
22
22#include <ctype.h> 23#include <ctype.h>
24#include <sys/types.h>
23#include <setjmp.h> 25#include <setjmp.h>
24#include "lisp.h" 26#include "lisp.h"
25#include "commands.h" 27#include "commands.h"
diff --git a/src/sysdep.c b/src/sysdep.c
index a57b8c0382d..ca7de4f54bb 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -304,7 +304,7 @@ wait_for_termination (int pid)
304{ 304{
305 while (1) 305 while (1)
306 { 306 {
307#if defined (BSD_SYSTEM) || defined (HPUX) 307#if (defined (BSD_SYSTEM) || defined (HPUX)) && !defined(__GNU__)
308 /* Note that kill returns -1 even if the process is just a zombie now. 308 /* Note that kill returns -1 even if the process is just a zombie now.
309 But inevitably a SIGCHLD interrupt should be generated 309 But inevitably a SIGCHLD interrupt should be generated
310 and child_sig will do wait3 and make the process go away. */ 310 and child_sig will do wait3 and make the process go away. */
diff --git a/src/term.c b/src/term.c
index cae83f4d269..28709138a17 100644
--- a/src/term.c
+++ b/src/term.c
@@ -3121,7 +3121,7 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
3121 terminal = create_terminal (); 3121 terminal = create_terminal ();
3122#ifdef MSDOS 3122#ifdef MSDOS
3123 if (been_here > 0) 3123 if (been_here > 0)
3124 maybe_fatal (1, 0, "Attempt to create another terminal %s", "", 3124 maybe_fatal (0, 0, "Attempt to create another terminal %s", "",
3125 name, ""); 3125 name, "");
3126 been_here = 1; 3126 been_here = 1;
3127 tty = &the_only_display_info; 3127 tty = &the_only_display_info;
@@ -3627,7 +3627,7 @@ vfatal (const char *str, va_list ap)
3627 3627
3628/* Auxiliary error-handling function for init_tty. 3628/* Auxiliary error-handling function for init_tty.
3629 Delete TERMINAL, then call error or fatal with str1 or str2, 3629 Delete TERMINAL, then call error or fatal with str1 or str2,
3630 respectively, according to MUST_SUCCEED. */ 3630 respectively, according to whether MUST_SUCCEED is zero or not. */
3631 3631
3632static void 3632static void
3633maybe_fatal (int must_succeed, struct terminal *terminal, 3633maybe_fatal (int must_succeed, struct terminal *terminal,
diff --git a/src/textprop.c b/src/textprop.c
index 64265fd679c..aad090c5b41 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -233,7 +233,7 @@ interval_has_all_properties (Lisp_Object plist, INTERVAL i)
233 if (! EQ (Fcar (XCDR (tail1)), Fcar (XCDR (tail2)))) 233 if (! EQ (Fcar (XCDR (tail1)), Fcar (XCDR (tail2))))
234 return 0; 234 return 0;
235 235
236 /* Property has same value on both lists; go to next one. */ 236 /* Property has same value on both lists; go to next one. */
237 found = 1; 237 found = 1;
238 break; 238 break;
239 } 239 }
@@ -1759,15 +1759,9 @@ text_property_stickiness (Lisp_Object prop, Lisp_Object pos, Lisp_Object buffer)
1759} 1759}
1760 1760
1761 1761
1762/* I don't think this is the right interface to export; how often do you 1762/* Copying properties between objects. */
1763 want to do something like this, other than when you're copying objects
1764 around?
1765 1763
1766 I think it would be better to have a pair of functions, one which 1764/* Add properties from START to END of SRC, starting at POS in DEST.
1767 returns the text properties of a region as a list of ranges and
1768 plists, and another which applies such a list to another object. */
1769
1770/* Add properties from SRC to SRC of SRC, starting at POS in DEST.
1771 SRC and DEST may each refer to strings or buffers. 1765 SRC and DEST may each refer to strings or buffers.
1772 Optional sixth argument PROP causes only that property to be copied. 1766 Optional sixth argument PROP causes only that property to be copied.
1773 Properties are copied to DEST as if by `add-text-properties'. 1767 Properties are copied to DEST as if by `add-text-properties'.
@@ -2307,6 +2301,4 @@ inherits it if NONSTICKINESS is nil. The `front-sticky' and
2307 defsubr (&Sremove_list_of_text_properties); 2301 defsubr (&Sremove_list_of_text_properties);
2308 defsubr (&Stext_property_any); 2302 defsubr (&Stext_property_any);
2309 defsubr (&Stext_property_not_all); 2303 defsubr (&Stext_property_not_all);
2310/* defsubr (&Serase_text_properties); */
2311/* defsubr (&Scopy_text_properties); */
2312} 2304}
diff --git a/src/w32.c b/src/w32.c
index d715c39fa81..2fbb3b6cb4c 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -34,6 +34,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
34#include <mbstring.h> /* for _mbspbrk */ 34#include <mbstring.h> /* for _mbspbrk */
35#include <math.h> 35#include <math.h>
36#include <setjmp.h> 36#include <setjmp.h>
37#include <time.h>
37 38
38/* must include CRT headers *before* config.h */ 39/* must include CRT headers *before* config.h */
39 40
@@ -62,6 +63,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
62 63
63#undef strerror 64#undef strerror
64 65
66#undef localtime
67
65#include "lisp.h" 68#include "lisp.h"
66 69
67#include <pwd.h> 70#include <pwd.h>
@@ -1942,6 +1945,12 @@ gettimeofday (struct timeval *tv, struct timezone *tz)
1942 1945
1943 tv->tv_sec = tb.time; 1946 tv->tv_sec = tb.time;
1944 tv->tv_usec = tb.millitm * 1000L; 1947 tv->tv_usec = tb.millitm * 1000L;
1948 /* Implementation note: _ftime sometimes doesn't update the dstflag
1949 according to the new timezone when the system timezone is
1950 changed. We could fix that by using GetSystemTime and
1951 GetTimeZoneInformation, but that doesn't seem necessary, since
1952 Emacs always calls gettimeofday with the 2nd argument NULL (see
1953 EMACS_GET_TIME). */
1945 if (tz) 1954 if (tz)
1946 { 1955 {
1947 tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */ 1956 tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */
@@ -5678,6 +5687,19 @@ sys_write (int fd, const void * buffer, unsigned int count)
5678 return nchars; 5687 return nchars;
5679} 5688}
5680 5689
5690/* The Windows CRT functions are "optimized for speed", so they don't
5691 check for timezone and DST changes if they were last called less
5692 than 1 minute ago (see http://support.microsoft.com/kb/821231). So
5693 all Emacs features that repeatedly call time functions (e.g.,
5694 display-time) are in real danger of missing timezone and DST
5695 changes. Calling tzset before each localtime call fixes that. */
5696struct tm *
5697sys_localtime (const time_t *t)
5698{
5699 tzset ();
5700 return localtime (t);
5701}
5702
5681static void 5703static void
5682check_windows_init_file (void) 5704check_windows_init_file (void)
5683{ 5705{
@@ -6102,5 +6124,72 @@ serial_configure (struct Lisp_Process *p, Lisp_Object contact)
6102 p->childp = childp2; 6124 p->childp = childp2;
6103} 6125}
6104 6126
6105/* end of w32.c */ 6127#ifdef HAVE_GNUTLS
6128
6129ssize_t
6130emacs_gnutls_pull (gnutls_transport_ptr_t p, void* buf, size_t sz)
6131{
6132 int n, sc, err;
6133 SELECT_TYPE fdset;
6134 EMACS_TIME timeout;
6135 struct Lisp_Process *process = (struct Lisp_Process *)p;
6136 int fd = process->infd;
6137
6138 for (;;)
6139 {
6140 n = sys_read(fd, (char*)buf, sz);
6141
6142 if (n >= 0)
6143 return n;
6144
6145 err = errno;
6146
6147 if (err == EWOULDBLOCK)
6148 {
6149 /* Set a small timeout. */
6150 EMACS_SET_SECS_USECS(timeout, 1, 0);
6151 FD_ZERO (&fdset);
6152 FD_SET ((int)fd, &fdset);
6153
6154 /* Use select with the timeout to poll the selector. */
6155 sc = select (fd + 1, &fdset, (SELECT_TYPE *)0, (SELECT_TYPE *)0,
6156 &timeout);
6157
6158 if (sc > 0)
6159 continue; /* Try again. */
6160
6161 /* Translate the WSAEWOULDBLOCK alias EWOULDBLOCK to EAGAIN.
6162 Also accept select return 0 as an indicator to EAGAIN. */
6163 if (sc == 0 || errno == EWOULDBLOCK)
6164 err = EAGAIN;
6165 else
6166 err = errno; /* Other errors are just passed on. */
6167 }
6106 6168
6169 gnutls_transport_set_errno (process->gnutls_state, err);
6170
6171 return -1;
6172 }
6173}
6174
6175ssize_t
6176emacs_gnutls_push (gnutls_transport_ptr_t p, const void* buf, size_t sz)
6177{
6178 struct Lisp_Process *process = (struct Lisp_Process *)p;
6179 int fd = process->outfd;
6180 ssize_t n = sys_write(fd, buf, sz);
6181
6182 /* 0 or more bytes written means everything went fine. */
6183 if (n >= 0)
6184 return n;
6185
6186 /* Negative bytes written means we got an error in errno.
6187 Translate the WSAEWOULDBLOCK alias EWOULDBLOCK to EAGAIN. */
6188 gnutls_transport_set_errno (process->gnutls_state,
6189 errno == EWOULDBLOCK ? EAGAIN : errno);
6190
6191 return -1;
6192}
6193#endif /* HAVE_GNUTLS */
6194
6195/* end of w32.c */
diff --git a/src/w32.h b/src/w32.h
index 9279ddbe579..4086c4190e1 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -143,5 +143,17 @@ extern void syms_of_fontset (void);
143extern int _sys_read_ahead (int fd); 143extern int _sys_read_ahead (int fd);
144extern int _sys_wait_accept (int fd); 144extern int _sys_wait_accept (int fd);
145 145
146#ifdef HAVE_GNUTLS
147#include <gnutls/gnutls.h>
148
149/* GnuTLS pull (read from remote) interface. */
150extern ssize_t emacs_gnutls_pull (gnutls_transport_ptr_t p,
151 void* buf, size_t sz);
152
153/* GnuTLS push (write to remote) interface. */
154extern ssize_t emacs_gnutls_push (gnutls_transport_ptr_t p,
155 const void* buf, size_t sz);
156#endif /* HAVE_GNUTLS */
157
146#endif /* EMACS_W32_H */ 158#endif /* EMACS_W32_H */
147 159
diff --git a/src/xdisp.c b/src/xdisp.c
index b44c27335a6..6d3c142f62a 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -3855,7 +3855,7 @@ display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
3855} 3855}
3856 3856
3857 3857
3858/* Set up IT from a single `display' specification PROP. OBJECT 3858/* Set up IT from a single `display' property specification SPEC. OBJECT
3859 is the object in which the `display' property was found. *POSITION 3859 is the object in which the `display' property was found. *POSITION
3860 is the position at which it was found. DISPLAY_REPLACED_P non-zero 3860 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3861 means that we previously saw a display specification which already 3861 means that we previously saw a display specification which already
@@ -3865,7 +3865,7 @@ display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
3865 OVERLAY is the overlay this `display' property came from, 3865 OVERLAY is the overlay this `display' property came from,
3866 or nil if it was a text property. 3866 or nil if it was a text property.
3867 3867
3868 If PROP is a `space' or `image' specification, and in some other 3868 If SPEC is a `space' or `image' specification, and in some other
3869 cases too, set *POSITION to the position where the `display' 3869 cases too, set *POSITION to the position where the `display'
3870 property ends. 3870 property ends.
3871 3871
@@ -3875,7 +3875,7 @@ display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
3875static int 3875static int
3876handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, 3876handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
3877 Lisp_Object overlay, struct text_pos *position, 3877 Lisp_Object overlay, struct text_pos *position,
3878 int display_replaced_before_p) 3878 int display_replaced_p)
3879{ 3879{
3880 Lisp_Object form; 3880 Lisp_Object form;
3881 Lisp_Object location, value; 3881 Lisp_Object location, value;
@@ -4171,7 +4171,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4171#endif /* not HAVE_WINDOW_SYSTEM */ 4171#endif /* not HAVE_WINDOW_SYSTEM */
4172 || (CONSP (value) && EQ (XCAR (value), Qspace))); 4172 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4173 4173
4174 if (valid_p && !display_replaced_before_p) 4174 if (valid_p && !display_replaced_p)
4175 { 4175 {
4176 /* Save current settings of IT so that we can restore them 4176 /* Save current settings of IT so that we can restore them
4177 when we are finished with the glyph property value. */ 4177 when we are finished with the glyph property value. */
@@ -8373,22 +8373,10 @@ vmessage (const char *m, va_list ap)
8373 { 8373 {
8374 if (m) 8374 if (m)
8375 { 8375 {
8376 char *buf = FRAME_MESSAGE_BUF (f); 8376 size_t len;
8377 size_t bufsize = FRAME_MESSAGE_BUF_SIZE (f);
8378 int len;
8379 8377
8380 memset (buf, 0, bufsize); 8378 len = doprnt (FRAME_MESSAGE_BUF (f),
8381 len = vsnprintf (buf, bufsize, m, ap); 8379 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
8382
8383 /* Do any truncation at a character boundary. */
8384 if (! (0 <= len && len < bufsize))
8385 {
8386 char *end = memchr (buf, 0, bufsize);
8387 for (len = end ? end - buf : bufsize;
8388 len && ! CHAR_HEAD_P (buf[len - 1]);
8389 len--)
8390 continue;
8391 }
8392 8380
8393 message2 (FRAME_MESSAGE_BUF (f), len, 0); 8381 message2 (FRAME_MESSAGE_BUF (f), len, 0);
8394 } 8382 }
@@ -26997,6 +26985,7 @@ init_xdisp (void)
26997 26985
26998 mini_w = XWINDOW (minibuf_window); 26986 mini_w = XWINDOW (minibuf_window);
26999 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w))); 26987 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
26988 echo_area_window = minibuf_window;
27000 26989
27001 if (!noninteractive) 26990 if (!noninteractive)
27002 { 26991 {
diff --git a/src/xfaces.c b/src/xfaces.c
index 9721df04cab..a26289e8a88 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -331,7 +331,7 @@ Lisp_Object Qexpanded;
331static Lisp_Object Qultra_expanded; 331static Lisp_Object Qultra_expanded;
332static Lisp_Object Qreleased_button, Qpressed_button; 332static Lisp_Object Qreleased_button, Qpressed_button;
333static Lisp_Object QCstyle, QCcolor, QCline_width; 333static Lisp_Object QCstyle, QCcolor, QCline_width;
334static Lisp_Object Qunspecified; 334Lisp_Object Qunspecified; /* used in dosfns.c */
335static Lisp_Object Qignore_defface; 335static Lisp_Object Qignore_defface;
336 336
337char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg"; 337char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg";