blob: 1c53a457d46ba17e3215f65476e3771a129de8e0 [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */
2
Jari Aalto31859422009-01-12 13:36:28 +00003/* Copyright (C) 1988-2009 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00004
Jari Aalto31859422009-01-12 13:36:28 +00005 This file is part of the GNU Readline Library (Readline), a library
6 for reading lines of text with interactive input and history editing.
Jari Aalto726f6381996-08-26 18:22:31 +00007
Jari Aalto31859422009-01-12 13:36:28 +00008 Readline is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
Jari Aalto726f6381996-08-26 18:22:31 +000012
Jari Aalto31859422009-01-12 13:36:28 +000013 Readline is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
Jari Aalto726f6381996-08-26 18:22:31 +000017
18 You should have received a copy of the GNU General Public License
Jari Aalto31859422009-01-12 13:36:28 +000019 along with Readline. If not, see <http://www.gnu.org/licenses/>.
20*/
Jari Aalto726f6381996-08-26 18:22:31 +000021
Jari Aaltoccc6cda1996-12-23 17:02:34 +000022#if defined (HAVE_CONFIG_H)
23# include <config.h>
24#endif
25
Jari Aaltod166f041997-06-05 14:59:13 +000026#if defined (HAVE_UNISTD_H)
Jari Aaltocce855b1998-04-17 19:52:44 +000027# ifdef _MINIX
28# include <sys/types.h>
29# endif
Jari Aaltod166f041997-06-05 14:59:13 +000030# include <unistd.h>
31#endif
32
Jari Aalto726f6381996-08-26 18:22:31 +000033#if defined (HAVE_STRING_H)
34# include <string.h>
35#else /* !HAVE_STRING_H */
36# include <strings.h>
37#endif /* !HAVE_STRING_H */
38
39#if defined (HAVE_STDLIB_H)
40# include <stdlib.h>
41#else
42# include "ansi_stdlib.h"
43#endif /* HAVE_STDLIB_H */
44
Jari Aalto726f6381996-08-26 18:22:31 +000045#include <sys/types.h>
Jari Aalto95732b42005-12-07 14:08:12 +000046#if defined (HAVE_PWD_H)
Jari Aalto726f6381996-08-26 18:22:31 +000047#include <pwd.h>
Jari Aalto95732b42005-12-07 14:08:12 +000048#endif
Jari Aalto726f6381996-08-26 18:22:31 +000049
Jari Aaltoccc6cda1996-12-23 17:02:34 +000050#include "tilde.h"
51
Jari Aaltobb706242000-03-17 21:46:59 +000052#if defined (TEST) || defined (STATIC_MALLOC)
Jari Aaltof73dda02001-11-13 17:56:06 +000053static void *xmalloc (), *xrealloc ();
Jari Aaltobb706242000-03-17 21:46:59 +000054#else
Jari Aaltof73dda02001-11-13 17:56:06 +000055# include "xmalloc.h"
Jari Aaltobb706242000-03-17 21:46:59 +000056#endif /* TEST || STATIC_MALLOC */
57
Jari Aaltoccc6cda1996-12-23 17:02:34 +000058#if !defined (HAVE_GETPW_DECLS)
Jari Aalto95732b42005-12-07 14:08:12 +000059# if defined (HAVE_GETPWUID)
Jari Aaltof73dda02001-11-13 17:56:06 +000060extern struct passwd *getpwuid PARAMS((uid_t));
Jari Aalto95732b42005-12-07 14:08:12 +000061# endif
62# if defined (HAVE_GETPWNAM)
Jari Aaltof73dda02001-11-13 17:56:06 +000063extern struct passwd *getpwnam PARAMS((const char *));
Jari Aalto95732b42005-12-07 14:08:12 +000064# endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +000065#endif /* !HAVE_GETPW_DECLS */
Jari Aalto726f6381996-08-26 18:22:31 +000066
67#if !defined (savestring)
Jari Aaltof73dda02001-11-13 17:56:06 +000068#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x))
Jari Aalto726f6381996-08-26 18:22:31 +000069#endif /* !savestring */
70
71#if !defined (NULL)
72# if defined (__STDC__)
73# define NULL ((void *) 0)
74# else
75# define NULL 0x0
76# endif /* !__STDC__ */
77#endif /* !NULL */
78
Jari Aaltob72432f1999-02-19 17:11:39 +000079/* If being compiled as part of bash, these will be satisfied from
80 variables.o. If being compiled as part of readline, they will
81 be satisfied from shell.o. */
Jari Aaltof73dda02001-11-13 17:56:06 +000082extern char *sh_get_home_dir PARAMS((void));
83extern char *sh_get_env_value PARAMS((const char *));
Jari Aaltob72432f1999-02-19 17:11:39 +000084
Jari Aalto726f6381996-08-26 18:22:31 +000085/* The default value of tilde_additional_prefixes. This is set to
86 whitespace preceding a tilde so that simple programs which do not
87 perform any word separation get desired behaviour. */
Jari Aalto28ef6c32001-04-06 19:14:31 +000088static const char *default_prefixes[] =
89 { " ~", "\t~", (const char *)NULL };
Jari Aalto726f6381996-08-26 18:22:31 +000090
91/* The default value of tilde_additional_suffixes. This is set to
92 whitespace or newline so that simple programs which do not
93 perform any word separation get desired behaviour. */
Jari Aalto28ef6c32001-04-06 19:14:31 +000094static const char *default_suffixes[] =
95 { " ", "\n", (const char *)NULL };
Jari Aalto726f6381996-08-26 18:22:31 +000096
Jari Aaltod166f041997-06-05 14:59:13 +000097/* If non-null, this contains the address of a function that the application
98 wants called before trying the standard tilde expansions. The function
99 is called with the text sans tilde, and returns a malloc()'ed string
100 which is the expansion, or a NULL pointer if the expansion fails. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000101tilde_hook_func_t *tilde_expansion_preexpansion_hook = (tilde_hook_func_t *)NULL;
Jari Aaltod166f041997-06-05 14:59:13 +0000102
Jari Aalto726f6381996-08-26 18:22:31 +0000103/* If non-null, this contains the address of a function to call if the
104 standard meaning for expanding a tilde fails. The function is called
105 with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
106 which is the expansion, or a NULL pointer if there is no expansion. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000107tilde_hook_func_t *tilde_expansion_failure_hook = (tilde_hook_func_t *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +0000108
109/* When non-null, this is a NULL terminated array of strings which
110 are duplicates for a tilde prefix. Bash uses this to expand
111 `=~' and `:~'. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000112char **tilde_additional_prefixes = (char **)default_prefixes;
Jari Aalto726f6381996-08-26 18:22:31 +0000113
114/* When non-null, this is a NULL terminated array of strings which match
115 the end of a username, instead of just "/". Bash sets this to
116 `:' and `=~'. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000117char **tilde_additional_suffixes = (char **)default_suffixes;
Jari Aalto726f6381996-08-26 18:22:31 +0000118
Jari Aaltof73dda02001-11-13 17:56:06 +0000119static int tilde_find_prefix PARAMS((const char *, int *));
120static int tilde_find_suffix PARAMS((const char *));
121static char *isolate_tilde_prefix PARAMS((const char *, int *));
122static char *glue_prefix_and_suffix PARAMS((char *, const char *, int));
123
Jari Aalto726f6381996-08-26 18:22:31 +0000124/* Find the start of a tilde expansion in STRING, and return the index of
125 the tilde which starts the expansion. Place the length of the text
126 which identified this tilde starter in LEN, excluding the tilde itself. */
127static int
128tilde_find_prefix (string, len)
Jari Aaltof73dda02001-11-13 17:56:06 +0000129 const char *string;
Jari Aalto726f6381996-08-26 18:22:31 +0000130 int *len;
131{
132 register int i, j, string_len;
Jari Aaltobb706242000-03-17 21:46:59 +0000133 register char **prefixes;
134
135 prefixes = tilde_additional_prefixes;
Jari Aalto726f6381996-08-26 18:22:31 +0000136
137 string_len = strlen (string);
138 *len = 0;
139
Jari Aaltod166f041997-06-05 14:59:13 +0000140 if (*string == '\0' || *string == '~')
Jari Aalto726f6381996-08-26 18:22:31 +0000141 return (0);
142
143 if (prefixes)
144 {
145 for (i = 0; i < string_len; i++)
146 {
147 for (j = 0; prefixes[j]; j++)
148 {
149 if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0)
150 {
151 *len = strlen (prefixes[j]) - 1;
152 return (i + *len);
153 }
154 }
155 }
156 }
157 return (string_len);
158}
159
160/* Find the end of a tilde expansion in STRING, and return the index of
161 the character which ends the tilde definition. */
162static int
163tilde_find_suffix (string)
Jari Aaltof73dda02001-11-13 17:56:06 +0000164 const char *string;
Jari Aalto726f6381996-08-26 18:22:31 +0000165{
166 register int i, j, string_len;
Jari Aaltod166f041997-06-05 14:59:13 +0000167 register char **suffixes;
Jari Aalto726f6381996-08-26 18:22:31 +0000168
Jari Aaltod166f041997-06-05 14:59:13 +0000169 suffixes = tilde_additional_suffixes;
Jari Aalto726f6381996-08-26 18:22:31 +0000170 string_len = strlen (string);
171
172 for (i = 0; i < string_len; i++)
173 {
Jari Aaltobb706242000-03-17 21:46:59 +0000174#if defined (__MSDOS__)
175 if (string[i] == '/' || string[i] == '\\' /* || !string[i] */)
176#else
Jari Aaltod166f041997-06-05 14:59:13 +0000177 if (string[i] == '/' /* || !string[i] */)
Jari Aaltobb706242000-03-17 21:46:59 +0000178#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000179 break;
180
181 for (j = 0; suffixes && suffixes[j]; j++)
182 {
183 if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0)
184 return (i);
185 }
186 }
187 return (i);
188}
189
190/* Return a new string which is the result of tilde expanding STRING. */
191char *
192tilde_expand (string)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000193 const char *string;
Jari Aalto726f6381996-08-26 18:22:31 +0000194{
Jari Aaltod166f041997-06-05 14:59:13 +0000195 char *result;
Jari Aalto726f6381996-08-26 18:22:31 +0000196 int result_size, result_index;
197
Jari Aaltod166f041997-06-05 14:59:13 +0000198 result_index = result_size = 0;
199 if (result = strchr (string, '~'))
Jari Aaltof73dda02001-11-13 17:56:06 +0000200 result = (char *)xmalloc (result_size = (strlen (string) + 16));
Jari Aaltod166f041997-06-05 14:59:13 +0000201 else
Jari Aaltof73dda02001-11-13 17:56:06 +0000202 result = (char *)xmalloc (result_size = (strlen (string) + 1));
Jari Aalto726f6381996-08-26 18:22:31 +0000203
204 /* Scan through STRING expanding tildes as we come to them. */
205 while (1)
206 {
207 register int start, end;
208 char *tilde_word, *expansion;
209 int len;
210
211 /* Make START point to the tilde which starts the expansion. */
212 start = tilde_find_prefix (string, &len);
213
214 /* Copy the skipped text into the result. */
215 if ((result_index + start + 1) > result_size)
Jari Aaltof73dda02001-11-13 17:56:06 +0000216 result = (char *)xrealloc (result, 1 + (result_size += (start + 20)));
Jari Aalto726f6381996-08-26 18:22:31 +0000217
218 strncpy (result + result_index, string, start);
219 result_index += start;
220
221 /* Advance STRING to the starting tilde. */
222 string += start;
223
224 /* Make END be the index of one after the last character of the
225 username. */
226 end = tilde_find_suffix (string);
227
228 /* If both START and END are zero, we are all done. */
229 if (!start && !end)
230 break;
231
232 /* Expand the entire tilde word, and copy it into RESULT. */
Jari Aaltof73dda02001-11-13 17:56:06 +0000233 tilde_word = (char *)xmalloc (1 + end);
Jari Aalto726f6381996-08-26 18:22:31 +0000234 strncpy (tilde_word, string, end);
235 tilde_word[end] = '\0';
236 string += end;
237
238 expansion = tilde_expand_word (tilde_word);
Jari Aalto31859422009-01-12 13:36:28 +0000239 xfree (tilde_word);
Jari Aalto726f6381996-08-26 18:22:31 +0000240
241 len = strlen (expansion);
Jari Aalto28ef6c32001-04-06 19:14:31 +0000242#ifdef __CYGWIN__
Jari Aaltobb706242000-03-17 21:46:59 +0000243 /* Fix for Cygwin to prevent ~user/xxx from expanding to //xxx when
Jari Aalto28ef6c32001-04-06 19:14:31 +0000244 $HOME for `user' is /. On cygwin, // denotes a network drive. */
Jari Aaltobb706242000-03-17 21:46:59 +0000245 if (len > 1 || *expansion != '/' || *string != '/')
246#endif
247 {
248 if ((result_index + len + 1) > result_size)
Jari Aaltof73dda02001-11-13 17:56:06 +0000249 result = (char *)xrealloc (result, 1 + (result_size += (len + 20)));
Jari Aalto726f6381996-08-26 18:22:31 +0000250
Jari Aaltobb706242000-03-17 21:46:59 +0000251 strcpy (result + result_index, expansion);
252 result_index += len;
253 }
Jari Aalto31859422009-01-12 13:36:28 +0000254 xfree (expansion);
Jari Aalto726f6381996-08-26 18:22:31 +0000255 }
256
257 result[result_index] = '\0';
258
259 return (result);
260}
261
Jari Aaltod166f041997-06-05 14:59:13 +0000262/* Take FNAME and return the tilde prefix we want expanded. If LENP is
263 non-null, the index of the end of the prefix into FNAME is returned in
264 the location it points to. */
265static char *
266isolate_tilde_prefix (fname, lenp)
Jari Aaltof73dda02001-11-13 17:56:06 +0000267 const char *fname;
Jari Aaltod166f041997-06-05 14:59:13 +0000268 int *lenp;
269{
270 char *ret;
271 int i;
272
Jari Aaltof73dda02001-11-13 17:56:06 +0000273 ret = (char *)xmalloc (strlen (fname));
Jari Aaltobb706242000-03-17 21:46:59 +0000274#if defined (__MSDOS__)
275 for (i = 1; fname[i] && fname[i] != '/' && fname[i] != '\\'; i++)
276#else
Jari Aaltod166f041997-06-05 14:59:13 +0000277 for (i = 1; fname[i] && fname[i] != '/'; i++)
Jari Aaltobb706242000-03-17 21:46:59 +0000278#endif
Jari Aaltod166f041997-06-05 14:59:13 +0000279 ret[i - 1] = fname[i];
280 ret[i - 1] = '\0';
281 if (lenp)
282 *lenp = i;
283 return ret;
284}
285
Jari Aalto95732b42005-12-07 14:08:12 +0000286#if 0
287/* Public function to scan a string (FNAME) beginning with a tilde and find
288 the portion of the string that should be passed to the tilde expansion
289 function. Right now, it just calls tilde_find_suffix and allocates new
290 memory, but it can be expanded to do different things later. */
291char *
292tilde_find_word (fname, flags, lenp)
293 const char *fname;
294 int flags, *lenp;
295{
296 int x;
297 char *r;
298
299 x = tilde_find_suffix (fname);
300 if (x == 0)
301 {
302 r = savestring (fname);
303 if (lenp)
304 *lenp = 0;
305 }
306 else
307 {
308 r = (char *)xmalloc (1 + x);
309 strncpy (r, fname, x);
310 r[x] = '\0';
311 if (lenp)
312 *lenp = x;
313 }
314
315 return r;
316}
317#endif
318
Jari Aaltod166f041997-06-05 14:59:13 +0000319/* Return a string that is PREFIX concatenated with SUFFIX starting at
320 SUFFIND. */
321static char *
322glue_prefix_and_suffix (prefix, suffix, suffind)
Jari Aaltof73dda02001-11-13 17:56:06 +0000323 char *prefix;
324 const char *suffix;
Jari Aaltod166f041997-06-05 14:59:13 +0000325 int suffind;
326{
327 char *ret;
328 int plen, slen;
329
330 plen = (prefix && *prefix) ? strlen (prefix) : 0;
331 slen = strlen (suffix + suffind);
Jari Aaltof73dda02001-11-13 17:56:06 +0000332 ret = (char *)xmalloc (plen + slen + 1);
Jari Aaltobb706242000-03-17 21:46:59 +0000333 if (plen)
Jari Aaltod166f041997-06-05 14:59:13 +0000334 strcpy (ret, prefix);
335 strcpy (ret + plen, suffix + suffind);
336 return ret;
337}
338
Jari Aalto726f6381996-08-26 18:22:31 +0000339/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
Jari Aaltod166f041997-06-05 14:59:13 +0000340 tilde. If there is no expansion, call tilde_expansion_failure_hook.
341 This always returns a newly-allocated string, never static storage. */
Jari Aalto726f6381996-08-26 18:22:31 +0000342char *
343tilde_expand_word (filename)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000344 const char *filename;
Jari Aalto726f6381996-08-26 18:22:31 +0000345{
Jari Aaltod166f041997-06-05 14:59:13 +0000346 char *dirname, *expansion, *username;
347 int user_len;
348 struct passwd *user_entry;
Jari Aalto726f6381996-08-26 18:22:31 +0000349
Jari Aaltod166f041997-06-05 14:59:13 +0000350 if (filename == 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000351 return ((char *)NULL);
Jari Aalto726f6381996-08-26 18:22:31 +0000352
Jari Aaltod166f041997-06-05 14:59:13 +0000353 if (*filename != '~')
354 return (savestring (filename));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000355
Jari Aaltod166f041997-06-05 14:59:13 +0000356 /* A leading `~/' or a bare `~' is *always* translated to the value of
357 $HOME or the home directory of the current user, regardless of any
358 preexpansion hook. */
359 if (filename[1] == '\0' || filename[1] == '/')
Jari Aalto726f6381996-08-26 18:22:31 +0000360 {
Jari Aaltod166f041997-06-05 14:59:13 +0000361 /* Prefix $HOME to the rest of the string. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000362 expansion = sh_get_env_value ("HOME");
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000363
364 /* If there is no HOME variable, look up the directory in
365 the password database. */
Jari Aaltod166f041997-06-05 14:59:13 +0000366 if (expansion == 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000367 expansion = sh_get_home_dir ();
Jari Aaltod166f041997-06-05 14:59:13 +0000368
369 return (glue_prefix_and_suffix (expansion, filename, 1));
370 }
371
372 username = isolate_tilde_prefix (filename, &user_len);
373
374 if (tilde_expansion_preexpansion_hook)
375 {
376 expansion = (*tilde_expansion_preexpansion_hook) (username);
377 if (expansion)
Jari Aalto726f6381996-08-26 18:22:31 +0000378 {
Jari Aaltod166f041997-06-05 14:59:13 +0000379 dirname = glue_prefix_and_suffix (expansion, filename, user_len);
Jari Aalto31859422009-01-12 13:36:28 +0000380 xfree (username);
Chet Ramey495aee42011-11-22 19:11:26 -0500381 xfree (expansion);
Jari Aaltod166f041997-06-05 14:59:13 +0000382 return (dirname);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000383 }
Jari Aaltod166f041997-06-05 14:59:13 +0000384 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000385
Jari Aaltod166f041997-06-05 14:59:13 +0000386 /* No preexpansion hook, or the preexpansion hook failed. Look in the
387 password database. */
388 dirname = (char *)NULL;
Jari Aalto95732b42005-12-07 14:08:12 +0000389#if defined (HAVE_GETPWNAM)
Jari Aaltod166f041997-06-05 14:59:13 +0000390 user_entry = getpwnam (username);
Jari Aalto95732b42005-12-07 14:08:12 +0000391#else
392 user_entry = 0;
393#endif
Jari Aaltod166f041997-06-05 14:59:13 +0000394 if (user_entry == 0)
395 {
396 /* If the calling program has a special syntax for expanding tildes,
397 and we couldn't find a standard expansion, then let them try. */
398 if (tilde_expansion_failure_hook)
399 {
400 expansion = (*tilde_expansion_failure_hook) (username);
401 if (expansion)
402 {
403 dirname = glue_prefix_and_suffix (expansion, filename, user_len);
Chet Ramey495aee42011-11-22 19:11:26 -0500404 xfree (expansion);
Jari Aaltod166f041997-06-05 14:59:13 +0000405 }
406 }
Jari Aaltod166f041997-06-05 14:59:13 +0000407 /* If we don't have a failure hook, or if the failure hook did not
408 expand the tilde, return a copy of what we were passed. */
409 if (dirname == 0)
410 dirname = savestring (filename);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000411 }
Jari Aalto06285672006-10-10 14:15:34 +0000412#if defined (HAVE_GETPWENT)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000413 else
Jari Aalto06285672006-10-10 14:15:34 +0000414 dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len);
415#endif
416
Jari Aalto31859422009-01-12 13:36:28 +0000417 xfree (username);
Jari Aalto95732b42005-12-07 14:08:12 +0000418#if defined (HAVE_GETPWENT)
Jari Aaltod166f041997-06-05 14:59:13 +0000419 endpwent ();
Jari Aalto95732b42005-12-07 14:08:12 +0000420#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000421 return (dirname);
422}
423
424
425#if defined (TEST)
426#undef NULL
427#include <stdio.h>
428
429main (argc, argv)
430 int argc;
431 char **argv;
432{
433 char *result, line[512];
434 int done = 0;
435
436 while (!done)
437 {
438 printf ("~expand: ");
439 fflush (stdout);
440
441 if (!gets (line))
442 strcpy (line, "done");
443
444 if ((strcmp (line, "done") == 0) ||
445 (strcmp (line, "quit") == 0) ||
446 (strcmp (line, "exit") == 0))
447 {
448 done = 1;
449 break;
450 }
451
452 result = tilde_expand (line);
453 printf (" --> %s\n", result);
454 free (result);
455 }
456 exit (0);
457}
458
459static void memory_error_and_abort ();
460
Jari Aaltof73dda02001-11-13 17:56:06 +0000461static void *
Jari Aalto726f6381996-08-26 18:22:31 +0000462xmalloc (bytes)
Jari Aaltof73dda02001-11-13 17:56:06 +0000463 size_t bytes;
Jari Aalto726f6381996-08-26 18:22:31 +0000464{
Jari Aaltof73dda02001-11-13 17:56:06 +0000465 void *temp = (char *)malloc (bytes);
Jari Aalto726f6381996-08-26 18:22:31 +0000466
467 if (!temp)
468 memory_error_and_abort ();
469 return (temp);
470}
471
Jari Aaltof73dda02001-11-13 17:56:06 +0000472static void *
Jari Aalto726f6381996-08-26 18:22:31 +0000473xrealloc (pointer, bytes)
Jari Aaltof73dda02001-11-13 17:56:06 +0000474 void *pointer;
Jari Aalto726f6381996-08-26 18:22:31 +0000475 int bytes;
476{
Jari Aaltof73dda02001-11-13 17:56:06 +0000477 void *temp;
Jari Aalto726f6381996-08-26 18:22:31 +0000478
479 if (!pointer)
Jari Aaltof73dda02001-11-13 17:56:06 +0000480 temp = malloc (bytes);
Jari Aalto726f6381996-08-26 18:22:31 +0000481 else
Jari Aaltof73dda02001-11-13 17:56:06 +0000482 temp = realloc (pointer, bytes);
Jari Aalto726f6381996-08-26 18:22:31 +0000483
484 if (!temp)
485 memory_error_and_abort ();
486
487 return (temp);
488}
489
490static void
491memory_error_and_abort ()
492{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000493 fprintf (stderr, "readline: out of virtual memory\n");
Jari Aalto726f6381996-08-26 18:22:31 +0000494 abort ();
495}
496
497/*
498 * Local variables:
499 * compile-command: "gcc -g -DTEST -o tilde tilde.c"
500 * end:
501 */
502#endif /* TEST */