Annotation of coherent/d/usr/bin/elvis/regsub.c, revision 1.1.1.1

1.1       root        1: /* regsub.c */
                      2: 
                      3: /* This file contains the regsub() function, which performs substitutions
                      4:  * after a regexp match has been found.
                      5:  */
                      6: 
                      7: #include <ctype.h>
                      8: #include "config.h"
                      9: #include "vi.h"
                     10: #include "regexp.h"
                     11: 
                     12: static char *previous; /* a copy of the text from the previous substitution */
                     13: 
                     14: /* perform substitutions after a regexp match */
                     15: void regsub(re, src, dst)
                     16:        regexp          *re;
                     17:        REG char        *src;
                     18:        REG char        *dst;
                     19: {
                     20:        REG char        *cpy;
                     21:        REG char        *end;
                     22:        REG char        c;
                     23:        char            *start;
                     24: #ifndef CRUNCH
                     25:        int             mod;
                     26: 
                     27:        mod = 0;
                     28: #endif
                     29: 
                     30:        start = src;
                     31:        while ((c = *src++) != '\0')
                     32:        {
                     33: #ifndef NO_MAGIC
                     34:                /* recognize any meta characters */
                     35:                if (c == '&' && *o_magic)
                     36:                {
                     37:                        cpy = re->startp[0];
                     38:                        end = re->endp[0];
                     39:                }
                     40:                else if (c == '~' && *o_magic)
                     41:                {
                     42:                        cpy = previous;
                     43:                        if (cpy)
                     44:                                end = cpy + strlen(cpy);
                     45:                }
                     46:                else
                     47: #endif /* not NO_MAGIC */
                     48:                if (c == '\\')
                     49:                {
                     50:                        c = *src++;
                     51:                        switch (c)
                     52:                        {
                     53: #ifndef NO_MAGIC
                     54:                          case '0':
                     55:                          case '1':
                     56:                          case '2':
                     57:                          case '3':
                     58:                          case '4':
                     59:                          case '5':
                     60:                          case '6':
                     61:                          case '7':
                     62:                          case '8':
                     63:                          case '9':
                     64:                                /* \0 thru \9 mean "copy subexpression" */
                     65:                                c -= '0';
                     66:                                cpy = re->startp[c];
                     67:                                end = re->endp[c];
                     68:                                break;
                     69: # ifndef CRUNCH
                     70:                          case 'U':
                     71:                          case 'u':
                     72:                          case 'L':
                     73:                          case 'l':
                     74:                                /* \U and \L mean "convert to upper/lowercase" */
                     75:                                mod = c;
                     76:                                continue;
                     77: 
                     78:                          case 'E':
                     79:                          case 'e':
                     80:                                /* \E ends the \U or \L */
                     81:                                mod = 0;
                     82:                                continue;
                     83: # endif /* not CRUNCH */
                     84:                          case '&':
                     85:                                /* "\&" means "original text" */
                     86:                                if (*o_magic)
                     87:                                {
                     88:                                        *dst++ = c;
                     89:                                        continue;
                     90:                                }
                     91:                                cpy = re->startp[0];
                     92:                                end = re->endp[0];
                     93:                                break;
                     94: 
                     95:                          case '~':
                     96:                                /* "\~" means "previous text, if any" */
                     97:                                if (*o_magic)
                     98:                                {
                     99:                                        *dst++ = c;
                    100:                                        continue;
                    101:                                }
                    102:                                cpy = previous;
                    103:                                if (cpy)
                    104:                                        end = cpy + strlen(cpy);
                    105:                                break;
                    106: #else /* NO_MAGIC */
                    107:                          case '&':
                    108:                                /* "\&" means "original text" */
                    109:                                cpy = re->startp[0];
                    110:                                end = re->endp[0];
                    111:                                break;
                    112: 
                    113:                          case '~':
                    114:                                /* "\~" means "previous text, if any" */
                    115:                                cpy = previous;
                    116:                                if (cpy)
                    117:                                        end = cpy + strlen(cpy);
                    118:                                break;
                    119: #endif /* NO_MAGIC */
                    120:                          default:
                    121:                                /* ordinary char preceded by backslash */
                    122:                                *dst++ = c;
                    123:                                continue;
                    124:                        }
                    125:                }
                    126:                else
                    127:                {
                    128:                        /* ordinary character, so just copy it */
                    129:                        *dst++ = c;
                    130:                        continue;
                    131:                }
                    132: 
                    133:                /* Note: to reach this point in the code, we must have evaded
                    134:                 * all "continue" statements.  To do that, we must have hit
                    135:                 * a metacharacter that involves copying.
                    136:                 */
                    137: 
                    138:                /* if there is nothing to copy, loop */
                    139:                if (!cpy)
                    140:                        continue;
                    141: 
                    142:                /* copy over a portion of the original */
                    143:                while (cpy < end)
                    144:                {
                    145: #ifndef NO_MAGIC
                    146: # ifndef CRUNCH
                    147:                        switch (mod)
                    148:                        {
                    149:                          case 'U':
                    150:                          case 'u':
                    151:                                /* convert to uppercase */
                    152:                                if (isascii(*cpy) && islower(*cpy))
                    153:                                {
                    154:                                        *dst++ = toupper(*cpy);
                    155:                                        cpy++;
                    156:                                }
                    157:                                else
                    158:                                {
                    159:                                        *dst++ = *cpy++;
                    160:                                }
                    161:                                break;
                    162: 
                    163:                          case 'L':
                    164:                          case 'l':
                    165:                                /* convert to lowercase */
                    166:                                if (isascii(*cpy) && isupper(*cpy))
                    167:                                {
                    168:                                        *dst++ = tolower(*cpy);
                    169:                                        cpy++;
                    170:                                }
                    171:                                else
                    172:                                {
                    173:                                        *dst++ = *cpy++;
                    174:                                }
                    175:                                break;
                    176: 
                    177:                          default:
                    178:                                /* copy without any conversion */
                    179:                                *dst++ = *cpy++;
                    180:                        }
                    181: 
                    182:                        /* \u and \l end automatically after the first char */
                    183:                        if (mod && (mod == 'u' || mod == 'l'))
                    184:                        {
                    185:                                mod = 0;
                    186:                        }
                    187: # else /* CRUNCH */
                    188:                        *dst++ = *cpy++;
                    189: # endif /* CRUNCH */
                    190: #else /* NO_MAGIC */
                    191:                        *dst++ = *cpy++;
                    192: #endif /* NO_MAGIC */
                    193:                }
                    194:        }
                    195:        *dst = '\0';
                    196: 
                    197:        /* remember what text we inserted this time */
                    198:        if (previous)
                    199:                free(previous);
                    200:        previous = (char *)malloc((unsigned)(strlen(start) + 1));
                    201:        if (previous)
                    202:                strcpy(previous, start);
                    203: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.