diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 22 | ||||
| -rw-r--r-- | src/conf_post.h | 2 | ||||
| -rw-r--r-- | src/image.c | 11 | ||||
| -rw-r--r-- | src/keyboard.c | 7 | ||||
| -rw-r--r-- | src/search.c | 164 | ||||
| -rw-r--r-- | src/xgselect.c | 25 |
6 files changed, 213 insertions, 18 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index bb2e2bad555..fdbf922173b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,25 @@ | |||
| 1 | 2014-04-22 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Port to GCC 4.9.0 with --enable-gcc-warnings. | ||
| 4 | * image.c (struct my_jpeg_error_mgr) [lint]: Remove member fp. | ||
| 5 | All uses removed. | ||
| 6 | (jpeg_load_body) [lint]: Add a 'volatile' to pacify a buggy GCC in | ||
| 7 | a way that also works with GCC 4.9.0. | ||
| 8 | |||
| 9 | * search.c (Fnewline_cache_check): Remove unused locals. | ||
| 10 | |||
| 11 | 2014-04-22 Eli Zaretskii <eliz@gnu.org> | ||
| 12 | |||
| 13 | * search.c (find_newline1): New subroutine. | ||
| 14 | (Fnewline_cache_check): New function. | ||
| 15 | (syms_of_search): Defsubr it. | ||
| 16 | |||
| 17 | 2014-04-22 Jarek Czekalski <jarekczek@poczta.onet.pl> | ||
| 18 | |||
| 19 | Fix freezing with scroll bars of GTK3 Toolkit (bug#15801). | ||
| 20 | * keyboard.c (unblock_input): Add comment. | ||
| 21 | * xgselect.c (xg_select): Prevent Glib main loop recursion. | ||
| 22 | |||
| 1 | 2014-04-22 Daniel Colascione <dancol@dancol.org> | 23 | 2014-04-22 Daniel Colascione <dancol@dancol.org> |
| 2 | 24 | ||
| 3 | * lread.c (readevalloop_eager_expand_eval): New function | 25 | * lread.c (readevalloop_eager_expand_eval): New function |
diff --git a/src/conf_post.h b/src/conf_post.h index e9101ce1c57..2e78c2f5e25 100644 --- a/src/conf_post.h +++ b/src/conf_post.h | |||
| @@ -119,7 +119,7 @@ You lose; /* Emacs for DOS must be compiled with DJGPP */ | |||
| 119 | #endif | 119 | #endif |
| 120 | 120 | ||
| 121 | /* We must intercept 'opendir' calls to stash away the directory name, | 121 | /* We must intercept 'opendir' calls to stash away the directory name, |
| 122 | so we could reuse it in realinkat, see msdos.c. */ | 122 | so we could reuse it in readlinkat; see msdos.c. */ |
| 123 | #define opendir sys_opendir | 123 | #define opendir sys_opendir |
| 124 | 124 | ||
| 125 | /* The "portable" definition of _GL_INLINE on config.h does not work | 125 | /* The "portable" definition of _GL_INLINE on config.h does not work |
diff --git a/src/image.c b/src/image.c index bfbdfbc86b2..d558540c6e7 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -6262,9 +6262,6 @@ struct my_jpeg_error_mgr | |||
| 6262 | MY_JPEG_INVALID_IMAGE_SIZE, | 6262 | MY_JPEG_INVALID_IMAGE_SIZE, |
| 6263 | MY_JPEG_CANNOT_CREATE_X | 6263 | MY_JPEG_CANNOT_CREATE_X |
| 6264 | } failure_code; | 6264 | } failure_code; |
| 6265 | #ifdef lint | ||
| 6266 | FILE *fp; | ||
| 6267 | #endif | ||
| 6268 | }; | 6265 | }; |
| 6269 | 6266 | ||
| 6270 | 6267 | ||
| @@ -6479,7 +6476,8 @@ jpeg_load_body (struct frame *f, struct image *img, | |||
| 6479 | { | 6476 | { |
| 6480 | Lisp_Object file, specified_file; | 6477 | Lisp_Object file, specified_file; |
| 6481 | Lisp_Object specified_data; | 6478 | Lisp_Object specified_data; |
| 6482 | FILE *fp = NULL; | 6479 | /* The 'volatile' silences a bogus diagnostic; see GCC bug 54561. */ |
| 6480 | FILE * IF_LINT (volatile) fp = NULL; | ||
| 6483 | JSAMPARRAY buffer; | 6481 | JSAMPARRAY buffer; |
| 6484 | int row_stride, x, y; | 6482 | int row_stride, x, y; |
| 6485 | XImagePtr ximg = NULL; | 6483 | XImagePtr ximg = NULL; |
| @@ -6512,8 +6510,6 @@ jpeg_load_body (struct frame *f, struct image *img, | |||
| 6512 | return 0; | 6510 | return 0; |
| 6513 | } | 6511 | } |
| 6514 | 6512 | ||
| 6515 | IF_LINT (mgr->fp = fp); | ||
| 6516 | |||
| 6517 | /* Customize libjpeg's error handling to call my_error_exit when an | 6513 | /* Customize libjpeg's error handling to call my_error_exit when an |
| 6518 | error is detected. This function will perform a longjmp. */ | 6514 | error is detected. This function will perform a longjmp. */ |
| 6519 | mgr->cinfo.err = fn_jpeg_std_error (&mgr->pub); | 6515 | mgr->cinfo.err = fn_jpeg_std_error (&mgr->pub); |
| @@ -6552,9 +6548,6 @@ jpeg_load_body (struct frame *f, struct image *img, | |||
| 6552 | return 0; | 6548 | return 0; |
| 6553 | } | 6549 | } |
| 6554 | 6550 | ||
| 6555 | /* Silence a bogus diagnostic; see GCC bug 54561. */ | ||
| 6556 | IF_LINT (fp = mgr->fp); | ||
| 6557 | |||
| 6558 | /* Create the JPEG decompression object. Let it read from fp. | 6551 | /* Create the JPEG decompression object. Let it read from fp. |
| 6559 | Read the JPEG image header. */ | 6552 | Read the JPEG image header. */ |
| 6560 | fn_jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo); | 6553 | fn_jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo); |
diff --git a/src/keyboard.c b/src/keyboard.c index 678cf5abcbd..705e9191c61 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -7117,7 +7117,12 @@ unblock_input_to (int level) | |||
| 7117 | /* End critical section. | 7117 | /* End critical section. |
| 7118 | 7118 | ||
| 7119 | If doing signal-driven input, and a signal came in when input was | 7119 | If doing signal-driven input, and a signal came in when input was |
| 7120 | blocked, reinvoke the signal handler now to deal with it. */ | 7120 | blocked, reinvoke the signal handler now to deal with it. |
| 7121 | |||
| 7122 | It will also process queued input, if it was not read before. | ||
| 7123 | When a longer code sequence does not use block/unblock input | ||
| 7124 | at all, the whole input gathered up to the next call to | ||
| 7125 | unblock_input will be processed inside that call. */ | ||
| 7121 | 7126 | ||
| 7122 | void | 7127 | void |
| 7123 | unblock_input (void) | 7128 | unblock_input (void) |
diff --git a/src/search.c b/src/search.c index 9bec825abcd..ee449213ace 100644 --- a/src/search.c +++ b/src/search.c | |||
| @@ -3098,6 +3098,169 @@ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0, | |||
| 3098 | out - temp, | 3098 | out - temp, |
| 3099 | STRING_MULTIBYTE (string)); | 3099 | STRING_MULTIBYTE (string)); |
| 3100 | } | 3100 | } |
| 3101 | |||
| 3102 | /* Like find_newline, but doesn't use the cache, and only searches forward. */ | ||
| 3103 | static ptrdiff_t | ||
| 3104 | find_newline1 (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end, | ||
| 3105 | ptrdiff_t end_byte, ptrdiff_t count, ptrdiff_t *shortage, | ||
| 3106 | ptrdiff_t *bytepos, bool allow_quit) | ||
| 3107 | { | ||
| 3108 | if (count > 0) | ||
| 3109 | { | ||
| 3110 | if (!end) | ||
| 3111 | end = ZV, end_byte = ZV_BYTE; | ||
| 3112 | } | ||
| 3113 | else | ||
| 3114 | { | ||
| 3115 | if (!end) | ||
| 3116 | end = BEGV, end_byte = BEGV_BYTE; | ||
| 3117 | } | ||
| 3118 | if (end_byte == -1) | ||
| 3119 | end_byte = CHAR_TO_BYTE (end); | ||
| 3120 | |||
| 3121 | if (shortage != 0) | ||
| 3122 | *shortage = 0; | ||
| 3123 | |||
| 3124 | immediate_quit = allow_quit; | ||
| 3125 | |||
| 3126 | if (count > 0) | ||
| 3127 | while (start != end) | ||
| 3128 | { | ||
| 3129 | /* Our innermost scanning loop is very simple; it doesn't know | ||
| 3130 | about gaps, buffer ends, or the newline cache. ceiling is | ||
| 3131 | the position of the last character before the next such | ||
| 3132 | obstacle --- the last character the dumb search loop should | ||
| 3133 | examine. */ | ||
| 3134 | ptrdiff_t tem, ceiling_byte = end_byte - 1; | ||
| 3135 | |||
| 3136 | if (start_byte == -1) | ||
| 3137 | start_byte = CHAR_TO_BYTE (start); | ||
| 3138 | |||
| 3139 | /* The dumb loop can only scan text stored in contiguous | ||
| 3140 | bytes. BUFFER_CEILING_OF returns the last character | ||
| 3141 | position that is contiguous, so the ceiling is the | ||
| 3142 | position after that. */ | ||
| 3143 | tem = BUFFER_CEILING_OF (start_byte); | ||
| 3144 | ceiling_byte = min (tem, ceiling_byte); | ||
| 3145 | |||
| 3146 | { | ||
| 3147 | /* The termination address of the dumb loop. */ | ||
| 3148 | unsigned char *lim_addr = BYTE_POS_ADDR (ceiling_byte) + 1; | ||
| 3149 | ptrdiff_t lim_byte = ceiling_byte + 1; | ||
| 3150 | |||
| 3151 | /* Nonpositive offsets (relative to LIM_ADDR and LIM_BYTE) | ||
| 3152 | of the base, the cursor, and the next line. */ | ||
| 3153 | ptrdiff_t base = start_byte - lim_byte; | ||
| 3154 | ptrdiff_t cursor, next; | ||
| 3155 | |||
| 3156 | for (cursor = base; cursor < 0; cursor = next) | ||
| 3157 | { | ||
| 3158 | /* The dumb loop. */ | ||
| 3159 | unsigned char *nl = memchr (lim_addr + cursor, '\n', - cursor); | ||
| 3160 | next = nl ? nl - lim_addr : 0; | ||
| 3161 | |||
| 3162 | if (! nl) | ||
| 3163 | break; | ||
| 3164 | next++; | ||
| 3165 | |||
| 3166 | if (--count == 0) | ||
| 3167 | { | ||
| 3168 | immediate_quit = 0; | ||
| 3169 | if (bytepos) | ||
| 3170 | *bytepos = lim_byte + next; | ||
| 3171 | return BYTE_TO_CHAR (lim_byte + next); | ||
| 3172 | } | ||
| 3173 | } | ||
| 3174 | |||
| 3175 | start_byte = lim_byte; | ||
| 3176 | start = BYTE_TO_CHAR (start_byte); | ||
| 3177 | } | ||
| 3178 | } | ||
| 3179 | |||
| 3180 | immediate_quit = 0; | ||
| 3181 | if (shortage) | ||
| 3182 | *shortage = count; | ||
| 3183 | if (bytepos) | ||
| 3184 | { | ||
| 3185 | *bytepos = start_byte == -1 ? CHAR_TO_BYTE (start) : start_byte; | ||
| 3186 | eassert (*bytepos == CHAR_TO_BYTE (start)); | ||
| 3187 | } | ||
| 3188 | return start; | ||
| 3189 | } | ||
| 3190 | |||
| 3191 | DEFUN ("newline-cache-check", Fnewline_cache_check, Snewline_cache_check, | ||
| 3192 | 0, 1, 0, | ||
| 3193 | doc: /* Check the newline cache of BUFFER against buffer contents. | ||
| 3194 | |||
| 3195 | BUFFER defaults to the current buffer. | ||
| 3196 | |||
| 3197 | Value is an array of 2 sub-arrays of buffer positions for newlines, | ||
| 3198 | the first based on the cache, the second based on actually scanning | ||
| 3199 | the buffer. If the buffer doesn't have a cache, the value is nil. */) | ||
| 3200 | (Lisp_Object buffer) | ||
| 3201 | { | ||
| 3202 | struct buffer *buf; | ||
| 3203 | ptrdiff_t shortage, nl_count_cache, nl_count_buf; | ||
| 3204 | Lisp_Object cache_newlines, buf_newlines, val; | ||
| 3205 | ptrdiff_t from, found, i; | ||
| 3206 | |||
| 3207 | if (NILP (buffer)) | ||
| 3208 | buf = current_buffer; | ||
| 3209 | else | ||
| 3210 | { | ||
| 3211 | CHECK_BUFFER (buffer); | ||
| 3212 | buf = XBUFFER (buffer); | ||
| 3213 | } | ||
| 3214 | if (buf->base_buffer) | ||
| 3215 | buf = buf->base_buffer; | ||
| 3216 | |||
| 3217 | /* If the buffer doesn't have a newline cache, return nil. */ | ||
| 3218 | if (NILP (BVAR (buf, cache_long_scans)) | ||
| 3219 | || buf->newline_cache == NULL) | ||
| 3220 | return Qnil; | ||
| 3221 | |||
| 3222 | /* How many newlines are there according to the cache? */ | ||
| 3223 | find_newline (BUF_BEG (buf), BUF_BEG_BYTE (buf), | ||
| 3224 | BUF_Z (buf), BUF_Z_BYTE (buf), | ||
| 3225 | TYPE_MAXIMUM (ptrdiff_t), &shortage, NULL, true); | ||
| 3226 | nl_count_cache = TYPE_MAXIMUM (ptrdiff_t) - shortage; | ||
| 3227 | |||
| 3228 | /* Create vector and populate it. */ | ||
| 3229 | cache_newlines = make_uninit_vector (nl_count_cache); | ||
| 3230 | for (from = BUF_BEG( buf), found = from, i = 0; | ||
| 3231 | from < BUF_Z (buf); | ||
| 3232 | from = found, i++) | ||
| 3233 | { | ||
| 3234 | ptrdiff_t from_byte = CHAR_TO_BYTE (from); | ||
| 3235 | |||
| 3236 | found = find_newline (from, from_byte, 0, -1, 1, &shortage, NULL, true); | ||
| 3237 | if (shortage == 0) | ||
| 3238 | ASET (cache_newlines, i, make_number (found - 1)); | ||
| 3239 | } | ||
| 3240 | |||
| 3241 | /* Now do the same, but without using the cache. */ | ||
| 3242 | find_newline1 (BUF_BEG (buf), BUF_BEG_BYTE (buf), | ||
| 3243 | BUF_Z (buf), BUF_Z_BYTE (buf), | ||
| 3244 | TYPE_MAXIMUM (ptrdiff_t), &shortage, NULL, true); | ||
| 3245 | nl_count_buf = TYPE_MAXIMUM (ptrdiff_t) - shortage; | ||
| 3246 | buf_newlines = make_uninit_vector (nl_count_buf); | ||
| 3247 | for (from = BUF_BEG( buf), found = from, i = 0; | ||
| 3248 | from < BUF_Z (buf); | ||
| 3249 | from = found, i++) | ||
| 3250 | { | ||
| 3251 | ptrdiff_t from_byte = CHAR_TO_BYTE (from); | ||
| 3252 | |||
| 3253 | found = find_newline1 (from, from_byte, 0, -1, 1, &shortage, NULL, true); | ||
| 3254 | if (shortage == 0) | ||
| 3255 | ASET (buf_newlines, i, make_number (found - 1)); | ||
| 3256 | } | ||
| 3257 | |||
| 3258 | /* Construct the value and return it. */ | ||
| 3259 | val = make_uninit_vector (2); | ||
| 3260 | ASET (val, 0, cache_newlines); | ||
| 3261 | ASET (val, 1, buf_newlines); | ||
| 3262 | return val; | ||
| 3263 | } | ||
| 3101 | 3264 | ||
| 3102 | void | 3265 | void |
| 3103 | syms_of_search (void) | 3266 | syms_of_search (void) |
| @@ -3170,4 +3333,5 @@ is to bind it with `let' around a small expression. */); | |||
| 3170 | defsubr (&Smatch_data); | 3333 | defsubr (&Smatch_data); |
| 3171 | defsubr (&Sset_match_data); | 3334 | defsubr (&Sset_match_data); |
| 3172 | defsubr (&Sregexp_quote); | 3335 | defsubr (&Sregexp_quote); |
| 3336 | defsubr (&Snewline_cache_check); | ||
| 3173 | } | 3337 | } |
diff --git a/src/xgselect.c b/src/xgselect.c index 5f71ff84014..bf889a90e97 100644 --- a/src/xgselect.c +++ b/src/xgselect.c | |||
| @@ -28,6 +28,18 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 28 | #include <stdbool.h> | 28 | #include <stdbool.h> |
| 29 | #include <timespec.h> | 29 | #include <timespec.h> |
| 30 | #include "frame.h" | 30 | #include "frame.h" |
| 31 | #include "blockinput.h" | ||
| 32 | |||
| 33 | /* `xg_select' is a `pselect' replacement. Why do we need a separate function? | ||
| 34 | 1. Timeouts. Glib and Gtk rely on timer events. If we did pselect | ||
| 35 | with a greater timeout then the one scheduled by Glib, we would | ||
| 36 | not allow Glib to process its timer events. We want Glib to | ||
| 37 | work smoothly, so we need to reduce our timeout to match Glib. | ||
| 38 | 2. Descriptors. Glib may listen to more file descriptors than we do. | ||
| 39 | So we add Glib descriptors to our pselect pool, but we don't change | ||
| 40 | the value returned by the function. The return value matches only | ||
| 41 | the descriptors passed as arguments, making it compatible with | ||
| 42 | plain pselect. */ | ||
| 31 | 43 | ||
| 32 | int | 44 | int |
| 33 | xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, | 45 | xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, |
| @@ -47,12 +59,6 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, | |||
| 47 | bool need_to_dispatch; | 59 | bool need_to_dispatch; |
| 48 | USE_SAFE_ALLOCA; | 60 | USE_SAFE_ALLOCA; |
| 49 | 61 | ||
| 50 | /* Do not try to optimize with an initial check with g_main_context_pending | ||
| 51 | and a call to pselect if it returns false. If Gdk has a timeout for 0.01 | ||
| 52 | second, and Emacs has a timeout for 1 second, g_main_context_pending will | ||
| 53 | return false, but the timeout will be 1 second, thus missing the gdk | ||
| 54 | timeout with a lot. */ | ||
| 55 | |||
| 56 | context = g_main_context_default (); | 62 | context = g_main_context_default (); |
| 57 | 63 | ||
| 58 | if (rfds) all_rfds = *rfds; | 64 | if (rfds) all_rfds = *rfds; |
| @@ -136,8 +142,13 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, | |||
| 136 | if (need_to_dispatch) | 142 | if (need_to_dispatch) |
| 137 | { | 143 | { |
| 138 | int pselect_errno = errno; | 144 | int pselect_errno = errno; |
| 145 | /* Prevent g_main_dispatch recursion, that would occur without | ||
| 146 | block_input wrapper, because event handlers call | ||
| 147 | unblock_input. Event loop recursion was causing Bug#15801. */ | ||
| 148 | block_input (); | ||
| 139 | while (g_main_context_pending (context)) | 149 | while (g_main_context_pending (context)) |
| 140 | g_main_context_dispatch (context); | 150 | g_main_context_dispatch (context); |
| 151 | unblock_input (); | ||
| 141 | errno = pselect_errno; | 152 | errno = pselect_errno; |
| 142 | } | 153 | } |
| 143 | 154 | ||