]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - readline/readline/util.c
Move readline to the readline/readline subdirectory
[thirdparty/binutils-gdb.git] / readline / readline / util.c
CommitLineData
d60d9f65
SS
1/* util.c -- readline utility functions */
2
cb41b9e7 3/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
d60d9f65 4
cc88a640
JK
5 This file is part of the GNU Readline Library (Readline), a library
6 for reading lines of text with interactive input and history editing.
d60d9f65 7
cc88a640
JK
8 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
d60d9f65
SS
11 (at your option) any later version.
12
cc88a640
JK
13 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
d60d9f65
SS
16 GNU General Public License for more details.
17
cc88a640
JK
18 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
d60d9f65
SS
22#define READLINE_LIBRARY
23
24#if defined (HAVE_CONFIG_H)
25# include <config.h>
26#endif
27
28#include <sys/types.h>
29#include <fcntl.h>
30#include "posixjmp.h"
31
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
42#include <stdio.h>
43#include <ctype.h>
44
45/* System-specific feature definitions and include files. */
46#include "rldefs.h"
5bdf8622 47#include "rlmbutil.h"
d60d9f65
SS
48
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
1b17e766
EZ
56#include "rlprivate.h"
57#include "xmalloc.h"
7f3c5ec8 58#include "rlshell.h"
d60d9f65 59
d60d9f65
SS
60/* **************************************************************** */
61/* */
62/* Utility Functions */
63/* */
64/* **************************************************************** */
65
66/* Return 0 if C is not a member of the class of characters that belong
67 in words, or 1 if it is. */
68
69int _rl_allow_pathname_alphabetic_chars = 0;
cc88a640 70static const char * const pathname_alphabetic_chars = "/-_=~.#$";
d60d9f65
SS
71
72int
cb41b9e7 73rl_alphabetic (int c)
d60d9f65
SS
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
5bdf8622
DJ
82#if defined (HANDLE_MULTIBYTE)
83int
cc88a640 84_rl_walphabetic (wchar_t wc)
5bdf8622
DJ
85{
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
d60d9f65
SS
97/* How to abort things. */
98int
cb41b9e7 99_rl_abort_internal (void)
d60d9f65 100{
9255ee31 101 rl_ding ();
d60d9f65 102 rl_clear_message ();
5bdf8622 103 _rl_reset_argument ();
9255ee31 104 rl_clear_pending_input ();
d60d9f65 105
9255ee31
EZ
106 RL_UNSETSTATE (RL_STATE_MACRODEF);
107 while (rl_executing_macro)
d60d9f65
SS
108 _rl_pop_executing_macro ();
109
775e241e
TT
110 RL_UNSETSTATE (RL_STATE_MULTIKEY); /* XXX */
111
9255ee31 112 rl_last_func = (rl_command_func_t *)NULL;
775e241e
TT
113
114 _rl_longjmp (_rl_top_level, 1);
d60d9f65
SS
115 return (0);
116}
117
118int
cb41b9e7 119rl_abort (int count, int key)
d60d9f65
SS
120{
121 return (_rl_abort_internal ());
122}
123
cc88a640 124int
cb41b9e7 125_rl_null_function (int count, int key)
cc88a640
JK
126{
127 return 0;
128}
129
d60d9f65 130int
cb41b9e7 131rl_tty_status (int count, int key)
d60d9f65
SS
132{
133#if defined (TIOCSTAT)
134 ioctl (1, TIOCSTAT, (char *)0);
c862e87b 135 rl_refresh_line (count, key);
d60d9f65 136#else
9255ee31 137 rl_ding ();
d60d9f65
SS
138#endif
139 return 0;
140}
141
142/* Return a copy of the string between FROM and TO.
143 FROM is inclusive, TO is not. */
144char *
cb41b9e7 145rl_copy_text (int from, int to)
d60d9f65
SS
146{
147 register int length;
148 char *copy;
149
150 /* Fix it if the caller is confused. */
151 if (from > to)
152 SWAP (from, to);
153
154 length = to - from;
9255ee31 155 copy = (char *)xmalloc (1 + length);
d60d9f65
SS
156 strncpy (copy, rl_line_buffer + from, length);
157 copy[length] = '\0';
158 return (copy);
159}
160
161/* Increase the size of RL_LINE_BUFFER until it has enough space to hold
162 LEN characters. */
163void
cb41b9e7 164rl_extend_line_buffer (int len)
d60d9f65
SS
165{
166 while (len >= rl_line_buffer_len)
167 {
168 rl_line_buffer_len += DEFAULT_BUFFER_SIZE;
9255ee31 169 rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len);
d60d9f65
SS
170 }
171
172 _rl_set_the_line ();
173}
174
175
176/* A function for simple tilde expansion. */
177int
cb41b9e7 178rl_tilde_expand (int ignore, int key)
d60d9f65
SS
179{
180 register int start, end;
181 char *homedir, *temp;
182 int len;
183
184 end = rl_point;
185 start = end - 1;
186
187 if (rl_point == rl_end && rl_line_buffer[rl_point] == '~')
188 {
189 homedir = tilde_expand ("~");
190 _rl_replace_text (homedir, start, end);
cc88a640 191 xfree (homedir);
d60d9f65
SS
192 return (0);
193 }
775e241e 194 else if (start >= 0 && rl_line_buffer[start] != '~')
d60d9f65 195 {
cb41b9e7 196 for (; start >= 0 && !whitespace (rl_line_buffer[start]); start--)
d60d9f65
SS
197 ;
198 start++;
199 }
775e241e
TT
200 else if (start < 0)
201 start = 0;
d60d9f65
SS
202
203 end = start;
204 do
205 end++;
206 while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end);
207
208 if (whitespace (rl_line_buffer[end]) || end >= rl_end)
209 end--;
210
211 /* If the first character of the current word is a tilde, perform
212 tilde expansion and insert the result. If not a tilde, do
213 nothing. */
214 if (rl_line_buffer[start] == '~')
215 {
216 len = end - start + 1;
9255ee31 217 temp = (char *)xmalloc (len + 1);
d60d9f65
SS
218 strncpy (temp, rl_line_buffer + start, len);
219 temp[len] = '\0';
220 homedir = tilde_expand (temp);
cc88a640 221 xfree (temp);
d60d9f65
SS
222
223 _rl_replace_text (homedir, start, end);
cc88a640 224 xfree (homedir);
d60d9f65
SS
225 }
226
227 return (0);
228}
229
cc88a640
JK
230#if defined (USE_VARARGS)
231void
232#if defined (PREFER_STDARG)
233_rl_ttymsg (const char *format, ...)
234#else
235_rl_ttymsg (va_alist)
236 va_dcl
237#endif
238{
239 va_list args;
240#if defined (PREFER_VARARGS)
241 char *format;
242#endif
243
244#if defined (PREFER_STDARG)
245 va_start (args, format);
246#else
247 va_start (args);
248 format = va_arg (args, char *);
249#endif
250
251 fprintf (stderr, "readline: ");
252 vfprintf (stderr, format, args);
253 fprintf (stderr, "\n");
254 fflush (stderr);
255
256 va_end (args);
257
258 rl_forced_update_display ();
259}
260
261void
262#if defined (PREFER_STDARG)
263_rl_errmsg (const char *format, ...)
264#else
265_rl_errmsg (va_alist)
266 va_dcl
267#endif
268{
269 va_list args;
270#if defined (PREFER_VARARGS)
271 char *format;
272#endif
273
274#if defined (PREFER_STDARG)
275 va_start (args, format);
276#else
277 va_start (args);
278 format = va_arg (args, char *);
279#endif
280
281 fprintf (stderr, "readline: ");
282 vfprintf (stderr, format, args);
283 fprintf (stderr, "\n");
284 fflush (stderr);
285
286 va_end (args);
287}
288
289#else /* !USE_VARARGS */
290void
291_rl_ttymsg (format, arg1, arg2)
292 char *format;
293{
294 fprintf (stderr, "readline: ");
295 fprintf (stderr, format, arg1, arg2);
296 fprintf (stderr, "\n");
297
298 rl_forced_update_display ();
299}
300
301void
302_rl_errmsg (format, arg1, arg2)
303 char *format;
304{
305 fprintf (stderr, "readline: ");
306 fprintf (stderr, format, arg1, arg2);
307 fprintf (stderr, "\n");
308}
309#endif /* !USE_VARARGS */
310
d60d9f65
SS
311/* **************************************************************** */
312/* */
313/* String Utility Functions */
314/* */
315/* **************************************************************** */
316
317/* Determine if s2 occurs in s1. If so, return a pointer to the
318 match in s1. The compare is case insensitive. */
319char *
cb41b9e7 320_rl_strindex (const char *s1, const char *s2)
d60d9f65
SS
321{
322 register int i, l, len;
323
324 for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++)
325 if (_rl_strnicmp (s1 + i, s2, l) == 0)
9255ee31 326 return ((char *) (s1 + i));
d60d9f65
SS
327 return ((char *)NULL);
328}
329
9255ee31
EZ
330#ifndef HAVE_STRPBRK
331/* Find the first occurrence in STRING1 of any character from STRING2.
332 Return a pointer to the character in STRING1. */
333char *
cb41b9e7 334_rl_strpbrk (const char *string1, const char *string2)
9255ee31
EZ
335{
336 register const char *scan;
337#if defined (HANDLE_MULTIBYTE)
338 mbstate_t ps;
339 register int i, v;
340
341 memset (&ps, 0, sizeof (mbstate_t));
342#endif
343
344 for (; *string1; string1++)
345 {
346 for (scan = string2; *scan; scan++)
347 {
348 if (*string1 == *scan)
349 return ((char *)string1);
350 }
351#if defined (HANDLE_MULTIBYTE)
352 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
353 {
354 v = _rl_get_char_len (string1, &ps);
355 if (v > 1)
5bdf8622 356 string1 += v - 1; /* -1 to account for auto-increment in loop */
9255ee31
EZ
357 }
358#endif
359 }
360 return ((char *)NULL);
361}
362#endif
363
d60d9f65
SS
364#if !defined (HAVE_STRCASECMP)
365/* Compare at most COUNT characters from string1 to string2. Case
cc88a640 366 doesn't matter (strncasecmp). */
d60d9f65 367int
cb41b9e7 368_rl_strnicmp (const char *string1, const char *string2, int count)
d60d9f65 369{
775e241e
TT
370 register const char *s1;
371 register const char *s2;
372 register int d;
d60d9f65 373
cc88a640
JK
374 if (count <= 0 || (string1 == string2))
375 return 0;
376
377 s1 = string1;
378 s2 = string2;
379 do
d60d9f65 380 {
cc88a640
JK
381 d = _rl_to_lower (*s1) - _rl_to_lower (*s2); /* XXX - cast to unsigned char? */
382 if (d != 0)
383 return d;
384 if (*s1++ == '\0')
d60d9f65 385 break;
cc88a640 386 s2++;
d60d9f65 387 }
ab3a7f8f 388 while (--count != 0);
cc88a640
JK
389
390 return (0);
d60d9f65
SS
391}
392
cc88a640 393/* strcmp (), but caseless (strcasecmp). */
d60d9f65 394int
cb41b9e7 395_rl_stricmp (const char *string1, const char *string2)
d60d9f65 396{
775e241e
TT
397 register const char *s1;
398 register const char *s2;
399 register int d;
cc88a640
JK
400
401 s1 = string1;
402 s2 = string2;
d60d9f65 403
cc88a640
JK
404 if (s1 == s2)
405 return 0;
406
407 while ((d = _rl_to_lower (*s1) - _rl_to_lower (*s2)) == 0)
d60d9f65 408 {
cc88a640
JK
409 if (*s1++ == '\0')
410 return 0;
411 s2++;
d60d9f65 412 }
cc88a640
JK
413
414 return (d);
d60d9f65
SS
415}
416#endif /* !HAVE_STRCASECMP */
417
418/* Stupid comparison routine for qsort () ing strings. */
419int
cb41b9e7 420_rl_qsort_string_compare (char **s1, char **s2)
d60d9f65
SS
421{
422#if defined (HAVE_STRCOLL)
423 return (strcoll (*s1, *s2));
424#else
425 int result;
426
427 result = **s1 - **s2;
428 if (result == 0)
429 result = strcmp (*s1, *s2);
430
431 return result;
432#endif
433}
434
9255ee31 435/* Function equivalents for the macros defined in chardefs.h. */
cb41b9e7 436#define FUNCTION_FOR_MACRO(f) int (f) (int c) { return f (c); }
d60d9f65 437
9255ee31
EZ
438FUNCTION_FOR_MACRO (_rl_digit_p)
439FUNCTION_FOR_MACRO (_rl_digit_value)
440FUNCTION_FOR_MACRO (_rl_lowercase_p)
441FUNCTION_FOR_MACRO (_rl_pure_alphabetic)
442FUNCTION_FOR_MACRO (_rl_to_lower)
443FUNCTION_FOR_MACRO (_rl_to_upper)
444FUNCTION_FOR_MACRO (_rl_uppercase_p)
d60d9f65 445
cc88a640
JK
446/* A convenience function, to force memory deallocation to be performed
447 by readline. DLLs on Windows apparently require this. */
448void
cb41b9e7 449rl_free (void *mem)
cc88a640
JK
450{
451 if (mem)
452 free (mem);
453}
454
d60d9f65
SS
455/* Backwards compatibility, now that savestring has been removed from
456 all `public' readline header files. */
457#undef _rl_savestring
458char *
cb41b9e7 459_rl_savestring (const char *s)
d60d9f65 460{
9255ee31 461 return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s)));
d60d9f65 462}
cc88a640 463
775e241e 464#if defined (DEBUG)
cc88a640
JK
465#if defined (USE_VARARGS)
466static FILE *_rl_tracefp;
467
468void
469#if defined (PREFER_STDARG)
470_rl_trace (const char *format, ...)
471#else
472_rl_trace (va_alist)
473 va_dcl
474#endif
475{
476 va_list args;
477#if defined (PREFER_VARARGS)
478 char *format;
479#endif
480
481#if defined (PREFER_STDARG)
482 va_start (args, format);
483#else
484 va_start (args);
485 format = va_arg (args, char *);
486#endif
487
488 if (_rl_tracefp == 0)
489 _rl_tropen ();
490 vfprintf (_rl_tracefp, format, args);
491 fprintf (_rl_tracefp, "\n");
492 fflush (_rl_tracefp);
493
494 va_end (args);
495}
496
497int
cb41b9e7 498_rl_tropen (void)
cc88a640 499{
775e241e 500 char fnbuf[128], *x;
cc88a640
JK
501
502 if (_rl_tracefp)
503 fclose (_rl_tracefp);
7f3c5ec8
EZ
504#if defined (_WIN32) && !defined (__CYGWIN__)
505 /* Windows doesn't have /var/tmp, so open the trace file in the
506 user's temporary directory instead. */
cb41b9e7 507 snprintf (fnbuf, sizeof (fnbuf), "%s/rltrace.%ld",
7f3c5ec8
EZ
508 (sh_get_env_value ("TEMP")
509 ? sh_get_env_value ("TEMP")
510 : "."),
16bfc2f9 511 getpid ());
7f3c5ec8 512#else
16bfc2f9 513 sprintf (fnbuf, "/var/tmp/rltrace.%ld", (long) getpid ());
7f3c5ec8 514#endif
16bfc2f9 515 unlink (fnbuf);
cc88a640
JK
516 _rl_tracefp = fopen (fnbuf, "w+");
517 return _rl_tracefp != 0;
518}
519
520int
cb41b9e7 521_rl_trclose (void)
cc88a640
JK
522{
523 int r;
524
525 r = fclose (_rl_tracefp);
526 _rl_tracefp = 0;
527 return r;
528}
529
775e241e 530void
cb41b9e7 531_rl_settracefp (FILE *fp)
775e241e
TT
532{
533 _rl_tracefp = fp;
534}
535#endif
536#endif /* DEBUG */
537
538
539#if HAVE_DECL_AUDIT_USER_TTY && defined (HAVE_LIBAUDIT_H) && defined (ENABLE_TTY_AUDIT_SUPPORT)
540#include <sys/socket.h>
541#include <libaudit.h>
542#include <linux/audit.h>
543#include <linux/netlink.h>
544
545/* Report STRING to the audit system. */
546void
cb41b9e7 547_rl_audit_tty (char *string)
775e241e
TT
548{
549 struct audit_message req;
550 struct sockaddr_nl addr;
551 size_t size;
552 int fd;
553
554 fd = socket (PF_NETLINK, SOCK_RAW, NETLINK_AUDIT);
555 if (fd < 0)
556 return;
557 size = strlen (string) + 1;
558
559 if (NLMSG_SPACE (size) > MAX_AUDIT_MESSAGE_LENGTH)
560 return;
561
562 memset (&req, 0, sizeof(req));
563 req.nlh.nlmsg_len = NLMSG_SPACE (size);
564 req.nlh.nlmsg_type = AUDIT_USER_TTY;
565 req.nlh.nlmsg_flags = NLM_F_REQUEST;
566 req.nlh.nlmsg_seq = 0;
567 if (size && string)
568 memcpy (NLMSG_DATA(&req.nlh), string, size);
569 memset (&addr, 0, sizeof(addr));
570
571 addr.nl_family = AF_NETLINK;
572 addr.nl_pid = 0;
573 addr.nl_groups = 0;
574
575 sendto (fd, &req, req.nlh.nlmsg_len, 0, (struct sockaddr*)&addr, sizeof(addr));
576 close (fd);
577}
cc88a640 578#endif