Annotation of coherent/g/usr/bin/vi/regsub.c, revision 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 "config.h"
        !             8: #include "ctype.h"
        !             9: #include "vi.h"
        !            10: #include "regexp.h"
        !            11: 
        !            12: 
        !            13: /* perform substitutions after a regexp match */
        !            14: void regsub(re, src, dst)
        !            15:        regexp          *re;    /* the regexp with pointers into matched text */
        !            16:        REG char        *src;   /* the replacement string */
        !            17:        REG char        *dst;   /* where to put the result of the subst */
        !            18: {
        !            19:        REG char        *cpy;   /* pointer to start of text to copy */
        !            20:        REG char        *end;   /* pointer to end of text to copy */
        !            21:        REG char        c;
        !            22:        char            *start;
        !            23: #ifndef CRUNCH
        !            24:        int             mod = 0;/* used to track \U, \L, \u, \l, and \E */
        !            25:        int             len;    /* used to calculate length of subst string */
        !            26:        static char     *prev;  /* a copy of the text from the previous subst */
        !            27: 
        !            28:        /* replace \~ (or maybe ~) by previous substitution text */
        !            29: 
        !            30:        /* step 1: calculate the length of the new substitution text */
        !            31:        for (len = strlen(src), c = '\0', cpy = src; *cpy; cpy++)
        !            32:        {
        !            33: # ifdef NO_MAGIC
        !            34:                if (c == '\\' && *cpy == '~')
        !            35: # else
        !            36:                if (c == (*o_magic ? '\0' : '\\') && *cpy == '~')
        !            37: # endif
        !            38:                {
        !            39:                        if (!prev)
        !            40:                        {
        !            41:                                regerror("No prev text to substitute for ~");
        !            42:                                return;
        !            43:                        }
        !            44:                        len += strlen(prev) - 1;
        !            45: # ifndef NO_MAGIC
        !            46:                        if (!*o_magic)
        !            47: # endif
        !            48:                                len -= 1; /* because we lose the \ too */
        !            49:                }
        !            50: 
        !            51:                /* watch backslash quoting */
        !            52:                if (c != '\\' && *cpy == '\\')
        !            53:                        c = '\\';
        !            54:                else
        !            55:                        c = '\0';
        !            56:        }
        !            57: 
        !            58:        /* allocate memory for the ~ed version of src */
        !            59:        checkmem();
        !            60:        start = cpy = (char *)malloc((unsigned)(len + 1));
        !            61:        if (!cpy)
        !            62:        {
        !            63:                regerror("Not enough memory for ~ expansion");
        !            64:                return;
        !            65:        }
        !            66: 
        !            67:        /* copy src into start, replacing the ~s by the previous text */
        !            68:        while (*src)
        !            69:        {
        !            70: # ifndef NO_MAGIC
        !            71:                if (*o_magic && *src == '~')
        !            72:                {
        !            73:                        strcpy(cpy, prev);
        !            74:                        cpy += strlen(prev);
        !            75:                        src++;
        !            76:                }
        !            77:                else if (!*o_magic && *src == '\\' && *(src + 1) == '~')
        !            78: # else /* NO_MAGIC */
        !            79:                if (*src == '\\' && *(src + 1) == '~')
        !            80: # endif /* NO_MAGIC */
        !            81:                {
        !            82:                        strcpy(cpy, prev);
        !            83:                        cpy += strlen(prev);
        !            84:                        src += 2;
        !            85:                }
        !            86:                else
        !            87:                {
        !            88:                        *cpy++ = *src++;
        !            89:                }
        !            90:        }
        !            91:        *cpy = '\0';
        !            92: #ifdef DEBUG
        !            93:        if ((int)(cpy - start) != len)
        !            94:        {
        !            95:                msg("Bug in regsub.c! Predicted length = %d, Actual length = %d", len, (int)(cpy - start));
        !            96:        }
        !            97: #endif
        !            98:        checkmem();
        !            99: 
        !           100:        /* remember this as the "previous" for next time */
        !           101:        if (prev)
        !           102:                _free_(prev);
        !           103:        prev = src = start;
        !           104: 
        !           105: #endif /* undef CRUNCH */
        !           106: 
        !           107:        start = src;
        !           108:        while ((c = *src++) != '\0')
        !           109:        {
        !           110: #ifndef NO_MAGIC
        !           111:                /* recognize any meta characters */
        !           112:                if (c == '&' && *o_magic)
        !           113:                {
        !           114:                        cpy = re->startp[0];
        !           115:                        end = re->endp[0];
        !           116:                }
        !           117:                else
        !           118: #endif /* not NO_MAGIC */
        !           119:                if (c == '\\')
        !           120:                {
        !           121:                        c = *src++;
        !           122:                        switch (c)
        !           123:                        {
        !           124: #ifndef NO_MAGIC
        !           125:                          case '0':
        !           126:                          case '1':
        !           127:                          case '2':
        !           128:                          case '3':
        !           129:                          case '4':
        !           130:                          case '5':
        !           131:                          case '6':
        !           132:                          case '7':
        !           133:                          case '8':
        !           134:                          case '9':
        !           135:                                /* \0 thru \9 mean "copy subexpression" */
        !           136:                                c -= '0';
        !           137:                                cpy = re->startp[c];
        !           138:                                end = re->endp[c];
        !           139:                                break;
        !           140: # ifndef CRUNCH
        !           141:                          case 'U':
        !           142:                          case 'u':
        !           143:                          case 'L':
        !           144:                          case 'l':
        !           145:                                /* \U and \L mean "convert to upper/lowercase" */
        !           146:                                mod = c;
        !           147:                                continue;
        !           148: 
        !           149:                          case 'E':
        !           150:                          case 'e':
        !           151:                                /* \E ends the \U or \L */
        !           152:                                mod = 0;
        !           153:                                continue;
        !           154: # endif /* not CRUNCH */
        !           155:                          case '&':
        !           156:                                /* "\&" means "original text" */
        !           157:                                if (*o_magic)
        !           158:                                {
        !           159:                                        *dst++ = c;
        !           160:                                        continue;
        !           161:                                }
        !           162:                                cpy = re->startp[0];
        !           163:                                end = re->endp[0];
        !           164:                                break;
        !           165: 
        !           166: #else /* NO_MAGIC */
        !           167:                          case '&':
        !           168:                                /* "\&" means "original text" */
        !           169:                                cpy = re->startp[0];
        !           170:                                end = re->endp[0];
        !           171:                                break;
        !           172: #endif /* NO_MAGIC */
        !           173:                          default:
        !           174:                                /* ordinary char preceded by backslash */
        !           175:                                *dst++ = c;
        !           176:                                continue;
        !           177:                        }
        !           178:                }
        !           179: #ifndef CRUNCH
        !           180: # if OSK
        !           181:                else if (c == '\l')
        !           182: # else
        !           183:                else if (c == '\r')
        !           184: # endif
        !           185:                {
        !           186:                        /* transliterate ^M into newline */
        !           187:                        *dst++ = '\n';
        !           188:                        continue;
        !           189:                }
        !           190: #endif /* !CRUNCH */
        !           191:                else
        !           192:                {
        !           193:                        /* ordinary character, so just copy it */
        !           194:                        *dst++ = c;
        !           195:                        continue;
        !           196:                }
        !           197: 
        !           198:                /* Note: to reach this point in the code, we must have evaded
        !           199:                 * all "continue" statements.  To do that, we must have hit
        !           200:                 * a metacharacter that involves copying.
        !           201:                 */
        !           202: 
        !           203:                /* if there is nothing to copy, loop */
        !           204:                if (!cpy)
        !           205:                        continue;
        !           206: 
        !           207:                /* copy over a portion of the original */
        !           208:                while (cpy < end)
        !           209:                {
        !           210: #ifndef NO_MAGIC
        !           211: # ifndef CRUNCH
        !           212:                        switch (mod)
        !           213:                        {
        !           214:                          case 'U':
        !           215:                          case 'u':
        !           216:                                /* convert to uppercase */
        !           217:                                *dst++ = toupper(*cpy++);
        !           218:                                break;
        !           219: 
        !           220:                          case 'L':
        !           221:                          case 'l':
        !           222:                                /* convert to lowercase */
        !           223:                                *dst++ = tolower(*cpy++);
        !           224:                                break;
        !           225: 
        !           226:                          default:
        !           227:                                /* copy without any conversion */
        !           228:                                *dst++ = *cpy++;
        !           229:                        }
        !           230: 
        !           231:                        /* \u and \l end automatically after the first char */
        !           232:                        if (mod && (mod == 'u' || mod == 'l'))
        !           233:                        {
        !           234:                                mod = 0;
        !           235:                        }
        !           236: # else /* CRUNCH */
        !           237:                        *dst++ = *cpy++;
        !           238: # endif /* CRUNCH */
        !           239: #else /* NO_MAGIC */
        !           240:                        *dst++ = *cpy++;
        !           241: #endif /* NO_MAGIC */
        !           242:                }
        !           243:        }
        !           244:        *dst = '\0';
        !           245: }

unix.superglobalmegacorp.com

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