Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 275 lines (232 sloc) 7.423 kb
6335386 Martin Dietze Import Elvis 1.8 (written by Steve Kirkendall)
authored
1 /* misc.c */
cf92e3b Martin Dietze Import Elvis 2.0 (written by Steve Kirkendall)
authored
2 /* Copyright 1995 by Steve Kirkendall */
3
4
5 #include "elvis.h"
9f1c6f0 Martin Dietze 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 Martin Dietze Import Elvis 2.0 (written by Steve Kirkendall)
authored
9
6335386 Martin Dietze Import Elvis 1.8 (written by Steve Kirkendall)
authored
10
11
cf92e3b Martin Dietze Import Elvis 2.0 (written by Steve Kirkendall)
authored
12 /* This is used as a zero-length string */
13 CHAR empty[1];
6335386 Martin Dietze Import Elvis 1.8 (written by Steve Kirkendall)
authored
14
15
16
cf92e3b Martin Dietze Import Elvis 2.0 (written by Steve Kirkendall)
authored
17 /* This is used when we need a bunch of blanks */
9f1c6f0 Martin Dietze Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
18 CHAR blanks[80] = {
19 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
20 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
21 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
22 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
23 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
24 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
25 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
26 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '
27 };
6335386 Martin Dietze Import Elvis 1.8 (written by Steve Kirkendall)
authored
28
cf92e3b Martin Dietze 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 Martin Dietze 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 Martin Dietze Import Elvis 2.0 (written by Steve Kirkendall)
authored
61 int buildCHAR(refstr, ch)
9f1c6f0 Martin Dietze Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
62 #endif
cf92e3b Martin Dietze 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 Martin Dietze Import Elvis 1.8 (written by Steve Kirkendall)
authored
65 {
cf92e3b Martin Dietze 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 Martin Dietze Import Elvis 1.8 (written by Steve Kirkendall)
authored
69
cf92e3b Martin Dietze 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 Martin Dietze Import Elvis 1.8 (written by Steve Kirkendall)
authored
72 {
cf92e3b Martin Dietze Import Elvis 2.0 (written by Steve Kirkendall)
authored
73 len = 0;
9f1c6f0 Martin Dietze 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 Martin Dietze Import Elvis 2.0 (written by Steve Kirkendall)
authored
77 *refstr = (CHAR *)safealloc(GRANULARITY, sizeof(CHAR));
9f1c6f0 Martin Dietze Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
78 #endif
6335386 Martin Dietze Import Elvis 1.8 (written by Steve Kirkendall)
authored
79 }
80
cf92e3b Martin Dietze 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 Martin Dietze Import Elvis 1.8 (written by Steve Kirkendall)
authored
85 {
9f1c6f0 Martin Dietze 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 Martin Dietze Import Elvis 2.1 (written by Steve Kirkendall)
authored
89 newp = (CHAR *)safealloc(len + 1 + GRANULARITY, sizeof(CHAR));
9f1c6f0 Martin Dietze Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
90 #endif
cf92e3b Martin Dietze Import Elvis 2.0 (written by Steve Kirkendall)
authored
91 memcpy(newp, *refstr, len * sizeof(CHAR));
92 safefree(*refstr);
93 *refstr = newp;
6335386 Martin Dietze Import Elvis 1.8 (written by Steve Kirkendall)
authored
94 }
95
cf92e3b Martin Dietze 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 Martin Dietze Import Elvis 1.8 (written by Steve Kirkendall)
authored
100 }
101
102
8d1ac0c Martin Dietze 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 Martin Dietze 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 Martin Dietze Import Elvis 2.1 (written by Steve Kirkendall)
authored
111 int buildstr(refstr, add)
9f1c6f0 Martin Dietze Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
112 #endif
8d1ac0c Martin Dietze 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 Martin Dietze Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
119 #ifdef DEBUG_ALLOC
120 len = _buildCHAR(file, line, refstr, *add);
121 #else
8d1ac0c Martin Dietze Import Elvis 2.1 (written by Steve Kirkendall)
authored
122 len = buildCHAR(refstr, *add);
9f1c6f0 Martin Dietze Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
123 #endif
8d1ac0c Martin Dietze Import Elvis 2.1 (written by Steve Kirkendall)
authored
124 return len;
125 }
126
127
cf92e3b Martin Dietze 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 Martin Dietze Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
135 MARK wordatcursor(cursor, apostrophe)
cf92e3b Martin Dietze Import Elvis 2.0 (written by Steve Kirkendall)
authored
136 MARK cursor; /* some point in the word */
9f1c6f0 Martin Dietze Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
137 ELVBOOL apostrophe; /* allow apostrophe between letters? */
6335386 Martin Dietze Import Elvis 1.8 (written by Steve Kirkendall)
authored
138 {
cf92e3b Martin Dietze Import Elvis 2.0 (written by Steve Kirkendall)
authored
139 static MARKBUF retmark;/* the return value */
140 CHAR *p;
9f1c6f0 Martin Dietze Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
141 CHAR prev;
6335386 Martin Dietze Import Elvis 1.8 (written by Steve Kirkendall)
authored
142
cf92e3b Martin Dietze Import Elvis 2.0 (written by Steve Kirkendall)
authored
143 /* If "cursor" is NULL, fail */
144 if (!cursor)
6335386 Martin Dietze Import Elvis 1.8 (written by Steve Kirkendall)
authored
145 {
cf92e3b Martin Dietze Import Elvis 2.0 (written by Steve Kirkendall)
authored
146 return NULL;
6335386 Martin Dietze Import Elvis 1.8 (written by Steve Kirkendall)
authored
147 }
cf92e3b Martin Dietze 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 Martin Dietze Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
151 if (!p || (!elvalnum(*p) && *p != '_' && !(apostrophe && *p == '\'')))
cf92e3b Martin Dietze 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 Martin Dietze Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
161 prev = *p;
cf92e3b Martin Dietze Import Elvis 2.0 (written by Steve Kirkendall)
authored
162 scanprev(&p);
163 markaddoffset(&retmark, -1);
9f1c6f0 Martin Dietze Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
164 } while (p && (elvalnum(*p) || *p == '_' || (apostrophe && *p == '\'' && prev != '\'')));
cf92e3b Martin Dietze Import Elvis 2.0 (written by Steve Kirkendall)
authored
165 markaddoffset(&retmark, 1);
166
9f1c6f0 Martin Dietze 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 Martin Dietze 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 Martin Dietze Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
175 prev = *p;
cf92e3b Martin Dietze Import Elvis 2.0 (written by Steve Kirkendall)
authored
176 scannext(&p);
9f1c6f0 Martin Dietze 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 Martin Dietze 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 Martin Dietze Import Elvis 1.8 (written by Steve Kirkendall)
authored
198 }
8d1ac0c Martin Dietze 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 Martin Dietze Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
217 if ((*str == '\\' && str[1] && !elvalnum(str[1]))
8d1ac0c Martin Dietze 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 Martin Dietze 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.