/[emacs]/emacs/src/casefiddle.c
ViewVC logotype

Diff of /emacs/src/casefiddle.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.43 by monnier, Mon Oct 21 21:03:00 2002 UTC revision 1.43.6.1 by handa, Mon Sep 8 12:48:09 2003 UTC
# Line 22  Boston, MA 02111-1307, USA.  */ Line 22  Boston, MA 02111-1307, USA.  */
22  #include <config.h>  #include <config.h>
23  #include "lisp.h"  #include "lisp.h"
24  #include "buffer.h"  #include "buffer.h"
25  #include "charset.h"  #include "character.h"
26  #include "commands.h"  #include "commands.h"
27  #include "syntax.h"  #include "syntax.h"
28  #include "composite.h"  #include "composite.h"
# Line 37  casify_object (flag, obj) Line 37  casify_object (flag, obj)
37       enum case_action flag;       enum case_action flag;
38       Lisp_Object obj;       Lisp_Object obj;
39  {  {
40    register int i, c, len;    register int c, c1;
41    register int inword = flag == CASE_DOWN;    register int inword = flag == CASE_DOWN;
42    
43    /* If the case table is flagged as modified, rescan it.  */    /* If the case table is flagged as modified, rescan it.  */
# Line 51  casify_object (flag, obj) Line 51  casify_object (flag, obj)
51            int flagbits = (CHAR_ALT | CHAR_SUPER | CHAR_HYPER            int flagbits = (CHAR_ALT | CHAR_SUPER | CHAR_HYPER
52                            | CHAR_SHIFT | CHAR_CTL | CHAR_META);                            | CHAR_SHIFT | CHAR_CTL | CHAR_META);
53            int flags = XINT (obj) & flagbits;            int flags = XINT (obj) & flagbits;
54              int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
55    
56            c = DOWNCASE (XFASTINT (obj) & ~flagbits);            c1 = XFASTINT (obj) & ~flagbits;
57            if (inword)            if (! multibyte)
58              XSETFASTINT (obj, c | flags);              MAKE_CHAR_MULTIBYTE (c1);
59            else if (c == (XFASTINT (obj) & ~flagbits))            c = DOWNCASE (c1);
60              if (inword || c == c1)
61              {              {
62                c = UPCASE1 ((XFASTINT (obj) & ~flagbits));                if (! inword)
63                    c = UPCASE1 (c1);
64                  if (! multibyte)
65                    MAKE_CHAR_UNIBYTE (c);
66                XSETFASTINT (obj, c | flags);                XSETFASTINT (obj, c | flags);
67              }              }
68            return obj;            return obj;
# Line 66  casify_object (flag, obj) Line 71  casify_object (flag, obj)
71        if (STRINGP (obj))        if (STRINGP (obj))
72          {          {
73            int multibyte = STRING_MULTIBYTE (obj);            int multibyte = STRING_MULTIBYTE (obj);
74              int i, i_byte, len;
75              int size = SCHARS (obj);
76    
77            obj = Fcopy_sequence (obj);            obj = Fcopy_sequence (obj);
78            len = SBYTES (obj);            for (i = i_byte = 0; i < size; i++, i_byte += len)
   
           /* Scan all single-byte characters from start of string.  */  
           for (i = 0; i < len;)  
79              {              {
80                c = SREF (obj, i);                if (multibyte)
81                    c = STRING_CHAR_AND_LENGTH (SDATA (obj) + i_byte, 0, len);
82                if (multibyte && c >= 0x80)                else
83                  /* A multibyte character can't be handled in this                  {
84                     simple loop.  */                    c = SREF (obj, i_byte);
85                  break;                    len = 1;
86                      MAKE_CHAR_MULTIBYTE (c);
87                    }
88                  c1 = c;
89                if (inword && flag != CASE_CAPITALIZE_UP)                if (inword && flag != CASE_CAPITALIZE_UP)
90                  c = DOWNCASE (c);                  c = DOWNCASE (c);
91                else if (!UPPERCASEP (c)                else if (!UPPERCASEP (c)
92                         && (!inword || flag != CASE_CAPITALIZE_UP))                         && (!inword || flag != CASE_CAPITALIZE_UP))
93                  c = UPCASE1 (c);                  c = UPCASE1 (c1);
               /* If this char won't fit in a single-byte string.  
                  fall out to the multibyte case.  */  
               if (multibyte ? ! ASCII_BYTE_P (c)  
                   : ! SINGLE_BYTE_CHAR_P (c))  
                 break;  
   
               SSET (obj, i, c);  
94                if ((int) flag >= (int) CASE_CAPITALIZE)                if ((int) flag >= (int) CASE_CAPITALIZE)
95                  inword = SYNTAX (c) == Sword;                  inword = (SYNTAX (c) == Sword);
96                i++;                if (c != c1)
             }  
   
           /* If we didn't do the whole string as single-byte,  
              scan the rest in a more complex way.  */  
           if (i < len)  
             {  
               /* The work is not yet finished because of a multibyte  
                  character just encountered.  */  
               int fromlen, j_byte = i;  
               char *buf  
                 = (char *) alloca ((len - i) * MAX_MULTIBYTE_LENGTH + i);  
   
               /* Copy data already handled.  */  
               bcopy (SDATA (obj), buf, i);  
   
               /* From now on, I counts bytes.  */  
               while (i < len)  
97                  {                  {
98                    c = STRING_CHAR_AND_LENGTH (SDATA (obj) + i,                    if (! multibyte)
99                                                len - i, fromlen);                      {
100                    if (inword && flag != CASE_CAPITALIZE_UP)                        MAKE_CHAR_UNIBYTE (c);
101                      c = DOWNCASE (c);                        SSET (obj, i_byte, c);
102                    else if (!UPPERCASEP (c)                      }
103                             && (!inword || flag != CASE_CAPITALIZE_UP))                    else if (ASCII_CHAR_P (c1) && ASCII_CHAR_P (c))
104                      c = UPCASE1 (c);                      SSET (obj, i_byte,  c);
105                    i += fromlen;                    else
106                    j_byte += CHAR_STRING (c, buf + j_byte);                      {
107                    if ((int) flag >= (int) CASE_CAPITALIZE)                        Faset (obj, make_number (i), make_number (c));
108                      inword = SYNTAX (c) == Sword;                        i_byte += CHAR_BYTES (c) - len;
109                        }
110                  }                  }
               obj = make_multibyte_string (buf, SCHARS (obj),  
                                            j_byte);  
111              }              }
112            return obj;            return obj;
113          }          }
# Line 187  casify_region (flag, b, e) Line 169  casify_region (flag, b, e)
169       enum case_action flag;       enum case_action flag;
170       Lisp_Object b, e;       Lisp_Object b, e;
171  {  {
   register int i;  
172    register int c;    register int c;
173    register int inword = flag == CASE_DOWN;    register int inword = flag == CASE_DOWN;
174    register int multibyte = !NILP (current_buffer->enable_multibyte_characters);    register int multibyte = !NILP (current_buffer->enable_multibyte_characters);
175    int start, end;    int start, end;
176    int start_byte, end_byte;    int start_byte, end_byte;
177    int changed = 0;    int changed = 0;
178      int opoint = PT;
179      int opoint_byte = PT_BYTE;
180    
181    if (EQ (b, e))    if (EQ (b, e))
182      /* Not modifying because nothing marked */      /* Not modifying because nothing marked */
# Line 211  casify_region (flag, b, e) Line 194  casify_region (flag, b, e)
194    start_byte = CHAR_TO_BYTE (start);    start_byte = CHAR_TO_BYTE (start);
195    end_byte = CHAR_TO_BYTE (end);    end_byte = CHAR_TO_BYTE (end);
196    
197    for (i = start_byte; i < end_byte; i++, start++)    while (start < end)
198      {      {
199        int c2;        int c2, len;
200        c = c2 = FETCH_BYTE (i);  
201        if (multibyte && c >= 0x80)        if (multibyte)
202          /* A multibyte character can't be handled in this simple loop.  */          {
203          break;            c = FETCH_MULTIBYTE_CHAR (start_byte);
204              len = CHAR_BYTES (c);
205            }
206          else
207            {
208              c = FETCH_BYTE (start_byte);
209              MAKE_CHAR_MULTIBYTE (c);
210              len = 1;
211            }
212          c2 = c;
213        if (inword && flag != CASE_CAPITALIZE_UP)        if (inword && flag != CASE_CAPITALIZE_UP)
214          c = DOWNCASE (c);          c = DOWNCASE (c);
215        else if (!UPPERCASEP (c)        else if (!UPPERCASEP (c)
216                 && (!inword || flag != CASE_CAPITALIZE_UP))                 && (!inword || flag != CASE_CAPITALIZE_UP))
217          c = UPCASE1 (c);          c = UPCASE1 (c);
       FETCH_BYTE (i) = c;  
       if (c != c2)  
         changed = 1;  
218        if ((int) flag >= (int) CASE_CAPITALIZE)        if ((int) flag >= (int) CASE_CAPITALIZE)
219          inword = SYNTAX (c) == Sword && (inword || !SYNTAX_PREFIX (c));          inword = ((SYNTAX (c) == Sword) && (inword || !SYNTAX_PREFIX (c)));
220      }        if (c != c2)
   if (i < end_byte)  
     {  
       /* The work is not yet finished because of a multibyte character  
          just encountered.  */  
       int opoint = PT;  
       int opoint_byte = PT_BYTE;  
       int c2;  
   
       while (i < end_byte)  
221          {          {
222            if ((c = FETCH_BYTE (i)) >= 0x80)            changed = 1;
223              c = FETCH_MULTIBYTE_CHAR (i);            if (! multibyte)
224            c2 = c;              {
225            if (inword && flag != CASE_CAPITALIZE_UP)                MAKE_CHAR_UNIBYTE (c);
226              c2 = DOWNCASE (c);                FETCH_BYTE (start_byte) = c;
227            else if (!UPPERCASEP (c)              }
228                     && (!inword || flag != CASE_CAPITALIZE_UP))            else if (ASCII_CHAR_P (c2) && ASCII_CHAR_P (c))
229              c2 = UPCASE1 (c);              FETCH_BYTE (start_byte) = c;
230            if (c != c2)            else if (len == CHAR_BYTES (c))
231              {              {
232                int fromlen, tolen, j;                int j;
233                unsigned char str[MAX_MULTIBYTE_LENGTH];                unsigned char str[MAX_MULTIBYTE_LENGTH];
234    
235                changed = 1;                CHAR_STRING (c, str);
236                /* Handle the most likely case */                for (j = 0; j < len; ++j)
237                if (c < 0400 && c2 < 0400)                  FETCH_BYTE (start_byte + j) = str[j];
238                  FETCH_BYTE (i) = c2;              }
239                else if (fromlen = CHAR_STRING (c, str),            else
240                         tolen = CHAR_STRING (c2, str),              {
241                         fromlen == tolen)                TEMP_SET_PT_BOTH (start, start_byte);
242                  {                del_range_2 (start, start_byte, start + 1, start_byte + len, 0);
243                    for (j = 0; j < tolen; ++j)                insert_char (c);
244                      FETCH_BYTE (i + j) = str[j];                len = CHAR_BYTES (c);
                 }  
               else  
                 {  
                   error ("Can't casify letters that change length");  
 #if 0 /* This is approximately what we'd like to be able to do here */  
                   if (tolen < fromlen)  
                     del_range_1 (i + tolen, i + fromlen, 0, 0);  
                   else if (tolen > fromlen)  
                     {  
                       TEMP_SET_PT (i + fromlen);  
                       insert_1 (str + fromlen, tolen - fromlen, 1, 0, 0);  
                     }  
 #endif  
                 }  
245              }              }
           if ((int) flag >= (int) CASE_CAPITALIZE)  
             inword = SYNTAX (c2) == Sword;  
           INC_BOTH (start, i);  
246          }          }
247        TEMP_SET_PT_BOTH (opoint, opoint_byte);        start++;
248          start_byte += len;
249      }      }
250    
251    start = XFASTINT (b);    if (PT != opoint)
252        TEMP_SET_PT_BOTH (opoint, opoint_byte);
253    
254    if (changed)    if (changed)
255      {      {
256          start = XFASTINT (b);
257        signal_after_change (start, end - start, end - start);        signal_after_change (start, end - start, end - start);
258        update_compositions (start, end, CHECK_ALL);        update_compositions (start, end, CHECK_ALL);
259      }      }

Legend:
Removed from v.1.43  
changed lines
  Added in v.1.43.6.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26