|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.