/[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.40.2.2 by handa, Tue Mar 5 00:07:19 2002 UTC revision 1.40.2.3 by handa, Tue Aug 20 03:58:53 2002 UTC
# 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)
             XSETFASTINT (obj, c | flags);  
           else if (c == (XFASTINT (obj) & ~flagbits))  
58              {              {
59                c = UPCASE1 ((XFASTINT (obj) & ~flagbits));                MAKE_CHAR_UNIBYTE (c1);
60                }
61              c = DOWNCASE (c1);
62              if (inword || c == c1)
63                {
64                  if (! inword)
65                    c = UPCASE1 (c1);
66                  if (! multibyte)
67                    {
68                      MAKE_CHAR_MULTIBYTE (c);
69                    }
70                XSETFASTINT (obj, c | flags);                XSETFASTINT (obj, c | flags);
71              }              }
72            return obj;            return obj;
# Line 66  casify_object (flag, obj) Line 75  casify_object (flag, obj)
75        if (STRINGP (obj))        if (STRINGP (obj))
76          {          {
77            int multibyte = STRING_MULTIBYTE (obj);            int multibyte = STRING_MULTIBYTE (obj);
78              int i, i_byte, len;
79              int size = XSTRING (obj)->size;
80    
81            obj = Fcopy_sequence (obj);            obj = Fcopy_sequence (obj);
82            len = STRING_BYTES (XSTRING (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;)  
83              {              {
84                c = XSTRING (obj)->data[i];                if (multibyte)
85                    c = STRING_CHAR_AND_LENGTH (XSTRING (obj)->data + i_byte,
86                if (multibyte && c >= 0x80)                                              0, len);
87                  /* A multibyte character can't be handled in this                else
88                     simple loop.  */                  {
89                  break;                    c = XSTRING (obj)->data[i_byte];
90                      len = 1;
91                      MAKE_CHAR_MULTIBYTE (c);
92                    }
93                  c1 = c;
94                if (inword && flag != CASE_CAPITALIZE_UP)                if (inword && flag != CASE_CAPITALIZE_UP)
95                  c = DOWNCASE (c);                  c = DOWNCASE (c);
96                else if (!UPPERCASEP (c)                else if (!UPPERCASEP (c)
97                         && (!inword || flag != CASE_CAPITALIZE_UP))                         && (!inword || flag != CASE_CAPITALIZE_UP))
98                  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;  
   
               XSTRING (obj)->data[i] = c;  
99                if ((int) flag >= (int) CASE_CAPITALIZE)                if ((int) flag >= (int) CASE_CAPITALIZE)
100                  inword = SYNTAX (c) == Sword;                  inword = SYNTAX (c) == Sword;
101                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 (XSTRING (obj)->data, buf, i);  
   
               /* From now on, I counts bytes.  */  
               while (i < len)  
102                  {                  {
103                    c = STRING_CHAR_AND_LENGTH (XSTRING (obj)->data + i,                    if (! multibyte)
104                                                len - i, fromlen);                      {
105                    if (inword && flag != CASE_CAPITALIZE_UP)                        MAKE_CHAR_UNIBYTE (c);
106                      c = DOWNCASE (c);                        XSTRING (obj)->data[i_byte] = c;
107                    else if (!UPPERCASEP (c)                      }
108                             && (!inword || flag != CASE_CAPITALIZE_UP))                    else if (ASCII_CHAR_P (c1) && ASCII_CHAR_P (c))
109                      c = UPCASE1 (c);                      XSTRING (obj)->data[i_byte] = c;
110                    i += fromlen;                    else
111                    j_byte += CHAR_STRING (c, buf + j_byte);                      {
112                    if ((int) flag >= (int) CASE_CAPITALIZE)                        Faset (obj, make_number (i), make_number (c));
113                      inword = SYNTAX (c) == Sword;                        i_byte += CHAR_BYTES (c) - len;
114                        }
115                  }                  }
               obj = make_multibyte_string (buf, XSTRING (obj)->size,  
                                            j_byte);  
116              }              }
117            return obj;            return obj;
118          }          }
# Line 194  casify_region (flag, b, e) Line 181  casify_region (flag, b, e)
181    int start, end;    int start, end;
182    int start_byte, end_byte;    int start_byte, end_byte;
183    int changed = 0;    int changed = 0;
184      int opoint = PT;
185      int opoint_byte = PT_BYTE;
186    
187    if (EQ (b, e))    if (EQ (b, e))
188      /* Not modifying because nothing marked */      /* Not modifying because nothing marked */
# Line 211  casify_region (flag, b, e) Line 200  casify_region (flag, b, e)
200    start_byte = CHAR_TO_BYTE (start);    start_byte = CHAR_TO_BYTE (start);
201    end_byte = CHAR_TO_BYTE (end);    end_byte = CHAR_TO_BYTE (end);
202    
203    for (i = start_byte; i < end_byte; i++, start++)    while (start < end)
204      {      {
205        int c2;        int c2, len;
206        c = c2 = FETCH_BYTE (i);  
207        if (multibyte && c >= 0x80)        if (multibyte)
208          /* A multibyte character can't be handled in this simple loop.  */          {
209          break;            c = FETCH_MULTIBYTE_CHAR (start_byte);
210              len = CHAR_BYTES (c);
211            }
212          else
213            {
214              c = FETCH_BYTE (start_byte);
215              MAKE_CHAR_MULTIBYTE (c);
216              len = 1;
217            }
218          c2 = c;
219        if (inword && flag != CASE_CAPITALIZE_UP)        if (inword && flag != CASE_CAPITALIZE_UP)
220          c = DOWNCASE (c);          c = DOWNCASE (c);
221        else if (!UPPERCASEP (c)        else if (!UPPERCASEP (c)
222                 && (!inword || flag != CASE_CAPITALIZE_UP))                 && (!inword || flag != CASE_CAPITALIZE_UP))
223          c = UPCASE1 (c);          c = UPCASE1 (c);
       FETCH_BYTE (i) = c;  
       if (c != c2)  
         changed = 1;  
224        if ((int) flag >= (int) CASE_CAPITALIZE)        if ((int) flag >= (int) CASE_CAPITALIZE)
225          inword = SYNTAX (c) == Sword;          inword = SYNTAX (c) == Sword;
226      }        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)  
227          {          {
228            if ((c = FETCH_BYTE (i)) >= 0x80)            changed = 1;
229              c = FETCH_MULTIBYTE_CHAR (i);            if (! multibyte)
230            c2 = c;              {
231            if (inword && flag != CASE_CAPITALIZE_UP)                MAKE_CHAR_UNIBYTE (c);
232              c2 = DOWNCASE (c);                FETCH_BYTE (start_byte) = c;
233            else if (!UPPERCASEP (c)              }
234                     && (!inword || flag != CASE_CAPITALIZE_UP))            else if (ASCII_CHAR_P (c2) && ASCII_CHAR_P (c))
235              c2 = UPCASE1 (c);              FETCH_BYTE (start_byte) = c;
236            if (c != c2)            else if (len == CHAR_BYTES (c))
237              {              {
238                int fromlen, tolen, j;                int j;
239                unsigned char str[MAX_MULTIBYTE_LENGTH];                unsigned char str[MAX_MULTIBYTE_LENGTH];
240    
241                changed = 1;                CHAR_STRING (c, str);
242                /* Handle the most likely case */                for (j = 0; j < len; ++j)
243                if (multibyte ? (c < 0200 && c2 < 0200)                  FETCH_BYTE (start_byte + j) = str[j];
244                    : (c < 0400 && c2 < 0400))              }
245                  FETCH_BYTE (i) = c2;            else
246                else if (fromlen = CHAR_STRING (c, str),              {
247                         tolen = CHAR_STRING (c2, str),                TEMP_SET_PT_BOTH (start, start_byte);
248                         fromlen == tolen)                del_range_2 (start, start_byte, start + 1, start_byte + len, 0);
249                  {                insert_char (c);
250                    for (j = 0; j < tolen; ++j)                len = CHAR_BYTES (c);
                     FETCH_BYTE (i + j) = str[j];  
                 }  
               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  
                 }  
251              }              }
           if ((int) flag >= (int) CASE_CAPITALIZE)  
             inword = SYNTAX (c2) == Sword;  
           INC_BOTH (start, i);  
252          }          }
253        TEMP_SET_PT_BOTH (opoint, opoint_byte);        start++;
254          start_byte += len;
255      }      }
256    
   start = XFASTINT (b);  
257    if (changed)    if (changed)
258      {      {
259          start = XFASTINT (b);
260        signal_after_change (start, end - start, end - start);        signal_after_change (start, end - start, end - start);
261        update_compositions (start, end, CHECK_ALL);        update_compositions (start, end, CHECK_ALL);
262      }      }

Legend:
Removed from v.1.40.2.2  
changed lines
  Added in v.1.40.2.3

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