blob: fa3a66718f7421270ec05e8f02d578e22f82d6af [file] [log] [blame]
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001/* util.c -- readline utility functions */
2
Chet Rameyac50fba2014-02-26 09:36:43 -05003/* Copyright (C) 1987-2012 Free Software Foundation, Inc.
Jari Aaltoccc6cda1996-12-23 17:02:34 +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 Aaltoccc6cda1996-12-23 17:02:34 +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
Jari Aaltoccc6cda1996-12-23 17:02:34 +000011 (at your option) any later version.
12
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
Jari Aaltoccc6cda1996-12-23 17:02:34 +000016 GNU General Public License for more details.
17
Jari Aalto31859422009-01-12 13:36:28 +000018 You should have received a copy of the GNU General Public License
19 along with Readline. If not, see <http://www.gnu.org/licenses/>.
20*/
21
Jari Aaltoccc6cda1996-12-23 17:02:34 +000022#define READLINE_LIBRARY
23
24#if defined (HAVE_CONFIG_H)
25# include <config.h>
26#endif
27
Jari Aaltoccc6cda1996-12-23 17:02:34 +000028#include <sys/types.h>
29#include <fcntl.h>
Jari Aaltod166f041997-06-05 14:59:13 +000030#include "posixjmp.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000031
32#if defined (HAVE_UNISTD_H)
33# include <unistd.h> /* for _POSIX_VERSION */
34#endif /* HAVE_UNISTD_H */
35
36#if defined (HAVE_STDLIB_H)
37# include <stdlib.h>
38#else
39# include "ansi_stdlib.h"
40#endif /* HAVE_STDLIB_H */
41
Jari Aaltod166f041997-06-05 14:59:13 +000042#include <stdio.h>
43#include <ctype.h>
44
Jari Aaltoccc6cda1996-12-23 17:02:34 +000045/* System-specific feature definitions and include files. */
46#include "rldefs.h"
Jari Aalto95732b42005-12-07 14:08:12 +000047#include "rlmbutil.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000048
49#if defined (TIOCSTAT_IN_SYS_IOCTL)
50# include <sys/ioctl.h>
51#endif /* TIOCSTAT_IN_SYS_IOCTL */
52
53/* Some standard library routines. */
54#include "readline.h"
55
Jari Aaltobb706242000-03-17 21:46:59 +000056#include "rlprivate.h"
57#include "xmalloc.h"
58
Jari Aaltoccc6cda1996-12-23 17:02:34 +000059/* **************************************************************** */
60/* */
61/* Utility Functions */
62/* */
63/* **************************************************************** */
64
65/* Return 0 if C is not a member of the class of characters that belong
66 in words, or 1 if it is. */
67
68int _rl_allow_pathname_alphabetic_chars = 0;
Jari Aalto31859422009-01-12 13:36:28 +000069static const char * const pathname_alphabetic_chars = "/-_=~.#$";
Jari Aaltoccc6cda1996-12-23 17:02:34 +000070
71int
Jari Aalto28ef6c32001-04-06 19:14:31 +000072rl_alphabetic (c)
Jari Aaltoccc6cda1996-12-23 17:02:34 +000073 int c;
74{
75 if (ALPHABETIC (c))
76 return (1);
77
78 return (_rl_allow_pathname_alphabetic_chars &&
79 strchr (pathname_alphabetic_chars, c) != NULL);
80}
81
Jari Aalto95732b42005-12-07 14:08:12 +000082#if defined (HANDLE_MULTIBYTE)
83int
Chet Ramey00018032011-11-21 20:51:19 -050084_rl_walphabetic (wchar_t wc)
Jari Aalto95732b42005-12-07 14:08:12 +000085{
86 int c;
87
88 if (iswalnum (wc))
89 return (1);
90
91 c = wc & 0177;
92 return (_rl_allow_pathname_alphabetic_chars &&
93 strchr (pathname_alphabetic_chars, c) != NULL);
94}
95#endif
96
Jari Aaltoccc6cda1996-12-23 17:02:34 +000097/* How to abort things. */
98int
99_rl_abort_internal ()
100{
Jari Aalto28ef6c32001-04-06 19:14:31 +0000101 rl_ding ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000102 rl_clear_message ();
Jari Aalto95732b42005-12-07 14:08:12 +0000103 _rl_reset_argument ();
Jari Aalto28ef6c32001-04-06 19:14:31 +0000104 rl_clear_pending_input ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000105
Jari Aalto7117c2d2002-07-17 14:10:11 +0000106 RL_UNSETSTATE (RL_STATE_MACRODEF);
Jari Aalto28ef6c32001-04-06 19:14:31 +0000107 while (rl_executing_macro)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000108 _rl_pop_executing_macro ();
109
Jari Aalto28ef6c32001-04-06 19:14:31 +0000110 rl_last_func = (rl_command_func_t *)NULL;
Chet Rameyac50fba2014-02-26 09:36:43 -0500111#if defined (HAVE_POSIX_SIGSETJMP)
112 siglongjmp (_rl_top_level, 1);
113#else
Jari Aalto31859422009-01-12 13:36:28 +0000114 longjmp (_rl_top_level, 1);
Chet Rameyac50fba2014-02-26 09:36:43 -0500115#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000116 return (0);
117}
118
119int
120rl_abort (count, key)
121 int count, key;
122{
123 return (_rl_abort_internal ());
124}
125
126int
Chet Ramey00018032011-11-21 20:51:19 -0500127_rl_null_function (count, key)
128 int count, key;
129{
130 return 0;
131}
132
133int
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000134rl_tty_status (count, key)
135 int count, key;
136{
137#if defined (TIOCSTAT)
138 ioctl (1, TIOCSTAT, (char *)0);
Jari Aaltob72432f1999-02-19 17:11:39 +0000139 rl_refresh_line (count, key);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000140#else
Jari Aalto28ef6c32001-04-06 19:14:31 +0000141 rl_ding ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000142#endif
143 return 0;
144}
145
146/* Return a copy of the string between FROM and TO.
147 FROM is inclusive, TO is not. */
148char *
149rl_copy_text (from, to)
150 int from, to;
151{
152 register int length;
153 char *copy;
154
155 /* Fix it if the caller is confused. */
156 if (from > to)
157 SWAP (from, to);
158
159 length = to - from;
Jari Aaltof73dda02001-11-13 17:56:06 +0000160 copy = (char *)xmalloc (1 + length);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000161 strncpy (copy, rl_line_buffer + from, length);
162 copy[length] = '\0';
163 return (copy);
164}
165
166/* Increase the size of RL_LINE_BUFFER until it has enough space to hold
167 LEN characters. */
168void
169rl_extend_line_buffer (len)
170 int len;
171{
172 while (len >= rl_line_buffer_len)
173 {
174 rl_line_buffer_len += DEFAULT_BUFFER_SIZE;
Jari Aaltof73dda02001-11-13 17:56:06 +0000175 rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000176 }
177
178 _rl_set_the_line ();
179}
180
Jari Aaltocce855b1998-04-17 19:52:44 +0000181
182/* A function for simple tilde expansion. */
183int
184rl_tilde_expand (ignore, key)
185 int ignore, key;
186{
187 register int start, end;
188 char *homedir, *temp;
189 int len;
190
191 end = rl_point;
192 start = end - 1;
193
194 if (rl_point == rl_end && rl_line_buffer[rl_point] == '~')
195 {
196 homedir = tilde_expand ("~");
197 _rl_replace_text (homedir, start, end);
Jari Aalto31859422009-01-12 13:36:28 +0000198 xfree (homedir);
Jari Aaltocce855b1998-04-17 19:52:44 +0000199 return (0);
200 }
201 else if (rl_line_buffer[start] != '~')
202 {
203 for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--)
204 ;
205 start++;
206 }
207
208 end = start;
209 do
210 end++;
211 while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end);
212
213 if (whitespace (rl_line_buffer[end]) || end >= rl_end)
214 end--;
215
216 /* If the first character of the current word is a tilde, perform
217 tilde expansion and insert the result. If not a tilde, do
218 nothing. */
219 if (rl_line_buffer[start] == '~')
220 {
221 len = end - start + 1;
Jari Aaltof73dda02001-11-13 17:56:06 +0000222 temp = (char *)xmalloc (len + 1);
Jari Aaltocce855b1998-04-17 19:52:44 +0000223 strncpy (temp, rl_line_buffer + start, len);
224 temp[len] = '\0';
225 homedir = tilde_expand (temp);
Jari Aalto31859422009-01-12 13:36:28 +0000226 xfree (temp);
Jari Aaltocce855b1998-04-17 19:52:44 +0000227
228 _rl_replace_text (homedir, start, end);
Jari Aalto31859422009-01-12 13:36:28 +0000229 xfree (homedir);
Jari Aaltocce855b1998-04-17 19:52:44 +0000230 }
231
232 return (0);
233}
234
Jari Aalto31859422009-01-12 13:36:28 +0000235#if defined (USE_VARARGS)
236void
237#if defined (PREFER_STDARG)
238_rl_ttymsg (const char *format, ...)
239#else
240_rl_ttymsg (va_alist)
241 va_dcl
242#endif
243{
244 va_list args;
245#if defined (PREFER_VARARGS)
246 char *format;
247#endif
248
249#if defined (PREFER_STDARG)
250 va_start (args, format);
251#else
252 va_start (args);
253 format = va_arg (args, char *);
254#endif
255
256 fprintf (stderr, "readline: ");
257 vfprintf (stderr, format, args);
258 fprintf (stderr, "\n");
259 fflush (stderr);
260
261 va_end (args);
262
263 rl_forced_update_display ();
264}
265
266void
267#if defined (PREFER_STDARG)
268_rl_errmsg (const char *format, ...)
269#else
270_rl_errmsg (va_alist)
271 va_dcl
272#endif
273{
274 va_list args;
275#if defined (PREFER_VARARGS)
276 char *format;
277#endif
278
279#if defined (PREFER_STDARG)
280 va_start (args, format);
281#else
282 va_start (args);
283 format = va_arg (args, char *);
284#endif
285
286 fprintf (stderr, "readline: ");
287 vfprintf (stderr, format, args);
288 fprintf (stderr, "\n");
289 fflush (stderr);
290
291 va_end (args);
292}
293
294#else /* !USE_VARARGS */
295void
296_rl_ttymsg (format, arg1, arg2)
297 char *format;
298{
299 fprintf (stderr, "readline: ");
300 fprintf (stderr, format, arg1, arg2);
301 fprintf (stderr, "\n");
302
303 rl_forced_update_display ();
304}
305
306void
307_rl_errmsg (format, arg1, arg2)
308 char *format;
309{
310 fprintf (stderr, "readline: ");
311 fprintf (stderr, format, arg1, arg2);
312 fprintf (stderr, "\n");
313}
314#endif /* !USE_VARARGS */
315
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000316/* **************************************************************** */
317/* */
318/* String Utility Functions */
319/* */
320/* **************************************************************** */
321
322/* Determine if s2 occurs in s1. If so, return a pointer to the
323 match in s1. The compare is case insensitive. */
324char *
325_rl_strindex (s1, s2)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000326 register const char *s1, *s2;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000327{
328 register int i, l, len;
329
330 for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++)
331 if (_rl_strnicmp (s1 + i, s2, l) == 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000332 return ((char *) (s1 + i));
333 return ((char *)NULL);
334}
335
Jari Aaltof73dda02001-11-13 17:56:06 +0000336#ifndef HAVE_STRPBRK
Jari Aalto28ef6c32001-04-06 19:14:31 +0000337/* Find the first occurrence in STRING1 of any character from STRING2.
338 Return a pointer to the character in STRING1. */
339char *
340_rl_strpbrk (string1, string2)
341 const char *string1, *string2;
342{
343 register const char *scan;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000344#if defined (HANDLE_MULTIBYTE)
345 mbstate_t ps;
346 register int i, v;
347
348 memset (&ps, 0, sizeof (mbstate_t));
349#endif
Jari Aalto28ef6c32001-04-06 19:14:31 +0000350
351 for (; *string1; string1++)
352 {
353 for (scan = string2; *scan; scan++)
354 {
355 if (*string1 == *scan)
356 return ((char *)string1);
357 }
Jari Aalto7117c2d2002-07-17 14:10:11 +0000358#if defined (HANDLE_MULTIBYTE)
359 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
360 {
361 v = _rl_get_char_len (string1, &ps);
362 if (v > 1)
Jari Aaltob80f6442004-07-27 13:29:18 +0000363 string1 += v - 1; /* -1 to account for auto-increment in loop */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000364 }
365#endif
Jari Aalto28ef6c32001-04-06 19:14:31 +0000366 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000367 return ((char *)NULL);
368}
Jari Aaltof73dda02001-11-13 17:56:06 +0000369#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000370
371#if !defined (HAVE_STRCASECMP)
372/* Compare at most COUNT characters from string1 to string2. Case
Chet Ramey495aee42011-11-22 19:11:26 -0500373 doesn't matter (strncasecmp). */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000374int
375_rl_strnicmp (string1, string2, count)
Chet Rameyac50fba2014-02-26 09:36:43 -0500376 const char *string1;
377 const char *string2;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000378 int count;
379{
Chet Rameyac50fba2014-02-26 09:36:43 -0500380 register const char *s1;
381 register const char *s2;
382 register int d;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000383
Chet Ramey495aee42011-11-22 19:11:26 -0500384 if (count <= 0 || (string1 == string2))
385 return 0;
386
387 s1 = string1;
388 s2 = string2;
389 do
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000390 {
Chet Ramey495aee42011-11-22 19:11:26 -0500391 d = _rl_to_lower (*s1) - _rl_to_lower (*s2); /* XXX - cast to unsigned char? */
392 if (d != 0)
393 return d;
394 if (*s1++ == '\0')
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000395 break;
Chet Ramey495aee42011-11-22 19:11:26 -0500396 s2++;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000397 }
Chet Rameyac50fba2014-02-26 09:36:43 -0500398 while (--count != 0);
Chet Ramey495aee42011-11-22 19:11:26 -0500399
400 return (0);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000401}
402
Chet Ramey495aee42011-11-22 19:11:26 -0500403/* strcmp (), but caseless (strcasecmp). */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000404int
405_rl_stricmp (string1, string2)
Chet Rameyac50fba2014-02-26 09:36:43 -0500406 const char *string1;
407 const char *string2;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000408{
Chet Rameyac50fba2014-02-26 09:36:43 -0500409 register const char *s1;
410 register const char *s2;
411 register int d;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000412
Chet Ramey495aee42011-11-22 19:11:26 -0500413 s1 = string1;
414 s2 = string2;
415
416 if (s1 == s2)
417 return 0;
418
419 while ((d = _rl_to_lower (*s1) - _rl_to_lower (*s2)) == 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000420 {
Chet Ramey495aee42011-11-22 19:11:26 -0500421 if (*s1++ == '\0')
422 return 0;
423 s2++;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000424 }
Chet Ramey495aee42011-11-22 19:11:26 -0500425
426 return (d);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000427}
428#endif /* !HAVE_STRCASECMP */
429
430/* Stupid comparison routine for qsort () ing strings. */
431int
432_rl_qsort_string_compare (s1, s2)
433 char **s1, **s2;
434{
435#if defined (HAVE_STRCOLL)
436 return (strcoll (*s1, *s2));
437#else
438 int result;
439
440 result = **s1 - **s2;
441 if (result == 0)
442 result = strcmp (*s1, *s2);
443
444 return result;
445#endif
446}
447
Jari Aaltof73dda02001-11-13 17:56:06 +0000448/* Function equivalents for the macros defined in chardefs.h. */
449#define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000450
Jari Aaltof73dda02001-11-13 17:56:06 +0000451FUNCTION_FOR_MACRO (_rl_digit_p)
452FUNCTION_FOR_MACRO (_rl_digit_value)
453FUNCTION_FOR_MACRO (_rl_lowercase_p)
454FUNCTION_FOR_MACRO (_rl_pure_alphabetic)
455FUNCTION_FOR_MACRO (_rl_to_lower)
456FUNCTION_FOR_MACRO (_rl_to_upper)
457FUNCTION_FOR_MACRO (_rl_uppercase_p)
Jari Aaltocce855b1998-04-17 19:52:44 +0000458
Jari Aalto31859422009-01-12 13:36:28 +0000459/* A convenience function, to force memory deallocation to be performed
460 by readline. DLLs on Windows apparently require this. */
461void
462rl_free (mem)
463 void *mem;
464{
465 if (mem)
466 free (mem);
467}
468
Jari Aaltocce855b1998-04-17 19:52:44 +0000469/* Backwards compatibility, now that savestring has been removed from
470 all `public' readline header files. */
471#undef _rl_savestring
472char *
473_rl_savestring (s)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000474 const char *s;
Jari Aaltocce855b1998-04-17 19:52:44 +0000475{
Jari Aaltof73dda02001-11-13 17:56:06 +0000476 return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s)));
Jari Aaltocce855b1998-04-17 19:52:44 +0000477}
Jari Aalto31859422009-01-12 13:36:28 +0000478
479#if defined (USE_VARARGS)
480static FILE *_rl_tracefp;
481
482void
483#if defined (PREFER_STDARG)
484_rl_trace (const char *format, ...)
485#else
486_rl_trace (va_alist)
487 va_dcl
488#endif
489{
490 va_list args;
491#if defined (PREFER_VARARGS)
492 char *format;
493#endif
494
495#if defined (PREFER_STDARG)
496 va_start (args, format);
497#else
498 va_start (args);
499 format = va_arg (args, char *);
500#endif
501
502 if (_rl_tracefp == 0)
503 _rl_tropen ();
504 vfprintf (_rl_tracefp, format, args);
505 fprintf (_rl_tracefp, "\n");
506 fflush (_rl_tracefp);
507
508 va_end (args);
509}
510
511int
512_rl_tropen ()
513{
514 char fnbuf[128];
515
516 if (_rl_tracefp)
517 fclose (_rl_tracefp);
Chet Rameyac50fba2014-02-26 09:36:43 -0500518 sprintf (fnbuf, "/var/tmp/rltrace.%ld", (long)getpid());
Jari Aalto31859422009-01-12 13:36:28 +0000519 unlink(fnbuf);
520 _rl_tracefp = fopen (fnbuf, "w+");
521 return _rl_tracefp != 0;
522}
523
524int
525_rl_trclose ()
526{
527 int r;
528
529 r = fclose (_rl_tracefp);
530 _rl_tracefp = 0;
531 return r;
532}
533
Chet Rameyac50fba2014-02-26 09:36:43 -0500534void
535_rl_settracefp (fp)
536 FILE *fp;
537{
538 _rl_tracefp = fp;
539}
540#endif
541
542
543#if HAVE_DECL_AUDIT_USER_TTY && defined (ENABLE_TTY_AUDIT_SUPPORT)
544#include <sys/socket.h>
545#include <linux/audit.h>
546#include <linux/netlink.h>
547
548/* Report STRING to the audit system. */
549void
550_rl_audit_tty (string)
551 char *string;
552{
553 struct sockaddr_nl addr;
554 struct msghdr msg;
555 struct nlmsghdr nlm;
556 struct iovec iov[2];
557 size_t size;
558 int fd;
559
560 fd = socket (AF_NETLINK, SOCK_RAW, NETLINK_AUDIT);
561 if (fd < 0)
562 return;
563 size = strlen (string) + 1;
564
565 nlm.nlmsg_len = NLMSG_LENGTH (size);
566 nlm.nlmsg_type = AUDIT_USER_TTY;
567 nlm.nlmsg_flags = NLM_F_REQUEST;
568 nlm.nlmsg_seq = 0;
569 nlm.nlmsg_pid = 0;
570
571 iov[0].iov_base = &nlm;
572 iov[0].iov_len = sizeof (nlm);
573 iov[1].iov_base = string;
574 iov[1].iov_len = size;
575
576 addr.nl_family = AF_NETLINK;
577 addr.nl_pid = 0;
578 addr.nl_groups = 0;
579
580 msg.msg_name = &addr;
581 msg.msg_namelen = sizeof (addr);
582 msg.msg_iov = iov;
583 msg.msg_iovlen = 2;
584 msg.msg_control = NULL;
585 msg.msg_controllen = 0;
586 msg.msg_flags = 0;
587
588 (void)sendmsg (fd, &msg, 0);
589 close (fd);
590}
Jari Aalto31859422009-01-12 13:36:28 +0000591#endif