Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 275 lines (232 sloc) 7.423 kB
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
1 /* misc.c */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
2 /* Copyright 1995 by Steve Kirkendall */
3
4
5 #include "elvis.h"
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
6 #ifdef FEATURE_RCSID
7 char id_misc[] = "$Id: misc.c,v 2.20 2003/10/17 17:41:23 steve Exp $";
8 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
9
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
10
11
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
12 /* This is used as a zero-length string */
13 CHAR empty[1];
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
14
15
16
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
17 /* This is used when we need a bunch of blanks */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
18 CHAR blanks[80] = {
19 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
20 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
21 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
22 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
23 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
24 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
25 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
26 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '
27 };
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
28
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
29
30
31 /* These store the args list. The "arglist" variable points to a dynamically
32 * allocated array of (char *) pointers. Each element of the array ppoints to
33 * a dynamically allocated string, except that the last one is NULL. The
34 * "argnext" variable stores the index of the next (not current!) element
35 * to be edited.
36 */
37 char **arglist; /* array of strings (dynamically allocated) */
38 int argnext; /* index into arglist[] of next arg */
39
40
41
42 /* This function appends a single character to a dynamically-allocated
43 * string. A NUL character is always appended after the last character,
44 * but this function also supports NUL characters in the middle of the
45 * string.
46 *
47 * Only one string can be under construction at a time. To start a string,
48 * Call this function with a pointer to a (CHAR *) variable which is NULL.
49 * To append to that string, call this function with a pointer to the same
50 * (CHAR *) variable.
51 *
52 * This function updates the value of the (CHAR *) variable whenever it
53 * reallocates memory. It returns the number of characters added so far,
54 * excluding the terminal NUL.
55 */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
56 #ifdef DEBUG_ALLOC
57 int _buildCHAR(file, line, refstr, ch)
58 char *file;
59 int line;
60 #else
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
61 int buildCHAR(refstr, ch)
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
62 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
63 CHAR **refstr; /* pointer to variable which points to string */
64 _CHAR_ ch; /* character to append to that string */
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
65 {
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
66 static int len; /* length of the string so far */
67 CHAR *newp; /* new memory for the same string */
68 #define GRANULARITY 32 /* minimum number of chars to allocate */
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
69
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
70 /* if the string pointer is currently NULL, then start a new string */
71 if (!*refstr)
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
72 {
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
73 len = 0;
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
74 #ifdef DEBUG_ALLOC
75 *refstr = (CHAR *)_safealloc(file, line, ElvFalse, GRANULARITY, sizeof(CHAR));
76 #else
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
77 *refstr = (CHAR *)safealloc(GRANULARITY, sizeof(CHAR));
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
78 #endif
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
79 }
80
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
81 /* if the string is expanding beyond the current allocated memory,
82 * then allocate some new memory and copy the string into it.
83 */
84 if ((len + 1) % GRANULARITY == 0)
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
85 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
86 #ifdef DEBUG_ALLOC
87 newp = (CHAR *)_safealloc(file, line, ElvFalse, len + 1 + GRANULARITY, sizeof(CHAR));
88 #else
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
89 newp = (CHAR *)safealloc(len + 1 + GRANULARITY, sizeof(CHAR));
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
90 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
91 memcpy(newp, *refstr, len * sizeof(CHAR));
92 safefree(*refstr);
93 *refstr = newp;
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
94 }
95
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
96 /* append the new character, and a NUL character */
97 (*refstr)[len++] = ch;
98 (*refstr)[len] = '\0';
99 return len;
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
100 }
101
102
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
103 /* This function calls buildCHAR() for each character of an argument string.
104 * Note that the string is a plain old "char" string, not a "CHAR" string.
105 */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
106 #ifdef DEBUG_ALLOC
107 int _buildstr(file, line, refstr, add)
108 char *file;
109 int line;
110 #else
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
111 int buildstr(refstr, add)
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
112 #endif
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
113 CHAR **refstr; /* pointer to variable which points to string */
114 char *add; /* a string to be added */
115 {
116 int len;
117
118 for (len = 0; *add; add++)
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
119 #ifdef DEBUG_ALLOC
120 len = _buildCHAR(file, line, refstr, *add);
121 #else
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
122 len = buildCHAR(refstr, *add);
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
123 #endif
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
124 return len;
125 }
126
127
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
128 /* This function finds the endpoints of the word at a given point. Upon
129 * return, the offset of the argument MARK will have been changed to the
130 * character after the end of the word, and this function will return a
131 * static temporary MARK which points to the start of the word. Exception:
132 * If the argument MARK isn't on a word, this function leaves it unchanged
133 * and returns NULL.
134 */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
135 MARK wordatcursor(cursor, apostrophe)
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
136 MARK cursor; /* some point in the word */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
137 ELVBOOL apostrophe; /* allow apostrophe between letters? */
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
138 {
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
139 static MARKBUF retmark;/* the return value */
140 CHAR *p;
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
141 CHAR prev;
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
142
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
143 /* If "cursor" is NULL, fail */
144 if (!cursor)
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
145 {
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
146 return NULL;
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
147 }
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
148
149 /* If "cursor" isn't on a letter, digit, or underscore, then fail */
150 scanalloc(&p, cursor);
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
151 if (!p || (!elvalnum(*p) && *p != '_' && !(apostrophe && *p == '\'')))
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
152 {
153 scanfree(&p);
154 return NULL;
155 }
156
157 /* search back to the start of the word */
158 retmark = *cursor;
159 do
160 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
161 prev = *p;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
162 scanprev(&p);
163 markaddoffset(&retmark, -1);
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
164 } while (p && (elvalnum(*p) || *p == '_' || (apostrophe && *p == '\'' && prev != '\'')));
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
165 markaddoffset(&retmark, 1);
166
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
167 /* can't start on an apostrophe */
168 if (apostrophe && scanchar(&retmark) == '\'')
169 markaddoffset(&retmark, 1);
170
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
171 /* search forward to the end of the word */
172 scanseek(&p, cursor);
173 do
174 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
175 prev = *p;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
176 scannext(&p);
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
177 } while (p && (elvalnum(*p) || *p == '_' || (apostrophe && *p == '\'' && prev != '\'')));
178
179 /* can't end on an apostrophe */
180 if (apostrophe && prev == '\'')
181 {
182 scanprev(&p);
183 }
184
185 /* length must be at least 1 */
186 if (markoffset(scanmark(&p)) - markoffset(&retmark) < 1)
187 {
188 scanfree(&p);
189 return NULL;
190 }
191
192 /* move the cursor to the end of the word */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
193 marksetoffset(cursor, markoffset(scanmark(&p)));
194
195 /* clean up & return the front of the word */
196 scanfree(&p);
197 return &retmark;
6335386 @mbert Import Elvis 1.8 (written by Steve Kirkendall)
authored
198 }
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
199
200
201 /* Return a copy of str with backslashes before chars. The calling function
202 * is responsible for freeing the returned string when it is no longer needed.
203 *
204 * This also adds a backslash before each existing backslash, unless the
205 * existing backslash is followed by a letter or digit, or appears at the end
206 * of str.
207 */
208 CHAR *addquotes(chars, str)
209 CHAR *chars; /* list of chars to be quoted, other than backslash */
210 CHAR *str; /* the string to be quoted */
211 {
212 CHAR *tmp;
213
214 /* build a quoted copy of the string */
215 for (tmp = NULL; *str; str++)
216 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
217 if ((*str == '\\' && str[1] && !elvalnum(str[1]))
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
218 || CHARchr(chars, *str))
219 buildCHAR(&tmp, '\\');
220 buildCHAR(&tmp, *str);
221 }
222
223 /* if empty string, then return "" instead of NULL */
224 if (tmp == NULL)
225 tmp = (CHAR *)safealloc(1, sizeof(CHAR));
226
227 /* return the copy */
228 return tmp;
229 }
230
231 /* Return a copy of str, from which the backslash characters have been
232 * removed if they're followed by certain other characters. This is intended
233 * to be the exact opposite of the addquotes() function.
234 */
235 CHAR *removequotes(chars, str)
236 CHAR *chars; /* list of chars to be quoted, other than backslash */
237 CHAR *str; /* the string to be quoted */
238 {
239 CHAR *tmp;
240
241 /* build an unquoted copy of the string */
242 for (tmp = NULL; *str; str++)
243 {
244 if (*str != '\\'
245 || (!str[1] || (str[1] != '\\' && !CHARchr(chars, str[1]))))
246 buildCHAR(&tmp, *str);
247 }
248
249 /* if empty string, then return "" instead of NULL */
250 if (tmp == NULL)
251 tmp = (CHAR *)safealloc(1, sizeof(CHAR));
252
253 /* return the copy */
254 return tmp;
255 }
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
256
257 /* Compare two strings in a case-insensitive way */
258 int CHARncasecmp(s1, s2, len)
259 CHAR *s1, *s2; /* strings to compare */
260 int len; /* length of the strings to compare */
261 {
262 /* look for a difference */
263 while (len > 0 && elvtolower(*s1) == elvtolower(*s2))
264 {
265 len--;
266 s1++;
267 s2++;
268 }
269
270 /* return the difference */
271 if (len > 0)
272 len = elvtolower(*s1) - elvtolower(*s2);
273 return len;
274 }
Something went wrong with that request. Please try again.