comparison src/casefiddle.c @ 373:6240c7796c7a r21-2b2

Import from CVS: tag r21-2b2
author cvs
date Mon, 13 Aug 2007 11:04:06 +0200
parents 6cb5e14cd98e
children 8626e4521993
comparison
equal deleted inserted replaced
372:49e1ed2d7ed8 373:6240c7796c7a
1 /* XEmacs case conversion functions. 1 /* XEmacs case conversion functions.
2 Copyright (C) 1985, 1992, 1993, 1994 Free Software Foundation, Inc. 2 Copyright (C) 1985, 1992, 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
3 3
4 This file is part of XEmacs. 4 This file is part of XEmacs.
5 5
6 XEmacs is free software; you can redistribute it and/or modify it 6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the 7 under the terms of the GNU General Public License as published by the
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING. If not, write to 17 along with XEmacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */ 19 Boston, MA 02111-1307, USA. */
20 20
21 /* Synched up with: FSF 19.34. */ 21 /* Synched up with: FSF 19.34, but substantially rewritten by Martin. */
22 22
23 #include <config.h> 23 #include <config.h>
24 #include "lisp.h" 24 #include "lisp.h"
25 25
26 #include "buffer.h" 26 #include "buffer.h"
27 #include "commands.h"
28 #include "insdel.h" 27 #include "insdel.h"
29 #include "syntax.h" 28 #include "syntax.h"
30 29
31 enum case_action {CASE_UP, CASE_DOWN, CASE_CAPITALIZE, CASE_CAPITALIZE_UP}; 30 enum case_action {CASE_UP, CASE_DOWN, CASE_CAPITALIZE, CASE_CAPITALIZE_UP};
32 31
33 static Lisp_Object 32 static Lisp_Object
34 casify_object (enum case_action flag, Lisp_Object obj, Lisp_Object buffer) 33 casify_object (enum case_action flag, Lisp_Object obj, Lisp_Object buffer)
35 { 34 {
36 struct buffer *buf = decode_buffer (buffer, 0); 35 struct buffer *buf = decode_buffer (buffer, 0);
37 REGISTER int inword = (flag == CASE_DOWN); 36
38 struct Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->mirror_syntax_table); 37 retry:
39 38
40 while (1) 39 if (CHAR_OR_CHAR_INTP (obj))
41 { 40 {
42 if (CHAR_OR_CHAR_INTP (obj)) 41 Emchar c;
42 CHECK_CHAR_COERCE_INT (obj);
43 c = XCHAR (obj);
44 c = (flag == CASE_DOWN) ? DOWNCASE (buf, c) : UPCASE (buf, c);
45 return make_char (c);
46 }
47
48 if (STRINGP (obj))
49 {
50 struct Lisp_Char_Table *syntax_table =
51 XCHAR_TABLE (buf->mirror_syntax_table);
52 Bufbyte *storage =
53 alloca_array (Bufbyte, XSTRING_LENGTH (obj) * MAX_EMCHAR_LEN);
54 Bufbyte *newp = storage;
55 Bufbyte *oldp = XSTRING_DATA (obj);
56 int wordp = 0, wordp_prev;
57
58 while (*oldp)
43 { 59 {
44 Emchar c; 60 Emchar c = charptr_emchar (oldp);
45 CHECK_CHAR_COERCE_INT (obj); 61 switch (flag)
46 c = XCHAR (obj);
47 if (IN_TRT_TABLE_DOMAIN (c))
48 { 62 {
49 if (inword) 63 case CASE_UP:
50 obj = make_char (DOWNCASE (buf, c)); 64 c = UPCASE (buf, c);
51 else if (!UPPERCASEP (buf, c)) 65 break;
52 obj = make_char (UPCASE1 (buf, c)); 66 case CASE_DOWN:
67 c = DOWNCASE (buf, c);
68 break;
69 case CASE_CAPITALIZE:
70 case CASE_CAPITALIZE_UP:
71 wordp_prev = wordp;
72 wordp = WORD_SYNTAX_P (syntax_table, c);
73 if (!wordp) break;
74 if (wordp_prev)
75 {
76 if (flag == CASE_CAPITALIZE)
77 c = DOWNCASE (buf, c);
78 }
79 else
80 c = UPCASE (buf, c);
81 break;
53 } 82 }
54 return obj; 83
84 newp += set_charptr_emchar (newp, c);
85 INC_CHARPTR (oldp);
55 } 86 }
56 if (STRINGP (obj)) 87
57 { 88 return make_string (storage, newp - storage);
58 Charcount i;
59 Charcount len = XSTRING_CHAR_LENGTH (obj);
60 obj = Fcopy_sequence (obj);
61 for (i = 0; i < len; i++)
62 {
63 Emchar c = string_char (XSTRING (obj), i);
64 if (inword && flag != CASE_CAPITALIZE_UP)
65 c = DOWNCASE (buf, c);
66 else if (!UPPERCASEP (buf, c)
67 && (!inword || flag != CASE_CAPITALIZE_UP))
68 c = UPCASE1 (buf, c);
69 set_string_char (XSTRING (obj), i, c);
70 if ((int) flag >= (int) CASE_CAPITALIZE)
71 inword = WORD_SYNTAX_P (syntax_table, c);
72 }
73 return obj;
74 }
75 obj = wrong_type_argument (Qchar_or_string_p, obj);
76 } 89 }
90
91 obj = wrong_type_argument (Qchar_or_string_p, obj);
92 goto retry;
77 } 93 }
78 94
79 DEFUN ("upcase", Fupcase, 1, 2, 0, /* 95 DEFUN ("upcase", Fupcase, 1, 2, 0, /*
80 Convert argument to upper case and return that. 96 Convert OBJECT to upper case and return that.
81 The argument may be a character or string. The result has the same type. 97 OBJECT may be a character or string. The result has the same type.
82 The argument object is not altered--the value is a copy. 98 OBJECT is not altered--the value is a copy.
83 See also `capitalize', `downcase' and `upcase-initials'. 99 See also `capitalize', `downcase' and `upcase-initials'.
84 Optional second arg BUFFER specifies which buffer's case tables to use, 100 Optional second arg BUFFER specifies which buffer's case tables to use,
85 and defaults to the current buffer. 101 and defaults to the current buffer.
86 */ 102 */
87 (obj, buffer)) 103 (object, buffer))
88 { 104 {
89 return casify_object (CASE_UP, obj, buffer); 105 return casify_object (CASE_UP, object, buffer);
90 } 106 }
91 107
92 DEFUN ("downcase", Fdowncase, 1, 2, 0, /* 108 DEFUN ("downcase", Fdowncase, 1, 2, 0, /*
93 Convert argument to lower case and return that. 109 Convert OBJECT to lower case and return that.
94 The argument may be a character or string. The result has the same type. 110 OBJECT may be a character or string. The result has the same type.
95 The argument object is not altered--the value is a copy. 111 OBJECT is not altered--the value is a copy.
96 Optional second arg BUFFER specifies which buffer's case tables to use, 112 Optional second arg BUFFER specifies which buffer's case tables to use,
97 and defaults to the current buffer. 113 and defaults to the current buffer.
98 */ 114 */
99 (obj, buffer)) 115 (object, buffer))
100 { 116 {
101 return casify_object (CASE_DOWN, obj, buffer); 117 return casify_object (CASE_DOWN, object, buffer);
102 } 118 }
103 119
104 DEFUN ("capitalize", Fcapitalize, 1, 2, 0, /* 120 DEFUN ("capitalize", Fcapitalize, 1, 2, 0, /*
105 Convert argument to capitalized form and return that. 121 Convert OBJECT to capitalized form and return that.
106 This means that each word's first character is upper case 122 This means that each word's first character is upper case
107 and the rest is lower case. 123 and the rest is lower case.
108 The argument may be a character or string. The result has the same type. 124 OBJECT may be a character or string. The result has the same type.
109 The argument object is not altered--the value is a copy. 125 OBJECT is not altered--the value is a copy.
110 Optional second arg BUFFER specifies which buffer's case tables to use, 126 Optional second arg BUFFER specifies which buffer's case tables to use,
111 and defaults to the current buffer. 127 and defaults to the current buffer.
112 */ 128 */
113 (obj, buffer)) 129 (object, buffer))
114 { 130 {
115 return casify_object (CASE_CAPITALIZE, obj, buffer); 131 return casify_object (CASE_CAPITALIZE, object, buffer);
116 } 132 }
117 133
118 /* Like Fcapitalize but change only the initials. */ 134 /* Like Fcapitalize but change only the initial characters. */
119 135
120 DEFUN ("upcase-initials", Fupcase_initials, 1, 2, 0, /* 136 DEFUN ("upcase-initials", Fupcase_initials, 1, 2, 0, /*
121 Convert the initial of each word in the argument to upper case. 137 Convert the initial of each word in OBJECT to upper case.
122 Do not change the other letters of each word. 138 Do not change the other letters of each word.
123 The argument may be a character or string. The result has the same type. 139 OBJECT may be a character or string. The result has the same type.
124 The argument object is not altered--the value is a copy. 140 OBJECT is not altered--the value is a copy.
125 Optional second arg BUFFER specifies which buffer's case tables to use, 141 Optional second arg BUFFER specifies which buffer's case tables to use,
126 and defaults to the current buffer. 142 and defaults to the current buffer.
127 */ 143 */
128 (obj, buffer)) 144 (object, buffer))
129 { 145 {
130 return casify_object (CASE_CAPITALIZE_UP, obj, buffer); 146 return casify_object (CASE_CAPITALIZE_UP, object, buffer);
131 } 147 }
132 148
133 /* flag is CASE_UP, CASE_DOWN or CASE_CAPITALIZE or CASE_CAPITALIZE_UP. 149 /* flag is CASE_UP, CASE_DOWN or CASE_CAPITALIZE or CASE_CAPITALIZE_UP.
134 b and e specify range of buffer to operate on. */ 150 b and e specify range of buffer to operate on. */
135 151
138 struct buffer *buf) 154 struct buffer *buf)
139 { 155 {
140 /* This function can GC */ 156 /* This function can GC */
141 REGISTER Bufpos i; 157 REGISTER Bufpos i;
142 Bufpos start, end; 158 Bufpos start, end;
143 REGISTER int inword = (flag == CASE_DOWN);
144 struct Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->mirror_syntax_table); 159 struct Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
145 int mccount; 160 int mccount;
161 Emchar oldc, c;
162 int wordp = 0, wordp_prev;
146 163
147 if (EQ (b, e)) 164 if (EQ (b, e))
148 /* Not modifying because nothing marked */ 165 /* Not modifying because nothing marked */
149 return; 166 return;
150 167
153 mccount = begin_multiple_change (buf, start, end); 170 mccount = begin_multiple_change (buf, start, end);
154 record_change (buf, start, end - start); 171 record_change (buf, start, end - start);
155 172
156 for (i = start; i < end; i++) 173 for (i = start; i < end; i++)
157 { 174 {
158 Emchar c = BUF_FETCH_CHAR (buf, i); 175 c = oldc = BUF_FETCH_CHAR (buf, i);
159 Emchar oldc = c; 176
160 177 switch (flag)
161 if (inword && flag != CASE_CAPITALIZE_UP)
162 c = DOWNCASE (buf, c);
163 else if (!UPPERCASEP (buf, c)
164 && (!inword || flag != CASE_CAPITALIZE_UP))
165 c = UPCASE1 (buf, c);
166
167 if (oldc != c)
168 { 178 {
169 buffer_replace_char (buf, i, c, 1, (i == start)); 179 case CASE_UP:
170 BUF_MODIFF (buf)++; 180 c = UPCASE (buf, oldc);
181 break;
182 case CASE_DOWN:
183 c = DOWNCASE (buf, oldc);
184 break;
185 case CASE_CAPITALIZE:
186 case CASE_CAPITALIZE_UP:
187 /* !!#### need to revalidate the start and end pointers in case
188 the buffer was changed */
189 wordp_prev = wordp;
190 wordp = WORD_SYNTAX_P (syntax_table, c);
191 if (!wordp) continue;
192 if (wordp_prev)
193 {
194 if (flag == CASE_CAPITALIZE)
195 c = DOWNCASE (buf, c);
196 }
197 else
198 c = UPCASE (buf, c);
199 break;
171 } 200 }
172 /* !!#### need to revalidate the start and end pointers in case 201
173 the buffer was changed */ 202 if (oldc == c) continue;
174 if ((int) flag >= (int) CASE_CAPITALIZE) 203 buffer_replace_char (buf, i, c, 1, (i == start));
175 inword = WORD_SYNTAX_P (syntax_table, c); 204 BUF_MODIFF (buf)++;
176 } 205 }
206
177 end_multiple_change (buf, mccount); 207 end_multiple_change (buf, mccount);
178 } 208 }
179 209
180 static Lisp_Object 210 static Lisp_Object
181 casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e, 211 casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e,