diff options
| author | Paul Eggert | 2017-04-06 15:05:13 -0700 |
|---|---|---|
| committer | Paul Eggert | 2017-04-06 15:05:38 -0700 |
| commit | 451a0c8b6955006f5aaa8b660a9e0b935b4fa095 (patch) | |
| tree | dcec5107dc369c52eae279023b30153c9bc1463d /src | |
| parent | f3a0f3a1167237c543b95c7b0a59c0a7bf8434dc (diff) | |
| download | emacs-451a0c8b6955006f5aaa8b660a9e0b935b4fa095.tar.gz emacs-451a0c8b6955006f5aaa8b660a9e0b935b4fa095.zip | |
Minor casefiddle.c cleanups
* src/casefiddle.c: Redo recent changes to match GNU style,
and prefer C99-style decls within blocks.
(GREEK_CAPITAL_LETTER_SIGMA): Rename from CAPITAL_SIGMA, so that
we are merely using the Unicode name, and make it a constant
rather than a macro. All uses changed.
(SMALL_SIGMA): Remove; unused.
(GREEK_SMALL_LETTER_FINAL_SIGMA): Rename from SMALL_FINAL_SIGMA,
and make it a constant rather than a macro. All uses changed.
(do_casify_multibyte_string): Use ‘verify’ rather than an
unportable static_assertion local.
Diffstat (limited to 'src')
| -rw-r--r-- | src/casefiddle.c | 200 |
1 files changed, 102 insertions, 98 deletions
diff --git a/src/casefiddle.c b/src/casefiddle.c index 6fe584b8302..3b550470bf3 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c | |||
| @@ -33,24 +33,30 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 33 | enum case_action {CASE_UP, CASE_DOWN, CASE_CAPITALIZE, CASE_CAPITALIZE_UP}; | 33 | enum case_action {CASE_UP, CASE_DOWN, CASE_CAPITALIZE, CASE_CAPITALIZE_UP}; |
| 34 | 34 | ||
| 35 | /* State for casing individual characters. */ | 35 | /* State for casing individual characters. */ |
| 36 | struct casing_context { | 36 | struct casing_context |
| 37 | { | ||
| 37 | /* A char-table with title-case character mappings or nil. Non-nil implies | 38 | /* A char-table with title-case character mappings or nil. Non-nil implies |
| 38 | flag is CASE_CAPITALIZE or CASE_CAPITALIZE_UP. */ | 39 | flag is CASE_CAPITALIZE or CASE_CAPITALIZE_UP. */ |
| 39 | Lisp_Object titlecase_char_table; | 40 | Lisp_Object titlecase_char_table; |
| 41 | |||
| 40 | /* The unconditional special-casing Unicode property char tables for upper | 42 | /* The unconditional special-casing Unicode property char tables for upper |
| 41 | casing, lower casing and title casing respectively. */ | 43 | casing, lower casing and title casing respectively. */ |
| 42 | Lisp_Object specialcase_char_tables[3]; | 44 | Lisp_Object specialcase_char_tables[3]; |
| 43 | /* User-requested action. */ | 45 | |
| 46 | /* User-requested action. */ | ||
| 44 | enum case_action flag; | 47 | enum case_action flag; |
| 45 | /* If true, function operates on a buffer as opposed to a string or character. | 48 | |
| 46 | When run on a buffer, syntax_prefix_flag_p is taken into account when | 49 | /* If true, the function operates on a buffer as opposed to a string |
| 47 | determined inword flag. */ | 50 | or character. When run on a buffer, syntax_prefix_flag_p is |
| 51 | taken into account when determining whether the context is within | ||
| 52 | a word. */ | ||
| 48 | bool inbuffer; | 53 | bool inbuffer; |
| 49 | /* Whether we are inside of a word. */ | 54 | |
| 55 | /* Whether the context is within a word. */ | ||
| 50 | bool inword; | 56 | bool inword; |
| 51 | }; | 57 | }; |
| 52 | 58 | ||
| 53 | /* Initialise CTX structure for casing characters. */ | 59 | /* Initialize CTX structure for casing characters. */ |
| 54 | static void | 60 | static void |
| 55 | prepare_casing_context (struct casing_context *ctx, | 61 | prepare_casing_context (struct casing_context *ctx, |
| 56 | enum case_action flag, bool inbuffer) | 62 | enum case_action flag, bool inbuffer) |
| @@ -58,26 +64,30 @@ prepare_casing_context (struct casing_context *ctx, | |||
| 58 | ctx->flag = flag; | 64 | ctx->flag = flag; |
| 59 | ctx->inbuffer = inbuffer; | 65 | ctx->inbuffer = inbuffer; |
| 60 | ctx->inword = false; | 66 | ctx->inword = false; |
| 61 | ctx->titlecase_char_table = (int)flag < (int)CASE_CAPITALIZE ? Qnil : | 67 | ctx->titlecase_char_table |
| 62 | uniprop_table (intern_c_string ("titlecase")); | 68 | = (flag < CASE_CAPITALIZE ? Qnil |
| 63 | ctx->specialcase_char_tables[CASE_UP] = flag == CASE_DOWN ? Qnil : | 69 | : uniprop_table (intern_c_string ("titlecase"))); |
| 64 | uniprop_table (intern_c_string ("special-uppercase")); | 70 | ctx->specialcase_char_tables[CASE_UP] |
| 65 | ctx->specialcase_char_tables[CASE_DOWN] = flag == CASE_UP ? Qnil : | 71 | = (flag == CASE_DOWN ? Qnil |
| 66 | uniprop_table (intern_c_string ("special-lowercase")); | 72 | : uniprop_table (intern_c_string ("special-uppercase"))); |
| 67 | ctx->specialcase_char_tables[CASE_CAPITALIZE] = | 73 | ctx->specialcase_char_tables[CASE_DOWN] |
| 68 | (int)flag < (int)CASE_CAPITALIZE ? Qnil : | 74 | = (flag == CASE_UP ? Qnil |
| 69 | uniprop_table (intern_c_string ("special-titlecase")); | 75 | : uniprop_table (intern_c_string ("special-lowercase"))); |
| 76 | ctx->specialcase_char_tables[CASE_CAPITALIZE] | ||
| 77 | = (flag < CASE_CAPITALIZE ? Qnil | ||
| 78 | : uniprop_table (intern_c_string ("special-titlecase"))); | ||
| 70 | 79 | ||
| 71 | /* If the case table is flagged as modified, rescan it. */ | 80 | /* If the case table is flagged as modified, rescan it. */ |
| 72 | if (NILP (XCHAR_TABLE (BVAR (current_buffer, downcase_table))->extras[1])) | 81 | if (NILP (XCHAR_TABLE (BVAR (current_buffer, downcase_table))->extras[1])) |
| 73 | Fset_case_table (BVAR (current_buffer, downcase_table)); | 82 | Fset_case_table (BVAR (current_buffer, downcase_table)); |
| 74 | 83 | ||
| 75 | if (inbuffer && (int) flag >= (int) CASE_CAPITALIZE) | 84 | if (inbuffer && flag >= CASE_CAPITALIZE) |
| 76 | SETUP_BUFFER_SYNTAX_TABLE (); /* For syntax_prefix_flag_p. */ | 85 | SETUP_BUFFER_SYNTAX_TABLE (); /* For syntax_prefix_flag_p. */ |
| 77 | } | 86 | } |
| 78 | 87 | ||
| 79 | struct casing_str_buf { | 88 | struct casing_str_buf |
| 80 | unsigned char data[MAX_MULTIBYTE_LENGTH > 6 ? MAX_MULTIBYTE_LENGTH : 6]; | 89 | { |
| 90 | unsigned char data[max (6, MAX_MULTIBYTE_LENGTH)]; | ||
| 81 | unsigned char len_chars; | 91 | unsigned char len_chars; |
| 82 | unsigned char len_bytes; | 92 | unsigned char len_bytes; |
| 83 | }; | 93 | }; |
| @@ -87,24 +97,23 @@ struct casing_str_buf { | |||
| 87 | character has been changed. | 97 | character has been changed. |
| 88 | 98 | ||
| 89 | Since meaning of return value depends on arguments, it’s more convenient to | 99 | Since meaning of return value depends on arguments, it’s more convenient to |
| 90 | use case_single_character or case_character instead. */ | 100 | use case_single_character or case_character instead. */ |
| 91 | static int | 101 | static int |
| 92 | case_character_impl (struct casing_str_buf *buf, | 102 | case_character_impl (struct casing_str_buf *buf, |
| 93 | struct casing_context *ctx, int ch) | 103 | struct casing_context *ctx, int ch) |
| 94 | { | 104 | { |
| 95 | enum case_action flag; | 105 | enum case_action flag; |
| 96 | Lisp_Object prop; | 106 | Lisp_Object prop; |
| 97 | bool was_inword; | ||
| 98 | int cased; | 107 | int cased; |
| 99 | 108 | ||
| 100 | /* Update inword state */ | 109 | /* Update inword state */ |
| 101 | was_inword = ctx->inword; | 110 | bool was_inword = ctx->inword; |
| 102 | ctx->inword = SYNTAX (ch) == Sword && | 111 | ctx->inword = SYNTAX (ch) == Sword && |
| 103 | (!ctx->inbuffer || was_inword || !syntax_prefix_flag_p (ch)); | 112 | (!ctx->inbuffer || was_inword || !syntax_prefix_flag_p (ch)); |
| 104 | 113 | ||
| 105 | /* Normalise flag so its one of CASE_UP, CASE_DOWN or CASE_CAPITALIZE. */ | 114 | /* Normalize flag so its one of CASE_UP, CASE_DOWN or CASE_CAPITALIZE. */ |
| 106 | if (ctx->flag == CASE_CAPITALIZE) | 115 | if (ctx->flag == CASE_CAPITALIZE) |
| 107 | flag = (enum case_action)((int)ctx->flag - was_inword); | 116 | flag = ctx->flag - was_inword; |
| 108 | else if (ctx->flag != CASE_CAPITALIZE_UP) | 117 | else if (ctx->flag != CASE_CAPITALIZE_UP) |
| 109 | flag = ctx->flag; | 118 | flag = ctx->flag; |
| 110 | else if (!was_inword) | 119 | else if (!was_inword) |
| @@ -115,33 +124,34 @@ case_character_impl (struct casing_str_buf *buf, | |||
| 115 | goto done; | 124 | goto done; |
| 116 | } | 125 | } |
| 117 | 126 | ||
| 118 | /* Look through the special casing entries. */ | 127 | /* Look through the special casing entries. */ |
| 119 | if (buf && !NILP(ctx->specialcase_char_tables[(int)flag])) | 128 | if (buf && !NILP (ctx->specialcase_char_tables[(int)flag])) |
| 120 | { | 129 | { |
| 121 | prop = CHAR_TABLE_REF(ctx->specialcase_char_tables[(int)flag], ch); | 130 | prop = CHAR_TABLE_REF (ctx->specialcase_char_tables[(int)flag], ch); |
| 122 | if (STRINGP(prop)) | 131 | if (STRINGP (prop)) |
| 123 | { | 132 | { |
| 124 | struct Lisp_String *str = XSTRING(prop); | 133 | struct Lisp_String *str = XSTRING (prop); |
| 125 | if (STRING_BYTES(str) <= sizeof buf->data) | 134 | if (STRING_BYTES (str) <= sizeof buf->data) |
| 126 | { | 135 | { |
| 127 | buf->len_chars = str->size; | 136 | buf->len_chars = str->size; |
| 128 | buf->len_bytes = STRING_BYTES(str); | 137 | buf->len_bytes = STRING_BYTES (str); |
| 129 | memcpy(buf->data, str->data, buf->len_bytes); | 138 | memcpy (buf->data, str->data, buf->len_bytes); |
| 130 | return 1; | 139 | return 1; |
| 131 | } | 140 | } |
| 132 | } | 141 | } |
| 133 | } | 142 | } |
| 134 | 143 | ||
| 135 | /* Handle simple, one-to-one case. */ | 144 | /* Handle simple, one-to-one case. */ |
| 136 | if (flag == CASE_DOWN) | 145 | if (flag == CASE_DOWN) |
| 137 | cased = downcase (ch); | 146 | cased = downcase (ch); |
| 138 | else if (!NILP (ctx->titlecase_char_table) && | 147 | else if (!NILP (ctx->titlecase_char_table) |
| 139 | CHARACTERP (prop = CHAR_TABLE_REF (ctx->titlecase_char_table, ch))) | 148 | && CHARACTERP (prop |
| 149 | = CHAR_TABLE_REF (ctx->titlecase_char_table, ch))) | ||
| 140 | cased = XFASTINT (prop); | 150 | cased = XFASTINT (prop); |
| 141 | else | 151 | else |
| 142 | cased = upcase(ch); | 152 | cased = upcase (ch); |
| 143 | 153 | ||
| 144 | /* And we’re done. */ | 154 | /* And we’re done. */ |
| 145 | done: | 155 | done: |
| 146 | if (!buf) | 156 | if (!buf) |
| 147 | return cased; | 157 | return cased; |
| @@ -155,18 +165,17 @@ case_character_impl (struct casing_str_buf *buf, | |||
| 155 | casing. | 165 | casing. |
| 156 | 166 | ||
| 157 | The rule does not conflict with any other casing rules so while it is | 167 | The rule does not conflict with any other casing rules so while it is |
| 158 | a conditional one, it is independent on language. */ | 168 | a conditional one, it is independent of language. */ |
| 159 | 169 | ||
| 160 | #define CAPITAL_SIGMA 0x03A3 | 170 | enum { GREEK_CAPITAL_LETTER_SIGMA = 0x03A }; /* Σ */ |
| 161 | #define SMALL_SIGMA 0x03C3 | 171 | enum { GREEK_SMALL_LETTER_FINAL_SIGMA = 0x03C2 }; /* ς */ |
| 162 | #define SMALL_FINAL_SIGMA 0x03C2 | ||
| 163 | 172 | ||
| 164 | /* Based on CTX, case character CH accordingly. Update CTX as necessary. | 173 | /* Based on CTX, case character CH accordingly. Update CTX as necessary. |
| 165 | Return cased character. | 174 | Return cased character. |
| 166 | 175 | ||
| 167 | Special casing rules (such as upcase(fi) = FI) are not handled. For | 176 | Special casing rules (such as upcase(fi) = FI) are not handled. For |
| 168 | characters whose casing results in multiple code points, the character is | 177 | characters whose casing results in multiple code points, the character is |
| 169 | returned unchanged. */ | 178 | returned unchanged. */ |
| 170 | static inline int | 179 | static inline int |
| 171 | case_single_character (struct casing_context *ctx, int ch) | 180 | case_single_character (struct casing_context *ctx, int ch) |
| 172 | { | 181 | { |
| @@ -181,23 +190,21 @@ case_single_character (struct casing_context *ctx, int ch) | |||
| 181 | apply some rules which depend on proceeding state. | 190 | apply some rules which depend on proceeding state. |
| 182 | 191 | ||
| 183 | This is like case_single_character but also handles one-to-many casing | 192 | This is like case_single_character but also handles one-to-many casing |
| 184 | rules. */ | 193 | rules. */ |
| 185 | static bool | 194 | static bool |
| 186 | case_character (struct casing_str_buf *buf, struct casing_context *ctx, | 195 | case_character (struct casing_str_buf *buf, struct casing_context *ctx, |
| 187 | int ch, const unsigned char *next) | 196 | int ch, const unsigned char *next) |
| 188 | { | 197 | { |
| 189 | bool changed, was_inword; | 198 | bool was_inword = ctx->inword; |
| 190 | 199 | bool changed = case_character_impl (buf, ctx, ch); | |
| 191 | was_inword = ctx->inword; | ||
| 192 | changed = case_character_impl (buf, ctx, ch); | ||
| 193 | 200 | ||
| 194 | /* If we have just down-cased a capital sigma and the next character no longer | 201 | /* If we have just down-cased a capital sigma and the next character no longer |
| 195 | has a word syntax (i.e. current character is end of word), use final | 202 | has a word syntax (i.e. current character is end of word), use final |
| 196 | sigma. */ | 203 | sigma. */ |
| 197 | if (was_inword && ch == CAPITAL_SIGMA && changed && | 204 | if (was_inword && ch == GREEK_CAPITAL_LETTER_SIGMA && changed |
| 198 | (!next || SYNTAX (STRING_CHAR (next)) != Sword)) | 205 | && (!next || SYNTAX (STRING_CHAR (next)) != Sword)) |
| 199 | { | 206 | { |
| 200 | buf->len_bytes = CHAR_STRING (SMALL_FINAL_SIGMA, buf->data); | 207 | buf->len_bytes = CHAR_STRING (GREEK_SMALL_LETTER_FINAL_SIGMA, buf->data); |
| 201 | buf->len_chars = 1; | 208 | buf->len_chars = 1; |
| 202 | } | 209 | } |
| 203 | 210 | ||
| @@ -209,63 +216,64 @@ do_casify_natnum (struct casing_context *ctx, Lisp_Object obj) | |||
| 209 | { | 216 | { |
| 210 | int flagbits = (CHAR_ALT | CHAR_SUPER | CHAR_HYPER | 217 | int flagbits = (CHAR_ALT | CHAR_SUPER | CHAR_HYPER |
| 211 | | CHAR_SHIFT | CHAR_CTL | CHAR_META); | 218 | | CHAR_SHIFT | CHAR_CTL | CHAR_META); |
| 212 | int flags, ch = XFASTINT (obj), cased; | 219 | int ch = XFASTINT (obj); |
| 213 | bool multibyte; | ||
| 214 | 220 | ||
| 215 | /* If the character has higher bits set above the flags, return it unchanged. | 221 | /* If the character has higher bits set above the flags, return it unchanged. |
| 216 | It is not a real character. */ | 222 | It is not a real character. */ |
| 217 | if (UNSIGNED_CMP (ch, >, flagbits)) | 223 | if (UNSIGNED_CMP (ch, >, flagbits)) |
| 218 | return obj; | 224 | return obj; |
| 219 | 225 | ||
| 220 | flags = ch & flagbits; | 226 | int flags = ch & flagbits; |
| 221 | ch = ch & ~flagbits; | 227 | ch = ch & ~flagbits; |
| 222 | 228 | ||
| 223 | /* FIXME: Even if enable-multibyte-characters is nil, we may manipulate | 229 | /* FIXME: Even if enable-multibyte-characters is nil, we may manipulate |
| 224 | multibyte chars. This means we have a bug for latin-1 chars since when we | 230 | multibyte chars. This means we have a bug for latin-1 chars since when we |
| 225 | receive an int 128-255 we can't tell whether it's an eight-bit byte or | 231 | receive an int 128-255 we can't tell whether it's an eight-bit byte or |
| 226 | a latin-1 char. */ | 232 | a latin-1 char. */ |
| 227 | multibyte = ch >= 256 | 233 | bool multibyte = (ch >= 256 |
| 228 | || !NILP (BVAR (current_buffer, enable_multibyte_characters)); | 234 | || !NILP (BVAR (current_buffer, |
| 235 | enable_multibyte_characters))); | ||
| 229 | if (! multibyte) | 236 | if (! multibyte) |
| 230 | MAKE_CHAR_MULTIBYTE (ch); | 237 | MAKE_CHAR_MULTIBYTE (ch); |
| 231 | cased = case_single_character (ctx, ch); | 238 | int cased = case_single_character (ctx, ch); |
| 232 | if (cased == ch) | 239 | if (cased == ch) |
| 233 | return obj; | 240 | return obj; |
| 234 | 241 | ||
| 235 | if (! multibyte) | 242 | if (! multibyte) |
| 236 | MAKE_CHAR_UNIBYTE (cased); | 243 | MAKE_CHAR_UNIBYTE (cased); |
| 237 | XSETFASTINT (obj, cased | flags); | 244 | return make_natnum (cased | flags); |
| 238 | return obj; | ||
| 239 | } | 245 | } |
| 240 | 246 | ||
| 241 | static Lisp_Object | 247 | static Lisp_Object |
| 242 | do_casify_multibyte_string (struct casing_context *ctx, Lisp_Object obj) | 248 | do_casify_multibyte_string (struct casing_context *ctx, Lisp_Object obj) |
| 243 | { | 249 | { |
| 244 | /* We assume data is the first member of casing_str_buf structure so that if | 250 | /* Verify that ‘data’ is the first member of struct casing_str_buf |
| 245 | we cast a (char *) into (struct casing_str_buf *) the representation of the | 251 | so that when casting char * to struct casing_str_buf *, the |
| 246 | character is at the beginning of the buffer. This is why we don’t need | 252 | representation of the character is at the beginning of the |
| 247 | separate struct casing_str_buf object but rather write directly to o. */ | 253 | buffer. This is why we don’t need a separate struct |
| 248 | typedef char static_assertion[offsetof(struct casing_str_buf, data) ? -1 : 1]; | 254 | casing_str_buf object, and can write directly to the destination. */ |
| 255 | verify (offsetof (struct casing_str_buf, data) == 0); | ||
| 249 | 256 | ||
| 250 | ptrdiff_t size = SCHARS (obj), n; | 257 | ptrdiff_t size = SCHARS (obj), n; |
| 251 | int ch; | ||
| 252 | USE_SAFE_ALLOCA; | 258 | USE_SAFE_ALLOCA; |
| 253 | if (INT_MULTIPLY_WRAPV (size, MAX_MULTIBYTE_LENGTH, &n) || | 259 | if (INT_MULTIPLY_WRAPV (size, MAX_MULTIBYTE_LENGTH, &n) |
| 254 | INT_ADD_WRAPV (n, sizeof(struct casing_str_buf), &n)) | 260 | || INT_ADD_WRAPV (n, sizeof (struct casing_str_buf), &n)) |
| 255 | n = PTRDIFF_MAX; | 261 | n = PTRDIFF_MAX; |
| 256 | unsigned char *const dst = SAFE_ALLOCA (n), *const dst_end = dst + n; | 262 | unsigned char *dst = SAFE_ALLOCA (n); |
| 263 | unsigned char *dst_end = dst + n; | ||
| 257 | unsigned char *o = dst; | 264 | unsigned char *o = dst; |
| 258 | 265 | ||
| 259 | const unsigned char *src = SDATA (obj); | 266 | const unsigned char *src = SDATA (obj); |
| 260 | 267 | ||
| 261 | for (n = 0; size; --size) | 268 | for (n = 0; size; --size) |
| 262 | { | 269 | { |
| 263 | if (dst_end - o < sizeof(struct casing_str_buf)) | 270 | if (dst_end - o < sizeof (struct casing_str_buf)) |
| 264 | string_overflow (); | 271 | string_overflow (); |
| 265 | ch = STRING_CHAR_ADVANCE (src); | 272 | int ch = STRING_CHAR_ADVANCE (src); |
| 266 | case_character ((void *)o, ctx, ch, size > 1 ? src : NULL); | 273 | case_character ((struct casing_str_buf *) o, ctx, ch, |
| 267 | n += ((struct casing_str_buf *)o)->len_chars; | 274 | size > 1 ? src : NULL); |
| 268 | o += ((struct casing_str_buf *)o)->len_bytes; | 275 | n += ((struct casing_str_buf *) o)->len_chars; |
| 276 | o += ((struct casing_str_buf *) o)->len_bytes; | ||
| 269 | } | 277 | } |
| 270 | eassert (o <= dst_end); | 278 | eassert (o <= dst_end); |
| 271 | obj = make_multibyte_string ((char *) dst, n, o - dst); | 279 | obj = make_multibyte_string ((char *) dst, n, o - dst); |
| @@ -288,7 +296,8 @@ do_casify_unibyte_string (struct casing_context *ctx, Lisp_Object obj) | |||
| 288 | if (ch == cased) | 296 | if (ch == cased) |
| 289 | continue; | 297 | continue; |
| 290 | MAKE_CHAR_UNIBYTE (cased); | 298 | MAKE_CHAR_UNIBYTE (cased); |
| 291 | /* If the char can't be converted to a valid byte, just don't change it */ | 299 | /* If the char can't be converted to a valid byte, just don't |
| 300 | change it. */ | ||
| 292 | if (cased >= 0 && cased < 256) | 301 | if (cased >= 0 && cased < 256) |
| 293 | SSET (obj, i, cased); | 302 | SSET (obj, i, cased); |
| 294 | } | 303 | } |
| @@ -369,21 +378,20 @@ cased, e.g. fi, are returned unchanged. */) | |||
| 369 | *ENDP unspecified. | 378 | *ENDP unspecified. |
| 370 | 379 | ||
| 371 | Always return 0. This is so that interface of this function is the same as | 380 | Always return 0. This is so that interface of this function is the same as |
| 372 | do_casify_multibyte_region. */ | 381 | do_casify_multibyte_region. */ |
| 373 | static ptrdiff_t | 382 | static ptrdiff_t |
| 374 | do_casify_unibyte_region (struct casing_context *ctx, | 383 | do_casify_unibyte_region (struct casing_context *ctx, |
| 375 | ptrdiff_t *startp, ptrdiff_t *endp) | 384 | ptrdiff_t *startp, ptrdiff_t *endp) |
| 376 | { | 385 | { |
| 377 | ptrdiff_t first = -1, last = -1; /* Position of first and last changes. */ | 386 | ptrdiff_t first = -1, last = -1; /* Position of first and last changes. */ |
| 378 | ptrdiff_t pos = *startp, end = *endp; | 387 | ptrdiff_t end = *endp; |
| 379 | int ch, cased; | ||
| 380 | 388 | ||
| 381 | for (; pos < end; ++pos) | 389 | for (ptrdiff_t pos = *startp; pos < end; ++pos) |
| 382 | { | 390 | { |
| 383 | ch = FETCH_BYTE (pos); | 391 | int ch = FETCH_BYTE (pos); |
| 384 | MAKE_CHAR_MULTIBYTE (ch); | 392 | MAKE_CHAR_MULTIBYTE (ch); |
| 385 | 393 | ||
| 386 | cased = case_single_character (ctx, ch); | 394 | int cased = case_single_character (ctx, ch); |
| 387 | if (cased == ch) | 395 | if (cased == ch) |
| 388 | continue; | 396 | continue; |
| 389 | 397 | ||
| @@ -405,26 +413,22 @@ do_casify_unibyte_region (struct casing_context *ctx, | |||
| 405 | Return number of added characters (may be negative if more characters were | 413 | Return number of added characters (may be negative if more characters were |
| 406 | deleted then inserted), save first and last positions that has changed in | 414 | deleted then inserted), save first and last positions that has changed in |
| 407 | *STARTP and *ENDP respectively. If no characters were changed, return 0, | 415 | *STARTP and *ENDP respectively. If no characters were changed, return 0, |
| 408 | save -1 to *STARTP and leave *ENDP unspecified. */ | 416 | save -1 to *STARTP and leave *ENDP unspecified. */ |
| 409 | static ptrdiff_t | 417 | static ptrdiff_t |
| 410 | do_casify_multibyte_region (struct casing_context *ctx, | 418 | do_casify_multibyte_region (struct casing_context *ctx, |
| 411 | ptrdiff_t *startp, ptrdiff_t *endp) | 419 | ptrdiff_t *startp, ptrdiff_t *endp) |
| 412 | { | 420 | { |
| 413 | ptrdiff_t first = -1, last = -1; /* Position of first and last changes. */ | 421 | ptrdiff_t first = -1, last = -1; /* Position of first and last changes. */ |
| 414 | ptrdiff_t pos = *startp, pos_byte = CHAR_TO_BYTE (pos), size = *endp - pos; | 422 | ptrdiff_t pos = *startp, pos_byte = CHAR_TO_BYTE (pos), size = *endp - pos; |
| 415 | ptrdiff_t opoint = PT, added = 0; | 423 | ptrdiff_t opoint = PT, added = 0; |
| 416 | struct casing_str_buf buf; | ||
| 417 | bool changed; | ||
| 418 | int ch, len; | ||
| 419 | 424 | ||
| 420 | for (; size; --size) | 425 | for (; size; --size) |
| 421 | { | 426 | { |
| 422 | ch = STRING_CHAR_AND_LENGTH (BYTE_POS_ADDR (pos_byte), len); | 427 | int len; |
| 423 | changed = case_character ( | 428 | int ch = STRING_CHAR_AND_LENGTH (BYTE_POS_ADDR (pos_byte), len); |
| 424 | &buf, ctx, ch, | 429 | struct casing_str_buf buf; |
| 425 | size > 1 ? BYTE_POS_ADDR (pos_byte + len) : NULL); | 430 | if (!case_character (&buf, ctx, ch, |
| 426 | 431 | size > 1 ? BYTE_POS_ADDR (pos_byte + len) : NULL)) | |
| 427 | if (!changed) | ||
| 428 | { | 432 | { |
| 429 | pos_byte += len; | 433 | pos_byte += len; |
| 430 | ++pos; | 434 | ++pos; |
| @@ -468,19 +472,19 @@ do_casify_multibyte_region (struct casing_context *ctx, | |||
| 468 | static ptrdiff_t | 472 | static ptrdiff_t |
| 469 | casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e) | 473 | casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e) |
| 470 | { | 474 | { |
| 471 | ptrdiff_t start, end, orig_end, added; | 475 | ptrdiff_t added; |
| 472 | struct casing_context ctx; | 476 | struct casing_context ctx; |
| 473 | 477 | ||
| 474 | validate_region (&b, &e); | 478 | validate_region (&b, &e); |
| 475 | start = XFASTINT (b); | 479 | ptrdiff_t start = XFASTINT (b); |
| 476 | end = XFASTINT (e); | 480 | ptrdiff_t end = XFASTINT (e); |
| 477 | if (start == end) | 481 | if (start == end) |
| 478 | /* Not modifying because nothing marked */ | 482 | /* Not modifying because nothing marked. */ |
| 479 | return end; | 483 | return end; |
| 480 | modify_text (start, end); | 484 | modify_text (start, end); |
| 481 | prepare_casing_context (&ctx, flag, true); | 485 | prepare_casing_context (&ctx, flag, true); |
| 482 | 486 | ||
| 483 | orig_end = end; | 487 | ptrdiff_t orig_end = end; |
| 484 | record_delete (start, make_buffer_string (start, end, true), false); | 488 | record_delete (start, make_buffer_string (start, end, true), false); |
| 485 | if (NILP (BVAR (current_buffer, enable_multibyte_characters))) | 489 | if (NILP (BVAR (current_buffer, enable_multibyte_characters))) |
| 486 | { | 490 | { |