diff options
| author | Paul Eggert | 2011-04-25 23:17:52 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-04-25 23:17:52 -0700 |
| commit | 671875dac181f7f1337f21d013a9c3d5f235ddf2 (patch) | |
| tree | 4091c2537439713df8efe8d3376116a6db3eb1c5 /src | |
| parent | f904488ff40dcee3e340b63a6386dde124d1241c (diff) | |
| parent | 0c6b7b19e52ba18b5d4fd2d4b73b133a0a721603 (diff) | |
| download | emacs-671875dac181f7f1337f21d013a9c3d5f235ddf2.tar.gz emacs-671875dac181f7f1337f21d013a9c3d5f235ddf2.zip | |
Merge from mainline.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 178 | ||||
| -rw-r--r-- | src/Makefile.in | 6 | ||||
| -rw-r--r-- | src/buffer.c | 3 | ||||
| -rw-r--r-- | src/callint.c | 7 | ||||
| -rw-r--r-- | src/character.c | 35 | ||||
| -rw-r--r-- | src/charset.c | 10 | ||||
| -rw-r--r-- | src/coding.c | 4 | ||||
| -rw-r--r-- | src/deps.mk | 4 | ||||
| -rw-r--r-- | src/dispextern.h | 2 | ||||
| -rw-r--r-- | src/doc.c | 4 | ||||
| -rw-r--r-- | src/doprnt.c | 193 | ||||
| -rw-r--r-- | src/eval.c | 30 | ||||
| -rw-r--r-- | src/font.c | 6 | ||||
| -rw-r--r-- | src/gnutls.c | 360 | ||||
| -rw-r--r-- | src/gnutls.h | 2 | ||||
| -rw-r--r-- | src/lisp.h | 3 | ||||
| -rw-r--r-- | src/makefile.w32-in | 16 | ||||
| -rw-r--r-- | src/msdos.c | 12 | ||||
| -rw-r--r-- | src/msdos.h | 8 | ||||
| -rw-r--r-- | src/process.c | 16 | ||||
| -rw-r--r-- | src/s/ms-w32.h | 1 | ||||
| -rw-r--r-- | src/syntax.c | 2 | ||||
| -rw-r--r-- | src/sysdep.c | 2 | ||||
| -rw-r--r-- | src/term.c | 4 | ||||
| -rw-r--r-- | src/textprop.c | 14 | ||||
| -rw-r--r-- | src/w32.c | 91 | ||||
| -rw-r--r-- | src/w32.h | 12 | ||||
| -rw-r--r-- | src/xdisp.c | 27 | ||||
| -rw-r--r-- | src/xfaces.c | 2 |
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 @@ | |||
| 1 | 2011-04-25 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2011-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 | ||
| 53 | 2011-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 | ||
| 57 | 2011-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 | ||
| 89 | 2011-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 | ||
| 185 | 2011-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 | |||
| 190 | 2011-04-25 Teodor Zlatanov <tzz@lifelogs.com> | ||
| 191 | |||
| 192 | * w32.c (emacs_gnutls_push): Fix typo. | ||
| 193 | |||
| 194 | 2011-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 | |||
| 208 | 2011-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 | |||
| 233 | 2011-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 | |||
| 243 | 2011-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 | |||
| 289 | 2011-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 | |||
| 337 | 2011-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 | |||
| 344 | 2011-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 | |||
| 350 | 2011-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 | |||
| 191 | 2011-04-19 Eli Zaretskii <eliz@gnu.org> | 355 | 2011-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) |
| 359 | obj = $(base_obj) $(NS_OBJC_OBJ) | 359 | obj = $(base_obj) $(NS_OBJC_OBJ) |
| 360 | 360 | ||
| @@ -748,10 +748,10 @@ extraclean: distclean | |||
| 748 | ctagsfiles1 = [xyzXYZ]*.[hcm] | 748 | ctagsfiles1 = [xyzXYZ]*.[hcm] |
| 749 | ctagsfiles2 = [a-wA-W]*.[hcm] | 749 | ctagsfiles2 = [a-wA-W]*.[hcm] |
| 750 | 750 | ||
| 751 | TAGS: $(srcdir)/$(ctagsfiles1) $(srcdir)/$(ctagsfiles2) | 751 | TAGS: $(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) |
| 755 | frc: | 755 | frc: |
| 756 | TAGS-LISP: frc | 756 | TAGS-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. |
| 5555 | This 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 | ||
| 31 | Lisp_Object Qminus, Qplus; | 32 | Lisp_Object Qminus, Qplus; |
| 32 | Lisp_Object Qcall_interactively; | 33 | Lisp_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 | ||
| 172 | int | 172 | int |
| @@ -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 | ||
| 215 | int | 214 | int |
| 216 | translate_char (Lisp_Object table, int c) | 215 | translate_char (Lisp_Object table, int c) |
| @@ -494,19 +493,6 @@ usage: (string-width STRING) */) | |||
| 494 | return val; | 493 | return val; |
| 495 | } | 494 | } |
| 496 | 495 | ||
| 497 | DEFUN ("char-direction", Fchar_direction, Schar_direction, 1, 1, 0, | ||
| 498 | doc: /* Return the direction of CHAR. | ||
| 499 | The returned value is 0 for left-to-right and 1 for right-to-left. | ||
| 500 | usage: (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) |
| 46 | callint.o: callint.c window.h commands.h buffer.h keymap.h globals.h msdos.h \ | 46 | callint.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) | ||
| 48 | callproc.o: callproc.c epaths.h buffer.h commands.h lisp.h $(config_h) \ | 49 | callproc.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. |
| 83 | doc.o: doc.c lisp.h $(config_h) buffer.h keyboard.h keymap.h \ | 84 | doc.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 |
| 86 | doprnt.o: doprnt.c character.h lisp.h globals.h ../lib/unistd.h $(config_h) | ||
| 85 | dosfns.o: buffer.h termchar.h termhooks.h frame.h blockinput.h window.h \ | 87 | dosfns.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. */ |
| 66 | typedef struct ns_display_info Display_Info; | 66 | typedef struct ns_display_info Display_Info; |
| 67 | typedef Pixmap XImagePtr; | 67 | typedef Pixmap XImagePtr; |
| 68 | typedef XImagePtr XImagePtr_or_DC; | 68 | typedef XImagePtr XImagePtr_or_DC; |
| @@ -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 ("\ |
| 257 | Invalid 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 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| @@ -18,6 +18,79 @@ GNU General Public License for more details. | |||
| 18 | You should have received a copy of the GNU General Public License | 18 | You should have received a copy of the GNU General Public License |
| 19 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | 19 | along 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 | ||
| 54 | EMACS_INT | 131 | size_t |
| 55 | doprnt (char *buffer, register int bufsize, const char *format, | 132 | doprnt (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 | |||
| 34 | static int | ||
| 35 | emacs_gnutls_handle_error (gnutls_session_t, int err); | ||
| 36 | |||
| 37 | Lisp_Object Qgnutls_log_level; | ||
| 29 | Lisp_Object Qgnutls_code; | 38 | Lisp_Object Qgnutls_code; |
| 30 | Lisp_Object Qgnutls_anon, Qgnutls_x509pki; | 39 | Lisp_Object Qgnutls_anon, Qgnutls_x509pki; |
| 31 | Lisp_Object Qgnutls_e_interrupted, Qgnutls_e_again, | 40 | Lisp_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; |
| 33 | int global_initialized; | 42 | int 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'. */ |
| 36 | Lisp_Object Qgnutls_bootprop_priority; | 45 | Lisp_Object Qgnutls_bootprop_priority; |
| @@ -38,8 +47,27 @@ Lisp_Object Qgnutls_bootprop_trustfiles; | |||
| 38 | Lisp_Object Qgnutls_bootprop_keyfiles; | 47 | Lisp_Object Qgnutls_bootprop_keyfiles; |
| 39 | Lisp_Object Qgnutls_bootprop_callbacks; | 48 | Lisp_Object Qgnutls_bootprop_callbacks; |
| 40 | Lisp_Object Qgnutls_bootprop_loglevel; | 49 | Lisp_Object Qgnutls_bootprop_loglevel; |
| 50 | Lisp_Object Qgnutls_bootprop_hostname; | ||
| 51 | Lisp_Object Qgnutls_bootprop_verify_flags; | ||
| 52 | Lisp_Object Qgnutls_bootprop_verify_error; | ||
| 53 | Lisp_Object Qgnutls_bootprop_verify_hostname_error; | ||
| 54 | |||
| 55 | /* Callback keys for `gnutls-boot'. Unused currently. */ | ||
| 56 | Lisp_Object Qgnutls_bootprop_callbacks_verify; | ||
| 41 | 57 | ||
| 42 | static void | 58 | static void |
| 59 | gnutls_log_function (int level, const char* string) | ||
| 60 | { | ||
| 61 | message ("gnutls.c: [%d] %s", level, string); | ||
| 62 | } | ||
| 63 | |||
| 64 | static void | ||
| 65 | gnutls_log_function2 (int level, const char* string, const char* extra) | ||
| 66 | { | ||
| 67 | message ("gnutls.c: [%d] %s %s", level, string, extra); | ||
| 68 | } | ||
| 69 | |||
| 70 | static int | ||
| 43 | emacs_gnutls_handshake (struct Lisp_Process *proc) | 71 | emacs_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 | ||
| 73 | EMACS_INT | 132 | EMACS_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. */ | ||
| 199 | static int | ||
| 200 | emacs_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'. */) | |||
| 262 | Call `gnutls-global-deinit' when GnuTLS usage is no longer needed. | 371 | Call `gnutls-global-deinit' when GnuTLS usage is no longer needed. |
| 263 | Returns zero on success. */ | 372 | Returns zero on success. */ |
| 264 | static Lisp_Object | 373 | static Lisp_Object |
| 265 | gnutls_emacs_global_init (void) | 374 | emacs_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. |
| 279 | See also `gnutls-global-init'. */ | 388 | See also `gnutls-global-init'. */ |
| 280 | static Lisp_Object | 389 | static Lisp_Object |
| 281 | gnutls_emacs_global_deinit (void) | 390 | emacs_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 | ||
| 292 | static void | ||
| 293 | gnutls_log_function (int level, const char* string) | ||
| 294 | { | ||
| 295 | message ("gnutls.c: [%d] %s", level, string); | ||
| 296 | } | ||
| 297 | |||
| 298 | static void | ||
| 299 | gnutls_log_function2 (int level, const char* string, const char* extra) | ||
| 300 | { | ||
| 301 | message ("gnutls.c: [%d] %s %s", level, string, extra); | ||
| 302 | } | ||
| 303 | |||
| 304 | DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 3, 0, | 401 | DEFUN ("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. |
| 306 | Currently only client mode is supported. Returns a success/failure | 403 | Currently only client mode is supported. Returns a success/failure |
| @@ -309,12 +406,27 @@ value you can check with `gnutls-errorp'. | |||
| 309 | TYPE is a symbol, either `gnutls-anon' or `gnutls-x509pki'. | 406 | TYPE is a symbol, either `gnutls-anon' or `gnutls-x509pki'. |
| 310 | PROPLIST is a property list with the following keys: | 407 | PROPLIST 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' | ||
| 422 | gnutls_certificate_set_verify_flags. | ||
| 423 | |||
| 424 | :verify-error, if non-nil, makes failure of the certificate validation | ||
| 425 | an error. Otherwise it will be just a series of warnings. | ||
| 426 | |||
| 427 | :verify-hostname-error, if non-nil, makes a hostname mismatch an | ||
| 428 | error. Otherwise it will be just a warning. | ||
| 429 | |||
| 318 | The debug level will be set for this process AND globally for GnuTLS. | 430 | The debug level will be set for this process AND globally for GnuTLS. |
| 319 | So if you set it higher or lower at any point, it affects global | 431 | So if you set it higher or lower at any point, it affects global |
| 320 | debugging. | 432 | debugging. |
| @@ -327,6 +439,9 @@ Processes must be initialized with this function before other GnuTLS | |||
| 327 | functions are used. This function allocates resources which can only | 439 | functions are used. This function allocates resources which can only |
| 328 | be deallocated by calling `gnutls-deinit' or by calling it again. | 440 | be deallocated by calling `gnutls-deinit' or by calling it again. |
| 329 | 441 | ||
| 442 | The callbacks alist can have a `verify' key, associated with a | ||
| 443 | verification function (UNUSED). | ||
| 444 | |||
| 330 | Each authentication type may need additional information in order to | 445 | Each authentication type may need additional information in order to |
| 331 | work. For X.509 PKI (`gnutls-x509pki'), you probably need at least | 446 | work. For X.509 PKI (`gnutls-x509pki'), you probably need at least |
| 332 | one trustfile (usually a CA bundle). */) | 447 | one 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 | ||
| 552 | DEFUN ("gnutls-bye", Fgnutls_bye, | 816 | DEFUN ("gnutls-bye", Fgnutls_bye, |
| @@ -581,7 +845,10 @@ This function may also return `gnutls-e-again', or | |||
| 581 | void | 845 | void |
| 582 | syms_of_gnutls (void) | 846 | syms_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 | ||
| 25 | typedef enum | 26 | typedef 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 | |||
| 2782 | extern void float_to_string (char *, double); | 2782 | extern void float_to_string (char *, double); |
| 2783 | extern void syms_of_print (void); | 2783 | extern void syms_of_print (void); |
| 2784 | 2784 | ||
| 2785 | /* Defined in doprnt.c */ | ||
| 2786 | extern size_t doprnt (char *, size_t, const char *, const char *, va_list); | ||
| 2787 | |||
| 2785 | /* Defined in lread.c. */ | 2788 | /* Defined in lread.c. */ |
| 2786 | extern Lisp_Object Qvariable_documentation, Qstandard_input; | 2789 | extern Lisp_Object Qvariable_documentation, Qstandard_input; |
| 2787 | extern Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction; | 2790 | extern 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 \ | |||
| 225 | obj = $(GLOBAL_SOURCES:.c=.o) | 227 | obj = $(GLOBAL_SOURCES:.c=.o) |
| 226 | 228 | ||
| 227 | globals.h: gl-stamp | 229 | globals.h: gl-stamp |
| 230 | @cmd /c rem true | ||
| 228 | 231 | ||
| 229 | gl-stamp: ../lib-src/$(BLD)/make-docfile.exe $(GLOBAL_SOURCES) | 232 | gl-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 | ||
| 332 | TAGS: $(OBJ0) $(OBJ1) $(OBJ2) | 335 | TAGS: $(OBJ0) $(OBJ1) $(OBJ2) $(CURDIR)/m/intel386.h $(CURDIR)/s/ms-w32.h |
| 333 | $(MAKE) $(MFLAGS) TAGS-$(MAKETYPE) | 336 | $(MAKE) $(MFLAGS) TAGS-$(MAKETYPE) |
| 334 | 337 | ||
| 335 | TAGS-LISP: $(OBJ0) $(OBJ1) $(OBJ2) | 338 | TAGS-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 | ||
| 348 | TAGS-nmake: | 351 | TAGS-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 | ||
| 848 | extern unsigned char *encode_terminal_code (struct glyph *, int, | 848 | extern 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. */ |
| 2815 | static char *menu_help_message, *prev_menu_help_message; | 2815 | static 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. */ |
| 2818 | static int menu_help_paneno, menu_help_itemno; | 2818 | static 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 | ||
| 3034 | int | 3034 | int |
| 3035 | XMenuAddSelection (Display *bar, XMenu *menu, int pane, | 3035 | XMenuAddSelection (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 | |||
| 3086 | int | 3086 | int |
| 3087 | XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx, | 3087 | XMenuActivate (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 | ||
| 107 | XMenu *XMenuCreate (Display *, Window, char *); | 107 | XMenu *XMenuCreate (Display *, Window, char *); |
| 108 | int XMenuAddPane (Display *, XMenu *, const char *, int); | 108 | int XMenuAddPane (Display *, XMenu *, char const *, int); |
| 109 | int XMenuAddSelection (Display *, XMenu *, int, int, char *, int, char *); | 109 | int XMenuAddSelection (Display *, XMenu *, int, int, char *, int, char const *); |
| 110 | void XMenuLocate (Display *, XMenu *, int, int, int, int, | 110 | void XMenuLocate (Display *, XMenu *, int, int, int, int, |
| 111 | int *, int *, int *, int *); | 111 | int *, int *, int *, int *); |
| 112 | int XMenuActivate (Display *, XMenu *, int *, int *, int, int, unsigned, | 112 | int XMenuActivate (Display *, XMenu *, int *, int *, int, int, unsigned, |
| 113 | char **, void (*callback)(char *, int, int)); | 113 | char **, void (*callback)(char const *, int, int)); |
| 114 | void XMenuDestroy (Display *, XMenu *); | 114 | void 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 | ||
| 3632 | static void | 3632 | static void |
| 3633 | maybe_fatal (int must_succeed, struct terminal *terminal, | 3633 | maybe_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 | } |
| @@ -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. */ | ||
| 5696 | struct tm * | ||
| 5697 | sys_localtime (const time_t *t) | ||
| 5698 | { | ||
| 5699 | tzset (); | ||
| 5700 | return localtime (t); | ||
| 5701 | } | ||
| 5702 | |||
| 5681 | static void | 5703 | static void |
| 5682 | check_windows_init_file (void) | 5704 | check_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 | |||
| 6129 | ssize_t | ||
| 6130 | emacs_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 | |||
| 6175 | ssize_t | ||
| 6176 | emacs_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 */ | ||
| @@ -143,5 +143,17 @@ extern void syms_of_fontset (void); | |||
| 143 | extern int _sys_read_ahead (int fd); | 143 | extern int _sys_read_ahead (int fd); |
| 144 | extern int _sys_wait_accept (int fd); | 144 | extern 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. */ | ||
| 150 | extern ssize_t emacs_gnutls_pull (gnutls_transport_ptr_t p, | ||
| 151 | void* buf, size_t sz); | ||
| 152 | |||
| 153 | /* GnuTLS push (write to remote) interface. */ | ||
| 154 | extern 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) | |||
| 3875 | static int | 3875 | static int |
| 3876 | handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | 3876 | handle_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; | |||
| 331 | static Lisp_Object Qultra_expanded; | 331 | static Lisp_Object Qultra_expanded; |
| 332 | static Lisp_Object Qreleased_button, Qpressed_button; | 332 | static Lisp_Object Qreleased_button, Qpressed_button; |
| 333 | static Lisp_Object QCstyle, QCcolor, QCline_width; | 333 | static Lisp_Object QCstyle, QCcolor, QCline_width; |
| 334 | static Lisp_Object Qunspecified; | 334 | Lisp_Object Qunspecified; /* used in dosfns.c */ |
| 335 | static Lisp_Object Qignore_defface; | 335 | static Lisp_Object Qignore_defface; |
| 336 | 336 | ||
| 337 | char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg"; | 337 | char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg"; |