Annotation of embedaddon/readline/util.c, revision 1.1.1.1.2.3
1.1 misho 1: /* util.c -- readline utility functions */
2:
3: /* Copyright (C) 1987-2012 Free Software Foundation, Inc.
4:
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.
7:
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
11: (at your option) any later version.
12:
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
16: GNU General Public License for more details.
17:
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:
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"
47: #include "rlmbutil.h"
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:
56: #include "rlprivate.h"
57: #include "xmalloc.h"
58:
59: /* **************************************************************** */
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:
68: int _rl_allow_pathname_alphabetic_chars = 0;
69: static const char * const pathname_alphabetic_chars = "/-_=~.#$";
70:
71: int
72: rl_alphabetic (c)
73: 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:
82: #if defined (HANDLE_MULTIBYTE)
83: int
84: _rl_walphabetic (wchar_t wc)
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:
97: /* How to abort things. */
98: int
99: _rl_abort_internal ()
100: {
101: rl_ding ();
102: rl_clear_message ();
103: _rl_reset_argument ();
104: rl_clear_pending_input ();
105:
106: RL_UNSETSTATE (RL_STATE_MACRODEF);
107: while (rl_executing_macro)
108: _rl_pop_executing_macro ();
109:
110: rl_last_func = (rl_command_func_t *)NULL;
111: #if defined (HAVE_POSIX_SIGSETJMP)
112: siglongjmp (_rl_top_level, 1);
113: #else
114: longjmp (_rl_top_level, 1);
115: #endif
116: return (0);
117: }
118:
119: int
120: rl_abort (count, key)
121: int count, key;
122: {
123: return (_rl_abort_internal ());
124: }
125:
126: int
127: _rl_null_function (count, key)
128: int count, key;
129: {
130: return 0;
131: }
132:
133: int
134: rl_tty_status (count, key)
135: int count, key;
136: {
137: #if defined (TIOCSTAT)
138: ioctl (1, TIOCSTAT, (char *)0);
139: rl_refresh_line (count, key);
140: #else
141: rl_ding ();
142: #endif
143: return 0;
144: }
145:
146: /* Return a copy of the string between FROM and TO.
147: FROM is inclusive, TO is not. */
148: char *
149: rl_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;
160: copy = (char *)xmalloc (1 + length);
161: 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. */
168: void
169: rl_extend_line_buffer (len)
170: int len;
171: {
172: while (len >= rl_line_buffer_len)
173: {
174: rl_line_buffer_len += DEFAULT_BUFFER_SIZE;
175: rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len);
176: }
177:
178: _rl_set_the_line ();
179: }
180:
181:
182: /* A function for simple tilde expansion. */
183: int
184: rl_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);
198: xfree (homedir);
199: 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;
222: temp = (char *)xmalloc (len + 1);
223: strncpy (temp, rl_line_buffer + start, len);
224: temp[len] = '\0';
225: homedir = tilde_expand (temp);
226: xfree (temp);
227:
228: _rl_replace_text (homedir, start, end);
229: xfree (homedir);
230: }
231:
232: return (0);
233: }
234:
235: #if defined (USE_VARARGS)
236: void
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:
266: void
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 */
295: void
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:
306: void
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:
316: /* **************************************************************** */
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. */
324: char *
325: _rl_strindex (s1, s2)
326: register const char *s1, *s2;
327: {
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)
332: return ((char *) (s1 + i));
333: return ((char *)NULL);
334: }
335:
336: #ifndef HAVE_STRPBRK
337: /* Find the first occurrence in STRING1 of any character from STRING2.
338: Return a pointer to the character in STRING1. */
339: char *
340: _rl_strpbrk (string1, string2)
341: const char *string1, *string2;
342: {
343: register const char *scan;
344: #if defined (HANDLE_MULTIBYTE)
345: mbstate_t ps;
346: register int i, v;
347:
348: memset (&ps, 0, sizeof (mbstate_t));
349: #endif
350:
351: for (; *string1; string1++)
352: {
353: for (scan = string2; *scan; scan++)
354: {
355: if (*string1 == *scan)
356: return ((char *)string1);
357: }
358: #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)
363: string1 += v - 1; /* -1 to account for auto-increment in loop */
364: }
365: #endif
366: }
367: return ((char *)NULL);
368: }
369: #endif
370:
371: #if !defined (HAVE_STRCASECMP)
372: /* Compare at most COUNT characters from string1 to string2. Case
373: doesn't matter (strncasecmp). */
374: int
375: _rl_strnicmp (string1, string2, count)
376: const char *string1;
377: const char *string2;
378: int count;
379: {
380: register const char *s1;
381: register const char *s2;
382: register int d;
383:
384: if (count <= 0 || (string1 == string2))
385: return 0;
386:
387: s1 = string1;
388: s2 = string2;
389: do
390: {
391: 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')
395: break;
396: s2++;
397: }
398: while (--count != 0);
399:
400: return (0);
401: }
402:
403: /* strcmp (), but caseless (strcasecmp). */
404: int
405: _rl_stricmp (string1, string2)
406: const char *string1;
407: const char *string2;
408: {
409: register const char *s1;
410: register const char *s2;
411: register int d;
412:
413: 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)
420: {
421: if (*s1++ == '\0')
422: return 0;
423: s2++;
424: }
425:
426: return (d);
427: }
428: #endif /* !HAVE_STRCASECMP */
429:
430: /* Stupid comparison routine for qsort () ing strings. */
431: int
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:
448: /* Function equivalents for the macros defined in chardefs.h. */
449: #define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); }
450:
451: FUNCTION_FOR_MACRO (_rl_digit_p)
452: FUNCTION_FOR_MACRO (_rl_digit_value)
453: FUNCTION_FOR_MACRO (_rl_lowercase_p)
454: FUNCTION_FOR_MACRO (_rl_pure_alphabetic)
455: FUNCTION_FOR_MACRO (_rl_to_lower)
456: FUNCTION_FOR_MACRO (_rl_to_upper)
457: FUNCTION_FOR_MACRO (_rl_uppercase_p)
458:
459: /* A convenience function, to force memory deallocation to be performed
460: by readline. DLLs on Windows apparently require this. */
461: void
462: rl_free (mem)
463: void *mem;
464: {
465: if (mem)
466: free (mem);
467: }
468:
469: /* Backwards compatibility, now that savestring has been removed from
470: all `public' readline header files. */
471: #undef _rl_savestring
472: char *
473: _rl_savestring (s)
474: const char *s;
475: {
476: return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s)));
477: }
478:
1.1.1.1.2.3! misho 479: #if defined (DEBUG)
1.1 misho 480: #if defined (USE_VARARGS)
481: static FILE *_rl_tracefp;
482:
483: void
484: #if defined (PREFER_STDARG)
485: _rl_trace (const char *format, ...)
486: #else
487: _rl_trace (va_alist)
488: va_dcl
489: #endif
490: {
491: va_list args;
492: #if defined (PREFER_VARARGS)
493: char *format;
494: #endif
495:
496: #if defined (PREFER_STDARG)
497: va_start (args, format);
498: #else
499: va_start (args);
500: format = va_arg (args, char *);
501: #endif
502:
503: if (_rl_tracefp == 0)
504: _rl_tropen ();
505: vfprintf (_rl_tracefp, format, args);
506: fprintf (_rl_tracefp, "\n");
507: fflush (_rl_tracefp);
508:
509: va_end (args);
510: }
511:
512: int
513: _rl_tropen ()
514: {
515: char fnbuf[128];
516:
517: if (_rl_tracefp)
518: fclose (_rl_tracefp);
519: sprintf (fnbuf, "/var/tmp/rltrace.%ld", (long)getpid());
520: unlink(fnbuf);
521: _rl_tracefp = fopen (fnbuf, "w+");
522: return _rl_tracefp != 0;
523: }
524:
525: int
526: _rl_trclose ()
527: {
528: int r;
529:
530: r = fclose (_rl_tracefp);
531: _rl_tracefp = 0;
532: return r;
533: }
534:
535: void
536: _rl_settracefp (fp)
537: FILE *fp;
538: {
539: _rl_tracefp = fp;
540: }
541: #endif
1.1.1.1.2.3! misho 542: #endif /* DEBUG */
1.1 misho 543:
544:
545: #if HAVE_DECL_AUDIT_USER_TTY && defined (ENABLE_TTY_AUDIT_SUPPORT)
546: #include <sys/socket.h>
547: #include <linux/audit.h>
548: #include <linux/netlink.h>
549:
550: /* Report STRING to the audit system. */
551: void
552: _rl_audit_tty (string)
553: char *string;
554: {
555: struct sockaddr_nl addr;
556: struct msghdr msg;
557: struct nlmsghdr nlm;
558: struct iovec iov[2];
559: size_t size;
560: int fd;
561:
562: fd = socket (AF_NETLINK, SOCK_RAW, NETLINK_AUDIT);
563: if (fd < 0)
564: return;
565: size = strlen (string) + 1;
566:
567: nlm.nlmsg_len = NLMSG_LENGTH (size);
568: nlm.nlmsg_type = AUDIT_USER_TTY;
569: nlm.nlmsg_flags = NLM_F_REQUEST;
570: nlm.nlmsg_seq = 0;
571: nlm.nlmsg_pid = 0;
572:
573: iov[0].iov_base = &nlm;
574: iov[0].iov_len = sizeof (nlm);
575: iov[1].iov_base = string;
576: iov[1].iov_len = size;
577:
578: addr.nl_family = AF_NETLINK;
579: addr.nl_pid = 0;
580: addr.nl_groups = 0;
581:
582: msg.msg_name = &addr;
583: msg.msg_namelen = sizeof (addr);
584: msg.msg_iov = iov;
585: msg.msg_iovlen = 2;
586: msg.msg_control = NULL;
587: msg.msg_controllen = 0;
588: msg.msg_flags = 0;
589:
590: (void)sendmsg (fd, &msg, 0);
591: close (fd);
592: }
593: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>